Index: stable/11/contrib/elftoolchain/.cirrus.yml =================================================================== --- stable/11/contrib/elftoolchain/.cirrus.yml (nonexistent) +++ stable/11/contrib/elftoolchain/.cirrus.yml (revision 367466) @@ -0,0 +1,22 @@ +freebsd_11_task: + freebsd_instance: + image: freebsd-11-2-release-amd64 + install_script: pkg install -y git py27-yaml + script: + - fetch http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz + - tar -x -C test/tet -f tet3.8-src.tar.gz + - make + +debian_stable_task: + container: + image: debian:stable + setup_script: + - apt-get update + - apt-get install -y + binutils bison bmake curl flex g++ gcc git + libarchive-dev libbsd-dev libc6-dev libexpat1-dev lsb-release + m4 perl python-yaml sharutils zlib1g-dev + script: + - curl -O http://tetworks.opengroup.org/downloads/38/software/Sources/3.8/tet3.8-src.tar.gz + - tar -x -C test/tet -z -f tet3.8-src.tar.gz + - bmake Index: stable/11/contrib/elftoolchain/README.rst =================================================================== --- stable/11/contrib/elftoolchain/README.rst (nonexistent) +++ stable/11/contrib/elftoolchain/README.rst (revision 367466) @@ -0,0 +1,126 @@ +The Elftoolchain Project +======================== + +.. contents:: Table of Contents + +Description +----------- + +This software implements essential compilation tools and libraries for: + +- managing program objects conforming to the ELF_ object format, and +- for managing DWARF_ debugging information in ELF objects. + +The project currently implements the following utilities and +libraries: + +=========== ============================================ +Name Description +=========== ============================================ +ar Archive manager. +addr2line Debug tool. +brandelf Manage the ELF brand on executables. +c++filt Translate encoded symbols. +elfcopy Copy and translate between object formats. +elfdump Diagnostic tool. +findtextrel Find undesired text relocations. +libdwarf DWARF access library. +libelf ELF access library. +mcs Manage comment sections. +nm List symbols in an ELF object. +ranlib Add archive symbol tables to an archive. +readelf Display ELF information. +size List object sizes. +strings Extract printable strings. +strip Discard information from ELF objects. +=========== ============================================ + +.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format +.. _DWARF: http://www.dwarfstd.org/ + + +Project Documentation +--------------------- + +- Release notes for released versions of this software are present in + the file ``RELEASE-NOTES`` in the current directory. +- The file ``INSTALL`` in the current directory contains instructions + on building and installing this software. +- Reference documentation in the form of manual pages is provided for + the utilities and libraries developed by the project. +- Additional tutorial documentation is present in the + ``documentation`` directory. + + +Tracking Ongoing Development +---------------------------- + +The project uses subversion_ for its version control system. + +.. _subversion: https://subversion.apache.org/ + +The subversion branch for the current set of sources may be accessed +at the following URL:: + + https://sourceforge.net/p/elftoolchain/code/HEAD/tree/trunk/ + +The project's source tree may be checked out from its repository by +using the ``svn checkout`` command:: + + % svn checkout https://svn.code.sf.net/p/elftoolchain/code/trunk + +Checked-out sources may be kept upto-date by running ``svn update`` +inside the source directory:: + + % svn update + + +Instructions on building and installing the software are given in the +file ``INSTALL`` in the current directory. + +Downloading Released Software +----------------------------- + +Released versions of the project's software may also be downloaded +from SourceForge's `file release system`_. + +.. _file release system: http://sourceforge.net/projects/elftoolchain/files/ + +Copyright and License +--------------------- + +This code is copyright its authors, and is distributed under the `BSD +License`_. + +.. _BSD License: http://www.opensource.org/licenses/bsd-license.php + + +Developer Community +------------------- + +The project's developers may be contacted using the mailing list: +````. + + +Reporting Bugs +-------------- + +Please use our `bug tracker`_ for viewing existing bug reports and +for submitting new bug reports. + +.. _`bug tracker`: https://sourceforge.net/p/elftoolchain/tickets/ + + +Additional Information +---------------------- + +Additional information about the project may be found on the `project +website`_. + +.. _project website: http://elftoolchain.sourceforge.net/ + +.. $Id: README.rst 3677 2019-02-11 09:37:09Z jkoshy $ + +.. Local Variables: +.. mode: rst +.. End: Index: stable/11/contrib/elftoolchain/addr2line/addr2line.1 =================================================================== --- stable/11/contrib/elftoolchain/addr2line/addr2line.1 (revision 367465) +++ stable/11/contrib/elftoolchain/addr2line/addr2line.1 (revision 367466) @@ -1,182 +1,182 @@ .\" Copyright (c) 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 .\" in this position and unchanged. .\" 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 AUTHORS ``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 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: addr2line.1 3263 2015-11-30 04:25:54Z kaiwang27 $ +.\" $Id: addr2line.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" .Dd November 30, 2015 -.Os .Dt ADDR2LINE 1 +.Os .Sh NAME .Nm addr2line .Nd translate program addresses to source file names and line numbers .Sh SYNOPSIS .Nm .Op Fl a | Fl -addresses .Op Fl b Ar target | Fl -target Ns = Ns Ar target .Op Fl e Ar pathname | Fl -exe Ns = Ns Ar pathname .Op Fl f | Fl -functions .Op Fl i | Fl -inlines .Op Fl j Ar sectionname | Fl -section Ns = Ns Ar sectionname .Op Fl p | Fl -pretty-print .Op Fl s | Fl -basename .Op Fl C | Fl -demangle .Op Fl H | Fl -help .Op Fl V | Fl -version .Op Ar hexaddress Ns ... .Sh DESCRIPTION The .Nm utility translates program addresses specified by the command line arguments .Ar hexaddress to their corresponding source file names and line numbers. If no arguments are given to .Nm , it will read these addresses from standard input. .Pp Program addresses specified by arguments .Ar hexaddress are encoded using the conventions accepted by .Xr strtoull 3 . .Pp By default, .Nm will use the executable .Dq Pa a.out . The .Fl e option may be used to specified a different ELF object. .Pp The .Nm utility recognizes the following options: .Bl -tag -width indent .It Fl a | Fl -addresses Display the address prior to the line number information. .It Fl b Ar target | Fl -target Ns = Ns Ar target This option is recognized by .Nm but is ignored. It is supported for compatibility with GNU binutils. .It Fl e Ar pathname | Fl -exe Ns = Ns Ar pathname Use the ELF object specified by argument .Ar pathname to translate addresses. If this option is not specified, .Nm will use the file .Dq Pa a.out . .It Fl f | Fl -functions Display function names in addition to file and line number information. .It Fl i | Fl -inlines If the address specified belongs to an inlined function, also display the line number information for its caller, recursively until the first non-inlined caller. .It Fl j Ar sectionname | Fl -section Ns = Ns Ar sectionname The values specified by arguments .Ar hexaddress are to be treated as offsets into the section named .Ar sectionname . .It Fl p | -pretty-print Display the line number information on one line, in human readable manner. .It Fl s | -basename Display only the base name for each file name. .It Fl C | Fl -demangle Demangle C++ names. .It Fl H | Fl -help Print a help message. .It Fl V | Fl -version Print a version identifier and exit. .El .Sh OUTPUT FORMAT If the .Fl f option was not specified, .Nm will print the file name and line number for each address specified on a separate line. .Pp If the .Fl f option was specified, .Nm will print a line containing the name of the function corresponding to program address .Ar hexaddress , followed by a line with the file name and line number. .Pp If the .Fl p option was specified, .Nm will print line number information and function name on one line in human readable manner. If the .Fl i option was also specified, .Nm will print the caller function information prefixed with .Dq (inlined by) . .Pp The .Nm utility prints the file name and line number using the format .Dq FILENAME:LINENUMBER . .Pp If a file or function name could not be determined, .Nm will print a question mark in their place. If the line number could not be determined, .Nm will print a zero in its place. .Sh EXAMPLES To map address 080483c4 in the default executable .Pa a.out to a source file name and line number use: .D1 "% addr2line 080483c4" .Pp To map address 080483c4 in executable .Pa helloworld , use: .D1 "% addr2line -e helloworld 080483c4" .Pp To have .Nm act as a filter reading addresses from its standard input use: .D1 "% addr2line" .Pp To print the function name corresponding to an address in addition to its source file and line number use: .D1 "% addr2line -f 080483c4" .Sh EXIT STATUS .Ex -std .Sh SEE ALSO .Xr nm 1 , .Xr elfdump 1 , .Xr elfcopy 1 , .Xr strtoull 3 .Sh AUTHORS The .Nm utility was written by .An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . Index: stable/11/contrib/elftoolchain/addr2line/addr2line.c =================================================================== --- stable/11/contrib/elftoolchain/addr2line/addr2line.c (revision 367465) +++ stable/11/contrib/elftoolchain/addr2line/addr2line.c (revision 367466) @@ -1,734 +1,838 @@ /*- * Copyright (c) 2009 Kai Wang * 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 #include -#include "uthash.h" #include "_elftc.h" ELFTC_VCSID("$Id: addr2line.c 3499 2016-11-25 16:06:29Z emaste $"); struct Func { char *name; Dwarf_Unsigned lopc; Dwarf_Unsigned hipc; Dwarf_Unsigned call_file; Dwarf_Unsigned call_line; Dwarf_Ranges *ranges; Dwarf_Signed ranges_cnt; struct Func *inlined_caller; STAILQ_ENTRY(Func) next; }; struct CU { + RB_ENTRY(CU) entry; Dwarf_Off off; Dwarf_Unsigned lopc; Dwarf_Unsigned hipc; char **srcfiles; Dwarf_Signed nsrcfiles; STAILQ_HEAD(, Func) funclist; - UT_hash_handle hh; + Dwarf_Die die; + Dwarf_Debug dbg; }; static struct option longopts[] = { {"addresses", no_argument, NULL, 'a'}, {"target" , required_argument, NULL, 'b'}, {"demangle", no_argument, NULL, 'C'}, {"exe", required_argument, NULL, 'e'}, {"functions", no_argument, NULL, 'f'}, {"inlines", no_argument, NULL, 'i'}, {"section", required_argument, NULL, 'j'}, {"pretty-print", no_argument, NULL, 'p'}, {"basename", no_argument, NULL, 's'}, {"help", no_argument, NULL, 'H'}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; + static int demangle, func, base, inlines, print_addr, pretty_print; static char unknown[] = { '?', '?', '\0' }; static Dwarf_Addr section_base; -static struct CU *culist; +/* Need a new curlopc that stores last lopc value. */ +static Dwarf_Unsigned curlopc = ~0ULL; +static RB_HEAD(cutree, CU) cuhead = RB_INITIALIZER(&cuhead); +static int +lopccmp(struct CU *e1, struct CU *e2) +{ + return (e1->lopc < e2->lopc ? -1 : e1->lopc > e2->lopc); +} + +RB_PROTOTYPE(cutree, CU, entry, lopccmp); +RB_GENERATE(cutree, CU, entry, lopccmp) + #define USAGE_MESSAGE "\ Usage: %s [options] hexaddress...\n\ Map program addresses to source file names and line numbers.\n\n\ Options:\n\ -a | --addresses Display address prior to line number info.\n\ -b TGT | --target=TGT (Accepted but ignored).\n\ -e EXE | --exe=EXE Use program \"EXE\" to translate addresses.\n\ -f | --functions Display function names.\n\ -i | --inlines Display caller info for inlined functions.\n\ -j NAME | --section=NAME Values are offsets into section \"NAME\".\n\ -p | --pretty-print Display line number info and function name\n\ in human readable manner.\n\ -s | --basename Only show the base name for each file name.\n\ -C | --demangle Demangle C++ names.\n\ -H | --help Print a help message.\n\ -V | --version Print a version identifier and exit.\n" static void usage(void) { (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(1); } static void version(void) { fprintf(stderr, "%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); exit(0); } /* * Handle DWARF 4 'offset from' DW_AT_high_pc. Although we don't * fully support DWARF 4, some compilers (like FreeBSD Clang 3.5.1) * generate DW_AT_high_pc as an offset from DW_AT_low_pc. * * "If the value of the DW_AT_high_pc is of class address, it is the * relocated address of the first location past the last instruction * associated with the entity; if it is of class constant, the value * is an unsigned integer offset which when added to the low PC gives * the address of the first location past the last instruction * associated with the entity." * * DWARF4 spec, section 2.17.2. */ static int handle_high_pc(Dwarf_Die die, Dwarf_Unsigned lopc, Dwarf_Unsigned *hipc) { Dwarf_Error de; Dwarf_Half form; Dwarf_Attribute at; int ret; ret = dwarf_attr(die, DW_AT_high_pc, &at, &de); if (ret == DW_DLV_ERROR) { warnx("dwarf_attr failed: %s", dwarf_errmsg(de)); return (ret); } ret = dwarf_whatform(at, &form, &de); if (ret == DW_DLV_ERROR) { warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); return (ret); } if (dwarf_get_form_class(2, 0, 0, form) == DW_FORM_CLASS_CONSTANT) *hipc += lopc; return (DW_DLV_OK); } static struct Func * search_func(struct CU *cu, Dwarf_Unsigned addr) { struct Func *f, *f0; Dwarf_Unsigned lopc, hipc, addr_base; int i; f0 = NULL; STAILQ_FOREACH(f, &cu->funclist, next) { if (f->ranges != NULL) { addr_base = 0; for (i = 0; i < f->ranges_cnt; i++) { if (f->ranges[i].dwr_type == DW_RANGES_END) break; if (f->ranges[i].dwr_type == DW_RANGES_ADDRESS_SELECTION) { addr_base = f->ranges[i].dwr_addr2; continue; } /* DW_RANGES_ENTRY */ lopc = f->ranges[i].dwr_addr1 + addr_base; hipc = f->ranges[i].dwr_addr2 + addr_base; if (addr >= lopc && addr < hipc) { if (f0 == NULL || (lopc >= f0->lopc && hipc <= f0->hipc)) { f0 = f; f0->lopc = lopc; f0->hipc = hipc; break; } } } } else if (addr >= f->lopc && addr < f->hipc) { if (f0 == NULL || (f->lopc >= f0->lopc && f->hipc <= f0->hipc)) f0 = f; } } return (f0); } static void collect_func(Dwarf_Debug dbg, Dwarf_Die die, struct Func *parent, struct CU *cu) { Dwarf_Die ret_die, abst_die, spec_die; Dwarf_Error de; Dwarf_Half tag; Dwarf_Unsigned lopc, hipc, ranges_off; Dwarf_Signed ranges_cnt; Dwarf_Off ref; Dwarf_Attribute abst_at, spec_at; Dwarf_Ranges *ranges; const char *funcname; struct Func *f; int found_ranges, ret; f = NULL; abst_die = spec_die = NULL; if (dwarf_tag(die, &tag, &de)) { warnx("dwarf_tag: %s", dwarf_errmsg(de)); goto cont_search; } if (tag == DW_TAG_subprogram || tag == DW_TAG_entry_point || tag == DW_TAG_inlined_subroutine) { /* * Function address range can be specified by either * a DW_AT_ranges attribute which points to a range list or * by a pair of DW_AT_low_pc and DW_AT_high_pc attributes. */ ranges = NULL; ranges_cnt = 0; found_ranges = 0; if (dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off, &de) == DW_DLV_OK && dwarf_get_ranges(dbg, (Dwarf_Off) ranges_off, &ranges, &ranges_cnt, NULL, &de) == DW_DLV_OK) { if (ranges != NULL && ranges_cnt > 0) { found_ranges = 1; goto get_func_name; } } /* * Search for DW_AT_low_pc/DW_AT_high_pc if ranges pointer * not found. */ if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) || dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, &de)) goto cont_search; if (handle_high_pc(die, lopc, &hipc) != DW_DLV_OK) goto cont_search; get_func_name: /* * Most common case the function name is stored in DW_AT_name * attribute. */ if (dwarf_attrval_string(die, DW_AT_name, &funcname, &de) == DW_DLV_OK) goto add_func; /* * For inlined function, the actual name is probably in the DIE * referenced by DW_AT_abstract_origin. (if present) */ if (dwarf_attr(die, DW_AT_abstract_origin, &abst_at, &de) == DW_DLV_OK && dwarf_global_formref(abst_at, &ref, &de) == DW_DLV_OK && dwarf_offdie(dbg, ref, &abst_die, &de) == DW_DLV_OK && dwarf_attrval_string(abst_die, DW_AT_name, &funcname, &de) == DW_DLV_OK) goto add_func; /* * If DW_AT_name is not present, but DW_AT_specification is * present, then probably the actual name is in the DIE * referenced by DW_AT_specification. */ if (dwarf_attr(die, DW_AT_specification, &spec_at, &de) == DW_DLV_OK && dwarf_global_formref(spec_at, &ref, &de) == DW_DLV_OK && dwarf_offdie(dbg, ref, &spec_die, &de) == DW_DLV_OK && dwarf_attrval_string(spec_die, DW_AT_name, &funcname, &de) == DW_DLV_OK) goto add_func; /* Skip if no name associated with this DIE. */ goto cont_search; add_func: if ((f = calloc(1, sizeof(*f))) == NULL) err(EXIT_FAILURE, "calloc"); if ((f->name = strdup(funcname)) == NULL) err(EXIT_FAILURE, "strdup"); if (found_ranges) { f->ranges = ranges; f->ranges_cnt = ranges_cnt; } else { f->lopc = lopc; f->hipc = hipc; } if (tag == DW_TAG_inlined_subroutine) { f->inlined_caller = parent; dwarf_attrval_unsigned(die, DW_AT_call_file, &f->call_file, &de); dwarf_attrval_unsigned(die, DW_AT_call_line, &f->call_line, &de); } STAILQ_INSERT_TAIL(&cu->funclist, f, next); } cont_search: /* Search children. */ ret = dwarf_child(die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_child: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) { if (f != NULL) collect_func(dbg, ret_die, f, cu); else collect_func(dbg, ret_die, parent, cu); } /* Search sibling. */ ret = dwarf_siblingof(dbg, die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) collect_func(dbg, ret_die, parent, cu); /* Cleanup */ - dwarf_dealloc(dbg, die, DW_DLA_DIE); + if (die != cu->die) + dwarf_dealloc(dbg, die, DW_DLA_DIE); if (abst_die != NULL) dwarf_dealloc(dbg, abst_die, DW_DLA_DIE); if (spec_die != NULL) dwarf_dealloc(dbg, spec_die, DW_DLA_DIE); } static void print_inlines(struct CU *cu, struct Func *f, Dwarf_Unsigned call_file, Dwarf_Unsigned call_line) { char demangled[1024]; char *file; if (call_file > 0 && (Dwarf_Signed) call_file <= cu->nsrcfiles) file = cu->srcfiles[call_file - 1]; else file = unknown; if (pretty_print) printf(" (inlined by) "); if (func) { if (demangle && !elftc_demangle(f->name, demangled, sizeof(demangled), 0)) { if (pretty_print) printf("%s at ", demangled); else printf("%s\n", demangled); } else { if (pretty_print) printf("%s at ", f->name); else printf("%s\n", f->name); } } (void) printf("%s:%ju\n", base ? basename(file) : file, (uintmax_t) call_line); if (f->inlined_caller != NULL) print_inlines(cu, f->inlined_caller, f->call_file, f->call_line); } +static struct CU * +culookup(Dwarf_Unsigned addr) +{ + struct CU find, *res; + + find.lopc = addr; + res = RB_NFIND(cutree, &cuhead, &find); + if (res != NULL) { + if (res->lopc != addr) + res = RB_PREV(cutree, &cuhead, res); + if (res != NULL && addr >= res->lopc && addr < res->hipc) + return (res); + } else { + res = RB_MAX(cutree, &cuhead); + if (res != NULL && addr >= res->lopc && addr < res->hipc) + return (res); + } + return (NULL); +} + +/* + * Check whether addr falls into range(s) of current CU, and save current CU + * to lookup tree if so. + */ +static int +check_range(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Unsigned addr, + struct CU **cu) +{ + Dwarf_Error de; + Dwarf_Unsigned addr_base, lopc, hipc; + Dwarf_Off ranges_off; + Dwarf_Signed ranges_cnt; + Dwarf_Ranges *ranges; + int i, ret; + bool in_range; + + addr_base = 0; + ranges = NULL; + ranges_cnt = 0; + in_range = false; + + ret = dwarf_attrval_unsigned(die, DW_AT_ranges, &ranges_off, &de); + if (ret == DW_DLV_NO_ENTRY) { + if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) == + DW_DLV_OK) { + if (lopc == curlopc) + return (DW_DLV_ERROR); + if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, + &de) == DW_DLV_OK) { + /* + * Check if the address falls into the PC + * range of this CU. + */ + if (handle_high_pc(die, lopc, &hipc) != + DW_DLV_OK) + return (DW_DLV_ERROR); + } else { + /* Assume ~0ULL if DW_AT_high_pc not present */ + hipc = ~0ULL; + } + + if (addr >= lopc && addr < hipc) { + in_range = true; + } + } + } else if (ret == DW_DLV_OK) { + ret = dwarf_get_ranges(dbg, ranges_off, &ranges, + &ranges_cnt, NULL, &de); + if (ret != DW_DLV_OK) + return (ret); + + if (!ranges || ranges_cnt <= 0) + return (DW_DLV_ERROR); + + for (i = 0; i < ranges_cnt; i++) { + if (ranges[i].dwr_type == DW_RANGES_END) + return (DW_DLV_NO_ENTRY); + + if (ranges[i].dwr_type == + DW_RANGES_ADDRESS_SELECTION) { + addr_base = ranges[i].dwr_addr2; + continue; + } + + /* DW_RANGES_ENTRY */ + lopc = ranges[i].dwr_addr1 + addr_base; + hipc = ranges[i].dwr_addr2 + addr_base; + + if (lopc == curlopc) + return (DW_DLV_ERROR); + + if (addr >= lopc && addr < hipc){ + in_range = true; + break; + } + } + } else { + return (DW_DLV_ERROR); + } + + if (in_range) { + if ((*cu = calloc(1, sizeof(struct CU))) == NULL) + err(EXIT_FAILURE, "calloc"); + (*cu)->lopc = lopc; + (*cu)->hipc = hipc; + (*cu)->die = die; + (*cu)->dbg = dbg; + STAILQ_INIT(&(*cu)->funclist); + RB_INSERT(cutree, &cuhead, *cu); + curlopc = lopc; + return (DW_DLV_OK); + } else { + return (DW_DLV_NO_ENTRY); + } +} + static void translate(Dwarf_Debug dbg, Elf *e, const char* addrstr) { Dwarf_Die die, ret_die; Dwarf_Line *lbuf; Dwarf_Error de; Dwarf_Half tag; - Dwarf_Unsigned lopc, hipc, addr, lineno, plineno; + Dwarf_Unsigned addr, lineno, plineno; Dwarf_Signed lcount; Dwarf_Addr lineaddr, plineaddr; - Dwarf_Off off; struct CU *cu; struct Func *f; const char *funcname; char *file, *file0, *pfile; char demangled[1024]; int ec, i, ret; addr = strtoull(addrstr, NULL, 16); addr += section_base; lineno = 0; file = unknown; - cu = NULL; die = NULL; + ret = DW_DLV_OK; - while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, - &de)) == DW_DLV_OK) { + cu = culookup(addr); + if (cu != NULL) { + die = cu->die; + dbg = cu->dbg; + goto status_ok; + } + + while (true) { + /* + * We resume the CU scan from the last place we found a match. + * Because when we have 2 sequential addresses, and the second + * one is of the next CU, it is faster to just go to the next CU + * instead of starting from the beginning. + */ + ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, + &de); + if (ret == DW_DLV_NO_ENTRY) { + if (curlopc == ~0ULL) + goto out; + ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, + NULL, &de); + } die = NULL; while (dwarf_siblingof(dbg, die, &ret_die, &de) == DW_DLV_OK) { if (die != NULL) dwarf_dealloc(dbg, die, DW_DLA_DIE); die = ret_die; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); goto next_cu; } /* XXX: What about DW_TAG_partial_unit? */ if (tag == DW_TAG_compile_unit) break; } + if (ret_die == NULL) { warnx("could not find DW_TAG_compile_unit die"); goto next_cu; } - if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lopc, &de) == - DW_DLV_OK) { - if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &hipc, - &de) == DW_DLV_OK) { - /* - * Check if the address falls into the PC - * range of this CU. - */ - if (handle_high_pc(die, lopc, &hipc) != - DW_DLV_OK) - goto out; - } else { - /* Assume ~0ULL if DW_AT_high_pc not present */ - hipc = ~0ULL; - } - - /* - * Record the CU in the hash table for faster lookup - * later. - */ - if (dwarf_dieoffset(die, &off, &de) != DW_DLV_OK) { - warnx("dwarf_dieoffset failed: %s", - dwarf_errmsg(de)); - goto out; - } - HASH_FIND(hh, culist, &off, sizeof(off), cu); - if (cu == NULL) { - if ((cu = calloc(1, sizeof(*cu))) == NULL) - err(EXIT_FAILURE, "calloc"); - cu->off = off; - cu->lopc = lopc; - cu->hipc = hipc; - STAILQ_INIT(&cu->funclist); - HASH_ADD(hh, culist, off, sizeof(off), cu); - } - - if (addr >= lopc && addr < hipc) - break; - } - - next_cu: + ret = check_range(dbg, die, addr, &cu); + if (ret == DW_DLV_OK) + break; + if (ret == DW_DLV_ERROR) + goto out; +next_cu: if (die != NULL) { dwarf_dealloc(dbg, die, DW_DLA_DIE); die = NULL; } } if (ret != DW_DLV_OK || die == NULL) goto out; +status_ok: switch (dwarf_srclines(die, &lbuf, &lcount, &de)) { case DW_DLV_OK: break; case DW_DLV_NO_ENTRY: /* If a CU lacks debug info, just skip it. */ goto out; default: warnx("dwarf_srclines: %s", dwarf_errmsg(de)); goto out; } plineaddr = ~0ULL; plineno = 0; pfile = unknown; for (i = 0; i < lcount; i++) { if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) { warnx("dwarf_lineaddr: %s", dwarf_errmsg(de)); goto out; } if (dwarf_lineno(lbuf[i], &lineno, &de)) { warnx("dwarf_lineno: %s", dwarf_errmsg(de)); goto out; } if (dwarf_linesrc(lbuf[i], &file0, &de)) { warnx("dwarf_linesrc: %s", dwarf_errmsg(de)); } else file = file0; if (addr == lineaddr) goto out; else if (addr < lineaddr && addr > plineaddr) { lineno = plineno; file = pfile; goto out; } plineaddr = lineaddr; plineno = lineno; pfile = file; } out: f = NULL; funcname = NULL; if (ret == DW_DLV_OK && (func || inlines) && cu != NULL) { if (cu->srcfiles == NULL) if (dwarf_srcfiles(die, &cu->srcfiles, &cu->nsrcfiles, &de)) warnx("dwarf_srcfiles: %s", dwarf_errmsg(de)); if (STAILQ_EMPTY(&cu->funclist)) { collect_func(dbg, die, NULL, cu); die = NULL; } f = search_func(cu, addr); if (f != NULL) funcname = f->name; } if (print_addr) { if ((ec = gelf_getclass(e)) == ELFCLASSNONE) { warnx("gelf_getclass failed: %s", elf_errmsg(-1)); ec = ELFCLASS64; } if (ec == ELFCLASS32) { if (pretty_print) printf("0x%08jx: ", (uintmax_t) addr); else printf("0x%08jx\n", (uintmax_t) addr); } else { if (pretty_print) printf("0x%016jx: ", (uintmax_t) addr); else printf("0x%016jx\n", (uintmax_t) addr); } } if (func) { if (funcname == NULL) funcname = unknown; if (demangle && !elftc_demangle(funcname, demangled, sizeof(demangled), 0)) { if (pretty_print) printf("%s at ", demangled); else printf("%s\n", demangled); } else { if (pretty_print) printf("%s at ", funcname); else printf("%s\n", funcname); } } (void) printf("%s:%ju\n", base ? basename(file) : file, (uintmax_t) lineno); if (ret == DW_DLV_OK && inlines && cu != NULL && cu->srcfiles != NULL && f != NULL && f->inlined_caller != NULL) print_inlines(cu, f->inlined_caller, f->call_file, f->call_line); - - if (die != NULL) - dwarf_dealloc(dbg, die, DW_DLA_DIE); - - /* - * Reset internal CU pointer, so we will start from the first CU - * next round. - */ - while (ret != DW_DLV_NO_ENTRY) { - if (ret == DW_DLV_ERROR) - errx(EXIT_FAILURE, "dwarf_next_cu_header: %s", - dwarf_errmsg(de)); - ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, - &de); - } } static void find_section_base(const char *exe, Elf *e, const char *section) { Dwarf_Addr off; Elf_Scn *scn; GElf_Ehdr eh; GElf_Shdr sh; size_t shstrndx; int elferr; const char *name; if (gelf_getehdr(e, &eh) != &eh) { warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); return; } if (!elf_getshstrndx(e, &shstrndx)) { warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); return; } (void) elf_errno(); off = 0; scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); continue; } if ((name = elf_strptr(e, shstrndx, sh.sh_name)) == NULL) goto next; if (!strcmp(section, name)) { if (eh.e_type == ET_EXEC || eh.e_type == ET_DYN) { /* * For executables, section base is the virtual * address of the specified section. */ section_base = sh.sh_addr; } else if (eh.e_type == ET_REL) { /* * For relocatables, section base is the * relative offset of the specified section * to the start of the first section. */ section_base = off; } else warnx("unknown e_type %u", eh.e_type); return; } next: off += sh.sh_size; } elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); errx(EXIT_FAILURE, "%s: cannot find section %s", exe, section); } int main(int argc, char **argv) { Elf *e; Dwarf_Debug dbg; Dwarf_Error de; const char *exe, *section; char line[1024]; int fd, i, opt; exe = NULL; section = NULL; while ((opt = getopt_long(argc, argv, "ab:Ce:fij:psHV", longopts, NULL)) != -1) { switch (opt) { case 'a': print_addr = 1; break; case 'b': /* ignored */ break; case 'C': demangle = 1; break; case 'e': exe = optarg; break; case 'f': func = 1; break; case 'i': inlines = 1; break; case 'j': section = optarg; break; case 'p': pretty_print = 1; break; case 's': base = 1; break; case 'H': usage(); case 'V': version(); default: usage(); } } argv += optind; argc -= optind; if (exe == NULL) exe = "a.out"; if ((fd = open(exe, O_RDONLY)) < 0) err(EXIT_FAILURE, "%s", exe); if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &de)) errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(de)); if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de)); if (section) find_section_base(exe, e, section); else section_base = 0; if (argc > 0) for (i = 0; i < argc; i++) translate(dbg, e, argv[i]); else { setvbuf(stdout, NULL, _IOLBF, 0); while (fgets(line, sizeof(line), stdin) != NULL) translate(dbg, e, line); } dwarf_finish(dbg, &de); (void) elf_end(e); exit(0); } Index: stable/11/contrib/elftoolchain/ar/ar.1 =================================================================== --- stable/11/contrib/elftoolchain/ar/ar.1 (revision 367465) +++ stable/11/contrib/elftoolchain/ar/ar.1 (revision 367466) @@ -1,624 +1,627 @@ .\" Copyright (c) 2007,2009-2012 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: ar.1 3230 2015-07-27 17:11:38Z emaste $ +.\" $Id: ar.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" -.Dd July 27, 2015 -.Os +.Dd September 30, 2018 .Dt AR 1 +.Os .Sh NAME .Nm ar .Nd manage archives .Sh SYNOPSIS .Nm .Fl d -.Op Fl T .Op Fl f .Op Fl j +.Op Fl T .Op Fl v .Op Fl z .Ar archive .Ar .Nm .Fl m -.Op Fl T .Op Fl a Ar position-after .Op Fl b Ar position-before .Op Fl f .Op Fl i Ar position-before .Op Fl j .Op Fl s | Fl S +.Op Fl T .Op Fl z .Ar archive .Ar .Nm .Fl p -.Op Fl T .Op Fl f +.Op Fl s +.Op Fl T .Op Fl v .Ar archive .Op Ar .Nm .Fl q -.Op Fl T .Op Fl c .Op Fl D .Op Fl f .Op Fl F Ar flavor | Fl -flavor Ar flavor .Op Fl s | Fl S +.Op Fl T .Op Fl U .Op Fl v .Op Fl z .Ar archive .Ar .Nm .Fl r -.Op Fl T .Op Fl a Ar position-after .Op Fl b Ar position-before .Op Fl c .Op Fl D .Op Fl f .Op Fl F Ar flavor | Fl -flavor Ar flavor .Op Fl i Ar position-before .Op Fl j .Op Fl s | Fl S +.Op Fl T .Op Fl u .Op Fl U .Op Fl v .Op Fl z .Ar archive .Ar .Nm .Fl s .Op Fl D .Op Fl j .Op Fl U .Op Fl z .Ar archive .Nm .Fl t .Op Fl f +.Op Fl s .Op Fl T .Op Fl v .Ar archive .Op Ar .Nm .Fl x .Op Fl C -.Op Fl T .Op Fl f .Op Fl o +.Op Fl s +.Op Fl T .Op Fl u .Op Fl v .Ar archive .Op Ar .Nm .Fl M .Nm .Fl V .Sh DESCRIPTION The .Nm utility creates and maintains groups of files combined into an archive. Once an archive has been created, new files can be added to it, and existing files can be extracted, deleted or replaced. .Pp Files are named in the archive by their last file name component, so if a file referenced by a path containing a .Dq / is archived, it will be named by the last component of the path. Similarly when matching paths listed on the command line against file names stored in the archive, only the last component of the path will be compared. .Pp The normal use of .Nm is for the creation and maintenance of libraries suitable for use with the link editor .Xr ld 1 , although it is not restricted to this purpose. The .Nm utility can create and manage an archive symbol table (see .Xr ar 5 ) used to speed up link editing operations. If a symbol table is present in an archive, it will be kept up-to-date by subsequent operations on the archive. .Sh OPTIONS The .Nm utility supports the following options: .Bl -tag -width indent .It Fl a Ar member-after When used with option .Fl m this option specifies that the archive members specified by arguments .Ar are moved to after the archive member named by argument .Ar member-after . When used with option .Fl r this option specifies that the files specified by arguments .Ar are added after the archive member named by argument .Ar member-after . .It Fl b Ar member-before When used with option .Fl m this option specifies that the archive members specified by arguments .Ar are moved to before the archive member named by argument .Ar member-before . When used with option .Fl r this option specifies that the files specified by arguments .Ar are added before the archive member named by argument .Ar member-before . .It Fl c Suppress the informational message printed when a new archive is created using the .Fl r and .Fl q options. .It Fl C Prevent extracted files from replacing like-named files in the file system. .It Fl d Delete the members named by arguments .Ar from the archive specified by argument .Ar archive . The archive's symbol table, if present, is updated to reflect the new contents of the archive. .It Fl D When used in combination with the .Fl r or .Fl q option, insert 0's instead of the real mtime, uid and gid values and 0644 instead of file mode from the members named by arguments .Ar . This ensures that checksums on the resulting archives are reproducible when member contents are identical. If multiple .Fl D and .Fl U options are specified on the command line, the final one takes precedence. .It Fl f Synonymous with option .Fl T . .It Fl F Ar flavor | Fl -flavor Ar flavor Create archives with the specified archive format. Legal values for argument .Ar flavor are: .Bl -tag -width indent -compact .It Ar bsd Create BSD format archives. .It Ar gnu An alias for .Ar svr4 . .It Ar svr4 Create SVR4 format archives. .El If this option is not specified, .Nm will create archives using the SVR4 format. .It Fl i Ar member-before Synonymous with option .Fl b . .It Fl j This option is accepted for compatibility with the .Tn FreeBSD version of the .Nm utility, but is ignored. .It Fl l This option is accepted for compatibility with GNU .Xr ar 1 , but is ignored. .It Fl m Move archive members specified by arguments .Ar within the archive. If a position has been specified by one of the .Fl a , .Fl b or .Fl i options, the members are moved to before or after the specified position. If no position has been specified, the specified members are moved to the end of the archive. If the archive has a symbol table, it is updated to reflect the new contents of the archive. .It Fl M Read and execute MRI librarian commands from standard input. The commands understood by the .Nm utility are described in the section .Sx "MRI Librarian Commands" . .It Fl o Preserve the original modification times of members when extracting them. .It Fl p Write the contents of the specified archive members named by arguments .Ar to standard output. If no members were specified, the contents of all the files in the archive are written in the order they appear in the archive. .It Fl q Append the files specified by arguments .Ar to the archive specified by argument .Ar archive without checking if the files already exist in the archive. The archive symbol table will be updated as needed. If the file specified by the argument .Ar archive does not already exist, a new archive will be created. .It Fl r Replace (add) the files specified by arguments .Ar in the archive specified by argument .Ar archive , creating the archive if necessary. Replacing existing members will not change the order of members within the archive. If a file named in arguments .Ar does not exist, existing members in the archive that match that name are not changed. New files are added to the end of the archive unless one of the positioning options .Fl a , .Fl b or .Fl i is specified. The archive symbol table, if it exists, is updated to reflect the new state of the archive. .It Fl s Add an archive symbol table (see .Xr ar 5 ) to the archive specified by argument .Ar archive . Invoking .Nm with the .Fl s option alone is equivalent to invoking .Xr ranlib 1 . .It Fl S Do not generate an archive symbol table. .It Fl t For .Nm , list the files specified by arguments .Ar in the order in which they appear in the archive, one per line. If no files are specified, all files in the archive are listed. .It Fl T Use only the first fifteen characters of the archive member name or command line file name argument when naming archive members. .It Fl u Conditionally update the archive or extract members. When used with the .Fl r option, files named by arguments .Ar will be replaced in the archive if they are newer than their archived versions. When used with the .Fl x option, the members specified by arguments .Ar will be extracted only if they are newer than the corresponding files in the file system. .It Fl U When used in combination with the .Fl r or .Fl q option, insert the real mtime, uid and gid, and file mode values from the members named by arguments .Ar . If multiple .Fl D and .Fl U options are specified on the command line, the final one takes precedence. .It Fl v Provide verbose output. When used with the .Fl d , .Fl m , .Fl q or .Fl x options, .Nm gives a file-by-file description of the archive modification being performed, which consists of three white-space separated fields: the option letter, a dash .Dq "-" , and the file name. When used with the .Fl r option, .Nm displays the description as above, but the initial letter is an .Dq a if the file is added to the archive, or an .Dq r if the file replaces a file already in the archive. When used with the .Fl p option, the name of the file enclosed in .Dq < and .Dq > characters is written to standard output preceded by a single newline character and followed by two newline characters. The contents of the named file follow the file name. When used with the .Fl t option, .Nm displays eight whitespace separated fields: the file permissions as displayed by .Xr strmode 3 , decimal user and group IDs separated by a slash ( .Dq / Ns ) , the file size in bytes, the file modification time in .Xr strftime 3 format .Dq "%b %e %H:%M %Y" , and the name of the file. .It Fl V Print a version identifier and exit. .It Fl x Extract archive members specified by arguments .Ar into the current directory. If no members have been specified, extract all members of the archive. If the file corresponding to an extracted member does not exist it will be created. If the file corresponding to an extracted member does exist, its owner and group will not be changed while its contents will be overwritten and its permissions will set to that entered in the archive. The file's access and modification time would be that of the time of extraction unless the .Fl o option was specified. .It Fl z This option is accepted for compatibility with the .Tn FreeBSD version of the .Nm utility, but is ignored. .El .Ss "MRI Librarian Commands" If the .Fl M option is specified, the .Nm utility will read and execute commands from its standard input. If standard input is a terminal, the .Nm utility will display the prompt .Dq Li "AR >" before reading a line, and will continue operation even if errors are encountered. If standard input is not a terminal, the .Nm utility will not display a prompt and will terminate execution on encountering an error. .Pp Each input line contains a single command. Words in an input line are separated by whitespace characters. The first word of the line is the command, the remaining words are the arguments to the command. The command word may be specified in either case. Arguments may be separated by commas or blanks. .Pp Empty lines are allowed and are ignored. Long lines are continued by ending them with the .Dq Li + character. .Pp The .Dq Li * and .Dq Li "\;" characters start a comment. Comments extend till the end of the line. .Pp When executing an MRI librarian script the .Nm utility works on a temporary copy of an archive. Changes to the copy are made permanent using the .Ic save command. .Pp Commands understood by the .Nm utility are: .Bl -tag -width indent .It Ic addlib Ar archive | Ic addlib Ar archive Pq Ar member Oo Li , Ar member Oc Ns ... Add the contents of the archive named by argument .Ar archive to the current archive. If specific members are named using the arguments .Ar member , then those members are added to the current archive. If no members are specified, the entire contents of the archive are added to the current archive. .It Ic addmod Ar member Oo Li , Ar member Oc Ns ... Add the files named by arguments .Ar member to the current archive. .It Ic clear Discard all the contents of the current archive. .It Ic create Ar archive Create a new archive named by the argument .Ar archive , and makes it the current archive. If the named archive already exists, it will be overwritten when the .Ic save command is issued. .It Ic delete Ar module Oo Li , Ar member Oc Ns ... Delete the modules named by the arguments .Ar member from the current archive. .It Ic directory Ar archive Po Ar member Oo Li , Ar member Oc Ns ... Pc Op Ar outputfile List each named module in the archive. The format of the output depends on the verbosity setting set using the .Ic verbose command. Output is sent to standard output, or to the file specified by argument .Ar outputfile . .It Ic end Exit successfully from the .Nm utility. Any unsaved changes to the current archive will be discarded. .It Ic extract Ar member Oo Li , Ar member Oc Ns ... Extract the members named by the arguments .Ar member from the current archive. .It Ic list Display the contents of the current archive in verbose style. .It Ic open Ar archive Open the archive named by argument .Ar archive and make it the current archive. .It Ic replace Ar member Oo Li , Ar member Oc Ns ... Replace named members in the current archive with the files specified by arguments .Ar member . The files must be present in the current directory and the named modules must already exist in the current archive. .It Ic save Commit all changes to the current archive. .It Ic verbose Toggle the verbosity of the .Ic directory command. .El .Sh EXAMPLES To create a new archive .Pa ex.a containing three files .Pa ex1.o , .Pa ex2.o and .Pa ex3.o , use: .Dl "ar -rc ex.a ex1.o ex2.o ex3.o" .Pp To add an archive symbol table to an existing archive .Pa ex.a , use: .Dl "ar -s ex.a" .Pp To delete file .Pa ex1.o from archive .Pa ex.a , use: .D1 "ar -d ex.a ex1.o" .Pp To verbosely list the contents of archive .Pa ex.a , use: .D1 "ar -tv ex.a" .Pp To create a new archive .Pa ex.a containing the files .Pa ex1.o , and .Pa ex2.o , using MRI librarian commands, use the following script: .Bd -literal -offset indent create ex.a * specify the output archive addmod ex1.o ex2.o * add modules save * save pending changes end * exit the utility .Ed .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO .Xr ld 1 , .Xr ranlib 1 , .Xr archive 3 , .Xr elf 3 , .Xr strftime 3 , .Xr strmode 3 , .Xr ar 5 .Sh STANDARDS COMPLIANCE The .Nm utility's support for the .Fl a , .Fl b , .Fl c , .Fl i , .Fl m , .Fl p , .Fl q , .Fl r , .Fl s , .Fl t , .Fl u , .Fl v , .Fl C and .Fl T options is believed to be compliant with .St -p1003.2 . .Sh HISTORY An .Nm command first appeared in AT&T UNIX Version 1. In .Fx 8.0 , .An Kai Wang Aq Mt kaiw@FreeBSD.org reimplemented .Nm using the .Lb libarchive and the .Lb libelf . Index: stable/11/contrib/elftoolchain/ar/ar.5 =================================================================== --- stable/11/contrib/elftoolchain/ar/ar.5 (revision 367465) +++ stable/11/contrib/elftoolchain/ar/ar.5 (revision 367466) @@ -1,327 +1,329 @@ .\" 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: ar.5 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: ar.5 3642 2018-10-14 14:24:28Z jkoshy $ .\" -.Dd November 28, 2010 -.Os +.Dd September 30, 2018 .Dt AR 5 +.Os .Sh NAME .Nm ar .Nd archive file format for .Xr ar 1 and .Xr ranlib 1 .Sh SYNOPSIS .In ar.h .Sh DESCRIPTION .Xr ar 1 archives are created and managed by the .Xr ar 1 and .Xr ranlib 1 utilities. These archives are typically used during program development to hold libraries of program objects. An .Xr ar 1 archive is contained in a single operating system file. .Pp This manual page documents two variants of the .Xr ar 1 archive format: the BSD archive format, and the SVR4/GNU archive format. .Pp In both variants the archive file starts with an identifying byte sequence of the seven ASCII characters .Sq Li "!" followed by a ASCII linefeed character .Po see the constant .Dq ARMAG in the header file .In ar.h .Pc . .Pp Archive members follow the initial identifying byte sequence. Each archive member is prefixed by a fixed size header describing the file attributes associated with the member. .Ss "Archive Headers" An archive header describes the file attributes for the archive member that follows it. The .Xr ar 5 format only supports a limited number of attributes: the file name, the file creation time stamp, the uid and gid of the creator, the file mode and the file size. .Pp Archive headers are placed at an even byte offset in the archive file. If the data for an archive member ends at an odd byte offset, then a padding byte with value 0x0A is used to position the next archive header on an even byte offset. .Pp An archive header comprises the following fixed sized fields: .Bl -tag -width "Li ar_name" .It Ar ar_name (16 bytes) The file name of the archive member. +This field names a leaf file; absolute paths and relative paths containing +directory names are not supported. The format of this field varies between the BSD and SVR4/GNU formats and is described in more detail in the section .Sx "Representing File Names" below. .It Ar ar_date (12 bytes) The file modification time for the member in seconds since the epoch, encoded as a decimal number. .It Ar ar_uid (6 bytes) The uid associated with the archive member, encoded as a decimal number. .It Ar ar_gid (6 bytes) The gid associated with the archive member, encoded as a decimal number. .It Ar ar_mode (8 bytes) The file mode for the archive member, encoded as an octal number. .It Ar ar_size (10 bytes) In the SVR4/GNU archive format this field holds the size in bytes of the archive member, encoded as a decimal number. In the BSD archive format, for short file names, this field holds the size in bytes of the archive member, encoded as a decimal number. For long file names .Po see .Sx "Representing File Names" below .Pc , the field contains the combined size of the archive member and its file name, encoded as a decimal number. .It Ar ar_fmag (2 bytes) This field holds 2 bytes with values 0x96 and 0x0A respectively, marking the end of the header. .El .Pp Unused bytes in the fields of an archive header are set to the value 0x20. .Ss "Representing File Names" The BSD and SVR4/GNU variants use different schemes for encoding file names for members. .Bl -tag -width "SVR4/GNU" .It "BSD" File names that are up to 16 bytes long and which do not contain embedded spaces are stored directly in the .Ar ar_name field of the archive header. File names that are either longer than 16 bytes or which contain embedded spaces are stored immediately after the archive header and the .Ar ar_name field of the archive header is set to the string .Dq "#1/" followed by a decimal representation of the number of bytes needed for the file name. In addition, the .Ar ar_size field of the archive header is set to the decimal representation of the combined sizes of the archive member and the file name. The file contents of the member follows the file name without further padding. .Pp As an example, if the file name for a member was .Dq "A B" and its contents was the string .Dq "C D" , then the .Ar ar_name field of the header would contain .Dq Li "#1/3" , the .Ar ar_size field of the header would contain .Dq Li 6 , and the bytes immediately following the header would be 0x41, 0x20, 0x42, 0x43, 0x20 and 0x44 .Po ASCII .Dq "A BC D" .Pc . .It "SVR4/GNU" File names that are up to 15 characters long are stored directly in the .Ar ar_name field of the header, terminated by a .Dq Li / character. .Pp If the file name is larger than would fit in space for the .Ar ar_name field, then the actual file name is kept in the archive string table .Po see .Sx "Archive String Tables" below .Pc , and the decimal offset of the file name in the string table is stored in the .Ar ar_name field, prefixed by a .Dq Li / character. .Pp As an example, if the real file name has been stored at offset 768 in the archive string table, the .Ar ar_name field of the header will contain the string .Dq /768 . .El .Ss "Special Archive Members" The following archive members are special. .Bl -tag -width indent .It Dq Li / In the SVR4/GNU variant of the archive format, the archive member with name .Dq Li / denotes an archive symbol table. If present, this member will be the very first member in the archive. .It Dq Li // In the SVR4/GNU variant of the archive format, the archive member with name .Dq Li // denotes the archive string table. This special member is used to hold filenames that do not fit in the file name field of the header .Po see .Sx "Representing File Names" above .Pc . If present, this member immediately follows the archive symbol table if an archive symbol table is present, or is the first member otherwise. .It Dq Li "__.SYMDEF" This special member contains the archive symbol table in the BSD variant of the archive format. If present, this member will be the very first member in the archive. .El .Ss "Archive String Tables" An archive string table is used in the SVR4/GNU archive format to hold file names that are too large to fit into the constraints of the .Ar ar_name field of the archive header. An archive string table contains a sequence of file names. Each file name in the archive string table is terminated by the byte sequence 0x2F, 0x0A .Po the ASCII string .Dq "/\en" .Pc . No padding is used to separate adjacent file names. .Ss "Archive Symbol Tables" Archive symbol tables are used to speed up link editing by providing a mapping between the program symbols defined in the archive and the corresponding archive members. Archive symbol tables are managed by the .Xr ranlib 1 utility. .Pp The format of archive symbol tables is as follows: .Bl -tag -width "SVR4/GNU" .It BSD In the BSD archive format, the archive symbol table comprises of two parts: a part containing an array of .Vt "struct ranlib" descriptors, followed by a part containing a symbol string table. The sizes and layout of the structures that make up a BSD format archive symbol table are machine dependent. .Pp The part containing .Vt "struct ranlib" descriptors begins with a field containing the size in bytes of the array of .Vt "struct ranlib" descriptors encoded as a C .Vt long value. .Pp The array of .Vt "struct ranlib" descriptors follows the size field. Each .Vt "struct ranlib" descriptor describes one symbol. .Pp A .Vt "struct ranlib" descriptor comprises two fields: .Bl -tag -width "Ar ran_strx" -compact .It Ar ran_strx .Pq C Vt long This field contains the zero-based offset of the symbol name in the symbol string table. .It Ar ran_off .Pq C Vt long This field is the file offset to the archive header for the archive member defining the symbol. .El .Pp The part containing the symbol string table begins with a field containing the size in bytes of the string table, encoded as a C .Vt long value. This string table follows the size field, and contains NUL-terminated strings for the symbols in the symbol table. .It SVR4/GNU In the SVR4/GNU archive format, the archive symbol table starts with a 4-byte binary value containing the number of entries contained in the archive symbol table. This count of entries is stored most significant byte first. .Pp Next, there are .Ar count 4-byte numbers, each stored most significant byte first. Each number is a binary offset to the archive header for the member in the archive file for the corresponding symbol table entry. .Pp After the binary offset values, there are .Ar count NUL-terminated strings in sequence, holding the symbol names for the corresponding symbol table entries. .El .Sh STANDARDS COMPLIANCE The .Xr ar 1 archive format is not currently specified by a standard. .Pp This manual page documents the .Xr ar 1 archive formats used by the .Bx 4.4 and .Ux SVR4 operating system releases. .Sh SEE ALSO .Xr ar 1 , .Xr ld 1 , .Xr ranlib 1 , .Xr elf 3 , .Xr elf_getarsym 3 , .Xr elf_rand 3 Index: stable/11/contrib/elftoolchain/ar/ar.c =================================================================== --- stable/11/contrib/elftoolchain/ar/ar.c (revision 367465) +++ stable/11/contrib/elftoolchain/ar/ar.c (revision 367466) @@ -1,441 +1,445 @@ /*- * Copyright (c) 2007 Kai Wang * Copyright (c) 2007 Tim Kientzle * Copyright (c) 2007 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 * in this position and unchanged. * 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(S) ``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(S) 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. */ /*- * Copyright (c) 1990, 1993, 1994 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Hugh Smith at The University of Guelph. * * 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 "ar.h" -ELFTC_VCSID("$Id: ar.c 3319 2016-01-13 21:37:53Z jkoshy $"); +ELFTC_VCSID("$Id: ar.c 3629 2018-09-30 19:26:28Z jkoshy $"); enum options { OPTION_HELP }; static struct option longopts[] = { {"flavor", required_argument, NULL, 'F'}, {"help", no_argument, NULL, OPTION_HELP}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; static void bsdar_usage(void); static void ranlib_usage(void); static void set_mode(struct bsdar *bsdar, char opt); static void only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes); static void bsdar_version(void); int main(int argc, char **argv) { struct bsdar *bsdar, bsdar_storage; char *arcmd, *argv1_saved; size_t len; - int i, opt; + int exitcode, i, opt; bsdar = &bsdar_storage; memset(bsdar, 0, sizeof(*bsdar)); + exitcode = EXIT_SUCCESS; arcmd = argv1_saved = NULL; bsdar->output = stdout; if ((bsdar->progname = ELFTC_GETPROGNAME()) == NULL) bsdar->progname = "ar"; if (elf_version(EV_CURRENT) == EV_NONE) bsdar_errc(bsdar, 0, "ELF library initialization failed: %s", elf_errmsg(-1)); /* * Act like ranlib if our name ends in "ranlib"; this * accommodates names like "arm-freebsd7.1-ranlib", * "bsdranlib", etc. */ len = strlen(bsdar->progname); if (len >= strlen("ranlib") && strcmp(bsdar->progname + len - strlen("ranlib"), "ranlib") == 0) { while ((opt = getopt_long(argc, argv, "tDUV", longopts, NULL)) != -1) { switch(opt) { case 't': /* Ignored. */ break; case 'D': bsdar->options |= AR_D; break; case 'U': bsdar->options &= ~AR_D; break; case 'V': bsdar_version(); break; case OPTION_HELP: ranlib_usage(); default: ranlib_usage(); } } argv += optind; argc -= optind; if (*argv == NULL) ranlib_usage(); bsdar->options |= AR_S; while ((bsdar->filename = *argv++) != NULL) - ar_write_archive(bsdar, 's'); + exitcode |= ar_write_archive(bsdar, 's'); - exit(EXIT_SUCCESS); + exit(exitcode); } else { if (argc < 2) bsdar_usage(); /* * Tack on a leading '-', for old-style usage. */ if (*argv[1] != '-') { argv1_saved = argv[1]; len = strlen(argv[1]) + 2; if ((arcmd = malloc(len)) == NULL) bsdar_errc(bsdar, errno, "malloc failed"); (void) snprintf(arcmd, len, "-%s", argv[1]); argv[1] = arcmd; } } while ((opt = getopt_long(argc, argv, "abCcdDfF:ijlMmopqrSsTtUuVvxz", longopts, NULL)) != -1) { switch(opt) { case 'a': bsdar->options |= AR_A; break; case 'b': case 'i': bsdar->options |= AR_B; break; case 'C': bsdar->options |= AR_CC; break; case 'c': bsdar->options |= AR_C; break; case 'd': set_mode(bsdar, opt); break; case 'D': bsdar->options |= AR_D; break; case 'F': if (!strcasecmp(optarg, "svr4") || !strcasecmp(optarg, "gnu")) bsdar->options &= ~AR_BSD; else if (!strcasecmp(optarg, "bsd")) bsdar->options |= AR_BSD; else bsdar_usage(); break; case 'f': case 'T': bsdar->options |= AR_TR; break; case 'j': /* ignored */ break; case 'l': /* ignored, for GNU ar comptibility */ break; case 'M': set_mode(bsdar, opt); break; case 'm': set_mode(bsdar, opt); break; case 'o': bsdar->options |= AR_O; break; case 'p': set_mode(bsdar, opt); break; case 'q': set_mode(bsdar, opt); break; case 'r': set_mode(bsdar, opt); break; case 'S': bsdar->options |= AR_SS; break; case 's': bsdar->options |= AR_S; break; case 't': set_mode(bsdar, opt); break; case 'U': bsdar->options &= ~AR_D; break; case 'u': bsdar->options |= AR_U; break; case 'V': bsdar_version(); break; case 'v': bsdar->options |= AR_V; break; case 'x': set_mode(bsdar, opt); break; case 'z': /* ignored */ break; case OPTION_HELP: bsdar_usage(); default: bsdar_usage(); } } /* Restore argv[1] if we had modified it. */ if (arcmd != NULL) { argv[1] = argv1_saved; free(arcmd); arcmd = argv1_saved = NULL; } argv += optind; argc -= optind; if (*argv == NULL && bsdar->mode != 'M') bsdar_usage(); if (bsdar->options & AR_A && bsdar->options & AR_B) bsdar_errc(bsdar, 0, "only one of -a and -[bi] options allowed"); if (bsdar->options & AR_J && bsdar->options & AR_Z) bsdar_errc(bsdar, 0, "only one of -j and -z options allowed"); if (bsdar->options & AR_S && bsdar->options & AR_SS) bsdar_errc(bsdar, 0, "only one of -s and -S options allowed"); if (bsdar->options & (AR_A | AR_B)) { if (*argv == NULL) bsdar_errc(bsdar, 0, "no position operand specified"); if ((bsdar->posarg = basename(*argv)) == NULL) bsdar_errc(bsdar, errno, "basename failed"); argc--; argv++; } if (bsdar->options & AR_A) only_mode(bsdar, "-a", "mqr"); if (bsdar->options & AR_B) only_mode(bsdar, "-b", "mqr"); if (bsdar->options & AR_C) only_mode(bsdar, "-c", "qr"); if (bsdar->options & AR_CC) only_mode(bsdar, "-C", "x"); if (bsdar->options & AR_D) only_mode(bsdar, "-D", "qr"); if (bsdar->options & AR_O) only_mode(bsdar, "-o", "x"); if (bsdar->options & AR_SS) only_mode(bsdar, "-S", "mqr"); if (bsdar->options & AR_U) only_mode(bsdar, "-u", "qrx"); if (bsdar->mode == 'M') { ar_mode_script(bsdar); exit(EXIT_SUCCESS); } if ((bsdar->filename = *argv) == NULL) bsdar_usage(); bsdar->argc = --argc; bsdar->argv = ++argv; if ((!bsdar->mode || strchr("ptx", bsdar->mode)) && bsdar->options & AR_S) { - ar_write_archive(bsdar, 's'); + exitcode = ar_write_archive(bsdar, 's'); if (!bsdar->mode) - exit(EXIT_SUCCESS); + exit(exitcode); } switch(bsdar->mode) { case 'd': case 'm': case 'q': case 'r': - ar_write_archive(bsdar, bsdar->mode); + exitcode = ar_write_archive(bsdar, bsdar->mode); break; case 'p': case 't': case 'x': - ar_read_archive(bsdar, bsdar->mode); + exitcode = ar_read_archive(bsdar, bsdar->mode); break; default: bsdar_usage(); /* NOTREACHED */ } - for (i = 0; i < bsdar->argc; i++) - if (bsdar->argv[i] != NULL) + for (i = 0; i < bsdar->argc; i++) { + if (bsdar->argv[i] != NULL) { bsdar_warnc(bsdar, 0, "%s: not found in archive", bsdar->argv[i]); + exitcode = EXIT_FAILURE; + } + } - exit(EXIT_SUCCESS); + exit(exitcode); } static void set_mode(struct bsdar *bsdar, char opt) { if (bsdar->mode != '\0' && bsdar->mode != opt) bsdar_errc(bsdar, 0, "Can't specify both -%c and -%c", opt, bsdar->mode); bsdar->mode = opt; } static void only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes) { if (strchr(valid_modes, bsdar->mode) == NULL) bsdar_errc(bsdar, 0, "Option %s is not permitted in mode -%c", opt, bsdar->mode); } #define AR_USAGE_MESSAGE "\ Usage: %s [options] archive file...\n\ Manage archives.\n\n\ Where is one of:\n\ -d Delete members from the archive.\n\ -m Move archive members within the archive.\n\ -p Write the contents of members to standard output.\n\ -q Append files to an archive.\n\ -r Replace (add) files to an archive.\n\ -s Add an archive symbol to an archive.\n\ -t List files in an archive.\n\ -x Extract members from an archive.\n\ -M Execute MRI librarian commands.\n\ -V Print a version identifier and exit.\n\n\ Options:\n\ -a MEMBER Add members after the specified member.\n\ -b MEMBER | -i MEMBER\n\ Add members before the specified member.\n\ -c Do not print a message when creating a new archive.\n\ -f | -T Only use the first fifteen characters of the member name.\n\ -j (This option is accepted, but is ignored).\n\ -l (This option is accepted, but is ignored).\n\ -o Preserve modification times when extracting members.\n\ -u Conditionally update or extract members.\n\ -v Be verbose.\n\ -z (This option is accepted, but is ignored).\n\ -C Do not overwrite existing files in the file system.\n\ -D Use fixed metadata, for consistent archive checksums.\n\ -F FORMAT | --flavor=FORMAT\n\ Create archives with the specified format.\n\ -S Do not generate an archive symbol table.\n\ -U Use original metadata for archive members.\n" static void bsdar_usage(void) { (void) fprintf(stderr, AR_USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } #define RANLIB_USAGE_MESSAGE "\ Usage: %s [options] archive...\n\ Update or create archive symbol tables.\n\n\ Options:\n\ -t (This option is accepted, but ignored).\n\ -D Use fixed metadata, for consistent archive checksums.\n\ -U Use original metadata, for unique archive checksums.\n\ -V Print a version identifier and exit.\n" static void ranlib_usage(void) { (void)fprintf(stderr, RANLIB_USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } static void bsdar_version(void) { (void)printf("%s (%s, %s)\n", ELFTC_GETPROGNAME(), archive_version_string(), elftc_version()); exit(EXIT_SUCCESS); } Index: stable/11/contrib/elftoolchain/ar/ar.h =================================================================== --- stable/11/contrib/elftoolchain/ar/ar.h (revision 367465) +++ stable/11/contrib/elftoolchain/ar/ar.h (revision 367466) @@ -1,143 +1,143 @@ /*- * Copyright (c) 2007 Kai Wang * 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 * in this position and unchanged. * 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(S) ``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(S) 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: ar.h 2496 2012-04-24 02:33:40Z jkoshy $ + * $Id: ar.h 3629 2018-09-30 19:26:28Z jkoshy $ */ #include #include "_elftc.h" /* * ar(1) options. */ #define AR_A 0x0001 /* position-after */ #define AR_B 0x0002 /* position-before */ #define AR_C 0x0004 /* creating new archive */ #define AR_CC 0x0008 /* do not overwrite when extracting */ #define AR_J 0x0010 /* bzip2 compression */ #define AR_O 0x0020 /* preserve original mtime when extracting */ #define AR_S 0x0040 /* write archive symbol table */ #define AR_SS 0x0080 /* do not write archive symbol table */ #define AR_TR 0x0100 /* only keep first 15 chars for member name */ #define AR_U 0x0200 /* only extract or update newer members.*/ #define AR_V 0x0400 /* verbose mode */ #define AR_Z 0x0800 /* gzip compression */ #define AR_D 0x1000 /* insert dummy mode, mtime, uid and gid */ #define AR_BSD 0x2000 /* use the BSD archive format */ #define DEF_BLKSZ 10240 /* default block size */ /* Special names. */ #define AR_STRINGTAB_NAME_SVR4 "//" #define AR_SYMTAB_NAME_BSD "__.SYMDEF" #define AR_SYMTAB_NAME_SVR4 "/" /* * Convenient wrapper for general libarchive error handling. */ #define AC(CALL) do { \ if ((CALL)) \ bsdar_errc(bsdar, 0, "%s", \ archive_error_string(a)); \ } while (0) /* * The 'ACV' wrapper is used for libarchive APIs that changed from * returning 'void' to returning an 'int' in later versions of libarchive. */ #if ARCHIVE_VERSION_NUMBER >= 2000000 #define ACV(CALL) AC(CALL) #else #define ACV(CALL) do { \ (CALL); \ } while (0) #endif /* * In-memory representation of archive member(object). */ struct ar_obj { Elf *elf; /* object file descriptor */ char *name; /* member name */ uid_t uid; /* user id */ gid_t gid; /* group id */ mode_t md; /* octal file permissions */ size_t size; /* member size */ time_t mtime; /* modification time */ dev_t dev; /* inode's device */ ino_t ino; /* inode's number */ TAILQ_ENTRY(ar_obj) objs; }; /* * Structure encapsulates the "global" data for "ar" program. */ struct bsdar { const char *filename; /* archive name. */ const char *addlib; /* target of ADDLIB. */ const char *posarg; /* position arg for modifiers -a, -b. */ char mode; /* program mode */ int options; /* command line options */ FILE *output; /* default output stream */ const char *progname; /* program name */ int argc; char **argv; dev_t ar_dev; /* archive device. */ ino_t ar_ino; /* archive inode. */ /* * Fields for the archive string table. */ char *as; /* buffer for archive string table. */ size_t as_sz; /* current size of as table. */ size_t as_cap; /* capacity of as table buffer. */ /* * Fields for the archive symbol table. */ uint32_t s_cnt; /* current number of symbols. */ uint32_t *s_so; /* symbol offset table. */ size_t s_so_cap; /* capacity of so table buffer. */ char *s_sn; /* symbol name table */ size_t s_sn_cap; /* capacity of sn table buffer. */ size_t s_sn_sz; /* current size of sn table. */ /* Current member's offset (relative to the end of pseudo members.) */ off_t rela_off; TAILQ_HEAD(, ar_obj) v_obj; /* object(member) list */ }; void ar_mode_script(struct bsdar *ar); -void ar_read_archive(struct bsdar *_ar, int _mode); -void ar_write_archive(struct bsdar *_ar, int _mode); +int ar_read_archive(struct bsdar *_ar, int _mode); +int ar_write_archive(struct bsdar *_ar, int _mode); void bsdar_errc(struct bsdar *, int _code, const char *fmt, ...); int bsdar_is_pseudomember(struct bsdar *_ar, const char *_name); const char *bsdar_strmode(mode_t m); void bsdar_warnc(struct bsdar *, int _code, const char *fmt, ...); Index: stable/11/contrib/elftoolchain/ar/ranlib.1 =================================================================== --- stable/11/contrib/elftoolchain/ar/ranlib.1 (revision 367465) +++ stable/11/contrib/elftoolchain/ar/ranlib.1 (revision 367466) @@ -1,86 +1,86 @@ .\" Copyright (c) 2007,2009-2012 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: ranlib.1 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: ranlib.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" .Dd December 9, 2012 -.Os .Dt RANLIB 1 +.Os .Sh NAME .Nm ranlib .Nd update archive symbol tables .Sh SYNOPSIS .Nm .Op Fl D .Op Fl t .Ar archive Ns ... .Nm .Fl V .Sh DESCRIPTION The .Nm ranlib utility is used to update an existing archive symbol table in an .Xr ar 1 archive, or to add an archive symbol table to an archive lacking one. .Sh OPTIONS The .Nm utility supports the following options: .Bl -tag -width indent .It Fl D Use zeros for the mtime, uid and gid fields, and use mode 0644 for the file mode field for all archive member headers. This ensures that checksums on the resulting archives are reproducible when member contents are identical. .It Fl t This option is accepted, but is ignored. .It Fl V Print a version identifier and exit. .El .Sh EXAMPLES To update the archive symbol table for an archive .Pa lib.a , use: .Dl "ranlib lib.a" .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO .Xr ar 1 , .Xr ld 1 , .Xr archive 3 , .Xr elf 3 , .Xr ar 5 .Sh HISTORY The .Nm command first appeared in AT&T UNIX Version 7. .Pp In .Fx 8.0 , .An Kai Wang Aq Mt kaiw@FreeBSD.org reimplemented .Nm using the .Lb libarchive and the .Lb libelf . Index: stable/11/contrib/elftoolchain/ar/read.c =================================================================== --- stable/11/contrib/elftoolchain/ar/read.c (revision 367465) +++ stable/11/contrib/elftoolchain/ar/read.c (revision 367466) @@ -1,199 +1,221 @@ /*- * Copyright (c) 2007 Kai Wang * Copyright (c) 2007 Tim Kientzle * 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 * in this position and unchanged. * 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(S) ``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(S) 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 "ar.h" -ELFTC_VCSID("$Id: read.c 3180 2015-04-09 15:13:57Z emaste $"); +ELFTC_VCSID("$Id: read.c 3629 2018-09-30 19:26:28Z jkoshy $"); /* * Handle read modes: 'x', 't' and 'p'. + * + * Returns EXIT_SUCCESS if all operations completed successfully or returns + * EXIT_FAILURE otherwise. */ -void +int ar_read_archive(struct bsdar *bsdar, int mode) { FILE *out; struct archive *a; struct archive_entry *entry; struct stat sb; struct tm *tp; const char *bname; const char *name; mode_t md; size_t size; time_t mtime; uid_t uid; gid_t gid; char **av; char buf[25]; - char find; - int i, flags, r; + int found; + int exitcode, i, flags, r; assert(mode == 'p' || mode == 't' || mode == 'x'); if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, 0, "archive_read_new failed"); archive_read_support_format_ar(a); AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ)); + exitcode = EXIT_SUCCESS; out = bsdar->output; for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || r == ARCHIVE_FATAL) bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); if (r == ARCHIVE_EOF || r == ARCHIVE_FATAL) break; if (r == ARCHIVE_RETRY) { bsdar_warnc(bsdar, 0, "Retrying..."); continue; } if (archive_format(a) == ARCHIVE_FORMAT_AR_BSD) bsdar->options |= AR_BSD; else bsdar->options &= ~AR_BSD; if ((name = archive_entry_pathname(entry)) == NULL) break; /* Skip pseudo members. */ if (bsdar_is_pseudomember(bsdar, name)) continue; + /* The ar(5) format only supports 'leaf' file names. */ + if (strchr(name, '/')) { + bsdar_warnc(bsdar, 0, "ignoring entry: %s", + name); + continue; + } + + /* + * If we had been given a list of file names to process, check + * that the current entry is present in this list. + */ if (bsdar->argc > 0) { - find = 0; + found = 0; for(i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; if (*av == NULL) continue; + /* + * Per POSIX, only the basename of a file + * argument should be compared. + */ if ((bname = basename(*av)) == NULL) bsdar_errc(bsdar, errno, "basename failed"); if (strcmp(bname, name) != 0) continue; *av = NULL; - find = 1; + found = 1; break; } - if (!find) + if (!found) continue; } if (mode == 't') { if (bsdar->options & AR_V) { md = archive_entry_mode(entry); uid = archive_entry_uid(entry); gid = archive_entry_gid(entry); size = archive_entry_size(entry); mtime = archive_entry_mtime(entry); (void)fprintf(out, "%s %6d/%-6d %8ju ", bsdar_strmode(md) + 1, uid, gid, (uintmax_t)size); tp = localtime(&mtime); (void)strftime(buf, sizeof(buf), "%b %e %H:%M %Y", tp); (void)fprintf(out, "%s %s", buf, name); } else (void)fprintf(out, "%s", name); r = archive_read_data_skip(a); if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || r == ARCHIVE_FATAL) { (void)fprintf(out, "\n"); bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) break; (void)fprintf(out, "\n"); } else { /* mode == 'x' || mode = 'p' */ if (mode == 'p') { if (bsdar->options & AR_V) { (void)fprintf(out, "\n<%s>\n\n", name); fflush(out); } r = archive_read_data_into_fd(a, fileno(out)); } else { /* mode == 'x' */ if (stat(name, &sb) != 0) { if (errno != ENOENT) { - bsdar_warnc(bsdar, 0, + bsdar_warnc(bsdar, errno, "stat %s failed", bsdar->filename); continue; } } else { /* stat success, file exist */ if (bsdar->options & AR_CC) continue; if (bsdar->options & AR_U && archive_entry_mtime(entry) <= sb.st_mtime) continue; } if (bsdar->options & AR_V) (void)fprintf(out, "x - %s\n", name); - /* Disallow absolute paths. */ - if (name[0] == '/') { - bsdar_warnc(bsdar, 0, - "Absolute path '%s'", name); - continue; - } /* Basic path security flags. */ flags = ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_SECURE_NODOTDOT; if (bsdar->options & AR_O) flags |= ARCHIVE_EXTRACT_TIME; r = archive_read_extract(a, entry, flags); } - if (r) + if (r) { bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); + exitcode = EXIT_FAILURE; + } } } + + if (r == ARCHIVE_FATAL) + exitcode = EXIT_FAILURE; + AC(archive_read_close(a)); ACV(archive_read_free(a)); + + return (exitcode); } Index: stable/11/contrib/elftoolchain/ar/write.c =================================================================== --- stable/11/contrib/elftoolchain/ar/write.c (revision 367465) +++ stable/11/contrib/elftoolchain/ar/write.c (revision 367466) @@ -1,975 +1,986 @@ /*- * Copyright (c) 2007 Kai Wang * 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 * in this position and unchanged. * 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(S) ``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(S) 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 "ar.h" -ELFTC_VCSID("$Id: write.c 3183 2015-04-10 16:18:42Z emaste $"); +ELFTC_VCSID("$Id: write.c 3629 2018-09-30 19:26:28Z jkoshy $"); #define _ARMAG_LEN 8 /* length of the magic string */ #define _ARHDR_LEN 60 /* length of the archive header */ #define _INIT_AS_CAP 128 /* initial archive string table size */ #define _INIT_SYMOFF_CAP (256*(sizeof(uint32_t))) /* initial so table size */ #define _INIT_SYMNAME_CAP 1024 /* initial sn table size */ #define _MAXNAMELEN_SVR4 15 /* max member name length in svr4 variant */ #define _MAXNAMELEN_BSD 16 /* max member name length in bsd variant */ #define _TRUNCATE_LEN 15 /* number of bytes to keep for member name */ static void add_to_ar_str_table(struct bsdar *bsdar, const char *name); static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name); static struct ar_obj *create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime); static void create_symtab_entry(struct bsdar *bsdar, Elf *e); static void free_obj(struct ar_obj *obj); static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos); static void read_objs(struct bsdar *bsdar, const char *archive, int checkargv); static void write_cleanup(struct bsdar *bsdar); static void write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s); static void write_objs(struct bsdar *bsdar); /* * Create an object from a file, and return the created object * descriptor. Return NULL if either an error occurs, or if the '-u' * option was specified and the member is not newer than the existing * one in the archive. */ static struct ar_obj * create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime) { struct ar_obj *obj; struct stat sb; const char *bname; char *tmpname; int fd; if (name == NULL) return (NULL); obj = malloc(sizeof(struct ar_obj)); if (obj == NULL) bsdar_errc(bsdar, errno, "malloc failed"); obj->elf = NULL; if ((fd = open(name, O_RDONLY, 0)) < 0) { bsdar_warnc(bsdar, errno, "can't open file: %s", name); free(obj); return (NULL); } tmpname = strdup(name); if ((bname = basename(tmpname)) == NULL) bsdar_errc(bsdar, errno, "basename failed"); if (bsdar->options & AR_TR && strlen(bname) > _TRUNCATE_LEN) { if ((obj->name = malloc(_TRUNCATE_LEN + 1)) == NULL) bsdar_errc(bsdar, errno, "malloc failed"); (void)strncpy(obj->name, bname, _TRUNCATE_LEN); obj->name[_TRUNCATE_LEN] = '\0'; } else if ((obj->name = strdup(bname)) == NULL) bsdar_errc(bsdar, errno, "strdup failed"); free(tmpname); if (fstat(fd, &sb) < 0) { bsdar_warnc(bsdar, errno, "can't fstat file: %s", obj->name); goto giveup; } if (!S_ISREG(sb.st_mode)) { bsdar_warnc(bsdar, 0, "%s is not an ordinary file", obj->name); goto giveup; } if (sb.st_dev == bsdar->ar_dev && sb.st_ino == bsdar->ar_ino) { bsdar_warnc(bsdar, 0, "cannot add archive \"%s\" to itself", obj->name); goto giveup; } /* * If the '-u' option is specified and member is not newer * than the existing one, we should not replace the member. * However, if mtime == 0, i.e., if nonexistent members are to * be forcibly replaced, then the '-u' option is to be ignored. */ if (mtime != 0 && bsdar->options & AR_U && sb.st_mtime <= mtime) goto giveup; /* * When the '-D' option is specified, the mtime and UID/GID of * the member will be set to 0, and the file mode will be set * to 644. This ensures that checksums will match for two * archives containing identical content. */ if (bsdar->options & AR_D) { obj->uid = 0; obj->gid = 0; obj->mtime = 0; obj->md = S_IFREG | 0644; } else { obj->uid = sb.st_uid; obj->gid = sb.st_gid; obj->mtime = sb.st_mtime; obj->md = sb.st_mode; } obj->size = sb.st_size; obj->dev = sb.st_dev; obj->ino = sb.st_ino; if (obj->size == 0) { return (obj); } if ((obj->elf = elf_open(fd)) == NULL) { bsdar_warnc(bsdar, 0, "file initialization failed for %s: %s", obj->name, elf_errmsg(-1)); goto giveup; } /* * Read the object fully into memory and close its file * descriptor. */ if (elf_cntl(obj->elf, ELF_C_FDREAD) < 0) { bsdar_warnc(bsdar, 0, "%s could not be read in: %s", obj->name, elf_errmsg(-1)); goto giveup; } if (close(fd) < 0) bsdar_errc(bsdar, errno, "close failed: %s", obj->name); return (obj); giveup: if (obj->elf) elf_end(obj->elf); if (close(fd) < 0) bsdar_errc(bsdar, errno, "close failed: %s", obj->name); free(obj->name); free(obj); return (NULL); } /* * Free an object and its associated allocations. */ static void free_obj(struct ar_obj *obj) { if (obj->elf) elf_end(obj->elf); free(obj->name); free(obj); } /* * Insert an object into a list, either before/after the 'pos' obj or * at the end of the list. */ static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos) { if (obj == NULL) bsdar_errc(bsdar, 0, "try to insert a null obj"); if (pos == NULL || obj == pos) /* * If the object to move happens to be the position * obj, or if there is no position obj, move the * object to the end. */ goto tail; if (bsdar->options & AR_B) { TAILQ_INSERT_BEFORE(pos, obj, objs); return; } if (bsdar->options & AR_A) { TAILQ_INSERT_AFTER(&bsdar->v_obj, pos, obj, objs); return; } tail: TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); } /* * Read objects from archive into the 'v_obj' list. Note that * 'checkargv' is set when read_objs() is used to read objects from * the target of 'ADDLIB' command in ar script mode; in this case the * 'argv' array specifies the members that 'ADDLIB' is to operate on. */ static void read_objs(struct bsdar *bsdar, const char *archive, int checkargv) { struct archive *a; struct archive_entry *entry; struct ar_obj *obj; const char *name; const char *bname; char *buff; char **av; size_t size; int i, r, find; if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, 0, "archive_read_new failed"); archive_read_support_format_ar(a); AC(archive_read_open_filename(a, archive, DEF_BLKSZ)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_FATAL) bsdar_errc(bsdar, 0, "%s", archive_error_string(a)); if (r == ARCHIVE_EOF) break; if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); if (r == ARCHIVE_RETRY) { bsdar_warnc(bsdar, 0, "Retrying..."); continue; } name = archive_entry_pathname(entry); /* * Skip pseudo members. */ if (bsdar_is_pseudomember(bsdar, name)) continue; /* * If 'checkargv' is set, only read those members * specified in argv. */ if (checkargv && bsdar->argc > 0) { find = 0; for(i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; if (*av == NULL) continue; if ((bname = basename(*av)) == NULL) bsdar_errc(bsdar, errno, "basename failed"); if (strcmp(bname, name) != 0) continue; *av = NULL; find = 1; break; } if (!find) continue; } size = archive_entry_size(entry); if (size > 0) { if ((buff = malloc(size)) == NULL) bsdar_errc(bsdar, errno, "malloc failed"); if (archive_read_data(a, buff, size) != (ssize_t)size) { bsdar_warnc(bsdar, 0, "%s", archive_error_string(a)); free(buff); continue; } } else buff = NULL; obj = malloc(sizeof(struct ar_obj)); if (obj == NULL) bsdar_errc(bsdar, errno, "malloc failed"); obj->elf = NULL; if (buff) { obj->elf = elf_openmemory(buff, size); if (obj->elf == NULL) { bsdar_warnc(bsdar, 0, "elf_openmemory() " "failed for %s: %s", name, elf_errmsg(-1)); free(buff); free(obj); continue; } } if ((obj->name = strdup(name)) == NULL) bsdar_errc(bsdar, errno, "strdup failed"); obj->size = size; obj->uid = archive_entry_uid(entry); obj->gid = archive_entry_gid(entry); obj->md = archive_entry_mode(entry); obj->mtime = archive_entry_mtime(entry); obj->dev = 0; obj->ino = 0; TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs); } AC(archive_read_close(a)); ACV(archive_read_free(a)); } /* * Write an archive. + * + * Returns EXIT_SUCCESS if the write succeeded or EXIT_FAILURE otherwise. */ -void +int ar_write_archive(struct bsdar *bsdar, int mode) { struct ar_obj *nobj, *obj, *obj_temp, *pos; struct stat sb; const char *bname; char **av; - int i; + int exitcode, i; TAILQ_INIT(&bsdar->v_obj); + exitcode = EXIT_SUCCESS; nobj = NULL; pos = NULL; memset(&sb, 0, sizeof(sb)); assert(mode == 'A' || mode == 'd' || mode == 'm' || mode == 'q' || mode == 'r' || mode == 's'); /* * Test if the specified archive exists, to determine * whether we are creating a new archive. */ if (stat(bsdar->filename, &sb) != 0) { if (errno != ENOENT) { - bsdar_warnc(bsdar, 0, "stat %s failed", + bsdar_warnc(bsdar, errno, "stat %s failed", bsdar->filename); - return; + return (EXIT_FAILURE); } /* We do not create archive in mode 'd', 'm' and 's'. */ if (mode != 'r' && mode != 'q') { bsdar_warnc(bsdar, 0, "%s: no such file", bsdar->filename); - return; + return (EXIT_FAILURE); } /* Issue a message if the '-c' option was not specified. */ if (!(bsdar->options & AR_C)) bsdar_warnc(bsdar, 0, "creating %s", bsdar->filename); goto new_archive; } bsdar->ar_dev = sb.st_dev; bsdar->ar_ino = sb.st_ino; /* * First read members from the existing archive. */ read_objs(bsdar, bsdar->filename, 0); /* * For mode 's', no member will be moved, deleted or replaced. */ if (mode == 's') goto write_objs; /* * For mode 'q', we don't need to adjust existing members either. * Also, -a, -b and -i are ignored in this mode. New members are * always inserted at tail. */ if (mode == 'q') goto new_archive; /* * Mode 'A' adds the contents of another archive to the tail * of current archive. Note that mode 'A' is a special mode * for the 'ADDLIB' command in ar's script mode. Currently * there is no option that invokes this function from ar's * command line. */ if (mode == 'A') { /* * Read objects from the target archive of the * 'ADDLIB' command. If there are members specified in * 'argv', read those members only, otherwise the * entire archive will be read. */ read_objs(bsdar, bsdar->addlib, 1); goto write_objs; } /* * Try to find the position member specified by user. */ if (bsdar->options & AR_A || bsdar->options & AR_B) { TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { if (strcmp(obj->name, bsdar->posarg) == 0) { pos = obj; break; } } /* * If we cannot find the position specified by the * user, silently insert objects at the tail of the * list. */ if (pos == NULL) bsdar->options &= ~(AR_A | AR_B); } for (i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { if ((bname = basename(*av)) == NULL) bsdar_errc(bsdar, errno, "basename failed"); if (bsdar->options & AR_TR) { if (strncmp(bname, obj->name, _TRUNCATE_LEN)) continue; } else if (strcmp(bname, obj->name) != 0) continue; if (mode == 'r') { /* * If the new member should not * replace the old one, skip it. */ nobj = create_obj_from_file(bsdar, *av, obj->mtime); - if (nobj == NULL) + if (nobj == NULL) { + exitcode = EXIT_FAILURE; goto skip_obj; + } } if (bsdar->options & AR_V) (void)fprintf(bsdar->output, "%c - %s\n", mode, *av); TAILQ_REMOVE(&bsdar->v_obj, obj, objs); if (mode == 'd' || mode == 'r') free_obj(obj); if (mode == 'm') insert_obj(bsdar, obj, pos); if (mode == 'r') insert_obj(bsdar, nobj, pos); skip_obj: *av = NULL; break; } } new_archive: /* * When operating in mode 'r', directly add the specified * objects which do not exist in current archive. When * operating in mode 'q', all objects specified by the command * line args are appended to the archive, without checking * existing members in the archive. */ for (i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; if (*av != NULL && (mode == 'r' || mode == 'q')) { nobj = create_obj_from_file(bsdar, *av, 0); - if (nobj != NULL) - insert_obj(bsdar, nobj, pos); - if (bsdar->options & AR_V && nobj != NULL) + if (nobj == NULL) { + exitcode = EXIT_FAILURE; + *av = NULL; + continue; + } + insert_obj(bsdar, nobj, pos); + if (bsdar->options & AR_V) (void)fprintf(bsdar->output, "a - %s\n", *av); *av = NULL; } } write_objs: write_objs(bsdar); write_cleanup(bsdar); + + return (exitcode); } /* * Release memory. */ static void write_cleanup(struct bsdar *bsdar) { struct ar_obj *obj, *obj_temp; TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) { TAILQ_REMOVE(&bsdar->v_obj, obj, objs); free_obj(obj); } free(bsdar->as); free(bsdar->s_so); free(bsdar->s_sn); bsdar->as = NULL; bsdar->s_so = NULL; bsdar->s_sn = NULL; } /* * Wrapper for archive_write_data(). */ static void write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s) { if (archive_write_data(a, buf, s) != (ssize_t)s) bsdar_errc(bsdar, 0, "%s", archive_error_string(a)); } /* * Compute the size of the symbol table for an archive. */ static size_t bsdar_symtab_size(struct bsdar *bsdar) { size_t sz; if (bsdar->options & AR_BSD) { /* * A BSD style symbol table has two parts. * Each part is preceded by its size in bytes, * encoded as a C 'long'. In the first part, * there are 's_cnt' entries, each entry being * 2 'long's in size. The second part * contains a string table. */ sz = 2 * sizeof(long) + (bsdar->s_cnt * 2 * sizeof(long)) + bsdar->s_sn_sz; } else { /* * An SVR4 style symbol table comprises of a 32 bit * number holding the number of entries, followed by * that many 32-bit offsets, followed by a string * table. */ sz = sizeof(uint32_t) + bsdar->s_cnt * sizeof(uint32_t) + bsdar->s_sn_sz; } return (sz); } static void write_svr4_symtab_entry(struct bsdar *bsdar, struct archive *a) { int nr; uint32_t i; /* Translate offsets to big-endian form. */ for (i = 0; i < bsdar->s_cnt; i++) bsdar->s_so[i] = htobe32(bsdar->s_so[i]); nr = htobe32(bsdar->s_cnt); write_data(bsdar, a, &nr, sizeof(uint32_t)); write_data(bsdar, a, bsdar->s_so, sizeof(uint32_t) * bsdar->s_cnt); write_data(bsdar, a, bsdar->s_sn, bsdar->s_sn_sz); } static void write_bsd_symtab_entry(struct bsdar *bsdar, struct archive *a) { long br_sz, br_off, br_strx; char *s; uint32_t i; /* * Write out the size in the byte of the array of 'ranlib' * descriptors to follow. */ br_sz = (long) (bsdar->s_cnt * 2 * sizeof(long)); write_data(bsdar, a, &br_sz, sizeof(long)); /* * Write out the array of 'ranlib' descriptors. Each * descriptor comprises of (a) an offset into the following * string table and (b) a file offset to the relevant member. */ for (i = 0, s = bsdar->s_sn; i < bsdar->s_cnt; i++) { br_strx = (long) (s - bsdar->s_sn); br_off = (long) bsdar->s_so[i]; write_data(bsdar, a, &br_strx, sizeof(long)); write_data(bsdar, a, &br_off, sizeof(long)); /* Find the start of the next symbol in the string table. */ while (*s++ != '\0') ; } /* * Write out the size of the string table as a 'long', * followed by the string table itself. */ br_sz = (long) bsdar->s_sn_sz; write_data(bsdar, a, &br_sz, sizeof(long)); write_data(bsdar, a, bsdar->s_sn, bsdar->s_sn_sz); } /* * Write the resulting archive members. */ static void write_objs(struct bsdar *bsdar) { struct ar_obj *obj; struct archive *a; struct archive_entry *entry; size_t s_sz; /* size of archive symbol table. */ size_t pm_sz; /* size of pseudo members */ size_t namelen; /* size of member name. */ size_t obj_sz; /* size of object + extended header. */ int i; char *buf; const char *entry_name; bsdar->rela_off = 0; /* * Create the archive symbol table and the archive string * table, if needed. */ TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { if (!(bsdar->options & AR_SS) && obj->elf != NULL) create_symtab_entry(bsdar, obj->elf); obj_sz = 0; namelen = strlen(obj->name); if (bsdar->options & AR_BSD) { /* Account for the space used by the file name. */ if (namelen > _MAXNAMELEN_BSD || strchr(obj->name, ' ')) obj_sz += namelen; } else if (namelen > _MAXNAMELEN_SVR4) add_to_ar_str_table(bsdar, obj->name); obj_sz += obj->size; /* add the actual object size */ /* Roundup the final size and add the header length. */ bsdar->rela_off += _ARHDR_LEN + obj_sz + (obj_sz & 1); } /* * Pad the symbol name string table. It is treated specially * because symbol name table should be padded by a '\0', and * not '\n' as for normal members. The size of the 'sn' table * includes the pad byte. */ if (bsdar->s_cnt != 0 && bsdar->s_sn_sz % 2 != 0) bsdar->s_sn[bsdar->s_sn_sz++] = '\0'; /* * The archive string table is padded by a "\n" like a normal * member. The difference is that the size of archive string * table includes the pad byte, while normal members' size * fields do not. */ if (bsdar->as != NULL && bsdar->as_sz % 2 != 0) bsdar->as[bsdar->as_sz++] = '\n'; /* * If there is a symbol table, calculate the size of pseudo * members, and convert previously stored relative offsets to * absolute ones. * * absolute_offset = relative_offset + size_of_pseudo_members) */ s_sz = bsdar_symtab_size(bsdar); if (bsdar->s_cnt != 0) { pm_sz = _ARMAG_LEN + (_ARHDR_LEN + s_sz); if (bsdar->as != NULL) /* SVR4 archives only */ pm_sz += _ARHDR_LEN + bsdar->as_sz; for (i = 0; (size_t) i < bsdar->s_cnt; i++) bsdar->s_so[i] = bsdar->s_so[i] + pm_sz; } if ((a = archive_write_new()) == NULL) bsdar_errc(bsdar, 0, "archive_write_new failed"); if (bsdar->options & AR_BSD) archive_write_set_format_ar_bsd(a); else archive_write_set_format_ar_svr4(a); AC(archive_write_open_filename(a, bsdar->filename)); /* * Write the archive symbol table, if there is one. If * options '-s' was explicitly specified or if we were invoked * as 'ranlib', write the symbol table even if it is empty. */ if ((bsdar->s_cnt != 0 && !(bsdar->options & AR_SS)) || bsdar->options & AR_S) { if (bsdar->options & AR_BSD) entry_name = AR_SYMTAB_NAME_BSD; else entry_name = AR_SYMTAB_NAME_SVR4; entry = archive_entry_new(); archive_entry_copy_pathname(entry, entry_name); if ((bsdar->options & AR_D) == 0) archive_entry_set_mtime(entry, time(NULL), 0); archive_entry_set_size(entry, s_sz); AC(archive_write_header(a, entry)); if (bsdar->options & AR_BSD) write_bsd_symtab_entry(bsdar, a); else write_svr4_symtab_entry(bsdar, a); archive_entry_free(entry); } /* Write the archive string table, if any. */ if (bsdar->as != NULL) { entry = archive_entry_new(); archive_entry_copy_pathname(entry, AR_STRINGTAB_NAME_SVR4); archive_entry_set_size(entry, bsdar->as_sz); AC(archive_write_header(a, entry)); write_data(bsdar, a, bsdar->as, bsdar->as_sz); archive_entry_free(entry); } /* Write normal members. */ TAILQ_FOREACH(obj, &bsdar->v_obj, objs) { if ((buf = elf_rawfile(obj->elf, NULL)) == NULL) { bsdar_warnc(bsdar, 0, "elf_rawfile() failed: %s", elf_errmsg(-1)); continue; } entry = archive_entry_new(); archive_entry_copy_pathname(entry, obj->name); archive_entry_set_uid(entry, obj->uid); archive_entry_set_gid(entry, obj->gid); archive_entry_set_mode(entry, obj->md); archive_entry_set_size(entry, obj->size); archive_entry_set_mtime(entry, obj->mtime, 0); archive_entry_set_dev(entry, obj->dev); archive_entry_set_ino(entry, obj->ino); archive_entry_set_filetype(entry, AE_IFREG); AC(archive_write_header(a, entry)); write_data(bsdar, a, buf, obj->size); archive_entry_free(entry); } AC(archive_write_close(a)); ACV(archive_write_free(a)); } /* * Extract global symbols from ELF binary members. */ static void create_symtab_entry(struct bsdar *bsdar, Elf *e) { Elf_Scn *scn; GElf_Shdr shdr; GElf_Sym sym; Elf_Data *data; char *name; size_t n, shstrndx; int elferr, tabndx, len, i; if (elf_kind(e) != ELF_K_ELF) { /* Silently a ignore non-ELF member. */ return; } if (elf_getshstrndx(e, &shstrndx) == 0) { bsdar_warnc(bsdar, 0, "elf_getshstrndx failed: %s", elf_errmsg(-1)); return; } tabndx = -1; scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != &shdr) { bsdar_warnc(bsdar, 0, "elf_getshdr failed: %s", elf_errmsg(-1)); continue; } if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) { bsdar_warnc(bsdar, 0, "elf_strptr failed: %s", elf_errmsg(-1)); continue; } if (strcmp(name, ".strtab") == 0) { tabndx = elf_ndxscn(scn); break; } } elferr = elf_errno(); if (elferr != 0) bsdar_warnc(bsdar, 0, "elf_nextscn failed: %s", elf_errmsg(elferr)); if (tabndx == -1) { bsdar_warnc(bsdar, 0, "can't find .strtab section"); return; } scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != &shdr) { bsdar_warnc(bsdar, 0, "elf_getshdr failed: %s", elf_errmsg(-1)); continue; } if (shdr.sh_type != SHT_SYMTAB) continue; data = NULL; n = 0; while (n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL) { len = data->d_size / shdr.sh_entsize; for (i = 0; i < len; i++) { if (gelf_getsym(data, i, &sym) != &sym) { bsdar_warnc(bsdar, 0, "gelf_getsym failed: %s", elf_errmsg(-1)); continue; } /* Keep only global and weak symbols. */ if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL && GELF_ST_BIND(sym.st_info) != STB_WEAK) continue; /* Keep only defined symbols. */ if (sym.st_shndx == SHN_UNDEF) continue; if ((name = elf_strptr(e, tabndx, sym.st_name)) == NULL) { bsdar_warnc(bsdar, 0, "elf_strptr failed: %s", elf_errmsg(-1)); continue; } add_to_ar_sym_table(bsdar, name); } } } elferr = elf_errno(); if (elferr != 0) bsdar_warnc(bsdar, 0, "elf_nextscn failed: %s", elf_errmsg(elferr)); } /* * Append to the archive string table buffer. */ static void add_to_ar_str_table(struct bsdar *bsdar, const char *name) { if (bsdar->as == NULL) { bsdar->as_cap = _INIT_AS_CAP; bsdar->as_sz = 0; if ((bsdar->as = malloc(bsdar->as_cap)) == NULL) bsdar_errc(bsdar, errno, "malloc failed"); } /* * The space required for holding one member name in the 'as' * table includes: strlen(name) + (1 for '/') + (1 for '\n') + * (possibly 1 for padding). */ while (bsdar->as_sz + strlen(name) + 3 > bsdar->as_cap) { bsdar->as_cap *= 2; bsdar->as = realloc(bsdar->as, bsdar->as_cap); if (bsdar->as == NULL) bsdar_errc(bsdar, errno, "realloc failed"); } strncpy(&bsdar->as[bsdar->as_sz], name, strlen(name)); bsdar->as_sz += strlen(name); bsdar->as[bsdar->as_sz++] = '/'; bsdar->as[bsdar->as_sz++] = '\n'; } /* * Append to the archive symbol table buffer. */ static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name) { if (bsdar->s_so == NULL) { if ((bsdar->s_so = malloc(_INIT_SYMOFF_CAP)) == NULL) bsdar_errc(bsdar, errno, "malloc failed"); bsdar->s_so_cap = _INIT_SYMOFF_CAP; bsdar->s_cnt = 0; } if (bsdar->s_sn == NULL) { if ((bsdar->s_sn = malloc(_INIT_SYMNAME_CAP)) == NULL) bsdar_errc(bsdar, errno, "malloc failed"); bsdar->s_sn_cap = _INIT_SYMNAME_CAP; bsdar->s_sn_sz = 0; } if (bsdar->s_cnt * sizeof(uint32_t) >= bsdar->s_so_cap) { bsdar->s_so_cap *= 2; bsdar->s_so = realloc(bsdar->s_so, bsdar->s_so_cap); if (bsdar->s_so == NULL) bsdar_errc(bsdar, errno, "realloc failed"); } bsdar->s_so[bsdar->s_cnt] = bsdar->rela_off; bsdar->s_cnt++; /* * The space required for holding one symbol name in the 'sn' * table includes: strlen(name) + (1 for '\n') + (possibly 1 * for padding). */ while (bsdar->s_sn_sz + strlen(name) + 2 > bsdar->s_sn_cap) { bsdar->s_sn_cap *= 2; bsdar->s_sn = realloc(bsdar->s_sn, bsdar->s_sn_cap); if (bsdar->s_sn == NULL) bsdar_errc(bsdar, errno, "realloc failed"); } strncpy(&bsdar->s_sn[bsdar->s_sn_sz], name, strlen(name)); bsdar->s_sn_sz += strlen(name); bsdar->s_sn[bsdar->s_sn_sz++] = '\0'; } Index: stable/11/contrib/elftoolchain/common/_elftc.h =================================================================== --- stable/11/contrib/elftoolchain/common/_elftc.h (revision 367465) +++ stable/11/contrib/elftoolchain/common/_elftc.h (revision 367466) @@ -1,484 +1,489 @@ /*- * 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 3446 2016-05-03 01:31:17Z emaste $ */ /** ** Miscellaneous 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 /* --QUEUE-MACROS-- [[ */ /* * Supply macros missing from */ /* * Copyright (c) 1991, 1993 * The Regents of the University of California. 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #ifndef LIST_FOREACH_SAFE #define LIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = LIST_FIRST((head)); \ (var) && ((tvar) = LIST_NEXT((var), field), 1); \ (var) = (tvar)) #endif #ifndef SLIST_FOREACH_SAFE #define SLIST_FOREACH_SAFE(var, head, field, tvar) \ for ((var) = SLIST_FIRST((head)); \ (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ (var) = (tvar)) #endif #ifndef STAILQ_CONCAT #define STAILQ_CONCAT(head1, head2) do { \ if (!STAILQ_EMPTY((head2))) { \ *(head1)->stqh_last = (head2)->stqh_first; \ (head1)->stqh_last = (head2)->stqh_last; \ STAILQ_INIT((head2)); \ } \ } while (/*CONSTCOND*/0) #endif #ifndef STAILQ_EMPTY #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) #endif #ifndef STAILQ_ENTRY #define STAILQ_ENTRY(type) \ struct { \ struct type *stqe_next; /* next element */ \ } #endif #ifndef STAILQ_FIRST #define STAILQ_FIRST(head) ((head)->stqh_first) #endif #ifndef STAILQ_HEAD #define STAILQ_HEAD(name, type) \ struct name { \ struct type *stqh_first; /* first element */ \ struct type **stqh_last; /* addr of last next element */ \ } #endif #ifndef STAILQ_HEAD_INITIALIZER #define STAILQ_HEAD_INITIALIZER(head) \ { NULL, &(head).stqh_first } #endif #ifndef STAILQ_FOREACH #define STAILQ_FOREACH(var, head, field) \ for ((var) = ((head)->stqh_first); \ (var); \ (var) = ((var)->field.stqe_next)) #endif #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_INIT #define STAILQ_INIT(head) do { \ (head)->stqh_first = NULL; \ (head)->stqh_last = &(head)->stqh_first; \ } while (/*CONSTCOND*/0) #endif #ifndef STAILQ_INSERT_HEAD #define STAILQ_INSERT_HEAD(head, elm, field) do { \ if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ (head)->stqh_last = &(elm)->field.stqe_next; \ (head)->stqh_first = (elm); \ } while (/*CONSTCOND*/0) #endif #ifndef STAILQ_INSERT_TAIL #define STAILQ_INSERT_TAIL(head, elm, field) do { \ (elm)->field.stqe_next = NULL; \ *(head)->stqh_last = (elm); \ (head)->stqh_last = &(elm)->field.stqe_next; \ } while (/*CONSTCOND*/0) #endif #ifndef STAILQ_INSERT_AFTER #define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\ (head)->stqh_last = &(elm)->field.stqe_next; \ (listelm)->field.stqe_next = (elm); \ } while (/*CONSTCOND*/0) #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 STAILQ_NEXT #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) #endif #ifndef STAILQ_REMOVE #define STAILQ_REMOVE(head, elm, type, field) do { \ if ((head)->stqh_first == (elm)) { \ STAILQ_REMOVE_HEAD((head), field); \ } else { \ struct type *curelm = (head)->stqh_first; \ while (curelm->field.stqe_next != (elm)) \ curelm = curelm->field.stqe_next; \ if ((curelm->field.stqe_next = \ curelm->field.stqe_next->field.stqe_next) == NULL) \ (head)->stqh_last = &(curelm)->field.stqe_next; \ } \ } while (/*CONSTCOND*/0) #endif #ifndef STAILQ_REMOVE_HEAD #define STAILQ_REMOVE_HEAD(head, field) do { \ if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == \ NULL) \ (head)->stqh_last = &(head)->stqh_first; \ } while (/*CONSTCOND*/0) #endif /* * The STAILQ_SORT macro is adapted from Simon Tatham's O(n*log(n)) * mergesort algorithm. */ #ifndef STAILQ_SORT #define STAILQ_SORT(head, type, field, cmp) do { \ STAILQ_HEAD(, type) _la, _lb; \ struct type *_p, *_q, *_e; \ int _i, _sz, _nmerges, _psz, _qsz; \ \ _sz = 1; \ do { \ _nmerges = 0; \ STAILQ_INIT(&_lb); \ while (!STAILQ_EMPTY((head))) { \ _nmerges++; \ STAILQ_INIT(&_la); \ _psz = 0; \ for (_i = 0; _i < _sz && !STAILQ_EMPTY((head)); \ _i++) { \ _e = STAILQ_FIRST((head)); \ if (_e == NULL) \ break; \ _psz++; \ STAILQ_REMOVE_HEAD((head), field); \ STAILQ_INSERT_TAIL(&_la, _e, field); \ } \ _p = STAILQ_FIRST(&_la); \ _qsz = _sz; \ _q = STAILQ_FIRST((head)); \ while (_psz > 0 || (_qsz > 0 && _q != NULL)) { \ if (_psz == 0) { \ _e = _q; \ _q = STAILQ_NEXT(_q, field); \ STAILQ_REMOVE_HEAD((head), \ field); \ _qsz--; \ } else if (_qsz == 0 || _q == NULL) { \ _e = _p; \ _p = STAILQ_NEXT(_p, field); \ STAILQ_REMOVE_HEAD(&_la, field);\ _psz--; \ } else if (cmp(_p, _q) <= 0) { \ _e = _p; \ _p = STAILQ_NEXT(_p, field); \ STAILQ_REMOVE_HEAD(&_la, field);\ _psz--; \ } else { \ _e = _q; \ _q = STAILQ_NEXT(_q, field); \ STAILQ_REMOVE_HEAD((head), \ field); \ _qsz--; \ } \ STAILQ_INSERT_TAIL(&_lb, _e, field); \ } \ } \ (head)->stqh_first = _lb.stqh_first; \ (head)->stqh_last = _lb.stqh_last; \ _sz *= 2; \ } while (_nmerges > 1); \ } while (/*CONSTCOND*/0) #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 /* ]] --QUEUE-MACROS-- */ /* * VCS Ids. */ #ifndef ELFTC_VCSID #if defined(__DragonFly__) #define ELFTC_VCSID(ID) __RCSID(ID) #endif #if defined(__FreeBSD__) #define ELFTC_VCSID(ID) __FBSDID(ID) #endif #if defined(__APPLE__) || defined(__GLIBC__) || defined(__GNU__) || \ defined(__linux__) #if defined(__GNUC__) #define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") #else #define ELFTC_VCSID(ID) /**/ #endif #endif #if defined(__minix) #if defined(__GNUC__) #define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") #else #define ELFTC_VCSID(ID) /**/ #endif /* __GNU__ */ #endif #if defined(__NetBSD__) #define ELFTC_VCSID(ID) __RCSID(ID) #endif #if defined(__OpenBSD__) #if defined(__GNUC__) #define ELFTC_VCSID(ID) __asm__(".ident\t\"" ID "\"") #else #define ELFTC_VCSID(ID) /**/ #endif /* __GNUC__ */ #endif #endif /* ELFTC_VCSID */ /* * Provide an equivalent for getprogname(3). */ #ifndef ELFTC_GETPROGNAME #if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || \ defined(__minix) || defined(__NetBSD__) #include #define ELFTC_GETPROGNAME() getprogname() #endif /* __DragonFly__ || __FreeBSD__ || __minix || __NetBSD__ */ #if defined(__GLIBC__) || defined(__linux__) #ifndef _GNU_SOURCE /* * GLIBC based systems have a global 'char *' pointer referencing * the executable's name. */ extern const char *program_invocation_short_name; #endif /* !_GNU_SOURCE */ #define ELFTC_GETPROGNAME() program_invocation_short_name #endif /* __GLIBC__ || __linux__ */ #if defined(__OpenBSD__) extern const char *__progname; #define ELFTC_GETPROGNAME() __progname #endif /* __OpenBSD__ */ #endif /* ELFTC_GETPROGNAME */ /** ** Per-OS configuration. **/ #if defined(__APPLE__) #include #define htobe32(x) OSSwapHostToBigInt32(x) +#define htole32(x) OSSwapHostToLittleInt32(x) +#ifndef roundup2 #define roundup2 roundup +#endif -#define ELFTC_BYTE_ORDER _BYTE_ORDER -#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN -#define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN +#define ELFTC_BYTE_ORDER __DARWIN_BYTE_ORDER +#define ELFTC_BYTE_ORDER_LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN +#define ELFTC_BYTE_ORDER_BIG_ENDIAN __DARWIN_BIG_ENDIAN #define ELFTC_HAVE_MMAP 1 #define ELFTC_HAVE_STRMODE 1 #define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 #endif /* __APPLE__ */ #if defined(__DragonFly__) #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_MMAP 1 #endif #if defined(__GLIBC__) || 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 #define ELFTC_HAVE_MMAP 1 /* * Debian GNU/Linux and Debian GNU/kFreeBSD do not have strmode(3). */ #define ELFTC_HAVE_STRMODE 0 /* Whether we need to supply {be,le}32dec. */ #define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 +#ifndef roundup2 #define roundup2 roundup +#endif #endif /* __GLIBC__ || __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_MMAP 1 #define ELFTC_HAVE_STRMODE 1 #if __FreeBSD_version <= 900000 #define ELFTC_BROKEN_YY_NO_INPUT 1 #endif #endif /* __FreeBSD__ */ #if defined(__minix) #define ELFTC_HAVE_MMAP 0 #endif /* __minix */ #if defined(__NetBSD__) #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_MMAP 1 #define ELFTC_HAVE_STRMODE 1 #if __NetBSD_Version__ <= 599002100 /* from src/doc/CHANGES: flex(1): Import flex-2.5.35 [christos 20091025] */ /* and 5.99.21 was from Wed Oct 21 21:28:36 2009 UTC */ # define ELFTC_BROKEN_YY_NO_INPUT 1 #endif #endif /* __NetBSD __ */ #if defined(__OpenBSD__) #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_MMAP 1 #define ELFTC_HAVE_STRMODE 1 #define ELFTC_NEED_BYTEORDER_EXTENSIONS 1 #define roundup2 roundup #endif /* __OpenBSD__ */ #endif /* _ELFTC_H */ Index: stable/11/contrib/elftoolchain/common/elfdefinitions.h =================================================================== --- stable/11/contrib/elftoolchain/common/elfdefinitions.h (revision 367465) +++ stable/11/contrib/elftoolchain/common/elfdefinitions.h (revision 367466) @@ -1,2900 +1,2952 @@ /*- * 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 3515 2017-01-24 22:04:22Z emaste $ + * $Id: elfdefinitions.h 3769 2019-06-29 15:15:02Z emaste $ */ /* * 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. + * ia64, powerpc, and RISC-V 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") + "uses static thread-local storage") \ +_ELF_DEFINE_DF(DF_1_BIND_NOW, 0x1, \ + "process relocation entries at load time") \ +_ELF_DEFINE_DF(DF_1_GLOBAL, 0x2, \ + "unused") \ +_ELF_DEFINE_DF(DF_1_GROUP, 0x4, \ + "object is a member of a group") \ +_ELF_DEFINE_DF(DF_1_NODELETE, 0x8, \ + "object cannot be deleted from a process") \ +_ELF_DEFINE_DF(DF_1_LOADFLTR, 0x10, \ + "immediate load filtees") \ +_ELF_DEFINE_DF(DF_1_INITFIRST, 0x20, \ + "initialize object first") \ +_ELF_DEFINE_DF(DF_1_NOOPEN, 0x40, \ + "disallow dlopen()") \ +_ELF_DEFINE_DF(DF_1_ORIGIN, 0x80, \ + "object being loaded may refer to $ORIGIN") \ +_ELF_DEFINE_DF(DF_1_DIRECT, 0x100, \ + "direct bindings enabled") \ +_ELF_DEFINE_DF(DF_1_INTERPOSE, 0x400, \ + "object is interposer") \ +_ELF_DEFINE_DF(DF_1_NODEFLIB, 0x800, \ + "ignore default library search path") \ +_ELF_DEFINE_DF(DF_1_NODUMP, 0x1000, \ + "disallow dldump()") \ +_ELF_DEFINE_DF(DF_1_CONFALT, 0x2000, \ + "object is a configuration alternative") \ +_ELF_DEFINE_DF(DF_1_ENDFILTEE, 0x4000, \ + "filtee terminates filter search") \ +_ELF_DEFINE_DF(DF_1_DISPRELDNE, 0x8000, \ + "displacement relocation done") \ +_ELF_DEFINE_DF(DF_1_DISPRELPND, 0x10000, \ + "displacement relocation pending") #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_SUNW_ASLR, 0x60000023UL, \ "Address Space Layout Randomization flag") \ _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, 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_TLSDESC_PLT, 0x6FFFFEF6UL, \ "location of PLT entry for TLS descriptor resolver calls") \ _ELF_DEFINE_DT(DT_TLSDESC_GOT, 0x6FFFFEF7UL, \ "location of GOT entry used by TLS descriptor resolver PLT entry") \ _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 referred 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_EABI_UNKNOWN, 0x00000000UL, \ "Unknown or GNU ARM EABI version number") \ _ELF_DEFINE_EF(EF_ARM_EABI_VER1, 0x01000000UL, \ "ARM EABI version 1") \ _ELF_DEFINE_EF(EF_ARM_EABI_VER2, 0x02000000UL, \ "ARM EABI version 2") \ _ELF_DEFINE_EF(EF_ARM_EABI_VER3, 0x03000000UL, \ "ARM EABI version 3") \ _ELF_DEFINE_EF(EF_ARM_EABI_VER4, 0x04000000UL, \ "ARM EABI version 4") \ _ELF_DEFINE_EF(EF_ARM_EABI_VER5, 0x05000000UL, \ "ARM EABI version 5") \ _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_RISCV_RVC, 0x00000001UL, \ + "Compressed instruction extension") \ +_ELF_DEFINE_EF(EF_RISCV_FLOAT_ABI_MASK, 0x00000006UL, \ + "Floating point ABI") \ +_ELF_DEFINE_EF(EF_RISCV_FLOAT_ABI_SOFT, 0x00000000UL, \ + "Software emulated floating point") \ +_ELF_DEFINE_EF(EF_RISCV_FLOAT_ABI_SINGLE, 0x00000002UL, \ + "Single precision floating point") \ +_ELF_DEFINE_EF(EF_RISCV_FLOAT_ABI_DOUBLE, 0x00000004UL, \ + "Double precision floating point") \ +_ELF_DEFINE_EF(EF_RISCV_FLOAT_ABI_QUAD, 0x00000006UL, \ + "Quad precision floating point") \ +_ELF_DEFINE_EF(EF_RISCV_RVE, 0x00000008UL, \ + "RV32E embedded ABI") \ +_ELF_DEFINE_EF(EF_RISCV_TSO, 0x00000010UL, \ + "RVTSO memory consistency model") \ _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_CLOUDABI, 17, "Nuxi CloudABI") \ _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_IAMCU, 6, "Intel MCU") \ _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_AARCH64, 183, \ "AArch64 (64-bit ARM)") \ _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") \ _ELF_DEFINE_EM(EM_56800EX, 200, \ "Freescale 56800EX Digital Signal Controller") \ _ELF_DEFINE_EM(EM_BA1, 201, "Beyond BA1 CPU architecture") \ _ELF_DEFINE_EM(EM_BA2, 202, "Beyond BA2 CPU architecture") \ _ELF_DEFINE_EM(EM_XCORE, 203, "XMOS xCORE processor family") \ _ELF_DEFINE_EM(EM_MCHP_PIC, 204, "Microchip 8-bit PIC(r) family") \ _ELF_DEFINE_EM(EM_INTEL205, 205, "Reserved by Intel") \ _ELF_DEFINE_EM(EM_INTEL206, 206, "Reserved by Intel") \ _ELF_DEFINE_EM(EM_INTEL207, 207, "Reserved by Intel") \ _ELF_DEFINE_EM(EM_INTEL208, 208, "Reserved by Intel") \ _ELF_DEFINE_EM(EM_INTEL209, 209, "Reserved by Intel") \ _ELF_DEFINE_EM(EM_KM32, 210, "KM211 KM32 32-bit processor") \ _ELF_DEFINE_EM(EM_KMX32, 211, "KM211 KMX32 32-bit processor") \ _ELF_DEFINE_EM(EM_KMX16, 212, "KM211 KMX16 16-bit processor") \ _ELF_DEFINE_EM(EM_KMX8, 213, "KM211 KMX8 8-bit processor") \ _ELF_DEFINE_EM(EM_KVARC, 214, "KM211 KMX32 KVARC processor") \ _ELF_DEFINE_EM(EM_RISCV, 243, "RISC-V") #undef _ELF_DEFINE_EM #define _ELF_DEFINE_EM(N, V, DESCR) N = V , enum { _ELF_DEFINE_ELF_MACHINES() EM__LAST__ }; /* Other synonyms. */ #define EM_AMD64 EM_X86_64 #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 / mask for .gnu.versym sections. */ #define VERSYM_VERSION 0x7fff #define VERSYM_HIDDEN 0x8000 /* * 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_OPENBSD_RANDOMIZE,0x65A3DBE6UL, \ "Segment filled with random data") \ _ELF_DEFINE_PT(PT_OPENBSD_WXNEEDED, 0x65A3DBE7UL, \ "Program violates W^X") \ _ELF_DEFINE_PT(PT_OPENBSD_BOOTDATA, 0x65A41BE6UL, \ "Boot data") \ _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_COMPRESSED, 0x800, \ "holds compressed data") \ _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_MIPS_ABIFLAGS, 0x7000002AUL, \ "ABI flags") \ _ELF_DEFINE_SHT(SHT_SPARC_GOTDATA, 0x70000000UL, \ "SPARC-specific data") \ _ELF_DEFINE_SHT(SHT_X86_64_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_AMD64_UNWIND SHT_X86_64_UNWIND #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_GNU_UNIQUE, 10, "unique symbol (GNU)") \ _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_GNU_IFUNC, 10, "indirect function") \ _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_SPARC_REGISTER, 13, "SPARC register information") \ _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_JUMP_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_TLS_TPOFF, 14) \ _ELF_DEFINE_RELOC(R_386_TLS_IE, 15) \ _ELF_DEFINE_RELOC(R_386_TLS_GOTIE, 16) \ _ELF_DEFINE_RELOC(R_386_TLS_LE, 17) \ _ELF_DEFINE_RELOC(R_386_TLS_GD, 18) \ _ELF_DEFINE_RELOC(R_386_TLS_LDM, 19) \ _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) \ _ELF_DEFINE_RELOC(R_386_TLS_GD_32, 24) \ _ELF_DEFINE_RELOC(R_386_TLS_GD_PUSH, 25) \ _ELF_DEFINE_RELOC(R_386_TLS_GD_CALL, 26) \ _ELF_DEFINE_RELOC(R_386_TLS_GD_POP, 27) \ _ELF_DEFINE_RELOC(R_386_TLS_LDM_32, 28) \ _ELF_DEFINE_RELOC(R_386_TLS_LDM_PUSH, 29) \ _ELF_DEFINE_RELOC(R_386_TLS_LDM_CALL, 30) \ _ELF_DEFINE_RELOC(R_386_TLS_LDM_POP, 31) \ _ELF_DEFINE_RELOC(R_386_TLS_LDO_32, 32) \ _ELF_DEFINE_RELOC(R_386_TLS_IE_32, 33) \ _ELF_DEFINE_RELOC(R_386_TLS_LE_32, 34) \ _ELF_DEFINE_RELOC(R_386_TLS_DTPMOD32, 35) \ _ELF_DEFINE_RELOC(R_386_TLS_DTPOFF32, 36) \ _ELF_DEFINE_RELOC(R_386_TLS_TPOFF32, 37) \ _ELF_DEFINE_RELOC(R_386_SIZE32, 38) \ _ELF_DEFINE_RELOC(R_386_TLS_GOTDESC, 39) \ _ELF_DEFINE_RELOC(R_386_TLS_DESC_CALL, 40) \ _ELF_DEFINE_RELOC(R_386_TLS_DESC, 41) \ _ELF_DEFINE_RELOC(R_386_IRELATIVE, 42) \ _ELF_DEFINE_RELOC(R_386_GOT32X, 43) /* */ #define _ELF_DEFINE_AARCH64_RELOCATIONS() \ _ELF_DEFINE_RELOC(R_AARCH64_NONE, 0) \ _ELF_DEFINE_RELOC(R_AARCH64_ABS64, 257) \ _ELF_DEFINE_RELOC(R_AARCH64_ABS32, 258) \ _ELF_DEFINE_RELOC(R_AARCH64_ABS16, 259) \ _ELF_DEFINE_RELOC(R_AARCH64_PREL64, 260) \ _ELF_DEFINE_RELOC(R_AARCH64_PREL32, 261) \ _ELF_DEFINE_RELOC(R_AARCH64_PREL16, 262) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G0, 263) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G0_NC, 264) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G1, 265) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G1_NC, 266) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G2, 267) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G2_NC, 268) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_UABS_G3, 269) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G0, 270) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G1, 271) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_SABS_G2, 272) \ _ELF_DEFINE_RELOC(R_AARCH64_LD_PREL_LO19, 273) \ _ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_LO21, 274) \ _ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_PG_HI21, 275) \ _ELF_DEFINE_RELOC(R_AARCH64_ADR_PREL_PG_HI21_NC, 276) \ _ELF_DEFINE_RELOC(R_AARCH64_ADD_ABS_LO12_NC, 277) \ _ELF_DEFINE_RELOC(R_AARCH64_LDST8_ABS_LO12_NC, 278) \ _ELF_DEFINE_RELOC(R_AARCH64_TSTBR14, 279) \ _ELF_DEFINE_RELOC(R_AARCH64_CONDBR19, 280) \ _ELF_DEFINE_RELOC(R_AARCH64_JUMP26, 282) \ _ELF_DEFINE_RELOC(R_AARCH64_CALL26, 283) \ _ELF_DEFINE_RELOC(R_AARCH64_LDST16_ABS_LO12_NC, 284) \ _ELF_DEFINE_RELOC(R_AARCH64_LDST32_ABS_LO12_NC, 285) \ _ELF_DEFINE_RELOC(R_AARCH64_LDST64_ABS_LO12_NC, 286) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G0, 287) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G0_NC, 288) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G1, 289) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G1_NC, 290) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G2, 291) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G2_NC, 292) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_PREL_G3, 293) \ _ELF_DEFINE_RELOC(R_AARCH64_LDST128_ABS_LO12_NC, 299) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G0, 300) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G0_NC, 301) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G1, 302) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G1_NC, 303) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G2, 304) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G2_NC, 305) \ _ELF_DEFINE_RELOC(R_AARCH64_MOVW_GOTOFF_G3, 306) \ _ELF_DEFINE_RELOC(R_AARCH64_GOTREL64, 307) \ _ELF_DEFINE_RELOC(R_AARCH64_GOTREL32, 308) \ _ELF_DEFINE_RELOC(R_AARCH64_GOT_LD_PREL19, 309) \ _ELF_DEFINE_RELOC(R_AARCH64_LD64_GOTOFF_LO15, 310) \ _ELF_DEFINE_RELOC(R_AARCH64_ADR_GOT_PAGE, 311) \ _ELF_DEFINE_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 312) \ _ELF_DEFINE_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 313) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 512) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 513) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 514) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSGD_MOVW_G1, 515) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSGD_MOVW_G0_NC, 516) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADR_PREL21, 517) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADR_PAGE21, 518) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_LO12_NC, 519) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_G1, 520) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_G0_NC, 521) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LD_PREL19, 522) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G2, 523) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1, 524) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC, 525) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0, 526) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC, 527) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_HI12, 529) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC, 530) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12, 531) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC, 532) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12, 533) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC, 534) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12, 535) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC, 536) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12, 537) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC, 538) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1, 539) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC, 540) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, 541) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, 542) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19, 543) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G2, 544) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1, 545) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC, 546) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0, 547) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC, 548) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_HI12, 549) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12, 550) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC, 551) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12, 552) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC, 553) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12, 554) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC, 555) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12, 556) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC, 557) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12, 558) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC, 559) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LD_PREL19, 560) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADR_PREL21, 561) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADR_PAGE21, 562) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LD64_LO12, 563) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADD_LO12, 564) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_OFF_G1, 565) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_OFF_G0_NC, 566) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_LDR, 567) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_ADD, 568) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC_CALL, 569) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 570) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 571) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 572) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 573) \ _ELF_DEFINE_RELOC(R_AARCH64_COPY, 1024) \ _ELF_DEFINE_RELOC(R_AARCH64_GLOB_DAT, 1025) \ _ELF_DEFINE_RELOC(R_AARCH64_JUMP_SLOT, 1026) \ _ELF_DEFINE_RELOC(R_AARCH64_RELATIVE, 1027) \ _ELF_DEFINE_RELOC(R_AARCH64_TLS_DTPREL64, 1028) \ _ELF_DEFINE_RELOC(R_AARCH64_TLS_DTPMOD64, 1029) \ _ELF_DEFINE_RELOC(R_AARCH64_TLS_TPREL64, 1030) \ _ELF_DEFINE_RELOC(R_AARCH64_TLSDESC, 1031) \ _ELF_DEFINE_RELOC(R_AARCH64_IRELATIVE, 1032) /* * 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) /* * Relocation definitions from the ARM ELF ABI, version "ARM IHI * 0044E" released on 30th November 2012. */ #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_TLS_DESC, 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_PCREL_7_0, 32) \ _ELF_DEFINE_RELOC(R_ARM_ALU_PCREL_15_8, 33) \ _ELF_DEFINE_RELOC(R_ARM_ALU_PCREL_23_15, 34) \ _ELF_DEFINE_RELOC(R_ARM_LDR_SBREL_11_0_NC, 35) \ _ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_19_12_NC, 36) \ _ELF_DEFINE_RELOC(R_ARM_ALU_SBREL_27_20_CK, 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_THM_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_PRIVATE_0, 112) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_1, 113) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_2, 114) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_3, 115) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_4, 116) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_5, 117) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_6, 118) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_7, 119) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_8, 120) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_9, 121) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_10, 122) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_11, 123) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_12, 124) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_13, 125) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_14, 126) \ _ELF_DEFINE_RELOC(R_ARM_PRIVATE_15, 127) \ _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) \ _ELF_DEFINE_RELOC(R_ARM_THM_GOT_BREL12, 131) \ _ELF_DEFINE_RELOC(R_ARM_IRELATIVE, 140) #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_PCREL21BI, 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_SHIFT5, 16) \ _ELF_DEFINE_RELOC(R_MIPS_SHIFT6, 17) \ _ELF_DEFINE_RELOC(R_MIPS_64, 18) \ _ELF_DEFINE_RELOC(R_MIPS_GOT_DISP, 19) \ _ELF_DEFINE_RELOC(R_MIPS_GOT_PAGE, 20) \ _ELF_DEFINE_RELOC(R_MIPS_GOT_OFST, 21) \ _ELF_DEFINE_RELOC(R_MIPS_GOT_HI16, 22) \ _ELF_DEFINE_RELOC(R_MIPS_GOT_LO16, 23) \ _ELF_DEFINE_RELOC(R_MIPS_SUB, 24) \ _ELF_DEFINE_RELOC(R_MIPS_CALLHI16, 30) \ _ELF_DEFINE_RELOC(R_MIPS_CALLLO16, 31) \ _ELF_DEFINE_RELOC(R_MIPS_JALR, 37) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_DTPMOD32, 38) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_DTPREL32, 39) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_DTPMOD64, 40) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_DTPREL64, 41) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_GD, 42) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_LDM, 43) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_DTPREL_HI16, 44) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_DTPREL_LO16, 45) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_GOTTPREL, 46) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_TPREL32, 47) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_TPREL64, 48) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_TPREL_HI16, 49) \ _ELF_DEFINE_RELOC(R_MIPS_TLS_TPREL_LO16, 50) #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_PPC_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_RISCV_RELOCATIONS() \ _ELF_DEFINE_RELOC(R_RISCV_NONE, 0) \ _ELF_DEFINE_RELOC(R_RISCV_32, 1) \ _ELF_DEFINE_RELOC(R_RISCV_64, 2) \ _ELF_DEFINE_RELOC(R_RISCV_RELATIVE, 3) \ _ELF_DEFINE_RELOC(R_RISCV_COPY, 4) \ _ELF_DEFINE_RELOC(R_RISCV_JUMP_SLOT, 5) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_DTPMOD32, 6) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_DTPMOD64, 7) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_DTPREL32, 8) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_DTPREL64, 9) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_TPREL32, 10) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_TPREL64, 11) \ _ELF_DEFINE_RELOC(R_RISCV_BRANCH, 16) \ _ELF_DEFINE_RELOC(R_RISCV_JAL, 17) \ _ELF_DEFINE_RELOC(R_RISCV_CALL, 18) \ _ELF_DEFINE_RELOC(R_RISCV_CALL_PLT, 19) \ _ELF_DEFINE_RELOC(R_RISCV_GOT_HI20, 20) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_GOT_HI20, 21) \ _ELF_DEFINE_RELOC(R_RISCV_TLS_GD_HI20, 22) \ _ELF_DEFINE_RELOC(R_RISCV_PCREL_HI20, 23) \ _ELF_DEFINE_RELOC(R_RISCV_PCREL_LO12_I, 24) \ _ELF_DEFINE_RELOC(R_RISCV_PCREL_LO12_S, 25) \ _ELF_DEFINE_RELOC(R_RISCV_HI20, 26) \ _ELF_DEFINE_RELOC(R_RISCV_LO12_I, 27) \ _ELF_DEFINE_RELOC(R_RISCV_LO12_S, 28) \ _ELF_DEFINE_RELOC(R_RISCV_TPREL_HI20, 29) \ _ELF_DEFINE_RELOC(R_RISCV_TPREL_LO12_I, 30) \ _ELF_DEFINE_RELOC(R_RISCV_TPREL_LO12_S, 31) \ _ELF_DEFINE_RELOC(R_RISCV_TPREL_ADD, 32) \ _ELF_DEFINE_RELOC(R_RISCV_ADD8, 33) \ _ELF_DEFINE_RELOC(R_RISCV_ADD16, 34) \ _ELF_DEFINE_RELOC(R_RISCV_ADD32, 35) \ _ELF_DEFINE_RELOC(R_RISCV_ADD64, 36) \ _ELF_DEFINE_RELOC(R_RISCV_SUB8, 37) \ _ELF_DEFINE_RELOC(R_RISCV_SUB16, 38) \ _ELF_DEFINE_RELOC(R_RISCV_SUB32, 39) \ _ELF_DEFINE_RELOC(R_RISCV_SUB64, 40) \ _ELF_DEFINE_RELOC(R_RISCV_GNU_VTINHERIT, 41) \ _ELF_DEFINE_RELOC(R_RISCV_GNU_VTENTRY, 42) \ _ELF_DEFINE_RELOC(R_RISCV_ALIGN, 43) \ _ELF_DEFINE_RELOC(R_RISCV_RVC_BRANCH, 44) \ _ELF_DEFINE_RELOC(R_RISCV_RVC_JUMP, 45) \ _ELF_DEFINE_RELOC(R_RISCV_RVC_LUI, 46) \ _ELF_DEFINE_RELOC(R_RISCV_GPREL_I, 47) \ _ELF_DEFINE_RELOC(R_RISCV_GPREL_S, 48) #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_GLOB_JMP, 42) \ _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_TLS_GD_HI22, 56) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_GD_LO10, 57) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_GD_ADD, 58) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_GD_CALL, 59) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDM_HI22, 60) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDM_LO10, 61) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDM_ADD, 62) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDM_CALL, 63) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDO_HIX22, 64) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDO_LOX10, 65) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LDO_ADD, 66) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_IE_HI22, 67) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_IE_LO10, 68) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_IE_LD, 69) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_IE_LDX, 70) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_IE_ADD, 71) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LE_HIX22, 72) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_LE_LOX10, 73) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_DTPMOD32, 74) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_DTPMOD64, 75) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_DTPOFF32, 76) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_DTPOFF64, 77) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_TPOFF32, 78) \ _ELF_DEFINE_RELOC(R_SPARC_TLS_TPOFF64, 79) \ _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_GOT64, 27) \ _ELF_DEFINE_RELOC(R_X86_64_GOTPCREL64, 28) \ _ELF_DEFINE_RELOC(R_X86_64_GOTPC64, 29) \ _ELF_DEFINE_RELOC(R_X86_64_GOTPLT64, 30) \ _ELF_DEFINE_RELOC(R_X86_64_PLTOFF64, 31) \ _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) \ _ELF_DEFINE_RELOC(R_X86_64_IRELATIVE, 37) \ _ELF_DEFINE_RELOC(R_X86_64_RELATIVE64, 38) \ _ELF_DEFINE_RELOC(R_X86_64_GOTPCRELX, 41) \ _ELF_DEFINE_RELOC(R_X86_64_REX_GOTPCRELX, 42) #define _ELF_DEFINE_RELOCATIONS() \ _ELF_DEFINE_386_RELOCATIONS() \ _ELF_DEFINE_AARCH64_RELOCATIONS() \ _ELF_DEFINE_AMD64_RELOCATIONS() \ _ELF_DEFINE_ARM_RELOCATIONS() \ _ELF_DEFINE_IA64_RELOCATIONS() \ _ELF_DEFINE_MIPS_RELOCATIONS() \ _ELF_DEFINE_PPC32_RELOCATIONS() \ _ELF_DEFINE_PPC64_RELOCATIONS() \ _ELF_DEFINE_RISCV_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; /* The name of a shared object. */ Elf64_Word l_time_stamp; /* 32-bit timestamp. */ Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */ Elf64_Word l_version; /* Interface version string index. */ Elf64_Word l_flags; /* Flags (LL_*). */ } 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") +_ELF_DEFINE_NT(NT_LWPSINFO, 17, "Linux lwpinfo_t type") \ +_ELF_DEFINE_NT(NT_FREEBSD_NOINIT_TAG, 2, "FreeBSD no .init tag") \ +_ELF_DEFINE_NT(NT_FREEBSD_ARCH_TAG, 3, "FreeBSD arch tag") \ +_ELF_DEFINE_NT(NT_FREEBSD_FEATURE_CTL, 4, "FreeBSD feature control") #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 information") #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; /* Segment flags. */ Elf64_Off p_offset; /* File offset to segment. */ Elf64_Addr p_vaddr; /* Virtual address in memory. */ Elf64_Addr p_paddr; /* Physical address (if relevant). */ Elf64_Xword p_filesz; /* Size of segment in file. */ Elf64_Xword p_memsz; /* Size of segment in memory. */ 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; /* type and binding attributes */ unsigned char st_other; /* visibility */ Elf64_Half st_shndx; /* index of related section */ Elf64_Addr st_value; /* value for the symbol */ Elf64_Xword st_size; /* size of associated data */ } 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)) +#define ELF64_R_INFO(S,T) \ + (((Elf64_Xword) (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_ */ Index: stable/11/contrib/elftoolchain/common/native-elf-format =================================================================== --- stable/11/contrib/elftoolchain/common/native-elf-format (revision 367465) +++ stable/11/contrib/elftoolchain/common/native-elf-format (revision 367466) @@ -1,49 +1,51 @@ #!/bin/sh # -# $Id: native-elf-format 3293 2016-01-07 19:26:27Z emaste $ +# $Id: native-elf-format 3735 2019-04-25 19:44:47Z 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} LC_ALL=C 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, "MIPS")) { elfarch = "EM_MIPS"; - } else if (match($0, ".*[xX]86-64")) { + } else if (match($0, ".*[xX]86[-_]64")) { elfarch = "EM_X86_64"; + } else if (match($0, "PowerPC64")) { + elfarch = "EM_PPC64"; } 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); }' Index: stable/11/contrib/elftoolchain/cxxfilt/c++filt.1 =================================================================== --- stable/11/contrib/elftoolchain/cxxfilt/c++filt.1 (revision 367465) +++ stable/11/contrib/elftoolchain/cxxfilt/c++filt.1 (revision 367466) @@ -1,109 +1,109 @@ .\" Copyright (c) 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 .\" in this position and unchanged. .\" 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 AUTHORS ``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 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: c++filt.1 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: c++filt.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" .Dd August 24, 2011 -.Os .Dt C++FILT 1 +.Os .Sh NAME .Nm c++filt .Nd decode C++ symbols .Sh SYNOPSIS .Nm .Op Fl -help .Op Fl _ | Fl -strip-underscores .Op Fl n | Fl -no-strip-underscores .Op Fl p | Fl -no-params .Op Fl s Ar scheme | Fl -format Ns = Ns Ar scheme .Op Fl V | Fl -version .Op Ar encoded-names ... .Sh DESCRIPTION The .Nm utility translates encoded C++ symbol names to human-readable form. .Pp The .Nm utility has two operating modes. .Bl -bullet .It If arguments .Ar encoded-names are not specified, then .Nm will act as a filter, reading from standard input and writing to standard output. .It If arguments .Ar encoded-names are specified, then .Nm will decode each such argument in turn, writing its decoded form to standard output. .El .Pp The .Nm utility recognizes the following options: .Bl -tag -width indent .It Fl -help Print a help message and exit. .It Fl _ | Fl -strip-underscores Remove a leading underscore from symbol names prior to decoding them. .It Fl n | Fl -no-strip-underscores Do not remove leading underscores from names. .It Fl p | Fl -no-params This option is recognized but ignored. .It Fl s Ar scheme | Fl -format Ns = Ns Ar scheme Select the encoding scheme to use. Argument .Ar scheme can be one of the following: .Bl -tag -width "gnu-v5" .It Ar arm Use the encoding scheme specified by the C++ Annotated Reference Manual. .It Ar auto Guess the encoding scheme from the input. .It Ar gnu Use the encoding scheme used by the GNU C++ compiler. .It Ar gnu-v3 Use the encoding scheme used by the GNU C++ compiler, version 3. .El .It Fl V | Fl -version Print a version identifier for .Nm and exit. .El .Sh EXIT STATUS .Ex -std .Sh SEE ALSO .Xr nm 1 , .Xr strip 1 , .Xr elftc_demangle 3 .Sh AUTHORS The .Nm utility was written by .An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . Index: stable/11/contrib/elftoolchain/elfcopy/ascii.c =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/ascii.c (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/ascii.c (revision 367466) @@ -1,1079 +1,1073 @@ /*- * Copyright (c) 2010,2011 Kai Wang * 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 "elfcopy.h" -ELFTC_VCSID("$Id: ascii.c 3487 2016-08-24 18:12:08Z emaste $"); +ELFTC_VCSID("$Id: ascii.c 3757 2019-06-28 01:15:28Z emaste $"); static void append_data(struct section *s, const void *buf, size_t sz); static char hex_digit(uint8_t n); static int hex_value(int x); static void finalize_data_section(struct section *s); static int ishexdigit(int x); static int ihex_read(const char *line, char *type, uint64_t *addr, uint64_t *num, uint8_t *data, size_t *sz); static void ihex_write(int ofd, int type, uint64_t addr, uint64_t num, const void *buf, size_t sz); static void ihex_write_00(int ofd, uint64_t addr, const void *buf, size_t sz); static void ihex_write_01(int ofd); static void ihex_write_04(int ofd, uint16_t addr); static void ihex_write_05(int ofd, uint64_t e_entry); static struct section *new_data_section(struct elfcopy *ecp, int sec_index, uint64_t off, uint64_t addr); static int read_num(const char *line, int *len, uint64_t *num, size_t sz, int *checksum); static int srec_read(const char *line, char *type, uint64_t *addr, uint8_t *data, size_t *sz); static void srec_write(int ofd, char type, uint64_t addr, const void *buf, size_t sz); static void srec_write_symtab(int ofd, const char *ofn, Elf *e, Elf_Scn *scn, GElf_Shdr *sh); static void srec_write_S0(int ofd, const char *ofn); static void srec_write_Sd(int ofd, char dr, uint64_t addr, const void *buf, size_t sz, size_t rlen); static void srec_write_Se(int ofd, uint64_t e_entry, int forceS3); static void write_num(char *line, int *len, uint64_t num, size_t sz, int *checksum); #define _LINE_BUFSZ 1024 #define _DATA_BUFSZ 256 /* * Convert ELF object to S-Record. */ void create_srec(struct elfcopy *ecp, int ifd, int ofd, const char *ofn) { Elf *e; Elf_Scn *scn; Elf_Data *d; GElf_Ehdr eh; GElf_Shdr sh; uint64_t max_addr; size_t rlen; int elferr, addr_sz; char dr; if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); /* Output a symbol table for `symbolsrec' target. */ if (!strncmp(ecp->otgt, "symbolsrec", strlen("symbolsrec"))) { scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if (sh.sh_type != SHT_SYMTAB) continue; srec_write_symtab(ofd, ofn, e, scn, &sh); break; } } if (ecp->flags & SREC_FORCE_S3) dr = '3'; else { /* * Find maximum address size in the first iteration. */ max_addr = 0; scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((sh.sh_flags & SHF_ALLOC) == 0 || sh.sh_type == SHT_NOBITS || sh.sh_size == 0) continue; if ((uint64_t) sh.sh_addr > max_addr) max_addr = sh.sh_addr; } elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); if (max_addr <= 0xFFFF) dr = '1'; else if (max_addr <= 0xFFFFFF) dr = '2'; else dr = '3'; } if (ecp->flags & SREC_FORCE_LEN) { addr_sz = dr - '0' + 1; if (ecp->srec_len < 1) rlen = 1; else if (ecp->srec_len + addr_sz + 1 > 255) rlen = 255 - (addr_sz + 1); else rlen = ecp->srec_len; } else rlen = 16; /* Generate S0 record which contains the output filename. */ srec_write_S0(ofd, ofn); /* Generate S{1,2,3} data records for section data. */ scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((sh.sh_flags & SHF_ALLOC) == 0 || sh.sh_type == SHT_NOBITS || sh.sh_size == 0) continue; if (sh.sh_addr > 0xFFFFFFFF) { warnx("address space too big for S-Record file"); continue; } (void) elf_errno(); if ((d = elf_getdata(scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); continue; } if (d->d_buf == NULL || d->d_size == 0) continue; srec_write_Sd(ofd, dr, sh.sh_addr, d->d_buf, d->d_size, rlen); } elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); /* Generate S{7,8,9} end of block record. */ if (gelf_getehdr(e, &eh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); srec_write_Se(ofd, eh.e_entry, ecp->flags & SREC_FORCE_S3); } void create_elf_from_srec(struct elfcopy *ecp, int ifd) { char line[_LINE_BUFSZ], name[_LINE_BUFSZ]; uint8_t data[_DATA_BUFSZ]; GElf_Ehdr oeh; struct section *s, *shtab; FILE *ifp; uint64_t addr, entry, off, sec_addr; uintmax_t st_value; size_t sz; int _ifd, first, sec_index, in_symtab, symtab_created; char *rlt; char type; if ((_ifd = dup(ifd)) < 0) err(EXIT_FAILURE, "dup failed"); if ((ifp = fdopen(_ifd, "r")) == NULL) err(EXIT_FAILURE, "fdopen failed"); /* Create EHDR for output .o file. */ if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) errx(EXIT_FAILURE, "gelf_newehdr failed: %s", elf_errmsg(-1)); if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Initialise e_ident fields. */ oeh.e_ident[EI_CLASS] = ecp->oec; oeh.e_ident[EI_DATA] = ecp->oed; /* * TODO: Set OSABI according to the OS platform where elfcopy(1) * was build. (probably) */ oeh.e_ident[EI_OSABI] = ELFOSABI_NONE; oeh.e_machine = ecp->oem; oeh.e_type = ET_REL; oeh.e_entry = 0; ecp->flags |= RELOCATABLE; /* Create .shstrtab section */ init_shstrtab(ecp); ecp->shstrtab->off = 0; /* Data sections are inserted after EHDR. */ off = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); if (off == 0) errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); /* Create data sections. */ s = NULL; first = 1; sec_index = 1; sec_addr = entry = 0; while (fgets(line, _LINE_BUFSZ, ifp) != NULL) { sz = 0; if (line[0] == '\r' || line[0] == '\n') continue; if (line[0] == '$' && line[1] == '$') { ecp->flags |= SYMTAB_EXIST; while ((rlt = fgets(line, _LINE_BUFSZ, ifp)) != NULL) { if (line[0] == '$' && line[1] == '$') break; } if (rlt == NULL) break; continue; } if (line[0] != 'S' || line[1] < '0' || line[1] > '9') { warnx("Invalid srec record"); continue; } if (srec_read(line, &type, &addr, data, &sz) < 0) { warnx("Invalid srec record or mismatched checksum"); continue; } switch (type) { case '1': case '2': case '3': if (sz == 0) break; if (first || sec_addr != addr) { if (s != NULL) finalize_data_section(s); s = new_data_section(ecp, sec_index, off, addr); if (s == NULL) { warnx("new_data_section failed"); break; } sec_index++; sec_addr = addr; first = 0; } append_data(s, data, sz); off += sz; sec_addr += sz; break; case '7': case '8': case '9': entry = addr; break; default: break; } } if (s != NULL) finalize_data_section(s); if (ferror(ifp)) warn("fgets failed"); /* Insert .shstrtab after data sections. */ if ((ecp->shstrtab->os = elf_newscn(ecp->eout)) == NULL) errx(EXIT_FAILURE, "elf_newscn failed: %s", elf_errmsg(-1)); insert_to_sec_list(ecp, ecp->shstrtab, 1); /* Insert section header table here. */ shtab = insert_shtab(ecp, 1); /* * Rescan and create symbol table if we found '$$' section in * the first scan. */ symtab_created = 0; in_symtab = 0; if (ecp->flags & SYMTAB_EXIST) { if (fseek(ifp, 0, SEEK_SET) < 0) { warn("fseek failed"); ecp->flags &= ~SYMTAB_EXIST; goto done; } while (fgets(line, _LINE_BUFSZ, ifp) != NULL) { if (in_symtab) { if (line[0] == '$' && line[1] == '$') { in_symtab = 0; continue; } if (sscanf(line, "%s $%jx", name, &st_value) != 2) { warnx("Invalid symbolsrec record"); continue; } if (!symtab_created) { create_external_symtab(ecp); symtab_created = 1; } add_to_symtab(ecp, name, st_value, 0, SHN_ABS, ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); } if (line[0] == '$' && line[1] == '$') { in_symtab = 1; continue; } } } if (ferror(ifp)) warn("fgets failed"); if (symtab_created) { finalize_external_symtab(ecp); create_symtab_data(ecp); /* Count in .symtab and .strtab section headers. */ shtab->sz += gelf_fsize(ecp->eout, ELF_T_SHDR, 2, EV_CURRENT); } else ecp->flags &= ~SYMTAB_EXIST; done: fclose(ifp); /* Set entry point. */ oeh.e_entry = entry; /* * Write the underlying ehdr. Note that it should be called * before elf_setshstrndx() since it will overwrite e->e_shstrndx. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); - /* Generate section name string table (.shstrtab). */ - set_shstrtab(ecp); - /* Update sh_name pointer for each section header entry. */ update_shdr(ecp, 0); /* Renew oeh to get the updated e_shstrndx. */ if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Resync section offsets. */ resync_sections(ecp); /* Store SHDR offset in EHDR. */ oeh.e_shoff = shtab->off; /* Update ehdr since we modified e_shoff. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); /* Write out the output elf object. */ if (elf_update(ecp->eout, ELF_C_WRITE) < 0) errx(EXIT_FAILURE, "elf_update() failed: %s", elf_errmsg(-1)); /* Release allocated resource. */ free_elf(ecp); } void create_ihex(int ifd, int ofd) { Elf *e; Elf_Scn *scn; Elf_Data *d; GElf_Ehdr eh; GElf_Shdr sh; int elferr; uint16_t addr_hi, old_addr_hi; if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); old_addr_hi = 0; scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((sh.sh_flags & SHF_ALLOC) == 0 || sh.sh_type == SHT_NOBITS || sh.sh_size == 0) continue; if (sh.sh_addr > 0xFFFFFFFF) { warnx("address space too big for Intel Hex file"); continue; } (void) elf_errno(); if ((d = elf_getdata(scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); continue; } if (d->d_buf == NULL || d->d_size == 0) continue; addr_hi = (sh.sh_addr >> 16) & 0xFFFF; if (addr_hi > 0 && addr_hi != old_addr_hi) { /* Write 04 record if addr_hi is new. */ old_addr_hi = addr_hi; ihex_write_04(ofd, addr_hi); } ihex_write_00(ofd, sh.sh_addr, d->d_buf, d->d_size); } elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); if (gelf_getehdr(e, &eh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); ihex_write_05(ofd, eh.e_entry); ihex_write_01(ofd); } void create_elf_from_ihex(struct elfcopy *ecp, int ifd) { char line[_LINE_BUFSZ]; uint8_t data[_DATA_BUFSZ]; GElf_Ehdr oeh; struct section *s, *shtab; FILE *ifp; uint64_t addr, addr_base, entry, num, off, rec_addr, sec_addr; size_t sz; int _ifd, first, sec_index; char type; if ((_ifd = dup(ifd)) < 0) err(EXIT_FAILURE, "dup failed"); if ((ifp = fdopen(_ifd, "r")) == NULL) err(EXIT_FAILURE, "fdopen failed"); /* Create EHDR for output .o file. */ if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) errx(EXIT_FAILURE, "gelf_newehdr failed: %s", elf_errmsg(-1)); if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Initialise e_ident fields. */ oeh.e_ident[EI_CLASS] = ecp->oec; oeh.e_ident[EI_DATA] = ecp->oed; /* * TODO: Set OSABI according to the OS platform where elfcopy(1) * was build. (probably) */ oeh.e_ident[EI_OSABI] = ELFOSABI_NONE; oeh.e_machine = ecp->oem; oeh.e_type = ET_REL; oeh.e_entry = 0; ecp->flags |= RELOCATABLE; /* Create .shstrtab section */ init_shstrtab(ecp); ecp->shstrtab->off = 0; /* Data sections are inserted after EHDR. */ off = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); if (off == 0) errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); /* Create data sections. */ s = NULL; first = 1; sec_index = 1; addr_base = rec_addr = sec_addr = entry = 0; while (fgets(line, _LINE_BUFSZ, ifp) != NULL) { if (line[0] == '\r' || line[0] == '\n') continue; if (line[0] != ':') { warnx("Invalid ihex record"); continue; } if (ihex_read(line, &type, &addr, &num, data, &sz) < 0) { warnx("Invalid ihex record or mismatched checksum"); continue; } switch (type) { case '0': /* Data record. */ if (sz == 0) break; rec_addr = addr_base + addr; if (first || sec_addr != rec_addr) { if (s != NULL) finalize_data_section(s); s = new_data_section(ecp, sec_index, off, rec_addr); if (s == NULL) { warnx("new_data_section failed"); break; } sec_index++; sec_addr = rec_addr; first = 0; } append_data(s, data, sz); off += sz; sec_addr += sz; break; case '1': /* End of file record. */ goto done; case '2': /* Extended segment address record. */ addr_base = addr << 4; break; case '3': /* Start segment address record (CS:IP). Ignored. */ break; case '4': /* Extended linear address record. */ addr_base = num << 16; break; case '5': /* Start linear address record. */ entry = num; break; default: break; } } done: if (s != NULL) finalize_data_section(s); if (ferror(ifp)) warn("fgets failed"); fclose(ifp); /* Insert .shstrtab after data sections. */ if ((ecp->shstrtab->os = elf_newscn(ecp->eout)) == NULL) errx(EXIT_FAILURE, "elf_newscn failed: %s", elf_errmsg(-1)); insert_to_sec_list(ecp, ecp->shstrtab, 1); /* Insert section header table here. */ shtab = insert_shtab(ecp, 1); /* Set entry point. */ oeh.e_entry = entry; /* * Write the underlying ehdr. Note that it should be called * before elf_setshstrndx() since it will overwrite e->e_shstrndx. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); - - /* Generate section name string table (.shstrtab). */ - set_shstrtab(ecp); /* Update sh_name pointer for each section header entry. */ update_shdr(ecp, 0); /* Renew oeh to get the updated e_shstrndx. */ if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Resync section offsets. */ resync_sections(ecp); /* Store SHDR offset in EHDR. */ oeh.e_shoff = shtab->off; /* Update ehdr since we modified e_shoff. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); /* Write out the output elf object. */ if (elf_update(ecp->eout, ELF_C_WRITE) < 0) errx(EXIT_FAILURE, "elf_update() failed: %s", elf_errmsg(-1)); /* Release allocated resource. */ free_elf(ecp); } #define _SEC_NAMESZ 64 #define _SEC_INIT_CAP 1024 static struct section * new_data_section(struct elfcopy *ecp, int sec_index, uint64_t off, uint64_t addr) { char *name; if ((name = malloc(_SEC_NAMESZ)) == NULL) errx(EXIT_FAILURE, "malloc failed"); snprintf(name, _SEC_NAMESZ, ".sec%d", sec_index); return (create_external_section(ecp, name, name, NULL, 0, off, SHT_PROGBITS, ELF_T_BYTE, SHF_ALLOC | SHF_WRITE, 1, addr, 0)); } static void finalize_data_section(struct section *s) { Elf_Data *od; if ((od = elf_newdata(s->os)) == NULL) errx(EXIT_FAILURE, "elf_newdata() failed: %s", elf_errmsg(-1)); od->d_align = s->align; od->d_off = 0; od->d_buf = s->buf; od->d_size = s->sz; od->d_version = EV_CURRENT; } static void append_data(struct section *s, const void *buf, size_t sz) { uint8_t *p; if (s->buf == NULL) { s->sz = 0; s->cap = _SEC_INIT_CAP; if ((s->buf = malloc(s->cap)) == NULL) err(EXIT_FAILURE, "malloc failed"); } while (sz + s->sz > s->cap) { s->cap *= 2; if ((s->buf = realloc(s->buf, s->cap)) == NULL) err(EXIT_FAILURE, "realloc failed"); } p = s->buf; memcpy(&p[s->sz], buf, sz); s->sz += sz; } static int srec_read(const char *line, char *type, uint64_t *addr, uint8_t *data, size_t *sz) { uint64_t count, _checksum, num; size_t addr_sz; int checksum, i, len; checksum = 0; len = 2; if (read_num(line, &len, &count, 1, &checksum) < 0) return (-1); *type = line[1]; switch (*type) { case '0': case '1': case '5': case '9': addr_sz = 2; break; case '2': case '8': addr_sz = 3; break; case '3': case '7': addr_sz = 4; break; default: return (-1); } if (read_num(line, &len, addr, addr_sz, &checksum) < 0) return (-1); count -= addr_sz + 1; if (*type >= '0' && *type <= '3') { for (i = 0; (uint64_t) i < count; i++) { if (read_num(line, &len, &num, 1, &checksum) < 0) return -1; data[i] = (uint8_t) num; } *sz = count; } else *sz = 0; if (read_num(line, &len, &_checksum, 1, NULL) < 0) return (-1); if ((int) _checksum != (~checksum & 0xFF)) return (-1); return (0); } static void srec_write_symtab(int ofd, const char *ofn, Elf *e, Elf_Scn *scn, GElf_Shdr *sh) { char line[_LINE_BUFSZ]; GElf_Sym sym; Elf_Data *d; const char *name; size_t sc; int elferr, i; #define _WRITE_LINE do { \ if (write(ofd, line, strlen(line)) != (ssize_t) strlen(line)) \ errx(EXIT_FAILURE, "write failed"); \ } while (0) (void) elf_errno(); if ((d = elf_getdata(scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); return; } if (d->d_buf == NULL || d->d_size == 0) return; snprintf(line, sizeof(line), "$$ %s\r\n", ofn); _WRITE_LINE; sc = d->d_size / sh->sh_entsize; for (i = 1; (size_t) i < sc; i++) { if (gelf_getsym(d, i, &sym) != &sym) { warnx("gelf_getsym failed: %s", elf_errmsg(-1)); continue; } if (GELF_ST_TYPE(sym.st_info) == STT_SECTION || GELF_ST_TYPE(sym.st_info) == STT_FILE) continue; if ((name = elf_strptr(e, sh->sh_link, sym.st_name)) == NULL) { warnx("elf_strptr failed: %s", elf_errmsg(-1)); continue; } snprintf(line, sizeof(line), " %s $%jx\r\n", name, (uintmax_t) sym.st_value); _WRITE_LINE; } snprintf(line, sizeof(line), "$$ \r\n"); _WRITE_LINE; #undef _WRITE_LINE } static void srec_write_S0(int ofd, const char *ofn) { srec_write(ofd, '0', 0, ofn, strlen(ofn)); } static void srec_write_Sd(int ofd, char dr, uint64_t addr, const void *buf, size_t sz, size_t rlen) { const uint8_t *p, *pe; p = buf; pe = p + sz; while (pe - p >= (int) rlen) { srec_write(ofd, dr, addr, p, rlen); addr += rlen; p += rlen; } if (pe - p > 0) srec_write(ofd, dr, addr, p, pe - p); } static void srec_write_Se(int ofd, uint64_t e_entry, int forceS3) { char er; if (e_entry > 0xFFFFFFFF) { warnx("address space too big for S-Record file"); return; } if (forceS3) er = '7'; else { if (e_entry <= 0xFFFF) er = '9'; else if (e_entry <= 0xFFFFFF) er = '8'; else er = '7'; } srec_write(ofd, er, e_entry, NULL, 0); } static void srec_write(int ofd, char type, uint64_t addr, const void *buf, size_t sz) { char line[_LINE_BUFSZ]; const uint8_t *p, *pe; int len, addr_sz, checksum; if (type == '0' || type == '1' || type == '5' || type == '9') addr_sz = 2; else if (type == '2' || type == '8') addr_sz = 3; else addr_sz = 4; checksum = 0; line[0] = 'S'; line[1] = type; len = 2; write_num(line, &len, addr_sz + sz + 1, 1, &checksum); write_num(line, &len, addr, addr_sz, &checksum); for (p = buf, pe = p + sz; p < pe; p++) write_num(line, &len, *p, 1, &checksum); write_num(line, &len, ~checksum & 0xFF, 1, NULL); line[len++] = '\r'; line[len++] = '\n'; if (write(ofd, line, len) != (ssize_t) len) err(EXIT_FAILURE, "write failed"); } static void ihex_write_00(int ofd, uint64_t addr, const void *buf, size_t sz) { uint16_t addr_hi, old_addr_hi; const uint8_t *p, *pe; old_addr_hi = (addr >> 16) & 0xFFFF; p = buf; pe = p + sz; while (pe - p >= 16) { ihex_write(ofd, 0, addr, 0, p, 16); addr += 16; p += 16; addr_hi = (addr >> 16) & 0xFFFF; if (addr_hi != old_addr_hi) { old_addr_hi = addr_hi; ihex_write_04(ofd, addr_hi); } } if (pe - p > 0) ihex_write(ofd, 0, addr, 0, p, pe - p); } static int ihex_read(const char *line, char *type, uint64_t *addr, uint64_t *num, uint8_t *data, size_t *sz) { uint64_t count, _checksum; int checksum, i, len; *sz = 0; checksum = 0; len = 1; if (read_num(line, &len, &count, 1, &checksum) < 0) return (-1); if (read_num(line, &len, addr, 2, &checksum) < 0) return (-1); if (line[len++] != '0') return (-1); *type = line[len++]; checksum += *type - '0'; switch (*type) { case '0': for (i = 0; (uint64_t) i < count; i++) { if (read_num(line, &len, num, 1, &checksum) < 0) return (-1); data[i] = (uint8_t) *num; } *sz = count; break; case '1': if (count != 0) return (-1); break; case '2': case '4': if (count != 2) return (-1); if (read_num(line, &len, num, 2, &checksum) < 0) return (-1); break; case '3': case '5': if (count != 4) return (-1); if (read_num(line, &len, num, 4, &checksum) < 0) return (-1); break; default: return (-1); } if (read_num(line, &len, &_checksum, 1, &checksum) < 0) return (-1); if ((checksum & 0xFF) != 0) { return (-1); } return (0); } static void ihex_write_01(int ofd) { ihex_write(ofd, 1, 0, 0, NULL, 0); } static void ihex_write_04(int ofd, uint16_t addr) { ihex_write(ofd, 4, 0, addr, NULL, 2); } static void ihex_write_05(int ofd, uint64_t e_entry) { if (e_entry > 0xFFFFFFFF) { warnx("address space too big for Intel Hex file"); return; } ihex_write(ofd, 5, 0, e_entry, NULL, 4); } static void ihex_write(int ofd, int type, uint64_t addr, uint64_t num, const void *buf, size_t sz) { char line[_LINE_BUFSZ]; const uint8_t *p, *pe; int len, checksum; if (sz > 16) errx(EXIT_FAILURE, "Internal: ihex_write() sz too big"); checksum = 0; line[0] = ':'; len = 1; write_num(line, &len, sz, 1, &checksum); write_num(line, &len, addr, 2, &checksum); write_num(line, &len, type, 1, &checksum); if (sz > 0) { if (buf != NULL) { for (p = buf, pe = p + sz; p < pe; p++) write_num(line, &len, *p, 1, &checksum); } else write_num(line, &len, num, sz, &checksum); } write_num(line, &len, (~checksum + 1) & 0xFF, 1, NULL); line[len++] = '\r'; line[len++] = '\n'; if (write(ofd, line, len) != (ssize_t) len) err(EXIT_FAILURE, "write failed"); } static int read_num(const char *line, int *len, uint64_t *num, size_t sz, int *checksum) { uint8_t b; *num = 0; for (; sz > 0; sz--) { if (!ishexdigit(line[*len]) || !ishexdigit(line[*len + 1])) return (-1); b = (hex_value(line[*len]) << 4) | hex_value(line[*len + 1]); *num = (*num << 8) | b; *len += 2; if (checksum != NULL) *checksum = (*checksum + b) & 0xFF; } return (0); } static void write_num(char *line, int *len, uint64_t num, size_t sz, int *checksum) { uint8_t b; for (; sz > 0; sz--) { b = (num >> ((sz - 1) * 8)) & 0xFF; line[*len] = hex_digit((b >> 4) & 0xF); line[*len + 1] = hex_digit(b & 0xF); *len += 2; if (checksum != NULL) *checksum = (*checksum + b) & 0xFF; } } static char hex_digit(uint8_t n) { return ((n < 10) ? '0' + n : 'A' + (n - 10)); } static int hex_value(int x) { if (isdigit(x)) return (x - '0'); else if (x >= 'a' && x <= 'f') return (x - 'a' + 10); else return (x - 'A' + 10); } static int ishexdigit(int x) { if (isdigit(x)) return (1); if ((x >= 'a' && x <= 'f') || (x >= 'A' && x <= 'F')) return (1); return (0); } Index: stable/11/contrib/elftoolchain/elfcopy/binary.c =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/binary.c (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/binary.c (revision 367466) @@ -1,293 +1,294 @@ /*- * Copyright (c) 2010,2011 Kai Wang * 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 "elfcopy.h" -ELFTC_VCSID("$Id: binary.c 3611 2018-04-16 21:35:18Z jkoshy $"); +ELFTC_VCSID("$Id: binary.c 3757 2019-06-28 01:15:28Z emaste $"); /* * Convert ELF object to `binary'. Sections with SHF_ALLOC flag set * are copied to the result binary. The relative offsets for each section * are retained, so the result binary file might contain "holes". */ void create_binary(int ifd, int ofd) { Elf *e; Elf_Scn *scn; Elf_Data *d; + Elf64_Addr baseaddr; GElf_Shdr sh; - off_t base, off; + off_t baseoff, off; int elferr; if ((e = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); - base = 0; - if (lseek(ofd, base, SEEK_SET) < 0) + baseaddr = 0; + baseoff = 0; + if (lseek(ofd, baseoff, SEEK_SET) < 0) err(EXIT_FAILURE, "lseek failed"); /* * Find base offset in the first iteration. */ - base = -1; + baseoff = -1; scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((sh.sh_flags & SHF_ALLOC) == 0 || sh.sh_type == SHT_NOBITS || sh.sh_size == 0) continue; - if (base == -1 || (off_t) sh.sh_offset < base) - base = sh.sh_offset; + if (baseoff == -1 || (off_t) sh.sh_offset < baseoff) { + baseoff = sh.sh_offset; + baseaddr = sh.sh_addr; + } } elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); - if (base == -1) + if (baseoff == -1) return; /* * Write out sections in the second iteration. */ scn = NULL; while ((scn = elf_nextscn(e, scn)) != NULL) { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((sh.sh_flags & SHF_ALLOC) == 0 || sh.sh_type == SHT_NOBITS || sh.sh_size == 0) continue; (void) elf_errno(); if ((d = elf_rawdata(scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(-1)); continue; } if (d->d_buf == NULL || d->d_size == 0) continue; - /* lseek to section offset relative to `base'. */ - off = sh.sh_offset - base; + /* lseek to section offset relative to `baseaddr'. */ + off = sh.sh_addr - baseaddr; if (lseek(ofd, off, SEEK_SET) < 0) err(EXIT_FAILURE, "lseek failed"); /* Write out section contents. */ if (write(ofd, d->d_buf, d->d_size) != (ssize_t) d->d_size) err(EXIT_FAILURE, "write failed"); } elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); } #define _SYMBOL_NAMSZ 1024 /* * Convert `binary' to ELF object. The input `binary' is converted to * a relocatable (.o) file, a few symbols will also be created to make * it easier to access the binary data in other compilation units. */ void create_elf_from_binary(struct elfcopy *ecp, int ifd, const char *ifn) { char name[_SYMBOL_NAMSZ]; struct section *sec, *sec_temp, *shtab; struct stat sb; GElf_Ehdr oeh; GElf_Shdr sh; void *content; uint64_t off, data_start, data_end, data_size; char *sym_basename, *p; /* Reset internal section list. */ if (!TAILQ_EMPTY(&ecp->v_sec)) TAILQ_FOREACH_SAFE(sec, &ecp->v_sec, sec_list, sec_temp) { TAILQ_REMOVE(&ecp->v_sec, sec, sec_list); free(sec); } if (fstat(ifd, &sb) == -1) err(EXIT_FAILURE, "fstat failed"); /* Read the input binary file to a internal buffer. */ if ((content = malloc(sb.st_size)) == NULL) err(EXIT_FAILURE, "malloc failed"); if (read(ifd, content, sb.st_size) != sb.st_size) err(EXIT_FAILURE, "read failed"); /* * TODO: copy the input binary to output binary verbatim if -O is not * specified. */ /* Create EHDR for output .o file. */ if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) errx(EXIT_FAILURE, "gelf_newehdr failed: %s", elf_errmsg(-1)); if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Initialise e_ident fields. */ oeh.e_ident[EI_CLASS] = ecp->oec; oeh.e_ident[EI_DATA] = ecp->oed; /* * TODO: Set OSABI according to the OS platform where elfcopy(1) * was build. (probably) */ oeh.e_ident[EI_OSABI] = ELFOSABI_NONE; oeh.e_machine = ecp->oem; oeh.e_type = ET_REL; oeh.e_entry = 0; ecp->flags |= RELOCATABLE; /* Create .shstrtab section */ init_shstrtab(ecp); ecp->shstrtab->off = 0; /* * Create `.data' section which contains the binary data. The * section is inserted immediately after EHDR. */ off = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); if (off == 0) errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); (void) create_external_section(ecp, ".data", NULL, content, sb.st_size, off, SHT_PROGBITS, ELF_T_BYTE, SHF_ALLOC | SHF_WRITE, 1, 0, 1); /* Insert .shstrtab after .data section. */ if ((ecp->shstrtab->os = elf_newscn(ecp->eout)) == NULL) errx(EXIT_FAILURE, "elf_newscn failed: %s", elf_errmsg(-1)); insert_to_sec_list(ecp, ecp->shstrtab, 1); /* Insert section header table here. */ shtab = insert_shtab(ecp, 1); /* Count in .symtab and .strtab section headers. */ shtab->sz += gelf_fsize(ecp->eout, ELF_T_SHDR, 2, EV_CURRENT); if ((sym_basename = strdup(ifn)) == NULL) err(1, "strdup"); for (p = sym_basename; *p != '\0'; p++) if (!isalnum(*p & 0xFF)) *p = '_'; #define _GEN_SYMNAME(S) do { \ snprintf(name, sizeof(name), "%s%s%s", "_binary_", sym_basename, S); \ } while (0) /* * Create symbol table. */ create_external_symtab(ecp); data_start = 0; data_end = data_start + sb.st_size; data_size = sb.st_size; _GEN_SYMNAME("_start"); add_to_symtab(ecp, name, data_start, 0, 1, ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); _GEN_SYMNAME("_end"); add_to_symtab(ecp, name, data_end, 0, 1, ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); _GEN_SYMNAME("_size"); add_to_symtab(ecp, name, data_size, 0, SHN_ABS, ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0, 1); finalize_external_symtab(ecp); create_symtab_data(ecp); #undef _GEN_SYMNAME free(sym_basename); /* * Write the underlying ehdr. Note that it should be called * before elf_setshstrndx() since it will overwrite e->e_shstrndx. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); - /* Generate section name string table (.shstrtab). */ - ecp->flags |= SYMTAB_EXIST; - set_shstrtab(ecp); - /* Update sh_name pointer for each section header entry. */ + ecp->flags |= SYMTAB_EXIST; update_shdr(ecp, 0); /* Properly set sh_link field of .symtab section. */ if (gelf_getshdr(ecp->symtab->os, &sh) == NULL) errx(EXIT_FAILURE, "692 gelf_getshdr() failed: %s", elf_errmsg(-1)); sh.sh_link = elf_ndxscn(ecp->strtab->os); if (!gelf_update_shdr(ecp->symtab->os, &sh)) errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", elf_errmsg(-1)); /* Renew oeh to get the updated e_shstrndx. */ if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Resync section offsets. */ resync_sections(ecp); /* Store SHDR offset in EHDR. */ oeh.e_shoff = shtab->off; /* Update ehdr since we modified e_shoff. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); /* Write out the output elf object. */ if (elf_update(ecp->eout, ELF_C_WRITE) < 0) errx(EXIT_FAILURE, "elf_update() failed: %s", elf_errmsg(-1)); /* Release allocated resource. */ free(content); free_elf(ecp); } Index: stable/11/contrib/elftoolchain/elfcopy/elfcopy.1 =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/elfcopy.1 (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/elfcopy.1 (revision 367466) @@ -1,369 +1,369 @@ .\" Copyright (c) 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 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: elfcopy.1 3565 2017-08-31 02:24:19Z emaste $ +.\" $Id: elfcopy.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" .Dd August 30, 2017 -.Os .Dt ELFCOPY 1 +.Os .Sh NAME .Nm elfcopy , .Nm objcopy .Nd copy and translate object files .Sh SYNOPSIS .Nm .Op Fl I Ar objformat | Fl s Ar objformat | Fl -input-target= Ns Ar objformat .Op Fl K Ar symbolname | Fl -keep-symbol= Ns Ar symbolname .Op Fl L Ar symbolname | Fl -localize-symbol= Ns Ar symbolname .Op Fl N Ar symbolname | Fl -strip-symbol= Ns Ar symbolname .Op Fl O Ar objformat | Fl -output-target= Ns Ar objformat .Op Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname .Op Fl S | Fl -strip-all .Op Fl V | Fl -version .Op Fl W Ar symbolname | Fl -weaken-symbol= Ns Ar symbolname .Op Fl X | Fl -discard-locals .Op Fl d | Fl g | Fl -strip-debug .Op Fl h | Fl -help .Op Fl j Ar sectionname | Fl -only-section= Ns Ar sectionname .Op Fl p | Fl -preserve-dates .Op Fl w | Fl -wildcard .Op Fl x | Fl -discard-all .Op Fl -add-gnu-debuglink Ns = Ns Ar filename .Op Fl -add-section Ar sectionname Ns = Ns Ar filename .Oo .Fl -adjust-section-vma Ar section Ns {+|-|=} Ns Ar val | .Fl -change-section-address Ar section Ns {+|-|=} Ns Ar val .Oc .Oo .Fl -adjust-start Ns = Ns Ar increment | .Fl -change-start Ns = Ns Ar increment .Oc .Oo .Fl -adjust-vma Ns = Ns Ar increment | .Fl -change-addresses Ns = Ns Ar increment .Oc .Op Fl -adjust-warnings | Fl -change-warnings .Op Fl -change-section-lma Ar section Ns {+|-|=} Ns Ar val .Op Fl -change-section-vma Ar section Ns {+|-|=} Ns Ar val .Op Fl -extract-dwo .Op Fl -gap-fill Ns = Ns Ar val .Op Fl -globalize-symbol Ns = Ns ar symbolname .Op Fl -globalize-symbols Ns = Ns Ar filename .Op Fl -localize-hidden .Op Fl -localize-symbols Ns = Ns Ar filename .Op Fl -no-adjust-warnings | Fl -no-change-warnings .Op Fl -only-keep-debug .Op Fl -pad-to Ns = Ns Ar address .Op Fl -prefix-alloc-sections Ns = Ns Ar string .Op Fl -prefix-sections Ns = Ns Ar string .Op Fl -prefix-symbols Ns = Ns Ar string .Op Fl -rename-section Ar oldname Ns = Ns Ar newname Ns Op Ar ,flags .Op Fl -set-section-flags Ar sectionname Ns = Ns Ar flags .Op Fl -set-start Ns = Ns Ar address .Op Fl -srec-forceS3 .Op Fl -srec-len Ns = Ns Ar val .Op Fl -strip-dwo .Op Fl -strip-symbols= Ns Ar filename .Op Fl -strip-unneeded .Ar infile .Op Ar outfile .Sh DESCRIPTION The .Nm utility copies the content of the binary object named by argument .Ar infile to that named by argument .Ar outfile , transforming it according to the command line options specified. If argument .Ar outfile is not specified, .Nm will create a temporary file and will subsequently rename it as .Ar infile . .Pp The .Nm utility supports the following options: .Bl -tag -width indent .It Fl I Ar objformat | Fl s Ar objformat | Fl -input-target= Ns Ar objformat Specify that the input file named by the argument .Ar infile is in the object format specified by the argument .Ar objformat . .It Fl K Ar symbolname | Fl -keep-symbol= Ns Ar symbolname Copy the symbol named by argument .Ar symbolname to the output. .It Fl L Ar symbolname | Fl -localize-symbol= Ns Ar symbolname Make the symbol named by argument .Ar symbolname local to the output file. .It Fl N Ar symbol | Fl -strip-symbol= Ns Ar symbolname Do not copy the symbol named by argument .Ar symbolname to the output. .It Fl O Ar objformat | Fl -output-target= Ns Ar objformat Write the output file using the object format specified in argument .Ar objformat . The argument .Ar objformat should be one of the target names recognized by .Xr elftc_bfd_find_target 3 . .It Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname Remove any section with name .Ar sectionname from the output file. .It Fl S | Fl -strip-all Do not copy symbol and relocation information to the target file. .It Fl V | Fl -version Print a version identifier and exit. .It Fl W Ar symbolname | Fl -weaken-symbol= Ns Ar symbolname Mark the symbol named by argument .Ar symbolname as weak in the output. .It Fl X | Fl -discard-locals Do not copy compiler generated local symbols to the output. .It Fl d | Fl g | Fl -strip-debug Do not copy debugging information to the target file. .It Fl h | Fl -help Display a help message and exit. .It Fl j Ar sectionname | Fl -only-section= Ns Ar sectionname Copy only the section named by argument .Ar sectionname to the output. .It Fl p | Fl -preserve-dates Set the access and modification times of the output file to the same as those of the input. .It Fl w | Fl -wildcard Use shell-style patterns to name symbols. The following meta-characters are recognized in patterns: .Bl -tag -width "...." -compact .It Li ! If this is the first character of the pattern, invert the sense of the pattern match. .It Li * Matches any string of characters in a symbol name. .It Li ? Matches zero or one character in a symbol name. .It Li [ Mark the start of a character class. .It Li \e Remove the special meaning of the next character in the pattern. .It Li ] Mark the end of a character class. .El .It Fl x | Fl -discard-all Do not copy non-global symbols to the output. .It Fl -add-gnu-debuglink Ns = Ns Ar filename Create a .gnu_debuglink section in the output file that references the debug data in .Ar filename . .It Fl -add-section Ar sectionname Ns = Ns Ar filename Add a new section to the output file with name .Ar sectionname . The contents of the section are taken from the file named by argument .Ar filename . The size of the section will be the number of bytes in file .Ar filename . .It Xo .Fl -adjust-section-vma Ar section Ns {+|-|=} Ns Ar val | .Fl -change-section-address Ar section Ns {+|-|=} Ns Ar val .Xc Depending on the operator specified, increase, decrease or set both the virtual memory address and the load memory address of the section named by the argument .Ar section . The argument .Ar val specifies the desired increment, decrement or new value for the address. .It Xo .Fl -adjust-start Ns = Ns Ar increment | .Fl -change-start Ns = Ns Ar increment .Xc Increase the entry point address of the output ELF object by the value specified in the argument .Ar increment . .It Xo .Fl -adjust-vma Ns = Ns Ar increment | .Fl -change-addresses Ns = Ns Ar increment .Xc Increase the virtual memory address and the load memory address of all sections by the value specified by the argument .Ar increment . .It Fl -adjust-warnings | Fl -change-warnings Issue a warning if the section specified by the options .Fl -change-section-address , .Fl -change-section-lma or .Fl -change-section-vma does not exist in the input object. This is the default. .It Fl -change-section-lma Ar section Ns {+|-|=} Ns Ar val Change or set the load memory address of the section named by the argument .Ar section . Depending on the operator specified, the value in argument .Ar val will be used as an increment, a decrement or as the new value of the load memory address. .It Fl -change-section-vma Ar section Ns {+|-|=} Ns Ar val Change or set the virtual memory address of the section named by the argument .Ar section . Depending on the operator specified, the value in argument .Ar val will be used as an increment, a decrement or as the new value of the virtual memory address. .It Fl -extract-dwo Copy only .dwo debug sections to the output file. .It Fl -gap-fill Ns = Ns Ar val Fill the gaps between sections with the byte value specified by the argument .Ar val . .It Fl -globalize-symbol Ns = Ns Ar symbolname Make the symbol named by argument .Ar symbolname global, so that it is visible outside of the file in which it is defined. .It Fl -globalize-symbols Ns = Ns Ar filename Make each symbol listed in the file specified by .Ar filename global. .It Fl -localize-hidden Make all hidden symbols local to the output file. This includes symbols with internal visiblity. .It Fl -localize-symbols Ns = Ns Ar filename Make each symbol listed in the file specified by .Ar filename local to the output file. .It Fl -no-adjust-warnings | Fl -no-change-warnings Do not issue a warning if the section specified by the options .Fl -change-section-address , .Fl -change-section-lma or .Fl -change-section-vma is missing in the input object. .It Fl -only-keep-debug Copy only debugging information to the output file. .It Fl -pad-to Ns = Ns Ar address Pad the load memory address of the output object to the value specified by the argument .Ar address by increasing the size of the section with the highest load memory address. .It Fl -prefix-alloc-sections Ns = Ns Ar string Prefix the section names of all the allocated sections with .Ar string . .It Fl -prefix-sections Ns = Ns Ar string Prefix the section names of all the sections with .Ar string . .It Fl -prefix-symbols Ns = Ns Ar string Prefix the symbol names of all the symbols with .Ar string . .It Fl -rename-section Ar oldname Ns = Ns Ar newname Ns Op Ar ,flags Rename the section named by argument .Ar oldname to .Ar newname , optionally changing the sections flags to that specified by argument .Ar flags . Allowed values for the argument .Ar flags are as for option .Fl -set-section-flags below. .It Fl -set-section-flags Ar sectionname Ns = Ns Ar flags Set the flags for the section named by argument .Ar sectionname to those specified by argument .Ar flags . Argument .Ar flags is a comma separated list of the following flag names: .Bl -tag -width "readonly" -compact .It alloc The section occupies space in the output file. .It code The section contains machine instructions. .It contents This flag is accepted but is ignored. .It data The section contains writeable data. .It debug The section holds debugging information. .It load The section is loadable. .It noload The section should not be loaded into memory. .It readonly The section is not writable. .It rom The section contains ROM'able contents. .It share This flag is accepted but is ignored. .El .It Fl -set-start Ns = Ns Ar address Set the start address of the output ELF object to the value specified by the argument .Ar address . .It Fl -srec-forceS3 Only generate S-records of type .Dq S3 . This option is only meaningful when the output target is set to .Dq srec . .It Fl -srec-len Ns = Ns Ar val Set the maximum length of an S-record line to .Ar val . This option is only meaningful when the output target is set to .Dq srec . .It Fl -strip-dwo Do not copy .dwo debug sections to the output file. .It Fl -strip-symbols= Ns Ar filename Do not copy any of the symbols specified by .Ar filename to the output. .It Fl -strip-unneeded Do not copy symbols that are not needed for relocation processing. .El .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO .Xr ar 1 , .Xr ld 1 , .Xr mcs 1 , .Xr strip 1 , .Xr elf 3 , .Xr elftc_bfd_find_target 3 , .Xr ar 5 , .Xr elf 5 .Sh COMPATIBILITY The .Nm utility is expected to be option compatible with GNU .Nm objcopy . .Sh HISTORY .Nm has been implemented by .An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . Index: stable/11/contrib/elftoolchain/elfcopy/elfcopy.h =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/elfcopy.h (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/elfcopy.h (revision 367466) @@ -1,321 +1,324 @@ /*- * Copyright (c) 2007-2013 Kai Wang * 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: elfcopy.h 3446 2016-05-03 01:31:17Z emaste $ + * $Id: elfcopy.h 3757 2019-06-28 01:15:28Z emaste $ */ #include #include #include #include "_elftc.h" /* * User specified symbol operation (strip, keep, localize, globalize, * weaken, rename, etc). */ struct symop { const char *name; const char *newname; #define SYMOP_KEEP 0x0001U #define SYMOP_STRIP 0x0002U #define SYMOP_GLOBALIZE 0x0004U #define SYMOP_LOCALIZE 0x0008U #define SYMOP_KEEPG 0x0010U #define SYMOP_WEAKEN 0x0020U #define SYMOP_REDEF 0x0040U unsigned int op; STAILQ_ENTRY(symop) symop_list; }; /* File containing symbol list. */ struct symfile { dev_t dev; ino_t ino; size_t size; char *data; unsigned int op; STAILQ_ENTRY(symfile) symfile_list; }; /* Sections to copy/remove/rename/... */ struct sec_action { const char *name; const char *addopt; const char *newname; const char *string; uint64_t lma; uint64_t vma; int64_t lma_adjust; int64_t vma_adjust; #define SF_ALLOC 0x0001U #define SF_LOAD 0x0002U #define SF_NOLOAD 0x0004U #define SF_READONLY 0x0008U #define SF_DEBUG 0x0010U #define SF_CODE 0x0020U #define SF_DATA 0x0040U #define SF_ROM 0x0080U #define SF_SHARED 0X0100U #define SF_CONTENTS 0x0200U int flags; int add; int append; int compress; int copy; int print; int remove; int rename; int setflags; int setlma; int setvma; STAILQ_ENTRY(sec_action) sac_list; }; /* Sections to add from file. */ struct sec_add { char *name; char *content; size_t size; STAILQ_ENTRY(sec_add) sadd_list; }; struct segment; /* Internal data structure for sections. */ struct section { struct segment *seg; /* containing segment */ struct segment *seg_tls; /* tls segment */ const char *name; /* section name */ char *newname; /* new section name */ Elf_Scn *is; /* input scn */ Elf_Scn *os; /* output scn */ void *buf; /* section content */ uint8_t *pad; /* section padding */ uint64_t off; /* section offset */ uint64_t sz; /* section size */ uint64_t cap; /* section capacity */ uint64_t align; /* section alignment */ uint64_t type; /* section type */ uint64_t flags; /* section flags */ uint64_t vma; /* section virtual addr */ uint64_t lma; /* section load addr */ uint64_t pad_sz;/* section padding size */ int loadable; /* whether loadable */ int pseudo; int nocopy; + Elftc_String_Table *strtab; + TAILQ_ENTRY(section) sec_list; /* next section */ }; +TAILQ_HEAD(sectionlist, section); + /* Internal data structure for segments. */ struct segment { uint64_t vaddr; /* virtual addr (VMA) */ uint64_t paddr; /* physical addr (LMA) */ uint64_t off; /* file offset */ uint64_t fsz; /* file size */ uint64_t msz; /* memory size */ uint64_t type; /* segment type */ int remove; /* whether remove */ int nsec; /* number of sections contained */ struct section **v_sec; /* list of sections contained */ STAILQ_ENTRY(segment) seg_list; /* next segment */ }; /* * In-memory representation of ar(1) archive member(object). */ struct ar_obj { char *name; /* member name */ char *buf; /* member content */ void *maddr; /* mmap start address */ uid_t uid; /* user id */ gid_t gid; /* group id */ mode_t md; /* octal file permissions */ size_t size; /* member size */ time_t mtime; /* modification time */ STAILQ_ENTRY(ar_obj) objs; }; /* * Structure encapsulates the "global" data for "elfcopy" program. */ struct elfcopy { const char *progname; /* program name */ int iec; /* elfclass of input object */ Elftc_Bfd_Target_Flavor itf; /* flavour of input object */ Elftc_Bfd_Target_Flavor otf; /* flavour of output object */ const char *otgt; /* output target name */ int oec; /* elfclass of output object */ unsigned char oed; /* endianness of output object */ int oem; /* EM_XXX of output object */ int abi; /* OSABI of output object */ Elf *ein; /* ELF descriptor of input object */ Elf *eout; /* ELF descriptor of output object */ int iphnum; /* num. of input object phdr entries */ int ophnum; /* num. of output object phdr entries */ int nos; /* num. of output object sections */ enum { STRIP_NONE = 0, STRIP_ALL, STRIP_DEBUG, STRIP_DWO, STRIP_NONDEBUG, STRIP_NONDWO, STRIP_UNNEEDED } strip; #define EXECUTABLE 0x00000001U #define DYNAMIC 0x00000002U #define RELOCATABLE 0x00000004U #define SYMTAB_EXIST 0x00000010U #define SYMTAB_INTACT 0x00000020U #define KEEP_GLOBAL 0x00000040U #define DISCARD_LOCAL 0x00000080U #define WEAKEN_ALL 0x00000100U #define PRESERVE_DATE 0x00001000U #define SREC_FORCE_S3 0x00002000U #define SREC_FORCE_LEN 0x00004000U #define SET_START 0x00008000U #define GAP_FILL 0x00010000U #define WILDCARD 0x00020000U #define NO_CHANGE_WARN 0x00040000U #define SEC_ADD 0x00080000U #define SEC_APPEND 0x00100000U #define SEC_COMPRESS 0x00200000U #define SEC_PRINT 0x00400000U #define SEC_REMOVE 0x00800000U #define SEC_COPY 0x01000000U #define DISCARD_LLABEL 0x02000000U #define LOCALIZE_HIDDEN 0x04000000U int flags; /* elfcopy run control flags. */ int64_t change_addr; /* Section address adjustment. */ int64_t change_start; /* Entry point adjustment. */ uint64_t set_start; /* Entry point value. */ unsigned long srec_len; /* S-Record length. */ uint64_t pad_to; /* load address padding. */ uint8_t fill; /* gap fill value. */ char *prefix_sec; /* section prefix. */ char *prefix_alloc; /* alloc section prefix. */ char *prefix_sym; /* symbol prefix. */ char *debuglink; /* GNU debuglink file. */ struct section *symtab; /* .symtab section. */ struct section *strtab; /* .strtab section. */ struct section *shstrtab; /* .shstrtab section. */ uint64_t *secndx; /* section index map. */ uint64_t *symndx; /* symbol index map. */ unsigned char *v_rel; /* symbols needed by relocation. */ unsigned char *v_grp; /* symbols referred by section group. */ unsigned char *v_secsym; /* sections with section symbol. */ STAILQ_HEAD(, segment) v_seg; /* list of segments. */ STAILQ_HEAD(, sec_action) v_sac;/* list of section operations. */ STAILQ_HEAD(, sec_add) v_sadd; /* list of sections to add. */ STAILQ_HEAD(, symop) v_symop; /* list of symbols operations. */ STAILQ_HEAD(, symfile) v_symfile; /* list of symlist files. */ TAILQ_HEAD(, section) v_sec; /* list of sections. */ /* * Fields for the ar(1) archive. */ char *as; /* buffer for archive string table. */ size_t as_sz; /* current size of as table. */ size_t as_cap; /* capacity of as table buffer. */ uint32_t s_cnt; /* current number of symbols. */ uint32_t *s_so; /* symbol offset table. */ size_t s_so_cap; /* capacity of so table buffer. */ char *s_sn; /* symbol name table */ size_t s_sn_cap; /* capacity of sn table buffer. */ size_t s_sn_sz; /* current size of sn table. */ off_t rela_off; /* offset relative to pseudo members. */ STAILQ_HEAD(, ar_obj) v_arobj; /* archive object(member) list. */ }; void add_section(struct elfcopy *_ecp, const char *_optarg); void add_to_shstrtab(struct elfcopy *_ecp, const char *_name); void add_to_symop_list(struct elfcopy *_ecp, const char *_name, const char *_newname, unsigned int _op); void add_to_symtab(struct elfcopy *_ecp, const char *_name, uint64_t _st_value, uint64_t _st_size, uint16_t _st_shndx, unsigned char _st_info, unsigned char _st_other, int _ndx_known); int add_to_inseg_list(struct elfcopy *_ecp, struct section *_sec); void adjust_addr(struct elfcopy *_ecp); void copy_content(struct elfcopy *_ecp); void copy_data(struct section *_s); void copy_phdr(struct elfcopy *_ecp); void copy_shdr(struct elfcopy *_ecp, struct section *_s, const char *_name, int _copy, int _sec_flags); void create_binary(int _ifd, int _ofd); void create_elf(struct elfcopy *_ecp); void create_elf_from_binary(struct elfcopy *_ecp, int _ifd, const char *ifn); void create_elf_from_ihex(struct elfcopy *_ecp, int _ifd); void create_elf_from_srec(struct elfcopy *_ecp, int _ifd); struct section *create_external_section(struct elfcopy *_ecp, const char *_name, char *_newname, void *_buf, uint64_t _size, uint64_t _off, uint64_t _stype, Elf_Type _dtype, uint64_t flags, uint64_t _align, uint64_t _vma, int _loadable); void create_external_symtab(struct elfcopy *_ecp); void create_ihex(int _ifd, int _ofd); void create_pe(struct elfcopy *_ecp, int _ifd, int _ofd); void create_scn(struct elfcopy *_ecp); void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn); void create_symtab(struct elfcopy *_ecp); void create_symtab_data(struct elfcopy *_ecp); void create_tempfile(char **_fn, int *_fd); void finalize_external_symtab(struct elfcopy *_ecp); void free_elf(struct elfcopy *_ecp); void free_sec_act(struct elfcopy *_ecp); void free_sec_add(struct elfcopy *_ecp); void free_symtab(struct elfcopy *_ecp); void init_shstrtab(struct elfcopy *_ecp); void insert_to_sec_list(struct elfcopy *_ecp, struct section *_sec, int _tail); struct section *insert_shtab(struct elfcopy *_ecp, int tail); int is_remove_reloc_sec(struct elfcopy *_ecp, uint32_t _sh_info); int is_remove_section(struct elfcopy *_ecp, const char *_name); struct sec_action *lookup_sec_act(struct elfcopy *_ecp, const char *_name, int _add); struct symop *lookup_symop_list(struct elfcopy *_ecp, const char *_name, unsigned int _op); void resync_sections(struct elfcopy *_ecp); -void set_shstrtab(struct elfcopy *_ecp); void setup_phdr(struct elfcopy *_ecp); void update_shdr(struct elfcopy *_ecp, int _update_link); #ifndef LIBELF_AR int ac_detect_ar(int _ifd); void ac_create_ar(struct elfcopy *_ecp, int _ifd, int _ofd); #endif /* ! LIBELF_AR */ Index: stable/11/contrib/elftoolchain/elfcopy/main.c =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/main.c (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/main.c (revision 367466) @@ -1,1605 +1,1624 @@ /*- * Copyright (c) 2007-2013 Kai Wang * 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 "elfcopy.h" -ELFTC_VCSID("$Id: main.c 3577 2017-09-14 02:19:42Z emaste $"); +ELFTC_VCSID("$Id: main.c 3757 2019-06-28 01:15:28Z emaste $"); enum options { ECP_ADD_GNU_DEBUGLINK, ECP_ADD_SECTION, ECP_CHANGE_ADDR, ECP_CHANGE_SEC_ADDR, ECP_CHANGE_SEC_LMA, ECP_CHANGE_SEC_VMA, ECP_CHANGE_START, ECP_CHANGE_WARN, ECP_GAP_FILL, ECP_GLOBALIZE_SYMBOL, ECP_GLOBALIZE_SYMBOLS, ECP_KEEP_SYMBOLS, ECP_KEEP_GLOBAL_SYMBOLS, ECP_LOCALIZE_HIDDEN, ECP_LOCALIZE_SYMBOLS, ECP_NO_CHANGE_WARN, ECP_ONLY_DEBUG, ECP_ONLY_DWO, ECP_PAD_TO, ECP_PREFIX_ALLOC, ECP_PREFIX_SEC, ECP_PREFIX_SYM, ECP_REDEF_SYMBOL, ECP_REDEF_SYMBOLS, ECP_RENAME_SECTION, ECP_SET_OSABI, ECP_SET_SEC_FLAGS, ECP_SET_START, ECP_SREC_FORCE_S3, ECP_SREC_LEN, ECP_STRIP_DWO, ECP_STRIP_SYMBOLS, ECP_STRIP_UNNEEDED, ECP_WEAKEN_ALL, ECP_WEAKEN_SYMBOLS }; static struct option mcs_longopts[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; static struct option strip_longopts[] = { {"discard-all", no_argument, NULL, 'x'}, {"discard-locals", no_argument, NULL, 'X'}, {"help", no_argument, NULL, 'h'}, {"input-target", required_argument, NULL, 'I'}, {"keep-symbol", required_argument, NULL, 'K'}, {"only-keep-debug", no_argument, NULL, ECP_ONLY_DEBUG}, {"output-file", required_argument, NULL, 'o'}, {"output-target", required_argument, NULL, 'O'}, {"preserve-dates", no_argument, NULL, 'p'}, {"remove-section", required_argument, NULL, 'R'}, {"strip-all", no_argument, NULL, 's'}, {"strip-debug", no_argument, NULL, 'S'}, {"strip-symbol", required_argument, NULL, 'N'}, {"strip-unneeded", no_argument, NULL, ECP_STRIP_UNNEEDED}, {"version", no_argument, NULL, 'V'}, {"wildcard", no_argument, NULL, 'w'}, {NULL, 0, NULL, 0} }; static struct option elfcopy_longopts[] = { {"add-gnu-debuglink", required_argument, NULL, ECP_ADD_GNU_DEBUGLINK}, {"add-section", required_argument, NULL, ECP_ADD_SECTION}, {"adjust-section-vma", required_argument, NULL, ECP_CHANGE_SEC_ADDR}, {"adjust-vma", required_argument, NULL, ECP_CHANGE_ADDR}, {"adjust-start", required_argument, NULL, ECP_CHANGE_START}, {"adjust-warnings", no_argument, NULL, ECP_CHANGE_WARN}, {"binary-architecture", required_argument, NULL, 'B'}, {"change-addresses", required_argument, NULL, ECP_CHANGE_ADDR}, {"change-section-address", required_argument, NULL, ECP_CHANGE_SEC_ADDR}, {"change-section-lma", required_argument, NULL, ECP_CHANGE_SEC_LMA}, {"change-section-vma", required_argument, NULL, ECP_CHANGE_SEC_VMA}, {"change-start", required_argument, NULL, ECP_CHANGE_START}, {"change-warnings", no_argument, NULL, ECP_CHANGE_WARN}, {"discard-all", no_argument, NULL, 'x'}, {"discard-locals", no_argument, NULL, 'X'}, {"extract-dwo", no_argument, NULL, ECP_ONLY_DWO}, {"gap-fill", required_argument, NULL, ECP_GAP_FILL}, {"globalize-symbol", required_argument, NULL, ECP_GLOBALIZE_SYMBOL}, {"globalize-symbols", required_argument, NULL, ECP_GLOBALIZE_SYMBOLS}, {"help", no_argument, NULL, 'h'}, {"input-target", required_argument, NULL, 'I'}, {"keep-symbol", required_argument, NULL, 'K'}, {"keep-symbols", required_argument, NULL, ECP_KEEP_SYMBOLS}, {"keep-global-symbol", required_argument, NULL, 'G'}, {"keep-global-symbols", required_argument, NULL, ECP_KEEP_GLOBAL_SYMBOLS}, {"localize-hidden", no_argument, NULL, ECP_LOCALIZE_HIDDEN}, {"localize-symbol", required_argument, NULL, 'L'}, {"localize-symbols", required_argument, NULL, ECP_LOCALIZE_SYMBOLS}, {"no-adjust-warnings", no_argument, NULL, ECP_NO_CHANGE_WARN}, {"no-change-warnings", no_argument, NULL, ECP_NO_CHANGE_WARN}, {"only-keep-debug", no_argument, NULL, ECP_ONLY_DEBUG}, {"only-section", required_argument, NULL, 'j'}, {"osabi", required_argument, NULL, ECP_SET_OSABI}, {"output-target", required_argument, NULL, 'O'}, {"pad-to", required_argument, NULL, ECP_PAD_TO}, {"preserve-dates", no_argument, NULL, 'p'}, {"prefix-alloc-sections", required_argument, NULL, ECP_PREFIX_ALLOC}, {"prefix-sections", required_argument, NULL, ECP_PREFIX_SEC}, {"prefix-symbols", required_argument, NULL, ECP_PREFIX_SYM}, {"redefine-sym", required_argument, NULL, ECP_REDEF_SYMBOL}, {"redefine-syms", required_argument, NULL, ECP_REDEF_SYMBOLS}, {"remove-section", required_argument, NULL, 'R'}, {"rename-section", required_argument, NULL, ECP_RENAME_SECTION}, {"set-section-flags", required_argument, NULL, ECP_SET_SEC_FLAGS}, {"set-start", required_argument, NULL, ECP_SET_START}, {"srec-forceS3", no_argument, NULL, ECP_SREC_FORCE_S3}, {"srec-len", required_argument, NULL, ECP_SREC_LEN}, {"strip-all", no_argument, NULL, 'S'}, {"strip-debug", no_argument, 0, 'g'}, {"strip-dwo", no_argument, NULL, ECP_STRIP_DWO}, {"strip-symbol", required_argument, NULL, 'N'}, {"strip-symbols", required_argument, NULL, ECP_STRIP_SYMBOLS}, {"strip-unneeded", no_argument, NULL, ECP_STRIP_UNNEEDED}, {"version", no_argument, NULL, 'V'}, {"weaken", no_argument, NULL, ECP_WEAKEN_ALL}, {"weaken-symbol", required_argument, NULL, 'W'}, {"weaken-symbols", required_argument, NULL, ECP_WEAKEN_SYMBOLS}, {"wildcard", no_argument, NULL, 'w'}, {NULL, 0, NULL, 0} }; static struct { const char *name; int value; } sec_flags[] = { {"alloc", SF_ALLOC}, {"load", SF_LOAD}, {"noload", SF_NOLOAD}, {"readonly", SF_READONLY}, {"debug", SF_DEBUG}, {"code", SF_CODE}, {"data", SF_DATA}, {"rom", SF_ROM}, {"share", SF_SHARED}, {"contents", SF_CONTENTS}, {NULL, 0} }; static struct { const char *name; int abi; } osabis[] = { {"sysv", ELFOSABI_SYSV}, {"hpus", ELFOSABI_HPUX}, {"netbsd", ELFOSABI_NETBSD}, {"linux", ELFOSABI_LINUX}, {"hurd", ELFOSABI_HURD}, {"86open", ELFOSABI_86OPEN}, {"solaris", ELFOSABI_SOLARIS}, {"aix", ELFOSABI_AIX}, {"irix", ELFOSABI_IRIX}, {"freebsd", ELFOSABI_FREEBSD}, {"tru64", ELFOSABI_TRU64}, {"modesto", ELFOSABI_MODESTO}, {"openbsd", ELFOSABI_OPENBSD}, {"openvms", ELFOSABI_OPENVMS}, {"nsk", ELFOSABI_NSK}, {"cloudabi", ELFOSABI_CLOUDABI}, {"arm", ELFOSABI_ARM}, {"standalone", ELFOSABI_STANDALONE}, {NULL, 0} }; static int copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd, int in_place); static void create_file(struct elfcopy *ecp, const char *src, const char *dst); static void elfcopy_main(struct elfcopy *ecp, int argc, char **argv); static void elfcopy_usage(void); static void mcs_main(struct elfcopy *ecp, int argc, char **argv); static void mcs_usage(void); static void parse_sec_address_op(struct elfcopy *ecp, int optnum, const char *optname, char *s); static void parse_sec_flags(struct sec_action *sac, char *s); static void parse_symlist_file(struct elfcopy *ecp, const char *fn, unsigned int op); static void print_version(void); static void set_input_target(struct elfcopy *ecp, const char *target_name); static void set_osabi(struct elfcopy *ecp, const char *abi); static void set_output_target(struct elfcopy *ecp, const char *target_name); static void strip_main(struct elfcopy *ecp, int argc, char **argv); static void strip_usage(void); /* * An ELF object usually has a structure described by the * diagram below. * _____________ * | | * | NULL | <- always a SHT_NULL section * |_____________| * | | * | .interp | * |_____________| * | | * | ... | * |_____________| * | | * | .text | * |_____________| * | | * | ... | * |_____________| * | | * | .comment | <- above(include) this: normal sections * |_____________| * | | * | add sections| <- unloadable sections added by --add-section * |_____________| * | | * | .shstrtab | <- section name string table * |_____________| * | | * | shdrs | <- section header table * |_____________| * | | * | .symtab | <- symbol table, if any * |_____________| * | | * | .strtab | <- symbol name string table, if any * |_____________| * | | * | .rel.text | <- relocation info for .o files. * |_____________| */ void create_elf(struct elfcopy *ecp) { struct section *shtab; GElf_Ehdr ieh; GElf_Ehdr oeh; size_t ishnum; ecp->flags |= SYMTAB_INTACT; ecp->flags &= ~SYMTAB_EXIST; /* Create EHDR. */ if (gelf_getehdr(ecp->ein, &ieh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); if ((ecp->iec = gelf_getclass(ecp->ein)) == ELFCLASSNONE) errx(EXIT_FAILURE, "getclass() failed: %s", elf_errmsg(-1)); if (ecp->oec == ELFCLASSNONE) ecp->oec = ecp->iec; if (ecp->oed == ELFDATANONE) ecp->oed = ieh.e_ident[EI_DATA]; if (gelf_newehdr(ecp->eout, ecp->oec) == NULL) errx(EXIT_FAILURE, "gelf_newehdr failed: %s", elf_errmsg(-1)); if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); memcpy(oeh.e_ident, ieh.e_ident, sizeof(ieh.e_ident)); oeh.e_ident[EI_CLASS] = ecp->oec; oeh.e_ident[EI_DATA] = ecp->oed; if (ecp->abi != -1) oeh.e_ident[EI_OSABI] = ecp->abi; oeh.e_flags = ieh.e_flags; oeh.e_machine = ieh.e_machine; oeh.e_type = ieh.e_type; oeh.e_entry = ieh.e_entry; oeh.e_version = ieh.e_version; ecp->flags &= ~(EXECUTABLE | DYNAMIC | RELOCATABLE); if (ieh.e_type == ET_EXEC) ecp->flags |= EXECUTABLE; else if (ieh.e_type == ET_DYN) ecp->flags |= DYNAMIC; else if (ieh.e_type == ET_REL) ecp->flags |= RELOCATABLE; else errx(EXIT_FAILURE, "unsupported e_type"); if (!elf_getshnum(ecp->ein, &ishnum)) errx(EXIT_FAILURE, "elf_getshnum failed: %s", elf_errmsg(-1)); if (ishnum > 0 && (ecp->secndx = calloc(ishnum, sizeof(*ecp->secndx))) == NULL) err(EXIT_FAILURE, "calloc failed"); /* Read input object program header. */ setup_phdr(ecp); /* * Scan of input sections: we iterate through sections from input * object, skip sections need to be stripped, allot Elf_Scn and * create internal section structure for sections we want. * (i.e., determine output sections) */ create_scn(ecp); /* Apply section address changes, if any. */ adjust_addr(ecp); /* * Determine if the symbol table needs to be changed based on * command line options. */ if (ecp->strip == STRIP_DEBUG || ecp->strip == STRIP_UNNEEDED || ecp->flags & WEAKEN_ALL || ecp->flags & LOCALIZE_HIDDEN || ecp->flags & DISCARD_LOCAL || ecp->flags & DISCARD_LLABEL || ecp->prefix_sym != NULL || !STAILQ_EMPTY(&ecp->v_symop)) ecp->flags &= ~SYMTAB_INTACT; /* * Create symbol table. Symbols are filtered or stripped according to * command line args specified by user, and later updated for the new * layout of sections in the output object. */ if ((ecp->flags & SYMTAB_EXIST) != 0) create_symtab(ecp); /* * Write the underlying ehdr. Note that it should be called * before elf_setshstrndx() since it will overwrite e->e_shstrndx. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); /* * First processing of output sections: at this stage we copy the * content of each section from input to output object. Section * content will be modified and printed (mcs) if need. Also content of * relocation section probably will be filtered and updated according * to symbol table changes. */ copy_content(ecp); - /* Generate section name string table (.shstrtab). */ - set_shstrtab(ecp); - /* * Second processing of output sections: Update section headers. * At this stage we set name string index, update st_link and st_info * for output sections. */ update_shdr(ecp, 1); /* Renew oeh to get the updated e_shstrndx. */ if (gelf_getehdr(ecp->eout, &oeh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* * Insert SHDR table into the internal section list as a "pseudo" * section, so later it will get sorted and resynced just as "normal" * sections. * * Under FreeBSD, Binutils objcopy always put the section header * at the end of all the sections. We want to do the same here. * * However, note that the behaviour is still different with Binutils: * elfcopy checks the FreeBSD OSABI tag to tell whether it needs to * move the section headers, while Binutils is probably configured * this way when it's compiled on FreeBSD. */ if (oeh.e_ident[EI_OSABI] == ELFOSABI_FREEBSD) shtab = insert_shtab(ecp, 1); else shtab = insert_shtab(ecp, 0); /* * Resync section offsets in the output object. This is needed * because probably sections are modified or new sections are added, * as a result overlap/gap might appears. */ resync_sections(ecp); /* Store SHDR offset in EHDR. */ oeh.e_shoff = shtab->off; /* Put program header table immediately after the Elf header. */ if (ecp->ophnum > 0) { oeh.e_phoff = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); if (oeh.e_phoff == 0) errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); } /* * Update ELF object entry point if requested. */ if (ecp->change_addr != 0) oeh.e_entry += ecp->change_addr; if (ecp->flags & SET_START) oeh.e_entry = ecp->set_start; if (ecp->change_start != 0) oeh.e_entry += ecp->change_start; /* * Update ehdr again before we call elf_update(), since we * modified e_shoff and e_phoff. */ if (gelf_update_ehdr(ecp->eout, &oeh) == 0) errx(EXIT_FAILURE, "gelf_update_ehdr() failed: %s", elf_errmsg(-1)); if (ecp->ophnum > 0) copy_phdr(ecp); /* Write out the output elf object. */ if (elf_update(ecp->eout, ELF_C_WRITE) < 0) errx(EXIT_FAILURE, "elf_update() failed: %s", elf_errmsg(-1)); /* Release allocated resource. */ free_elf(ecp); } void free_elf(struct elfcopy *ecp) { struct segment *seg, *seg_temp; struct section *sec, *sec_temp; /* Free internal segment list. */ if (!STAILQ_EMPTY(&ecp->v_seg)) { STAILQ_FOREACH_SAFE(seg, &ecp->v_seg, seg_list, seg_temp) { STAILQ_REMOVE(&ecp->v_seg, seg, segment, seg_list); free(seg); } } /* Free symbol table buffers. */ free_symtab(ecp); + /* Free section name string table. */ + elftc_string_table_destroy(ecp->shstrtab->strtab); + /* Free internal section list. */ if (!TAILQ_EMPTY(&ecp->v_sec)) { TAILQ_FOREACH_SAFE(sec, &ecp->v_sec, sec_list, sec_temp) { TAILQ_REMOVE(&ecp->v_sec, sec, sec_list); if (sec->buf != NULL) free(sec->buf); if (sec->newname != NULL) free(sec->newname); if (sec->pad != NULL) free(sec->pad); free(sec); } } ecp->symtab = NULL; ecp->strtab = NULL; ecp->shstrtab = NULL; if (ecp->secndx != NULL) { free(ecp->secndx); ecp->secndx = NULL; } } /* Create a temporary file. */ void create_tempfile(char **fn, int *fd) { const char *tmpdir; char *cp, *tmpf; size_t tlen, plen; #define _TEMPFILE "ecp.XXXXXXXX" #define _TEMPFILEPATH "/tmp/ecp.XXXXXXXX" if (fn == NULL || fd == NULL) return; /* Repect TMPDIR environment variable. */ tmpdir = getenv("TMPDIR"); if (tmpdir != NULL && *tmpdir != '\0') { tlen = strlen(tmpdir); plen = strlen(_TEMPFILE); tmpf = malloc(tlen + plen + 2); if (tmpf == NULL) err(EXIT_FAILURE, "malloc failed"); strncpy(tmpf, tmpdir, tlen); cp = &tmpf[tlen - 1]; if (*cp++ != '/') *cp++ = '/'; strncpy(cp, _TEMPFILE, plen); cp[plen] = '\0'; } else { tmpf = strdup(_TEMPFILEPATH); if (tmpf == NULL) err(EXIT_FAILURE, "strdup failed"); } if ((*fd = mkstemp(tmpf)) == -1) err(EXIT_FAILURE, "mkstemp %s failed", tmpf); if (fchmod(*fd, 0644) == -1) err(EXIT_FAILURE, "fchmod %s failed", tmpf); *fn = tmpf; #undef _TEMPFILE #undef _TEMPFILEPATH } /* * Copy temporary file with path src and file descriptor infd to path dst. * If in_place is set act as if editing the file in place, avoiding rename() * to preserve hard and symbolic links. Output file remains open, with file * descriptor returned in outfd. */ static int copy_from_tempfile(const char *src, const char *dst, int infd, int *outfd, int in_place) { int tmpfd; /* * First, check if we can use rename(). */ if (in_place == 0) { if (rename(src, dst) >= 0) { *outfd = infd; return (0); } else if (errno != EXDEV) return (-1); /* * If the rename() failed due to 'src' and 'dst' residing in * two different file systems, invoke a helper function in * libelftc to do the copy. */ if (unlink(dst) < 0) return (-1); } if ((tmpfd = open(dst, O_CREAT | O_TRUNC | O_WRONLY, 0755)) < 0) return (-1); - if (elftc_copyfile(infd, tmpfd) < 0) + if (elftc_copyfile(infd, tmpfd) < 0) { + (void) close(tmpfd); return (-1); + } /* * Remove the temporary file from the file system * namespace, and close its file descriptor. */ - if (unlink(src) < 0) + if (unlink(src) < 0) { + (void) close(tmpfd); return (-1); + } (void) close(infd); /* * Return the file descriptor for the destination. */ *outfd = tmpfd; return (0); } static void create_file(struct elfcopy *ecp, const char *src, const char *dst) { struct stat sb; char *tempfile, *elftemp; int efd, ifd, ofd, ofd0, tfd; int in_place; tempfile = NULL; if (src == NULL) errx(EXIT_FAILURE, "internal: src == NULL"); if ((ifd = open(src, O_RDONLY)) == -1) err(EXIT_FAILURE, "open %s failed", src); if (fstat(ifd, &sb) == -1) err(EXIT_FAILURE, "fstat %s failed", src); if (dst == NULL) create_tempfile(&tempfile, &ofd); else if ((ofd = open(dst, O_RDWR|O_CREAT, 0755)) == -1) err(EXIT_FAILURE, "open %s failed", dst); #ifndef LIBELF_AR /* Detect and process ar(1) archive using libarchive. */ if (ac_detect_ar(ifd)) { ac_create_ar(ecp, ifd, ofd); goto copy_done; } #endif if (lseek(ifd, 0, SEEK_SET) < 0) err(EXIT_FAILURE, "lseek failed"); /* * If input object is not ELF file, convert it to an intermediate * ELF object before processing. */ if (ecp->itf != ETF_ELF) { /* * If the output object is not an ELF file, choose an arbitrary * ELF format for the intermediate file. srec, ihex and binary * formats are independent of class, endianness and machine * type so these choices do not affect the output. */ if (ecp->otf != ETF_ELF) { if (ecp->oec == ELFCLASSNONE) ecp->oec = ELFCLASS64; if (ecp->oed == ELFDATANONE) ecp->oed = ELFDATA2LSB; } create_tempfile(&elftemp, &efd); if ((ecp->eout = elf_begin(efd, ELF_C_WRITE, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); elf_flagelf(ecp->eout, ELF_C_SET, ELF_F_LAYOUT); if (ecp->itf == ETF_BINARY) create_elf_from_binary(ecp, ifd, src); else if (ecp->itf == ETF_IHEX) create_elf_from_ihex(ecp, ifd); else if (ecp->itf == ETF_SREC) create_elf_from_srec(ecp, ifd); else errx(EXIT_FAILURE, "Internal: invalid target flavour"); elf_end(ecp->eout); /* Open intermediate ELF object as new input object. */ close(ifd); if ((ifd = open(elftemp, O_RDONLY)) == -1) err(EXIT_FAILURE, "open %s failed", src); close(efd); if (unlink(elftemp) < 0) err(EXIT_FAILURE, "unlink %s failed", elftemp); free(elftemp); } if ((ecp->ein = elf_begin(ifd, ELF_C_READ, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); switch (elf_kind(ecp->ein)) { case ELF_K_NONE: errx(EXIT_FAILURE, "file format not recognized"); case ELF_K_ELF: if ((ecp->eout = elf_begin(ofd, ELF_C_WRITE, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); /* elfcopy(1) manage ELF layout by itself. */ elf_flagelf(ecp->eout, ELF_C_SET, ELF_F_LAYOUT); /* * Create output ELF object. */ create_elf(ecp); elf_end(ecp->eout); /* * Convert the output ELF object to binary/srec/ihex if need. */ if (ecp->otf != ETF_ELF) { /* * Create (another) tempfile for binary/srec/ihex * output object. */ if (tempfile != NULL) { if (unlink(tempfile) < 0) err(EXIT_FAILURE, "unlink %s failed", tempfile); free(tempfile); } create_tempfile(&tempfile, &ofd0); /* * Rewind the file descriptor being processed. */ if (lseek(ofd, 0, SEEK_SET) < 0) err(EXIT_FAILURE, "lseek failed for the output object"); /* * Call flavour-specific conversion routine. */ switch (ecp->otf) { case ETF_BINARY: create_binary(ofd, ofd0); break; case ETF_IHEX: create_ihex(ofd, ofd0); break; case ETF_SREC: create_srec(ecp, ofd, ofd0, dst != NULL ? dst : src); break; case ETF_PE: case ETF_EFI: #if WITH_PE create_pe(ecp, ofd, ofd0); #else errx(EXIT_FAILURE, "PE/EFI support not enabled" " at compile time"); #endif break; default: errx(EXIT_FAILURE, "Internal: unsupported" " output flavour %d", ecp->oec); } close(ofd); ofd = ofd0; } break; case ELF_K_AR: /* XXX: Not yet supported. */ break; default: errx(EXIT_FAILURE, "file format not supported"); } elf_end(ecp->ein); #ifndef LIBELF_AR copy_done: #endif if (tempfile != NULL) { in_place = 0; if (dst == NULL) { dst = src; if (lstat(dst, &sb) != -1 && (sb.st_nlink > 1 || S_ISLNK(sb.st_mode))) in_place = 1; } if (copy_from_tempfile(tempfile, dst, ofd, &tfd, in_place) < 0) err(EXIT_FAILURE, "creation of %s failed", dst); free(tempfile); tempfile = NULL; ofd = tfd; } if (strcmp(dst, "/dev/null") && fchmod(ofd, sb.st_mode) == -1) err(EXIT_FAILURE, "fchmod %s failed", dst); if ((ecp->flags & PRESERVE_DATE) && elftc_set_timestamps(dst, &sb) < 0) err(EXIT_FAILURE, "setting timestamps failed"); close(ifd); close(ofd); } static void elfcopy_main(struct elfcopy *ecp, int argc, char **argv) { struct sec_action *sac; const char *infile, *outfile; char *fn, *s; int opt; while ((opt = getopt_long(argc, argv, "dB:gG:I:j:K:L:N:O:pR:s:SwW:xXV", elfcopy_longopts, NULL)) != -1) { switch(opt) { case 'B': /* ignored */ break; case 'R': sac = lookup_sec_act(ecp, optarg, 1); if (sac->copy != 0) errx(EXIT_FAILURE, "both copy and remove specified"); sac->remove = 1; ecp->flags |= SEC_REMOVE; break; case 'S': ecp->strip = STRIP_ALL; break; case 'g': ecp->strip = STRIP_DEBUG; break; case 'G': ecp->flags |= KEEP_GLOBAL; add_to_symop_list(ecp, optarg, NULL, SYMOP_KEEPG); break; case 'I': case 's': set_input_target(ecp, optarg); break; case 'j': sac = lookup_sec_act(ecp, optarg, 1); if (sac->remove != 0) errx(EXIT_FAILURE, "both copy and remove specified"); sac->copy = 1; ecp->flags |= SEC_COPY; break; case 'K': add_to_symop_list(ecp, optarg, NULL, SYMOP_KEEP); break; case 'L': add_to_symop_list(ecp, optarg, NULL, SYMOP_LOCALIZE); break; case 'N': add_to_symop_list(ecp, optarg, NULL, SYMOP_STRIP); break; case 'O': set_output_target(ecp, optarg); break; case 'p': ecp->flags |= PRESERVE_DATE; break; case 'V': print_version(); break; case 'w': ecp->flags |= WILDCARD; break; case 'W': add_to_symop_list(ecp, optarg, NULL, SYMOP_WEAKEN); break; case 'x': ecp->flags |= DISCARD_LOCAL; break; case 'X': ecp->flags |= DISCARD_LLABEL; break; case ECP_ADD_GNU_DEBUGLINK: ecp->debuglink = optarg; break; case ECP_ADD_SECTION: add_section(ecp, optarg); break; case ECP_CHANGE_ADDR: ecp->change_addr = (int64_t) strtoll(optarg, NULL, 0); break; case ECP_CHANGE_SEC_ADDR: parse_sec_address_op(ecp, opt, "--change-section-addr", optarg); break; case ECP_CHANGE_SEC_LMA: parse_sec_address_op(ecp, opt, "--change-section-lma", optarg); break; case ECP_CHANGE_SEC_VMA: parse_sec_address_op(ecp, opt, "--change-section-vma", optarg); break; case ECP_CHANGE_START: ecp->change_start = (int64_t) strtoll(optarg, NULL, 0); break; case ECP_CHANGE_WARN: /* default */ break; case ECP_GAP_FILL: ecp->fill = (uint8_t) strtoul(optarg, NULL, 0); ecp->flags |= GAP_FILL; break; case ECP_GLOBALIZE_SYMBOL: add_to_symop_list(ecp, optarg, NULL, SYMOP_GLOBALIZE); break; case ECP_GLOBALIZE_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_GLOBALIZE); break; case ECP_KEEP_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_KEEP); break; case ECP_KEEP_GLOBAL_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_KEEPG); break; case ECP_LOCALIZE_HIDDEN: ecp->flags |= LOCALIZE_HIDDEN; break; case ECP_LOCALIZE_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_LOCALIZE); break; case ECP_NO_CHANGE_WARN: ecp->flags |= NO_CHANGE_WARN; break; case ECP_ONLY_DEBUG: ecp->strip = STRIP_NONDEBUG; break; case ECP_ONLY_DWO: ecp->strip = STRIP_NONDWO; break; case ECP_PAD_TO: ecp->pad_to = (uint64_t) strtoull(optarg, NULL, 0); break; case ECP_PREFIX_ALLOC: ecp->prefix_alloc = optarg; break; case ECP_PREFIX_SEC: ecp->prefix_sec = optarg; break; case ECP_PREFIX_SYM: ecp->prefix_sym = optarg; break; case ECP_REDEF_SYMBOL: if ((s = strchr(optarg, '=')) == NULL) errx(EXIT_FAILURE, "illegal format for --redefine-sym"); *s++ = '\0'; add_to_symop_list(ecp, optarg, s, SYMOP_REDEF); break; case ECP_REDEF_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_REDEF); break; case ECP_RENAME_SECTION: if ((fn = strchr(optarg, '=')) == NULL) errx(EXIT_FAILURE, "illegal format for --rename-section"); *fn++ = '\0'; /* Check for optional flags. */ if ((s = strchr(fn, ',')) != NULL) *s++ = '\0'; sac = lookup_sec_act(ecp, optarg, 1); sac->rename = 1; sac->newname = fn; if (s != NULL) parse_sec_flags(sac, s); break; case ECP_SET_OSABI: set_osabi(ecp, optarg); break; case ECP_SET_SEC_FLAGS: if ((s = strchr(optarg, '=')) == NULL) errx(EXIT_FAILURE, "illegal format for --set-section-flags"); *s++ = '\0'; sac = lookup_sec_act(ecp, optarg, 1); parse_sec_flags(sac, s); break; case ECP_SET_START: ecp->flags |= SET_START; ecp->set_start = (uint64_t) strtoull(optarg, NULL, 0); break; case ECP_SREC_FORCE_S3: ecp->flags |= SREC_FORCE_S3; break; case ECP_SREC_LEN: ecp->flags |= SREC_FORCE_LEN; ecp->srec_len = strtoul(optarg, NULL, 0); break; case ECP_STRIP_DWO: ecp->strip = STRIP_DWO; break; case ECP_STRIP_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_STRIP); break; case ECP_STRIP_UNNEEDED: ecp->strip = STRIP_UNNEEDED; break; case ECP_WEAKEN_ALL: ecp->flags |= WEAKEN_ALL; break; case ECP_WEAKEN_SYMBOLS: parse_symlist_file(ecp, optarg, SYMOP_WEAKEN); break; default: elfcopy_usage(); } } - if (optind == argc || optind + 2 < argc) + argc -= optind; + argv += optind; + + if (argc == 0 || argc > 2) elfcopy_usage(); - infile = argv[optind]; + infile = argv[0]; outfile = NULL; - if (optind + 1 < argc) - outfile = argv[optind + 1]; + if (argc > 1) + outfile = argv[1]; create_file(ecp, infile, outfile); } static void mcs_main(struct elfcopy *ecp, int argc, char **argv) { struct sec_action *sac; const char *string; int append, delete, compress, name, print; int opt, i; append = delete = compress = name = print = 0; string = NULL; while ((opt = getopt_long(argc, argv, "a:cdhn:pV", mcs_longopts, NULL)) != -1) { switch(opt) { case 'a': append = 1; string = optarg; /* XXX multiple -a not supported */ break; case 'c': compress = 1; break; case 'd': delete = 1; break; case 'n': name = 1; (void)lookup_sec_act(ecp, optarg, 1); break; case 'p': print = 1; break; case 'V': print_version(); break; case 'h': default: mcs_usage(); } } - if (optind == argc) + argc -= optind; + argv += optind; + + if (argc == 0) mcs_usage(); /* Must specify one operation at least. */ if (!append && !compress && !delete && !print) mcs_usage(); /* * If we are going to delete, ignore other operations. This is * different from the Solaris implementation, which can print * and delete a section at the same time, for example. Also, this * implementation do not respect the order between operations that * user specified, i.e., "mcs -pc a.out" equals to "mcs -cp a.out". */ if (delete) { append = compress = print = 0; ecp->flags |= SEC_REMOVE; } if (append) ecp->flags |= SEC_APPEND; if (compress) ecp->flags |= SEC_COMPRESS; if (print) ecp->flags |= SEC_PRINT; /* .comment is the default section to operate on. */ if (!name) (void)lookup_sec_act(ecp, ".comment", 1); STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { sac->append = append; sac->compress = compress; sac->print = print; sac->remove = delete; sac->string = string; } - for (i = optind; i < argc; i++) { + for (i = 0; i < argc; i++) { /* If only -p is specified, output to /dev/null */ if (print && !append && !compress && !delete) create_file(ecp, argv[i], "/dev/null"); else create_file(ecp, argv[i], NULL); } } static void strip_main(struct elfcopy *ecp, int argc, char **argv) { struct sec_action *sac; const char *outfile; int opt; int i; outfile = NULL; while ((opt = getopt_long(argc, argv, "hI:K:N:o:O:pR:sSdgVxXw", strip_longopts, NULL)) != -1) { switch(opt) { case 'R': sac = lookup_sec_act(ecp, optarg, 1); sac->remove = 1; ecp->flags |= SEC_REMOVE; break; case 's': ecp->strip = STRIP_ALL; break; case 'S': case 'g': case 'd': ecp->strip = STRIP_DEBUG; break; case 'I': /* ignored */ break; case 'K': add_to_symop_list(ecp, optarg, NULL, SYMOP_KEEP); break; case 'N': add_to_symop_list(ecp, optarg, NULL, SYMOP_STRIP); break; case 'o': outfile = optarg; break; case 'O': set_output_target(ecp, optarg); break; case 'p': ecp->flags |= PRESERVE_DATE; break; case 'V': print_version(); break; case 'w': ecp->flags |= WILDCARD; break; case 'x': ecp->flags |= DISCARD_LOCAL; break; case 'X': ecp->flags |= DISCARD_LLABEL; break; case ECP_ONLY_DEBUG: ecp->strip = STRIP_NONDEBUG; break; case ECP_STRIP_UNNEEDED: ecp->strip = STRIP_UNNEEDED; break; case 'h': default: strip_usage(); } } + argc -= optind; + argv += optind; + if (ecp->strip == 0 && ((ecp->flags & DISCARD_LOCAL) == 0) && ((ecp->flags & DISCARD_LLABEL) == 0) && lookup_symop_list(ecp, NULL, SYMOP_STRIP) == NULL) ecp->strip = STRIP_ALL; - if (optind == argc) + if (argc == 0) strip_usage(); + /* + * Only accept a single input file if an output file had been + * specified. + */ + if (outfile != NULL && argc != 1) + strip_usage(); - for (i = optind; i < argc; i++) + for (i = 0; i < argc; i++) create_file(ecp, argv[i], outfile); } static void parse_sec_flags(struct sec_action *sac, char *s) { const char *flag; int found, i; for (flag = strtok(s, ","); flag; flag = strtok(NULL, ",")) { found = 0; for (i = 0; sec_flags[i].name != NULL; i++) if (strcasecmp(sec_flags[i].name, flag) == 0) { sac->flags |= sec_flags[i].value; found = 1; break; } if (!found) errx(EXIT_FAILURE, "unrecognized section flag %s", flag); } } static void parse_sec_address_op(struct elfcopy *ecp, int optnum, const char *optname, char *s) { struct sec_action *sac; const char *name; char *v; char op; name = v = s; do { v++; } while (*v != '\0' && *v != '=' && *v != '+' && *v != '-'); if (*v == '\0' || *(v + 1) == '\0') errx(EXIT_FAILURE, "invalid format for %s", optname); op = *v; *v++ = '\0'; sac = lookup_sec_act(ecp, name, 1); switch (op) { case '=': if (optnum == ECP_CHANGE_SEC_LMA || optnum == ECP_CHANGE_SEC_ADDR) { sac->setlma = 1; sac->lma = (uint64_t) strtoull(v, NULL, 0); } if (optnum == ECP_CHANGE_SEC_VMA || optnum == ECP_CHANGE_SEC_ADDR) { sac->setvma = 1; sac->vma = (uint64_t) strtoull(v, NULL, 0); } break; case '+': if (optnum == ECP_CHANGE_SEC_LMA || optnum == ECP_CHANGE_SEC_ADDR) sac->lma_adjust = (int64_t) strtoll(v, NULL, 0); if (optnum == ECP_CHANGE_SEC_VMA || optnum == ECP_CHANGE_SEC_ADDR) sac->vma_adjust = (int64_t) strtoll(v, NULL, 0); break; case '-': if (optnum == ECP_CHANGE_SEC_LMA || optnum == ECP_CHANGE_SEC_ADDR) sac->lma_adjust = (int64_t) -strtoll(v, NULL, 0); if (optnum == ECP_CHANGE_SEC_VMA || optnum == ECP_CHANGE_SEC_ADDR) sac->vma_adjust = (int64_t) -strtoll(v, NULL, 0); break; default: break; } } static void parse_symlist_file(struct elfcopy *ecp, const char *fn, unsigned int op) { struct symfile *sf; struct stat sb; FILE *fp; char *data, *p, *line, *end, *e, *n; if (stat(fn, &sb) == -1) err(EXIT_FAILURE, "stat %s failed", fn); /* Check if we already read and processed this file. */ STAILQ_FOREACH(sf, &ecp->v_symfile, symfile_list) { if (sf->dev == sb.st_dev && sf->ino == sb.st_ino) goto process_symfile; } if ((fp = fopen(fn, "r")) == NULL) err(EXIT_FAILURE, "can not open %s", fn); if ((data = malloc(sb.st_size + 1)) == NULL) err(EXIT_FAILURE, "malloc failed"); if (sb.st_size > 0) if (fread(data, sb.st_size, 1, fp) != 1) err(EXIT_FAILURE, "fread failed"); fclose(fp); data[sb.st_size] = '\0'; if ((sf = calloc(1, sizeof(*sf))) == NULL) err(EXIT_FAILURE, "malloc failed"); sf->dev = sb.st_dev; sf->ino = sb.st_ino; sf->size = sb.st_size + 1; sf->data = data; process_symfile: /* * Basically what we do here is to convert EOL to '\0', and remove * leading and trailing whitespaces for each line. */ end = sf->data + sf->size; line = NULL; for(p = sf->data; p < end; p++) { if ((*p == '\t' || *p == ' ') && line == NULL) continue; if (*p == '\r' || *p == '\n' || *p == '\0') { *p = '\0'; if (line == NULL) continue; /* Skip comment. */ if (*line == '#') { line = NULL; continue; } e = p - 1; while(e != line && (*e == '\t' || *e == ' ')) *e-- = '\0'; if (op != SYMOP_REDEF) add_to_symop_list(ecp, line, NULL, op); else { if (strlen(line) < 3) errx(EXIT_FAILURE, "illegal format for" " --redefine-sym"); for(n = line + 1; n < e; n++) { if (*n == ' ' || *n == '\t') { while(*n == ' ' || *n == '\t') *n++ = '\0'; break; } } if (n >= e) errx(EXIT_FAILURE, "illegal format for" " --redefine-sym"); add_to_symop_list(ecp, line, n, op); } line = NULL; continue; } if (line == NULL) line = p; } } static void set_input_target(struct elfcopy *ecp, const char *target_name) { Elftc_Bfd_Target *tgt; if ((tgt = elftc_bfd_find_target(target_name)) == NULL) errx(EXIT_FAILURE, "%s: invalid target name", target_name); ecp->itf = elftc_bfd_target_flavor(tgt); } static void set_output_target(struct elfcopy *ecp, const char *target_name) { Elftc_Bfd_Target *tgt; if ((tgt = elftc_bfd_find_target(target_name)) == NULL) errx(EXIT_FAILURE, "%s: invalid target name", target_name); ecp->otf = elftc_bfd_target_flavor(tgt); if (ecp->otf == ETF_ELF) { ecp->oec = elftc_bfd_target_class(tgt); ecp->oed = elftc_bfd_target_byteorder(tgt); ecp->oem = elftc_bfd_target_machine(tgt); + ecp->abi = elftc_bfd_target_osabi(tgt); } if (ecp->otf == ETF_EFI || ecp->otf == ETF_PE) ecp->oem = elftc_bfd_target_machine(tgt); ecp->otgt = target_name; } static void set_osabi(struct elfcopy *ecp, const char *abi) { int i, found; found = 0; for (i = 0; osabis[i].name != NULL; i++) if (strcasecmp(osabis[i].name, abi) == 0) { ecp->abi = osabis[i].abi; found = 1; break; } if (!found) errx(EXIT_FAILURE, "unrecognized OSABI %s", abi); } #define ELFCOPY_USAGE_MESSAGE "\ Usage: %s [options] infile [outfile]\n\ Transform object files.\n\n\ Options:\n\ -d | -g | --strip-debug Remove debugging information from the output.\n\ -j SECTION | --only-section=SECTION\n\ Copy only the named section to the output.\n\ -p | --preserve-dates Preserve access and modification times.\n\ -w | --wildcard Use shell-style patterns to name symbols.\n\ -x | --discard-all Do not copy non-globals to the output.\n\ -I FORMAT | --input-target=FORMAT\n\ Specify object format for the input file.\n\ -K SYM | --keep-symbol=SYM Copy symbol SYM to the output.\n\ -L SYM | --localize-symbol=SYM\n\ Make symbol SYM local to the output file.\n\ -N SYM | --strip-symbol=SYM Do not copy symbol SYM to the output.\n\ -O FORMAT | --output-target=FORMAT\n\ Specify object format for the output file.\n\ FORMAT should be a target name understood by\n\ elftc_bfd_find_target(3).\n\ -R NAME | --remove-section=NAME\n\ Remove the named section.\n\ -S | --strip-all Remove all symbol and relocation information\n\ from the output.\n\ -V | --version Print a version identifier and exit.\n\ -W SYM | --weaken-symbol=SYM Mark symbol SYM as weak in the output.\n\ -X | --discard-locals Do not copy compiler generated symbols to\n\ the output.\n\ --add-section NAME=FILE Add the contents of FILE to the ELF object as\n\ a new section named NAME.\n\ --adjust-section-vma SECTION{=,+,-}VAL | \\\n\ --change-section-address SECTION{=,+,-}VAL\n\ Set or adjust the VMA and the LMA of the\n\ named section by VAL.\n\ --adjust-start=INCR | --change-start=INCR\n\ Add INCR to the start address for the ELF\n\ object.\n\ --adjust-vma=INCR | --change-addresses=INCR\n\ Increase the VMA and LMA of all sections by\n\ INCR.\n\ --adjust-warning | --change-warnings\n\ Issue warnings for non-existent sections.\n\ --change-section-lma SECTION{=,+,-}VAL\n\ Set or adjust the LMA address of the named\n\ section by VAL.\n\ --change-section-vma SECTION{=,+,-}VAL\n\ Set or adjust the VMA address of the named\n\ section by VAL.\n\ --gap-fill=VAL Fill the gaps between sections with bytes\n\ of value VAL.\n\ --localize-hidden Make all hidden symbols local to the output\n\ file.\n\ --no-adjust-warning| --no-change-warnings\n\ Do not issue warnings for non-existent\n\ sections.\n\ --only-keep-debug Copy only debugging information.\n\ --output-target=FORMAT Use the specified format for the output.\n\ --pad-to=ADDRESS Pad the output object up to the given address.\n\ --prefix-alloc-sections=STRING\n\ Prefix the section names of all the allocated\n\ sections with STRING.\n\ --prefix-sections=STRING Prefix the section names of all the sections\n\ with STRING.\n\ --prefix-symbols=STRING Prefix the symbol names of all the symbols\n\ with STRING.\n\ --rename-section OLDNAME=NEWNAME[,FLAGS]\n\ Rename and optionally change section flags.\n\ --set-section-flags SECTION=FLAGS\n\ Set section flags for the named section.\n\ Supported flags are: 'alloc', 'code',\n\ 'contents', 'data', 'debug', 'load',\n\ 'noload', 'readonly', 'rom', and 'shared'.\n\ --set-start=ADDRESS Set the start address of the ELF object.\n\ --srec-forceS3 Only generate S3 S-Records.\n\ --srec-len=LEN Set the maximum length of a S-Record line.\n\ --strip-unneeded Do not copy relocation information.\n" static void elfcopy_usage(void) { (void) fprintf(stderr, ELFCOPY_USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } #define MCS_USAGE_MESSAGE "\ Usage: %s [options] file...\n\ Manipulate the comment section in an ELF object.\n\n\ Options:\n\ -a STRING Append 'STRING' to the comment section.\n\ -c Remove duplicate entries from the comment section.\n\ -d Delete the comment section.\n\ -h | --help Print a help message and exit.\n\ -n NAME Operate on the ELF section with name 'NAME'.\n\ -p Print the contents of the comment section.\n\ -V | --version Print a version identifier and exit.\n" static void mcs_usage(void) { (void) fprintf(stderr, MCS_USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } #define STRIP_USAGE_MESSAGE "\ Usage: %s [options] file...\n\ Discard information from ELF objects.\n\n\ Options:\n\ -d | -g | -S | --strip-debug Remove debugging symbols.\n\ -h | --help Print a help message.\n\ -o FILE | --output-file FILE Write output to FILE.\n\ --only-keep-debug Keep debugging information only.\n\ -p | --preserve-dates Preserve access and modification times.\n\ -s | --strip-all Remove all symbols.\n\ --strip-unneeded Remove symbols not needed for relocation\n\ processing.\n\ -w | --wildcard Use shell-style patterns to name symbols.\n\ -x | --discard-all Discard all non-global symbols.\n\ -I TGT| --input-target=TGT (Accepted, but ignored).\n\ -K SYM | --keep-symbol=SYM Keep symbol 'SYM' in the output.\n\ -N SYM | --strip-symbol=SYM Remove symbol 'SYM' from the output.\n\ -O TGT | --output-target=TGT Set the output file format to 'TGT'.\n\ -R SEC | --remove-section=SEC Remove the section named 'SEC'.\n\ -V | --version Print a version identifier and exit.\n\ -X | --discard-locals Remove compiler-generated local symbols.\n" static void strip_usage(void) { (void) fprintf(stderr, STRIP_USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } static void print_version(void) { (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); exit(EXIT_SUCCESS); } /* * Compare the ending of s with end. */ static int strrcmp(const char *s, const char *end) { size_t endlen, slen; slen = strlen(s); endlen = strlen(end); if (slen >= endlen) s += slen - endlen; return (strcmp(s, end)); } int main(int argc, char **argv) { struct elfcopy *ecp; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "ELF library initialization failed: %s", elf_errmsg(-1)); ecp = calloc(1, sizeof(*ecp)); if (ecp == NULL) err(EXIT_FAILURE, "calloc failed"); - memset(ecp, 0, sizeof(*ecp)); ecp->itf = ecp->otf = ETF_ELF; ecp->iec = ecp->oec = ELFCLASSNONE; ecp->oed = ELFDATANONE; ecp->abi = -1; /* There is always an empty section. */ ecp->nos = 1; ecp->fill = 0; STAILQ_INIT(&ecp->v_seg); STAILQ_INIT(&ecp->v_sac); STAILQ_INIT(&ecp->v_sadd); STAILQ_INIT(&ecp->v_symop); STAILQ_INIT(&ecp->v_symfile); STAILQ_INIT(&ecp->v_arobj); TAILQ_INIT(&ecp->v_sec); if ((ecp->progname = ELFTC_GETPROGNAME()) == NULL) ecp->progname = "elfcopy"; if (strrcmp(ecp->progname, "strip") == 0) strip_main(ecp, argc, argv); else if (strrcmp(ecp->progname, "mcs") == 0) mcs_main(ecp, argc, argv); else { if (strrcmp(ecp->progname, "elfcopy") != 0 && strrcmp(ecp->progname, "objcopy") != 0) warnx("program mode not known, defaulting to elfcopy"); elfcopy_main(ecp, argc, argv); } free_sec_add(ecp); free_sec_act(ecp); free(ecp); exit(EXIT_SUCCESS); } Index: stable/11/contrib/elftoolchain/elfcopy/mcs.1 =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/mcs.1 (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/mcs.1 (revision 367466) @@ -1,125 +1,125 @@ .\" Copyright (c) 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: mcs.1 2247 2011-11-29 08:41:34Z jkoshy $ +.\" $Id: mcs.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" .Dd November 29, 2011 -.Os .Dt MCS 1 +.Os .Sh NAME .Nm mcs .Nd manipulate the comment section of an ELF object .Sh SYNOPSIS .Nm .Op Fl a Ar string .Op Fl c .Op Fl n Ar name .Op Fl p .Ar .Nm .Fl d .Op Fl n Ar name .Ar .Nm .Fl h | Fl -help .Nm .Fl V | Fl -version .Sh DESCRIPTION The .Nm utility is used to manipulate comment sections in an ELF object. If a command-line argument .Ar file names an .Xr ar 1 archive, then .Nm will operate on the ELF objects contained in the archive. .Pp By default .Nm operates on the ELF section named .Dq .comment . This may be changed using the .Fl n option. .Pp The .Nm utility supports the following options: .Bl -tag -width ".Fl a Ar string" .It Fl a Ar string Append the text in .Ar string to the comment section. This option may be specified multiple times. .It Fl c Compress the comment section by removing duplicate entries. .It Fl d Delete the comment section from the ELF object. .It Fl h | Fl -help Display a usage message and exit. .It Fl n Ar name Operate on the section named .Ar name . .It Fl p Print the contents of the comment section. This step is taken after actions specified by the .Fl a and .Fl c options (if any) are completed. .It Fl V | Fl -version Print a version identifier and exit. .El .Sh COMPATIBILITY The behavior of the .Nm utility differs from its SVR4 counterpart in the following ways: .Bl -bullet -compact .It If the .Fl d option is specified, it causes any .Fl a , .Fl c and .Fl p options present to be ignored. .It The order of options .Fl a , .Fl c , .Fl d , and .Fl p on the command line is not significant. .El .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO .Xr ar 1 , .Xr elfcopy 1 , .Xr ld 1 , .Xr nm 1 , .Xr strip 1 Index: stable/11/contrib/elftoolchain/elfcopy/sections.c =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/sections.c (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/sections.c (revision 367466) @@ -1,1741 +1,1753 @@ /*- * Copyright (c) 2007-2011,2014 Kai Wang * 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 "elfcopy.h" -ELFTC_VCSID("$Id: sections.c 3443 2016-04-15 18:57:54Z kaiwang27 $"); +ELFTC_VCSID("$Id: sections.c 3758 2019-06-28 01:16:50Z emaste $"); static void add_gnu_debuglink(struct elfcopy *ecp); static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc); static void check_section_rename(struct elfcopy *ecp, struct section *s); static void filter_reloc(struct elfcopy *ecp, struct section *s); static int get_section_flags(struct elfcopy *ecp, const char *name); static void insert_sections(struct elfcopy *ecp); -static void insert_to_strtab(struct section *t, const char *s); static int is_append_section(struct elfcopy *ecp, const char *name); static int is_compress_section(struct elfcopy *ecp, const char *name); static int is_debug_section(const char *name); static int is_dwo_section(const char *name); static int is_modify_section(struct elfcopy *ecp, const char *name); static int is_print_section(struct elfcopy *ecp, const char *name); -static int lookup_string(struct section *t, const char *s); static void modify_section(struct elfcopy *ecp, struct section *s); static void pad_section(struct elfcopy *ecp, struct section *s); static void print_data(const char *d, size_t sz); static void print_section(struct section *s); static void *read_section(struct section *s, size_t *size); +static void set_shstrtab(struct elfcopy *ecp); static void update_reloc(struct elfcopy *ecp, struct section *s); static void update_section_group(struct elfcopy *ecp, struct section *s); int is_remove_section(struct elfcopy *ecp, const char *name) { /* Always keep section name table */ if (strcmp(name, ".shstrtab") == 0) return 0; if (strcmp(name, ".symtab") == 0 || strcmp(name, ".strtab") == 0) { if (ecp->strip == STRIP_ALL && lookup_symop_list( ecp, NULL, SYMOP_KEEP) == NULL) return (1); else return (0); } if (ecp->strip == STRIP_DWO && is_dwo_section(name)) return (1); if (ecp->strip == STRIP_NONDWO && !is_dwo_section(name)) return (1); if (is_debug_section(name)) { if (ecp->strip == STRIP_ALL || ecp->strip == STRIP_DEBUG || ecp->strip == STRIP_UNNEEDED || (ecp->flags & DISCARD_LOCAL)) return (1); if (ecp->strip == STRIP_NONDEBUG) return (0); } if ((ecp->flags & SEC_REMOVE) || (ecp->flags & SEC_COPY)) { struct sec_action *sac; sac = lookup_sec_act(ecp, name, 0); if ((ecp->flags & SEC_REMOVE) && sac != NULL && sac->remove) return (1); if ((ecp->flags & SEC_COPY) && (sac == NULL || !sac->copy)) return (1); } return (0); } /* * Relocation section needs to be removed if the section it applies to * will be removed. */ int is_remove_reloc_sec(struct elfcopy *ecp, uint32_t sh_info) { const char *name; GElf_Shdr ish; Elf_Scn *is; size_t indx; int elferr; if (elf_getshstrndx(ecp->ein, &indx) == 0) errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", elf_errmsg(-1)); - is = NULL; - while ((is = elf_nextscn(ecp->ein, is)) != NULL) { - if (sh_info == elf_ndxscn(is)) { - if (gelf_getshdr(is, &ish) == NULL) - errx(EXIT_FAILURE, "gelf_getshdr failed: %s", - elf_errmsg(-1)); - if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == - NULL) - errx(EXIT_FAILURE, "elf_strptr failed: %s", - elf_errmsg(-1)); - if (is_remove_section(ecp, name)) - return (1); - else - return (0); - } + is = elf_getscn(ecp->ein, sh_info); + if (is != NULL) { + if (gelf_getshdr(is, &ish) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == + NULL) + errx(EXIT_FAILURE, "elf_strptr failed: %s", + elf_errmsg(-1)); + if (is_remove_section(ecp, name)) + return (1); + else + return (0); } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_nextscn failed: %s", elf_errmsg(elferr)); /* Remove reloc section if we can't find the target section. */ return (1); } static int is_append_section(struct elfcopy *ecp, const char *name) { struct sec_action *sac; sac = lookup_sec_act(ecp, name, 0); if (sac != NULL && sac->append != 0 && sac->string != NULL) return (1); return (0); } static int is_compress_section(struct elfcopy *ecp, const char *name) { struct sec_action *sac; sac = lookup_sec_act(ecp, name, 0); if (sac != NULL && sac->compress != 0) return (1); return (0); } static void check_section_rename(struct elfcopy *ecp, struct section *s) { struct sec_action *sac; char *prefix; size_t namelen; if (s->pseudo) return; sac = lookup_sec_act(ecp, s->name, 0); if (sac != NULL && sac->rename) s->name = sac->newname; if (!strcmp(s->name, ".symtab") || !strcmp(s->name, ".strtab") || !strcmp(s->name, ".shstrtab")) return; prefix = NULL; if (s->loadable && ecp->prefix_alloc != NULL) prefix = ecp->prefix_alloc; else if (ecp->prefix_sec != NULL) prefix = ecp->prefix_sec; if (prefix != NULL) { namelen = strlen(s->name) + strlen(prefix) + 1; if ((s->newname = malloc(namelen)) == NULL) err(EXIT_FAILURE, "malloc failed"); snprintf(s->newname, namelen, "%s%s", prefix, s->name); s->name = s->newname; } } static int get_section_flags(struct elfcopy *ecp, const char *name) { struct sec_action *sac; sac = lookup_sec_act(ecp, name, 0); if (sac != NULL && sac->flags) return sac->flags; return (0); } /* * Determine whether the section are debugging section. * According to libbfd, debugging sections are recognized * only by name. */ static int is_debug_section(const char *name) { const char *dbg_sec[] = { ".apple_", ".debug", ".gnu.linkonce.wi.", ".line", ".stab", NULL }; const char **p; for(p = dbg_sec; *p; p++) { if (strncmp(name, *p, strlen(*p)) == 0) return (1); } return (0); } static int is_dwo_section(const char *name) { size_t len; if ((len = strlen(name)) > 4 && strcmp(name + len - 4, ".dwo") == 0) return (1); return (0); } static int is_print_section(struct elfcopy *ecp, const char *name) { struct sec_action *sac; sac = lookup_sec_act(ecp, name, 0); if (sac != NULL && sac->print != 0) return (1); return (0); } static int is_modify_section(struct elfcopy *ecp, const char *name) { if (is_append_section(ecp, name) || is_compress_section(ecp, name)) return (1); return (0); } struct sec_action* lookup_sec_act(struct elfcopy *ecp, const char *name, int add) { struct sec_action *sac; if (name == NULL) return NULL; STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { if (strcmp(name, sac->name) == 0) return sac; } if (add == 0) return NULL; if ((sac = malloc(sizeof(*sac))) == NULL) errx(EXIT_FAILURE, "not enough memory"); memset(sac, 0, sizeof(*sac)); sac->name = name; STAILQ_INSERT_TAIL(&ecp->v_sac, sac, sac_list); return (sac); } void free_sec_act(struct elfcopy *ecp) { struct sec_action *sac, *sac_temp; STAILQ_FOREACH_SAFE(sac, &ecp->v_sac, sac_list, sac_temp) { STAILQ_REMOVE(&ecp->v_sac, sac, sec_action, sac_list); free(sac); } } void insert_to_sec_list(struct elfcopy *ecp, struct section *sec, int tail) { struct section *s; - if (!tail) { + if (tail || TAILQ_EMPTY(&ecp->v_sec) || + TAILQ_LAST(&ecp->v_sec, sectionlist)->off <= sec->off) { + TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list); + } else { TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (sec->off < s->off) { TAILQ_INSERT_BEFORE(s, sec, sec_list); - goto inc_nos; + break; } } } - TAILQ_INSERT_TAIL(&ecp->v_sec, sec, sec_list); - -inc_nos: if (sec->pseudo == 0) ecp->nos++; } /* * First step of section creation: create scn and internal section * structure, discard sections to be removed. */ void create_scn(struct elfcopy *ecp) { struct section *s; const char *name; Elf_Scn *is; GElf_Shdr ish; size_t indx; uint64_t oldndx, newndx; int elferr, sec_flags, reorder; + bool sections_added; /* * Insert a pseudo section that contains the ELF header * and program header. Used as reference for section offset * or load address adjustment. */ if ((s = calloc(1, sizeof(*s))) == NULL) err(EXIT_FAILURE, "calloc failed"); s->off = 0; s->sz = gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT) + gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT); s->align = 1; s->pseudo = 1; s->loadable = add_to_inseg_list(ecp, s); insert_to_sec_list(ecp, s, 0); /* Create internal .shstrtab section. */ init_shstrtab(ecp); if (elf_getshstrndx(ecp->ein, &indx) == 0) errx(EXIT_FAILURE, "elf_getshstrndx failed: %s", elf_errmsg(-1)); + sections_added = false; reorder = 0; is = NULL; while ((is = elf_nextscn(ecp->ein, is)) != NULL) { if (gelf_getshdr(is, &ish) == NULL) errx(EXIT_FAILURE, "gelf_getshdr failed: %s", elf_errmsg(-1)); if ((name = elf_strptr(ecp->ein, indx, ish.sh_name)) == NULL) errx(EXIT_FAILURE, "elf_strptr failed: %s", elf_errmsg(-1)); /* Skip sections to be removed. */ if (is_remove_section(ecp, name)) continue; /* * Relocation section need to be remove if the section * it applies will be removed. */ if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) if (ish.sh_info != 0 && is_remove_reloc_sec(ecp, ish.sh_info)) continue; /* * Section groups should be removed if symbol table will * be removed. (section group's signature stored in symbol * table) */ if (ish.sh_type == SHT_GROUP && ecp->strip == STRIP_ALL) continue; /* Get section flags set by user. */ sec_flags = get_section_flags(ecp, name); /* Create internal section object. */ if (strcmp(name, ".shstrtab") != 0) { if ((s = calloc(1, sizeof(*s))) == NULL) err(EXIT_FAILURE, "calloc failed"); s->name = name; s->is = is; s->off = ish.sh_offset; s->sz = ish.sh_size; s->align = ish.sh_addralign; s->type = ish.sh_type; s->flags = ish.sh_flags; s->vma = ish.sh_addr; /* * Search program headers to determine whether section * is loadable, but if user explicitly set section flags * while neither "load" nor "alloc" is set, we make the * section unloadable. * * Sections in relocatable object is loadable if * section flag SHF_ALLOC is set. */ if (sec_flags && (sec_flags & (SF_LOAD | SF_ALLOC)) == 0) s->loadable = 0; else { s->loadable = add_to_inseg_list(ecp, s); if ((ecp->flags & RELOCATABLE) && (ish.sh_flags & SHF_ALLOC)) s->loadable = 1; } } else { /* Assuming .shstrtab is "unloadable". */ s = ecp->shstrtab; s->off = ish.sh_offset; } oldndx = newndx = SHN_UNDEF; if (strcmp(name, ".symtab") != 0 && strcmp(name, ".strtab") != 0) { + /* Add new sections before .shstrtab if we have one. */ if (!strcmp(name, ".shstrtab")) { /* * Add sections specified by --add-section and * gnu debuglink. we want these sections have * smaller index than .shstrtab section. */ + sections_added = true; if (ecp->debuglink != NULL) add_gnu_debuglink(ecp); if (ecp->flags & SEC_ADD) insert_sections(ecp); } if ((s->os = elf_newscn(ecp->eout)) == NULL) errx(EXIT_FAILURE, "elf_newscn failed: %s", elf_errmsg(-1)); if ((newndx = elf_ndxscn(s->os)) == SHN_UNDEF) errx(EXIT_FAILURE, "elf_ndxscn failed: %s", elf_errmsg(-1)); } if ((oldndx = elf_ndxscn(is)) == SHN_UNDEF) errx(EXIT_FAILURE, "elf_ndxscn failed: %s", elf_errmsg(-1)); if (oldndx != SHN_UNDEF && newndx != SHN_UNDEF) ecp->secndx[oldndx] = newndx; /* * If strip action is STRIP_NONDEBUG(only keep debug), * change sections type of loadable sections and section * groups to SHT_NOBITS, and the content of those sections * will be discarded. However, SHT_NOTE sections should * be kept. */ if (ecp->strip == STRIP_NONDEBUG) { if (((ish.sh_flags & SHF_ALLOC) || (ish.sh_flags & SHF_GROUP)) && ish.sh_type != SHT_NOTE) s->type = SHT_NOBITS; } check_section_rename(ecp, s); /* create section header based on input object. */ if (strcmp(name, ".symtab") != 0 && strcmp(name, ".strtab") != 0 && strcmp(name, ".shstrtab") != 0) { copy_shdr(ecp, s, NULL, 0, sec_flags); /* * elfcopy puts .symtab, .strtab and .shstrtab * sections in the end of the output object. * If the input objects have more sections * after any of these 3 sections, the section * table will be reordered. section symbols * should be regenerated for relocations. */ if (reorder) ecp->flags &= ~SYMTAB_INTACT; } else reorder = 1; if (strcmp(name, ".symtab") == 0) { ecp->flags |= SYMTAB_EXIST; ecp->symtab = s; } if (strcmp(name, ".strtab") == 0) ecp->strtab = s; insert_to_sec_list(ecp, s, 0); } + if (!sections_added) { + if (ecp->debuglink != NULL) + add_gnu_debuglink(ecp); + if (ecp->flags & SEC_ADD) + insert_sections(ecp); + } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_nextscn failed: %s", elf_errmsg(elferr)); } struct section * insert_shtab(struct elfcopy *ecp, int tail) { struct section *s, *shtab; GElf_Ehdr ieh; int nsecs; /* * Treat section header table as a "pseudo" section, insert it * into section list, so later it will get sorted and resynced * just as normal sections. */ if ((shtab = calloc(1, sizeof(*shtab))) == NULL) errx(EXIT_FAILURE, "calloc failed"); if (!tail) { /* * "shoff" of input object is used as a hint for section * resync later. */ if (gelf_getehdr(ecp->ein, &ieh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); shtab->off = ieh.e_shoff; } else shtab->off = 0; /* Calculate number of sections in the output object. */ nsecs = 0; TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (!s->pseudo) nsecs++; } /* Remember there is always a null section, so we +1 here. */ shtab->sz = gelf_fsize(ecp->eout, ELF_T_SHDR, nsecs + 1, EV_CURRENT); if (shtab->sz == 0) errx(EXIT_FAILURE, "gelf_fsize() failed: %s", elf_errmsg(-1)); shtab->align = (ecp->oec == ELFCLASS32 ? 4 : 8); shtab->loadable = 0; shtab->pseudo = 1; insert_to_sec_list(ecp, shtab, tail); return (shtab); } void copy_content(struct elfcopy *ecp) { struct section *s; TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { /* Skip pseudo section. */ if (s->pseudo) continue; /* Skip special sections. */ if (strcmp(s->name, ".symtab") == 0 || strcmp(s->name, ".strtab") == 0 || strcmp(s->name, ".shstrtab") == 0) continue; /* * If strip action is STRIP_ALL, relocation info need * to be stripped. Skip filtering otherwisw. */ if (ecp->strip == STRIP_ALL && (s->type == SHT_REL || s->type == SHT_RELA)) filter_reloc(ecp, s); /* * The section indices in the SHT_GROUP section needs * to be updated since we might have stripped some * sections and changed section numbering. */ if (s->type == SHT_GROUP) update_section_group(ecp, s); if (is_modify_section(ecp, s->name)) modify_section(ecp, s); copy_data(s); /* * If symbol table is modified, relocation info might * need update, as symbol index may have changed. */ if ((ecp->flags & SYMTAB_INTACT) == 0 && (ecp->flags & SYMTAB_EXIST) && (s->type == SHT_REL || s->type == SHT_RELA)) update_reloc(ecp, s); if (is_print_section(ecp, s->name)) print_section(s); } } /* * Update section group section. The section indices in the SHT_GROUP * section need update after section numbering changed. */ static void update_section_group(struct elfcopy *ecp, struct section *s) { GElf_Shdr ish; Elf_Data *id; uint32_t *ws, *wd; uint64_t n; size_t ishnum; int i, j; if (!elf_getshnum(ecp->ein, &ishnum)) errx(EXIT_FAILURE, "elf_getshnum failed: %s", elf_errmsg(-1)); if (gelf_getshdr(s->is, &ish) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); if ((id = elf_getdata(s->is, NULL)) == NULL) errx(EXIT_FAILURE, "elf_getdata() failed: %s", elf_errmsg(-1)); if (ish.sh_size == 0) return; if (ish.sh_entsize == 0) ish.sh_entsize = 4; ws = id->d_buf; /* We only support COMDAT section. */ #ifndef GRP_COMDAT #define GRP_COMDAT 0x1 #endif if ((*ws & GRP_COMDAT) == 0) return; if ((s->buf = malloc(ish.sh_size)) == NULL) err(EXIT_FAILURE, "malloc failed"); s->sz = ish.sh_size; wd = s->buf; /* Copy the flag word as-is. */ *wd = *ws; /* Update the section indices. */ n = ish.sh_size / ish.sh_entsize; for(i = 1, j = 1; (uint64_t)i < n; i++) { if (ws[i] != SHN_UNDEF && ws[i] < ishnum && ecp->secndx[ws[i]] != 0) wd[j++] = ecp->secndx[ws[i]]; else s->sz -= 4; } s->nocopy = 1; } /* * Filter relocation entries, only keep those entries whose * symbol is in the keep list. */ static void filter_reloc(struct elfcopy *ecp, struct section *s) { const char *name; GElf_Shdr ish; GElf_Rel rel; GElf_Rela rela; Elf32_Rel *rel32; Elf64_Rel *rel64; Elf32_Rela *rela32; Elf64_Rela *rela64; Elf_Data *id; uint64_t cap, n, nrels, sym; int elferr, i; if (gelf_getshdr(s->is, &ish) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* We don't want to touch relocation info for dynamic symbols. */ if ((ecp->flags & SYMTAB_EXIST) == 0) { /* * No symbol table in output. If sh_link points to a section * that exists in the output object, this relocation section * is for dynamic symbols. Don't touch it. */ if (ish.sh_link != 0 && ecp->secndx[ish.sh_link] != 0) return; } else { /* Symbol table exist, check if index equals. */ if (ish.sh_link != elf_ndxscn(ecp->symtab->is)) return; } #define COPYREL(REL, SZ) do { \ if (nrels == 0) { \ if ((REL##SZ = malloc(cap * \ sizeof(*REL##SZ))) == NULL) \ err(EXIT_FAILURE, "malloc failed"); \ } \ if (nrels >= cap) { \ cap *= 2; \ if ((REL##SZ = realloc(REL##SZ, cap * \ sizeof(*REL##SZ))) == NULL) \ err(EXIT_FAILURE, "realloc failed"); \ } \ REL##SZ[nrels].r_offset = REL.r_offset; \ REL##SZ[nrels].r_info = REL.r_info; \ if (s->type == SHT_RELA) \ rela##SZ[nrels].r_addend = rela.r_addend; \ nrels++; \ } while (0) nrels = 0; cap = 4; /* keep list is usually small. */ rel32 = NULL; rel64 = NULL; rela32 = NULL; rela64 = NULL; if ((id = elf_getdata(s->is, NULL)) == NULL) errx(EXIT_FAILURE, "elf_getdata() failed: %s", elf_errmsg(-1)); n = ish.sh_size / ish.sh_entsize; for(i = 0; (uint64_t)i < n; i++) { if (s->type == SHT_REL) { if (gelf_getrel(id, i, &rel) != &rel) errx(EXIT_FAILURE, "gelf_getrel failed: %s", elf_errmsg(-1)); sym = GELF_R_SYM(rel.r_info); } else { if (gelf_getrela(id, i, &rela) != &rela) errx(EXIT_FAILURE, "gelf_getrel failed: %s", elf_errmsg(-1)); sym = GELF_R_SYM(rela.r_info); } /* * If a relocation references a symbol and we are omitting * either that symbol or the entire symbol table we cannot * produce valid output, and so just omit the relocation. * Broken output like this is generally not useful, but some * uses of elfcopy/strip rely on it - for example, GCC's build * process uses it to check for build reproducibility by * stripping objects and comparing them. * * Relocations that do not reference a symbol are retained. */ if (sym != 0) { if (ish.sh_link == 0 || ecp->secndx[ish.sh_link] == 0) continue; name = elf_strptr(ecp->ein, elf_ndxscn(ecp->strtab->is), sym); if (name == NULL) errx(EXIT_FAILURE, "elf_strptr failed: %s", elf_errmsg(-1)); if (lookup_symop_list(ecp, name, SYMOP_KEEP) == NULL) continue; } if (ecp->oec == ELFCLASS32) { if (s->type == SHT_REL) COPYREL(rel, 32); else COPYREL(rela, 32); } else { if (s->type == SHT_REL) COPYREL(rel, 64); else COPYREL(rela, 64); } } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_getdata() failed: %s", elf_errmsg(elferr)); if (ecp->oec == ELFCLASS32) { if (s->type == SHT_REL) s->buf = rel32; else s->buf = rela32; } else { if (s->type == SHT_REL) s->buf = rel64; else s->buf = rela64; } s->sz = gelf_fsize(ecp->eout, (s->type == SHT_REL ? ELF_T_REL : ELF_T_RELA), nrels, EV_CURRENT); s->nocopy = 1; } static void update_reloc(struct elfcopy *ecp, struct section *s) { GElf_Shdr osh; GElf_Rel rel; GElf_Rela rela; Elf_Data *od; uint64_t n; int i; #define UPDATEREL(REL) do { \ if (gelf_get##REL(od, i, &REL) != &REL) \ errx(EXIT_FAILURE, "gelf_get##REL failed: %s", \ elf_errmsg(-1)); \ REL.r_info = GELF_R_INFO(ecp->symndx[GELF_R_SYM(REL.r_info)], \ GELF_R_TYPE(REL.r_info)); \ if (!gelf_update_##REL(od, i, &REL)) \ errx(EXIT_FAILURE, "gelf_update_##REL failed: %s", \ elf_errmsg(-1)); \ } while(0) if (s->sz == 0) return; if (gelf_getshdr(s->os, &osh) == NULL) errx(EXIT_FAILURE, "gelf_getehdr() failed: %s", elf_errmsg(-1)); /* Only process .symtab reloc info. */ if (osh.sh_link != elf_ndxscn(ecp->symtab->is)) return; if ((od = elf_getdata(s->os, NULL)) == NULL) errx(EXIT_FAILURE, "elf_getdata() failed: %s", elf_errmsg(-1)); n = osh.sh_size / osh.sh_entsize; for(i = 0; (uint64_t)i < n; i++) { if (s->type == SHT_REL) UPDATEREL(rel); else UPDATEREL(rela); } } static void pad_section(struct elfcopy *ecp, struct section *s) { GElf_Shdr osh; Elf_Data *od; if (s == NULL || s->pad_sz == 0) return; if ((s->pad = malloc(s->pad_sz)) == NULL) err(EXIT_FAILURE, "malloc failed"); memset(s->pad, ecp->fill, s->pad_sz); /* Create a new Elf_Data to contain the padding bytes. */ if ((od = elf_newdata(s->os)) == NULL) errx(EXIT_FAILURE, "elf_newdata() failed: %s", elf_errmsg(-1)); od->d_align = 1; od->d_off = s->sz; od->d_buf = s->pad; od->d_type = ELF_T_BYTE; od->d_size = s->pad_sz; od->d_version = EV_CURRENT; /* Update section header. */ if (gelf_getshdr(s->os, &osh) == NULL) errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); osh.sh_size = s->sz + s->pad_sz; if (!gelf_update_shdr(s->os, &osh)) errx(EXIT_FAILURE, "elf_update_shdr failed: %s", elf_errmsg(-1)); } +static int +section_type_alignment(int sht, int class) +{ + switch (sht) + { + case SHT_DYNAMIC: + case SHT_DYNSYM: + case SHT_FINI_ARRAY: + case SHT_GNU_HASH: + case SHT_INIT_ARRAY: + case SHT_PREINIT_ARRAY: + case SHT_REL: + case SHT_RELA: + case SHT_SYMTAB: + return (class == ELFCLASS64 ? 8 : 4); + case SHT_SUNW_move: + return (8); + case SHT_GNU_LIBLIST: + case SHT_GROUP: + case SHT_HASH: + case SHT_NOTE: + case SHT_SUNW_verdef: /* == SHT_GNU_verdef */ + case SHT_SUNW_verneed: /* == SHT_GNU_verneed */ + case SHT_SYMTAB_SHNDX: + return (4); + case SHT_SUNW_syminfo: + case SHT_SUNW_versym: /* == SHT_GNU_versym */ + return (2); + case SHT_NOBITS: + case SHT_PROGBITS: + case SHT_STRTAB: + case SHT_SUNW_dof: + return (1); + } + return (1); +} + void resync_sections(struct elfcopy *ecp) { struct section *s, *ps; GElf_Shdr osh; uint64_t off; int first; + int min_alignment; ps = NULL; first = 1; off = 0; TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (first) { off = s->off; first = 0; } /* * Ignore TLS sections with load address 0 and without * content. We don't need to adjust their file offset or * VMA, only the size matters. */ if (s->seg_tls != NULL && s->type == SHT_NOBITS && s->off == 0) continue; /* Align section offset. */ if (s->align == 0) s->align = 1; + min_alignment = section_type_alignment(s->type, ecp->oec); + if (s->align < INT_MAX && (int)s->align < min_alignment) { + warnx("section %s alignment %d increased to %d", + s->name, (int)s->align, min_alignment); + s->align = min_alignment; + } if (off <= s->off) { if (!s->loadable || (ecp->flags & RELOCATABLE)) s->off = roundup(off, s->align); } else { if (s->loadable && (ecp->flags & RELOCATABLE) == 0) warnx("moving loadable section %s, " "is this intentional?", s->name); s->off = roundup(off, s->align); } /* Calculate next section offset. */ off = s->off; if (s->pseudo || (s->type != SHT_NOBITS && s->type != SHT_NULL)) off += s->sz; if (s->pseudo) { ps = NULL; continue; } /* Count padding bytes added through --pad-to. */ if (s->pad_sz > 0) off += s->pad_sz; /* Update section header accordingly. */ if (gelf_getshdr(s->os, &osh) == NULL) errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); osh.sh_addr = s->vma; + osh.sh_addralign = s->align; osh.sh_offset = s->off; osh.sh_size = s->sz; if (!gelf_update_shdr(s->os, &osh)) errx(EXIT_FAILURE, "elf_update_shdr failed: %s", elf_errmsg(-1)); /* Add padding for previous section, if need. */ if (ps != NULL) { if (ps->pad_sz > 0) { /* Apply padding added by --pad-to. */ pad_section(ecp, ps); } else if ((ecp->flags & GAP_FILL) && (ps->off + ps->sz < s->off)) { /* * Fill the gap between sections by padding * the section with lower address. */ ps->pad_sz = s->off - (ps->off + ps->sz); pad_section(ecp, ps); } } ps = s; } /* Pad the last section, if need. */ if (ps != NULL && ps->pad_sz > 0) pad_section(ecp, ps); } static void modify_section(struct elfcopy *ecp, struct section *s) { struct sec_action *sac; size_t srcsz, dstsz, p, len; char *b, *c, *d, *src, *end; int dupe; src = read_section(s, &srcsz); if (src == NULL || srcsz == 0) { /* For empty section, we proceed if we need to append. */ if (!is_append_section(ecp, s->name)) return; } /* Allocate buffer needed for new section data. */ dstsz = srcsz; if (is_append_section(ecp, s->name)) { sac = lookup_sec_act(ecp, s->name, 0); dstsz += strlen(sac->string) + 1; } if ((b = malloc(dstsz)) == NULL) err(EXIT_FAILURE, "malloc failed"); s->buf = b; /* Compress section. */ p = 0; if (is_compress_section(ecp, s->name)) { end = src + srcsz; for(c = src; c < end;) { len = 0; while(c + len < end && c[len] != '\0') len++; if (c + len == end) { /* XXX should we warn here? */ strncpy(&b[p], c, len); p += len; break; } dupe = 0; for (d = b; d < b + p; ) { if (strcmp(d, c) == 0) { dupe = 1; break; } d += strlen(d) + 1; } if (!dupe) { strncpy(&b[p], c, len); b[p + len] = '\0'; p += len + 1; } c += len + 1; } } else { memcpy(b, src, srcsz); p += srcsz; } /* Append section. */ if (is_append_section(ecp, s->name)) { sac = lookup_sec_act(ecp, s->name, 0); len = strlen(sac->string); strncpy(&b[p], sac->string, len); b[p + len] = '\0'; p += len + 1; } s->sz = p; s->nocopy = 1; } static void print_data(const char *d, size_t sz) { const char *c; for (c = d; c < d + sz; c++) { if (*c == '\0') putchar('\n'); else putchar(*c); } } static void print_section(struct section *s) { Elf_Data *id; int elferr; if (s->buf != NULL && s->sz > 0) { print_data(s->buf, s->sz); } else { id = NULL; while ((id = elf_getdata(s->is, id)) != NULL || (id = elf_rawdata(s->is, id)) != NULL) { (void) elf_errno(); print_data(id->d_buf, id->d_size); } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_getdata() failed: %s", elf_errmsg(elferr)); } putchar('\n'); } static void * read_section(struct section *s, size_t *size) { Elf_Data *id; char *b; size_t sz; int elferr; sz = 0; b = NULL; id = NULL; while ((id = elf_getdata(s->is, id)) != NULL || (id = elf_rawdata(s->is, id)) != NULL) { (void) elf_errno(); if (b == NULL) b = malloc(id->d_size); else - b = malloc(sz + id->d_size); + b = realloc(b, sz + id->d_size); if (b == NULL) err(EXIT_FAILURE, "malloc or realloc failed"); memcpy(&b[sz], id->d_buf, id->d_size); sz += id->d_size; } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_getdata() failed: %s", elf_errmsg(elferr)); *size = sz; return (b); } void copy_shdr(struct elfcopy *ecp, struct section *s, const char *name, int copy, int sec_flags) { GElf_Shdr ish, osh; if (gelf_getshdr(s->is, &ish) == NULL) errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); if (gelf_getshdr(s->os, &osh) == NULL) errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); if (copy) (void) memcpy(&osh, &ish, sizeof(ish)); else { osh.sh_type = s->type; osh.sh_addr = s->vma; osh.sh_offset = s->off; osh.sh_size = s->sz; osh.sh_link = ish.sh_link; osh.sh_info = ish.sh_info; osh.sh_addralign = s->align; osh.sh_entsize = ish.sh_entsize; if (sec_flags) { osh.sh_flags = 0; if (sec_flags & SF_ALLOC) osh.sh_flags |= SHF_ALLOC; if ((sec_flags & SF_READONLY) == 0) osh.sh_flags |= SHF_WRITE; if (sec_flags & SF_CODE) osh.sh_flags |= SHF_EXECINSTR; if ((sec_flags & SF_CONTENTS) && s->type == SHT_NOBITS && s->sz > 0) { /* * Convert SHT_NOBITS section to section with * (zero'ed) content on file. */ osh.sh_type = s->type = SHT_PROGBITS; if ((s->buf = calloc(1, s->sz)) == NULL) err(EXIT_FAILURE, "malloc failed"); s->nocopy = 1; } } else { osh.sh_flags = ish.sh_flags; /* * Newer binutils as(1) emits the section flag * SHF_INFO_LINK for relocation sections. elfcopy * emits this flag in the output section if it's * missing in the input section, to remain compatible * with binutils. */ if (ish.sh_type == SHT_REL || ish.sh_type == SHT_RELA) osh.sh_flags |= SHF_INFO_LINK; } } if (name == NULL) add_to_shstrtab(ecp, s->name); else add_to_shstrtab(ecp, name); if (!gelf_update_shdr(s->os, &osh)) errx(EXIT_FAILURE, "elf_update_shdr failed: %s", elf_errmsg(-1)); } void copy_data(struct section *s) { Elf_Data *id, *od; int elferr; if (s->nocopy && s->buf == NULL) return; if ((id = elf_getdata(s->is, NULL)) == NULL) { (void) elf_errno(); if ((id = elf_rawdata(s->is, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "failed to read section:" " %s", s->name); return; } } if ((od = elf_newdata(s->os)) == NULL) errx(EXIT_FAILURE, "elf_newdata() failed: %s", elf_errmsg(-1)); if (s->nocopy) { /* Use s->buf as content if s->nocopy is set. */ od->d_align = id->d_align; od->d_off = 0; od->d_buf = s->buf; od->d_type = id->d_type; od->d_size = s->sz; od->d_version = id->d_version; } else { od->d_align = id->d_align; od->d_off = id->d_off; od->d_buf = id->d_buf; od->d_type = id->d_type; od->d_size = id->d_size; od->d_version = id->d_version; } /* * Alignment Fixup. libelf does not allow the alignment for * Elf_Data descriptor to be set to 0. In this case we workaround * it by setting the alignment to 1. * * According to the ELF ABI, alignment 0 and 1 has the same * meaning: the section has no alignment constraints. */ if (od->d_align == 0) od->d_align = 1; } struct section * create_external_section(struct elfcopy *ecp, const char *name, char *newname, void *buf, uint64_t size, uint64_t off, uint64_t stype, Elf_Type dtype, uint64_t flags, uint64_t align, uint64_t vma, int loadable) { struct section *s; Elf_Scn *os; Elf_Data *od; GElf_Shdr osh; if ((os = elf_newscn(ecp->eout)) == NULL) errx(EXIT_FAILURE, "elf_newscn() failed: %s", elf_errmsg(-1)); if ((s = calloc(1, sizeof(*s))) == NULL) err(EXIT_FAILURE, "calloc failed"); s->name = name; s->newname = newname; /* needs to be free()'ed */ s->off = off; s->sz = size; s->vma = vma; s->align = align; s->loadable = loadable; s->is = NULL; s->os = os; s->type = stype; s->nocopy = 1; insert_to_sec_list(ecp, s, 1); if (gelf_getshdr(os, &osh) == NULL) errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); osh.sh_flags = flags; osh.sh_type = s->type; osh.sh_addr = s->vma; osh.sh_addralign = s->align; if (!gelf_update_shdr(os, &osh)) errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", elf_errmsg(-1)); add_to_shstrtab(ecp, name); if (buf != NULL && size != 0) { if ((od = elf_newdata(os)) == NULL) errx(EXIT_FAILURE, "elf_newdata() failed: %s", elf_errmsg(-1)); od->d_align = align; od->d_off = 0; od->d_buf = buf; od->d_size = size; od->d_type = dtype; od->d_version = EV_CURRENT; } /* * Clear SYMTAB_INTACT, as we probably need to update/add new * STT_SECTION symbols into the symbol table. */ ecp->flags &= ~SYMTAB_INTACT; return (s); } /* * Insert sections specified by --add-section to the end of section list. */ static void insert_sections(struct elfcopy *ecp) { struct sec_add *sa; struct section *s; size_t off; uint64_t stype; /* Put these sections in the end of current list. */ off = 0; TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (s->type != SHT_NOBITS && s->type != SHT_NULL) off = s->off + s->sz; else off = s->off; } STAILQ_FOREACH(sa, &ecp->v_sadd, sadd_list) { /* TODO: Add section header vma/lma, flag changes here */ /* * The default section type for user added section is * SHT_PROGBITS. If the section name match certain patterns, * elfcopy will try to set a more appropriate section type. * However, data type is always set to ELF_T_BYTE and no * translation is performed by libelf. */ stype = SHT_PROGBITS; if (strcmp(sa->name, ".note") == 0 || strncmp(sa->name, ".note.", strlen(".note.")) == 0) stype = SHT_NOTE; (void) create_external_section(ecp, sa->name, NULL, sa->content, sa->size, off, stype, ELF_T_BYTE, 0, 1, 0, 0); } } void add_to_shstrtab(struct elfcopy *ecp, const char *name) { - struct section *s; - s = ecp->shstrtab; - insert_to_strtab(s, name); + if (elftc_string_table_insert(ecp->shstrtab->strtab, name) == 0) + errx(EXIT_FAILURE, "elftc_string_table_insert failed"); } void update_shdr(struct elfcopy *ecp, int update_link) { struct section *s; GElf_Shdr osh; int elferr; + /* Finalize the section name string table (.shstrtab). */ + set_shstrtab(ecp); + TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (s->pseudo) continue; if (gelf_getshdr(s->os, &osh) == NULL) errx(EXIT_FAILURE, "gelf_getshdr failed: %s", elf_errmsg(-1)); /* Find section name in string table and set sh_name. */ - osh.sh_name = lookup_string(ecp->shstrtab, s->name); + osh.sh_name = elftc_string_table_lookup(ecp->shstrtab->strtab, + s->name); /* * sh_link needs to be updated, since the index of the * linked section might have changed. */ if (update_link && osh.sh_link != 0) osh.sh_link = ecp->secndx[osh.sh_link]; /* * sh_info of relocation section links to the section to which * its relocation info applies. So it may need update as well. */ if ((s->type == SHT_REL || s->type == SHT_RELA) && osh.sh_info != 0) osh.sh_info = ecp->secndx[osh.sh_info]; /* * sh_info of SHT_GROUP section needs to point to the correct * string in the symbol table. */ if (s->type == SHT_GROUP && (ecp->flags & SYMTAB_EXIST) && (ecp->flags & SYMTAB_INTACT) == 0) osh.sh_info = ecp->symndx[osh.sh_info]; if (!gelf_update_shdr(s->os, &osh)) errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", elf_errmsg(-1)); } elferr = elf_errno(); if (elferr != 0) errx(EXIT_FAILURE, "elf_nextscn failed: %s", elf_errmsg(elferr)); } void init_shstrtab(struct elfcopy *ecp) { + Elf_Scn *shstrtab; + GElf_Shdr shdr; struct section *s; + size_t indx, sizehint; + if (elf_getshdrstrndx(ecp->ein, &indx) == 0) { + shstrtab = elf_getscn(ecp->ein, indx); + if (shstrtab == NULL) + errx(EXIT_FAILURE, "elf_getscn failed: %s", + elf_errmsg(-1)); + if (gelf_getshdr(shstrtab, &shdr) != &shdr) + errx(EXIT_FAILURE, "gelf_getshdr failed: %s", + elf_errmsg(-1)); + sizehint = shdr.sh_size; + } else { + /* Clear the error from elf_getshdrstrndx(3). */ + (void)elf_errno(); + sizehint = 0; + } + if ((ecp->shstrtab = calloc(1, sizeof(*ecp->shstrtab))) == NULL) err(EXIT_FAILURE, "calloc failed"); s = ecp->shstrtab; s->name = ".shstrtab"; s->is = NULL; s->sz = 0; s->align = 1; s->loadable = 0; s->type = SHT_STRTAB; s->vma = 0; + s->strtab = elftc_string_table_create(sizehint); - insert_to_strtab(s, ""); - insert_to_strtab(s, ".symtab"); - insert_to_strtab(s, ".strtab"); - insert_to_strtab(s, ".shstrtab"); + add_to_shstrtab(ecp, ""); + add_to_shstrtab(ecp, ".symtab"); + add_to_shstrtab(ecp, ".strtab"); + add_to_shstrtab(ecp, ".shstrtab"); } -void +static void set_shstrtab(struct elfcopy *ecp) { struct section *s; Elf_Data *data; GElf_Shdr sh; + const char *image; + size_t sz; s = ecp->shstrtab; if (s->os == NULL) { /* Input object does not contain .shstrtab section */ if ((s->os = elf_newscn(ecp->eout)) == NULL) errx(EXIT_FAILURE, "elf_newscn failed: %s", elf_errmsg(-1)); insert_to_sec_list(ecp, s, 1); } if (gelf_getshdr(s->os, &sh) == NULL) errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); sh.sh_addr = 0; sh.sh_addralign = 1; sh.sh_offset = s->off; sh.sh_type = SHT_STRTAB; sh.sh_flags = 0; sh.sh_entsize = 0; sh.sh_info = 0; sh.sh_link = 0; if ((data = elf_newdata(s->os)) == NULL) errx(EXIT_FAILURE, "elf_newdata() failed: %s", elf_errmsg(-1)); /* * If we don't have a symbol table, skip those a few bytes * which are reserved for this in the beginning of shstrtab. */ if (!(ecp->flags & SYMTAB_EXIST)) { - s->sz -= sizeof(".symtab\0.strtab"); - memmove(s->buf, (char *)s->buf + sizeof(".symtab\0.strtab"), - s->sz); + elftc_string_table_remove(s->strtab, ".symtab"); + elftc_string_table_remove(s->strtab, ".strtab"); } - sh.sh_size = s->sz; + image = elftc_string_table_image(s->strtab, &sz); + s->sz = sz; + + sh.sh_size = sz; if (!gelf_update_shdr(s->os, &sh)) errx(EXIT_FAILURE, "gelf_update_shdr() failed: %s", elf_errmsg(-1)); data->d_align = 1; - data->d_buf = s->buf; - data->d_size = s->sz; + data->d_buf = (void *)(uintptr_t)image; + data->d_size = sz; data->d_off = 0; data->d_type = ELF_T_BYTE; data->d_version = EV_CURRENT; if (!elf_setshstrndx(ecp->eout, elf_ndxscn(s->os))) errx(EXIT_FAILURE, "elf_setshstrndx() failed: %s", elf_errmsg(-1)); } void add_section(struct elfcopy *ecp, const char *arg) { struct sec_add *sa; struct stat sb; const char *s, *fn; FILE *fp; int len; if ((s = strchr(arg, '=')) == NULL) errx(EXIT_FAILURE, "illegal format for --add-section option"); if ((sa = malloc(sizeof(*sa))) == NULL) err(EXIT_FAILURE, "malloc failed"); len = s - arg; if ((sa->name = malloc(len + 1)) == NULL) err(EXIT_FAILURE, "malloc failed"); strncpy(sa->name, arg, len); sa->name[len] = '\0'; fn = s + 1; if (stat(fn, &sb) == -1) err(EXIT_FAILURE, "stat failed"); sa->size = sb.st_size; if (sa->size > 0) { if ((sa->content = malloc(sa->size)) == NULL) err(EXIT_FAILURE, "malloc failed"); if ((fp = fopen(fn, "r")) == NULL) err(EXIT_FAILURE, "can not open %s", fn); if (fread(sa->content, 1, sa->size, fp) == 0 || ferror(fp)) err(EXIT_FAILURE, "fread failed"); fclose(fp); } else sa->content = NULL; STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); ecp->flags |= SEC_ADD; } void free_sec_add(struct elfcopy *ecp) { struct sec_add *sa, *sa_temp; STAILQ_FOREACH_SAFE(sa, &ecp->v_sadd, sadd_list, sa_temp) { STAILQ_REMOVE(&ecp->v_sadd, sa, sec_add, sadd_list); free(sa->name); free(sa->content); free(sa); } } static void add_gnu_debuglink(struct elfcopy *ecp) { struct sec_add *sa; struct stat sb; FILE *fp; char *fnbase, *buf; int crc_off; int crc; if (ecp->debuglink == NULL) return; /* Read debug file content. */ if ((sa = malloc(sizeof(*sa))) == NULL) err(EXIT_FAILURE, "malloc failed"); if ((sa->name = strdup(".gnu_debuglink")) == NULL) err(EXIT_FAILURE, "strdup failed"); if (stat(ecp->debuglink, &sb) == -1) err(EXIT_FAILURE, "stat failed"); if (sb.st_size == 0) errx(EXIT_FAILURE, "empty debug link target %s", ecp->debuglink); if ((buf = malloc(sb.st_size)) == NULL) err(EXIT_FAILURE, "malloc failed"); if ((fp = fopen(ecp->debuglink, "r")) == NULL) err(EXIT_FAILURE, "can not open %s", ecp->debuglink); if (fread(buf, 1, sb.st_size, fp) == 0 || ferror(fp)) err(EXIT_FAILURE, "fread failed"); fclose(fp); /* Calculate crc checksum. */ crc = calc_crc32(buf, sb.st_size, 0xFFFFFFFF); free(buf); /* Calculate section size and the offset to store crc checksum. */ if ((fnbase = basename(ecp->debuglink)) == NULL) err(EXIT_FAILURE, "basename failed"); crc_off = roundup(strlen(fnbase) + 1, 4); sa->size = crc_off + 4; /* Section content. */ if ((sa->content = calloc(1, sa->size)) == NULL) err(EXIT_FAILURE, "malloc failed"); strncpy(sa->content, fnbase, strlen(fnbase)); if (ecp->oed == ELFDATA2LSB) { sa->content[crc_off] = crc & 0xFF; sa->content[crc_off + 1] = (crc >> 8) & 0xFF; sa->content[crc_off + 2] = (crc >> 16) & 0xFF; sa->content[crc_off + 3] = crc >> 24; } else { sa->content[crc_off] = crc >> 24; sa->content[crc_off + 1] = (crc >> 16) & 0xFF; sa->content[crc_off + 2] = (crc >> 8) & 0xFF; sa->content[crc_off + 3] = crc & 0xFF; } STAILQ_INSERT_TAIL(&ecp->v_sadd, sa, sadd_list); ecp->flags |= SEC_ADD; -} - -static void -insert_to_strtab(struct section *t, const char *s) -{ - const char *r; - char *b, *c; - size_t len, slen; - int append; - - if (t->sz == 0) { - t->cap = 512; - if ((t->buf = malloc(t->cap)) == NULL) - err(EXIT_FAILURE, "malloc failed"); - } - - slen = strlen(s); - append = 0; - b = t->buf; - for (c = b; c < b + t->sz;) { - len = strlen(c); - if (!append && len >= slen) { - r = c + (len - slen); - if (strcmp(r, s) == 0) - return; - } else if (len < slen && len != 0) { - r = s + (slen - len); - if (strcmp(c, r) == 0) { - t->sz -= len + 1; - memmove(c, c + len + 1, t->sz - (c - b)); - append = 1; - continue; - } - } - c += len + 1; - } - - while (t->sz + slen + 1 >= t->cap) { - t->cap *= 2; - if ((t->buf = realloc(t->buf, t->cap)) == NULL) - err(EXIT_FAILURE, "realloc failed"); - } - b = t->buf; - strncpy(&b[t->sz], s, slen); - b[t->sz + slen] = '\0'; - t->sz += slen + 1; -} - -static int -lookup_string(struct section *t, const char *s) -{ - const char *b, *c, *r; - size_t len, slen; - - slen = strlen(s); - b = t->buf; - for (c = b; c < b + t->sz;) { - len = strlen(c); - if (len >= slen) { - r = c + (len - slen); - if (strcmp(r, s) == 0) - return (r - b); - } - c += len + 1; - } - - return (-1); } static uint32_t crctable[256] = { 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL }; static uint32_t calc_crc32(const char *p, size_t len, uint32_t crc) { uint32_t i; for (i = 0; i < len; i++) { crc = crctable[(crc ^ *p++) & 0xFFL] ^ (crc >> 8); } return (crc ^ 0xFFFFFFFF); } Index: stable/11/contrib/elftoolchain/elfcopy/segments.c =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/segments.c (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/segments.c (revision 367466) @@ -1,592 +1,592 @@ /*- * Copyright (c) 2007-2010,2012 Kai Wang * 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 "elfcopy.h" -ELFTC_VCSID("$Id: segments.c 3449 2016-05-03 13:59:29Z emaste $"); +ELFTC_VCSID("$Id: segments.c 3615 2018-05-17 04:12:24Z kaiwang27 $"); static void insert_to_inseg_list(struct segment *seg, struct section *sec); /* * elfcopy's segment handling is relatively simpler and less powerful than * libbfd. Program headers are modified or copied from input to output objects, * but never re-generated. As a result, if the input object has incorrect * program headers, the output object's program headers will remain incorrect * or become even worse. */ /* * Check whether a section is "loadable". If so, add it to the * corresponding segment list(s) and return 1. */ int add_to_inseg_list(struct elfcopy *ecp, struct section *s) { struct segment *seg; int loadable; if (ecp->ophnum == 0) return (0); /* * Segment is a different view of an ELF object. One segment can * contain one or more sections, and one section can be included * in one or more segments, or not included in any segment at all. * We call those sections which can be found in one or more segments * "loadable" sections, and call the rest "unloadable" sections. * We keep track of "loadable" sections in their containing * segment(s)' v_sec queue. These information are later used to * recalculate the extents of segments, when sections are removed, * for example. */ loadable = 0; STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { if (s->off < seg->off || (s->vma < seg->vaddr && !s->pseudo)) continue; if (s->off + s->sz > seg->off + seg->fsz && s->type != SHT_NOBITS) continue; if (s->vma + s->sz > seg->vaddr + seg->msz) continue; if (seg->type == PT_TLS && ((s->flags & SHF_TLS) == 0)) continue; insert_to_inseg_list(seg, s); if (seg->type == PT_LOAD) s->seg = seg; else if (seg->type == PT_TLS) s->seg_tls = seg; if (s->pseudo) s->vma = seg->vaddr + (s->off - seg->off); if (seg->paddr > 0) s->lma = seg->paddr + (s->off - seg->off); else s->lma = 0; loadable = 1; } return (loadable); } void adjust_addr(struct elfcopy *ecp) { struct section *s, *s0; struct segment *seg; struct sec_action *sac; uint64_t dl, vma, lma, start, end; int found, i; /* * Apply VMA and global LMA changes in the first iteration. */ TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { /* Only adjust loadable section's address. */ if (!s->loadable) continue; /* Apply global VMA adjustment. */ if (ecp->change_addr != 0) s->vma += ecp->change_addr; /* Apply global LMA adjustment. */ if (ecp->change_addr != 0 && s->seg != NULL && s->seg->paddr > 0) s->lma += ecp->change_addr; } /* * Apply sections VMA change in the second iteration. */ TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (!s->loadable) continue; /* * Check if there is a VMA change request for this * section. */ sac = lookup_sec_act(ecp, s->name, 0); if (sac == NULL) continue; vma = s->vma; if (sac->setvma) vma = sac->vma; if (sac->vma_adjust != 0) vma += sac->vma_adjust; if (vma == s->vma) continue; /* * No need to make segment adjustment if the section doesn't * belong to any segment. */ if (s->seg == NULL) { s->vma = vma; continue; } /* * Check if the VMA change is viable. * * 1. Check if the new VMA is properly aligned accroding to * section alignment. * * 2. Compute the new extent of segment that contains this * section, make sure it doesn't overlap with other * segments. */ #ifdef DEBUG printf("VMA for section %s: %#jx\n", s->name, vma); #endif if (vma % s->align != 0) errx(EXIT_FAILURE, "The VMA %#jx for " "section %s is not aligned to %ju", (uintmax_t) vma, s->name, (uintmax_t) s->align); if (vma < s->vma) { /* Move section to lower address. */ if (vma < s->vma - s->seg->vaddr) errx(EXIT_FAILURE, "Not enough space to move " "section %s VMA to %#jx", s->name, (uintmax_t) vma); start = vma - (s->vma - s->seg->vaddr); if (s == s->seg->v_sec[s->seg->nsec - 1]) end = start + s->seg->msz; else end = s->seg->vaddr + s->seg->msz; } else { /* Move section to upper address. */ if (s == s->seg->v_sec[0]) start = vma; else start = s->seg->vaddr; end = vma + (s->seg->vaddr + s->seg->msz - s->vma); if (end < start) errx(EXIT_FAILURE, "Not enough space to move " "section %s VMA to %#jx", s->name, (uintmax_t) vma); } #ifdef DEBUG printf("new extent for segment containing %s: (%#jx,%#jx)\n", s->name, start, end); #endif STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { if (seg == s->seg || seg->type != PT_LOAD) continue; if (start > seg->vaddr + seg->msz) continue; if (end < seg->vaddr) continue; errx(EXIT_FAILURE, "The extent of segment containing " "section %s overlaps with segment(%#jx,%#jx)", s->name, (uintmax_t) seg->vaddr, (uintmax_t) (seg->vaddr + seg->msz)); } /* * Update section VMA and file offset. */ if (vma < s->vma) { /* * To move a section to lower VMA, we decrease * the VMA of the section and all the sections that * are before it, and we increase the file offsets * of all the sections that are after it. */ dl = s->vma - vma; for (i = 0; i < s->seg->nsec; i++) { s0 = s->seg->v_sec[i]; s0->vma -= dl; #ifdef DEBUG printf("section %s VMA set to %#jx\n", s0->name, (uintmax_t) s0->vma); #endif if (s0 == s) break; } for (i = i + 1; i < s->seg->nsec; i++) { s0 = s->seg->v_sec[i]; s0->off += dl; #ifdef DEBUG printf("section %s offset set to %#jx\n", s0->name, (uintmax_t) s0->off); #endif } } else { /* * To move a section to upper VMA, we increase * the VMA of the section and all the sections that * are after it, and we increase the their file * offsets too unless the section in question * is the first in its containing segment. */ dl = vma - s->vma; for (i = 0; i < s->seg->nsec; i++) if (s->seg->v_sec[i] == s) break; if (i >= s->seg->nsec) errx(EXIT_FAILURE, "Internal: section `%s' not" " found in its containing segement", s->name); for (; i < s->seg->nsec; i++) { s0 = s->seg->v_sec[i]; s0->vma += dl; #ifdef DEBUG printf("section %s VMA set to %#jx\n", s0->name, (uintmax_t) s0->lma); #endif if (s != s->seg->v_sec[0]) { s0->off += dl; #ifdef DEBUG printf("section %s offset set to %#jx\n", s0->name, (uintmax_t) s0->off); #endif } } } } /* * Apply load address padding. */ if (ecp->pad_to != 0) { /* * Find the section with highest VMA. */ s = NULL; STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { if (seg->type != PT_LOAD) continue; for (i = seg->nsec - 1; i >= 0; i--) if (seg->v_sec[i]->type != SHT_NOBITS) break; if (i < 0) continue; if (s == NULL) s = seg->v_sec[i]; else { s0 = seg->v_sec[i]; if (s0->vma > s->vma) s = s0; } } if (s == NULL) goto adjust_lma; /* No need to pad if the pad_to address is lower. */ if (ecp->pad_to <= s->vma + s->sz) goto adjust_lma; s->pad_sz = ecp->pad_to - (s->vma + s->sz); #ifdef DEBUG printf("pad section %s VMA to address %#jx by %#jx\n", s->name, (uintmax_t) ecp->pad_to, (uintmax_t) s->pad_sz); #endif } adjust_lma: /* * Apply sections LMA change in the third iteration. */ TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { /* * Only loadable section that's inside a segment can have * LMA adjusted. Also, if LMA of the containing segment is * set to 0, it probably means we should ignore the LMA. */ if (!s->loadable || s->seg == NULL || s->seg->paddr == 0) continue; /* * Check if there is a LMA change request for this * section. */ sac = lookup_sec_act(ecp, s->name, 0); if (sac == NULL) continue; if (!sac->setlma && sac->lma_adjust == 0) continue; lma = s->lma; if (sac->setlma) lma = sac->lma; if (sac->lma_adjust != 0) lma += sac->lma_adjust; if (lma == s->lma) continue; #ifdef DEBUG printf("LMA for section %s: %#jx\n", s->name, lma); #endif /* Check alignment. */ if (lma % s->align != 0) errx(EXIT_FAILURE, "The LMA %#jx for " "section %s is not aligned to %ju", (uintmax_t) lma, s->name, (uintmax_t) s->align); /* * Update section LMA. */ if (lma < s->lma) { /* * To move a section to lower LMA, we decrease * the LMA of the section and all the sections that * are before it. */ dl = s->lma - lma; for (i = 0; i < s->seg->nsec; i++) { s0 = s->seg->v_sec[i]; s0->lma -= dl; #ifdef DEBUG printf("section %s LMA set to %#jx\n", s0->name, (uintmax_t) s0->lma); #endif if (s0 == s) break; } } else { /* * To move a section to upper LMA, we increase * the LMA of the section and all the sections that * are after it. */ dl = lma - s->lma; for (i = 0; i < s->seg->nsec; i++) if (s->seg->v_sec[i] == s) break; if (i >= s->seg->nsec) errx(EXIT_FAILURE, "Internal: section `%s' not" " found in its containing segement", s->name); for (; i < s->seg->nsec; i++) { s0 = s->seg->v_sec[i]; s0->lma += dl; #ifdef DEBUG printf("section %s LMA set to %#jx\n", s0->name, (uintmax_t) s0->lma); #endif } } } /* * Issue a warning if there are VMA/LMA adjust requests for * some nonexistent sections. */ if ((ecp->flags & NO_CHANGE_WARN) == 0) { STAILQ_FOREACH(sac, &ecp->v_sac, sac_list) { if (!sac->setvma && !sac->setlma && !sac->vma_adjust && !sac->lma_adjust) continue; found = 0; TAILQ_FOREACH(s, &ecp->v_sec, sec_list) { if (s->pseudo || s->name == NULL) continue; if (!strcmp(s->name, sac->name)) { found = 1; break; } } if (!found) warnx("cannot find section `%s'", sac->name); } } } static void insert_to_inseg_list(struct segment *seg, struct section *sec) { struct section *s; int i; seg->nsec++; seg->v_sec = realloc(seg->v_sec, seg->nsec * sizeof(*seg->v_sec)); if (seg->v_sec == NULL) err(EXIT_FAILURE, "realloc failed"); /* * Sort the section in order of offset. */ for (i = seg->nsec - 1; i > 0; i--) { s = seg->v_sec[i - 1]; if (sec->off >= s->off) { seg->v_sec[i] = sec; break; } else seg->v_sec[i] = s; } if (i == 0) seg->v_sec[0] = sec; } void setup_phdr(struct elfcopy *ecp) { struct segment *seg; GElf_Phdr iphdr; size_t iphnum, i; if (elf_getphnum(ecp->ein, &iphnum) == 0) errx(EXIT_FAILURE, "elf_getphnum failed: %s", elf_errmsg(-1)); ecp->ophnum = ecp->iphnum = iphnum; if (iphnum == 0) return; /* If --only-keep-debug is specified, discard all program headers. */ if (ecp->strip == STRIP_NONDEBUG) { ecp->ophnum = 0; return; } for (i = 0; i < iphnum; i++) { if (gelf_getphdr(ecp->ein, i, &iphdr) != &iphdr) errx(EXIT_FAILURE, "gelf_getphdr failed: %s", elf_errmsg(-1)); if ((seg = calloc(1, sizeof(*seg))) == NULL) err(EXIT_FAILURE, "calloc failed"); seg->vaddr = iphdr.p_vaddr; seg->paddr = iphdr.p_paddr; seg->off = iphdr.p_offset; seg->fsz = iphdr.p_filesz; seg->msz = iphdr.p_memsz; seg->type = iphdr.p_type; STAILQ_INSERT_TAIL(&ecp->v_seg, seg, seg_list); } } void copy_phdr(struct elfcopy *ecp) { struct segment *seg; struct section *s; GElf_Phdr iphdr, ophdr; int i; STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { if (seg->type == PT_PHDR) { if (!TAILQ_EMPTY(&ecp->v_sec)) { s = TAILQ_FIRST(&ecp->v_sec); if (s->pseudo) { seg->vaddr = s->vma + gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); seg->paddr = s->lma + gelf_fsize(ecp->eout, ELF_T_EHDR, 1, EV_CURRENT); } } seg->fsz = seg->msz = gelf_fsize(ecp->eout, ELF_T_PHDR, ecp->ophnum, EV_CURRENT); continue; } if (seg->nsec > 0) { s = seg->v_sec[0]; seg->vaddr = s->vma; seg->paddr = s->lma; } seg->fsz = seg->msz = 0; for (i = 0; i < seg->nsec; i++) { s = seg->v_sec[i]; seg->msz = s->vma + s->sz - seg->vaddr; if (s->type != SHT_NOBITS) seg->fsz = s->off + s->sz - seg->off; } } /* * Allocate space for program headers, note that libelf keep * track of the number in internal variable, and a call to * elf_update is needed to update e_phnum of ehdr. */ if (gelf_newphdr(ecp->eout, ecp->ophnum) == NULL) errx(EXIT_FAILURE, "gelf_newphdr() failed: %s", elf_errmsg(-1)); /* * This elf_update() call is to update the e_phnum field in * ehdr. It's necessary because later we will call gelf_getphdr(), * which does sanity check by comparing ndx argument with e_phnum. */ if (elf_update(ecp->eout, ELF_C_NULL) < 0) errx(EXIT_FAILURE, "elf_update() failed: %s", elf_errmsg(-1)); /* * iphnum == ophnum, since we don't remove program headers even if * they no longer contain sections. */ i = 0; STAILQ_FOREACH(seg, &ecp->v_seg, seg_list) { if (i >= ecp->iphnum) break; if (gelf_getphdr(ecp->ein, i, &iphdr) != &iphdr) errx(EXIT_FAILURE, "gelf_getphdr failed: %s", elf_errmsg(-1)); if (gelf_getphdr(ecp->eout, i, &ophdr) != &ophdr) errx(EXIT_FAILURE, "gelf_getphdr failed: %s", elf_errmsg(-1)); ophdr.p_type = iphdr.p_type; ophdr.p_vaddr = seg->vaddr; ophdr.p_paddr = seg->paddr; ophdr.p_flags = iphdr.p_flags; ophdr.p_align = iphdr.p_align; ophdr.p_offset = seg->off; ophdr.p_filesz = seg->fsz; ophdr.p_memsz = seg->msz; if (!gelf_update_phdr(ecp->eout, i, &ophdr)) errx(EXIT_FAILURE, "gelf_update_phdr failed: %s", elf_errmsg(-1)); i++; } } Index: stable/11/contrib/elftoolchain/elfcopy/strip.1 =================================================================== --- stable/11/contrib/elftoolchain/elfcopy/strip.1 (revision 367465) +++ stable/11/contrib/elftoolchain/elfcopy/strip.1 (revision 367466) @@ -1,132 +1,141 @@ .\" Copyright (c) 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: strip.1 2069 2011-10-26 15:53:48Z jkoshy $ +.\" $Id: strip.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" -.Dd September 17, 2011 -.Os +.Dd July 27, 2019 .Dt STRIP 1 +.Os .Sh NAME .Nm strip .Nd discard information from ELF objects .Sh SYNOPSIS .Nm .Op Fl d | Fl g | Fl S | Fl -strip-debug .Op Fl h | Fl -help .Op Fl -only-keep-debug .Op Fl o Ar outputfile | Fl -output-file= Ns Ar outputfile .Op Fl p | Fl -preserve-dates .Op Fl s | Fl -strip-all .Op Fl -strip-unneeded .Op Fl w | Fl -wildcard .Op Fl x | Fl -discard-all .Op Fl I Ar format | Fl -input-target= Ns Ar format .Op Fl K Ar symbol | Fl -keep-symbol= Ns Ar symbol .Op Fl N Ar symbol | Fl -strip-symbol= Ns Ar symbol .Op Fl O Ar format | Fl -output-target= Ns Ar format .Op Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname .Op Fl V | Fl -version .Op Fl X | Fl -discard-locals .Ar .Sh DESCRIPTION The .Nm -utility is used to discard information from ELF objects. +utility is used to discard information from the ELF objects +specified by the arguments +.Ar . .Pp +If an explicit output file name is not specified using the +.Fl o +option, the +.Nm +utility will modify its input arguments in-place. +.Pp The .Nm utility supports the following options: .Bl -tag -width indent .It Fl d | Fl g | Fl S | Fl -strip-debug Remove debugging symbols only. .It Fl h | Fl -help Print a help message and exit. .It Fl -only-keep-debug Remove all content except that which would be used for debugging. .It Fl o Ar outputfile | Fl -output-file= Ns Ar outputfile Write the stripped object to file -.Ar outputfile . -The default behaviour is to modify objects in place. +.Ar outputfile +instead of modifying the input in-place. +Only a single input object should be specified if this option is used. .It Fl p | Fl -preserve-dates Preserve the object's access and modification times. .It Fl s | Fl -strip-all Remove all symbols. .It Fl -strip-unneeded Remove all symbols not needed for further relocation processing. .It Fl w | Fl -wildcard Use shell-style patterns to name symbols. The following meta-characters are recognized in patterns: .Bl -tag -width "...." -compact .It Li ! If this is the first character of the pattern, invert the sense of the pattern match. .It Li * Matches any string of characters in a symbol name. .It Li ? Matches zero or one character in a symbol name. .It Li [ Mark the start of a character class. .It Li \e Remove the special meaning of the next character in the pattern. .It Li ] Mark the end of a character class. .El .It Fl x | Fl -discard-all Discard all non-global symbols. .It Fl I Ar format | Fl -input-target= Ns Ar format These options are accepted, but are ignored. .It Fl K Ar symbol | Fl -keep-symbol= Ns Ar symbol Keep the symbol .Ar symbol even if it would otherwise be stripped. This option may be specified multiple times. .It Fl N Ar symbol | Fl -strip-symbol= Ns Ar symbol Remove the symbol .Ar symbol even if it would otherwise have been kept. This option may be specified multiple times. .It Fl O Ar format | Fl -output-target= Ns Ar format Set the output file format to .Ar format . For the full list of supported formats, please see the documentation for function .Xr elftc_bfd_find_target 3 . .It Fl R Ar sectionname | Fl -remove-section= Ns Ar sectionname Remove the section named by the argument .Ar sectionname . This option may be specified multiple times. .It Fl V | Fl -version Print a version identifier and exit. .It Fl X | Fl -discard-locals Remove compiler-generated local symbols. .El .Sh DIAGNOSTICS .Ex -std .Sh SEE ALSO .Xr ar 1 , .Xr elfcopy 1 , .Xr ld 1 , .Xr mcs 1 , .Xr elf 3 , .Xr elftc_bfd_find_target 3 , .Xr fnmatch 3 Index: stable/11/contrib/elftoolchain/elfdump/elfdump.c =================================================================== --- stable/11/contrib/elftoolchain/elfdump/elfdump.c (revision 367465) +++ stable/11/contrib/elftoolchain/elfdump/elfdump.c (revision 367466) @@ -1,2680 +1,2683 @@ /*- * Copyright (c) 2007-2012 Kai Wang * Copyright (c) 2003 David O'Brien. All rights reserved. * Copyright (c) 2001 Jake Burkholder * 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 #include #include #ifdef USE_LIBARCHIVE_AR #include #include #endif #include "_elftc.h" -ELFTC_VCSID("$Id: elfdump.c 3584 2017-11-05 20:51:43Z jkoshy $"); +ELFTC_VCSID("$Id: elfdump.c 3762 2019-06-28 21:06:24Z emaste $"); #if defined(ELFTC_NEED_ELF_NOTE_DEFINITION) #include "native-elf-format.h" #if ELFTC_CLASS == ELFCLASS32 typedef Elf32_Nhdr Elf_Note; #else typedef Elf64_Nhdr Elf_Note; #endif #endif /* elfdump(1) options. */ #define ED_DYN (1<<0) #define ED_EHDR (1<<1) #define ED_GOT (1<<2) #define ED_HASH (1<<3) #define ED_INTERP (1<<4) #define ED_NOTE (1<<5) #define ED_PHDR (1<<6) #define ED_REL (1<<7) #define ED_SHDR (1<<8) #define ED_SYMTAB (1<<9) #define ED_SYMVER (1<<10) #define ED_CHECKSUM (1<<11) #define ED_ALL ((1<<12)-1) /* elfdump(1) run control flags. */ #define SOLARIS_FMT (1<<0) #define PRINT_FILENAME (1<<1) #define PRINT_ARSYM (1<<2) #define ONLY_ARSYM (1<<3) /* Convenient print macro. */ #define PRT(...) fprintf(ed->out, __VA_ARGS__) /* Internal data structure for sections. */ struct section { const char *name; /* section name */ Elf_Scn *scn; /* section scn */ uint64_t off; /* section offset */ uint64_t sz; /* section size */ uint64_t entsize; /* section entsize */ uint64_t align; /* section alignment */ uint64_t type; /* section type */ uint64_t flags; /* section flags */ uint64_t addr; /* section virtual addr */ uint32_t link; /* section link ndx */ uint32_t info; /* section info ndx */ }; struct spec_name { const char *name; STAILQ_ENTRY(spec_name) sn_list; }; /* Structure encapsulates the global data for readelf(1). */ struct elfdump { FILE *out; /* output redirection. */ const char *filename; /* current processing file. */ const char *archive; /* archive name */ int options; /* command line options. */ int flags; /* run control flags. */ Elf *elf; /* underlying ELF descriptor. */ #ifndef USE_LIBARCHIVE_AR Elf *ar; /* ar(1) archive descriptor. */ #endif GElf_Ehdr ehdr; /* ELF header. */ int ec; /* ELF class. */ size_t shnum; /* #sections. */ struct section *sl; /* list of sections. */ STAILQ_HEAD(, spec_name) snl; /* list of names specified by -N. */ }; /* Relocation entry. */ struct rel_entry { union { GElf_Rel rel; GElf_Rela rela; } u_r; const char *symn; uint32_t type; }; #if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS) static __inline uint32_t be32dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); } static __inline uint32_t le32dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); } #endif /* http://www.sco.com/developers/gabi/latest/ch5.dynamic.html#tag_encodings */ static const char * d_tags(uint64_t tag) { static char unknown_buf[64]; switch (tag) { case DT_NULL: return "DT_NULL"; case DT_NEEDED: return "DT_NEEDED"; case DT_PLTRELSZ: return "DT_PLTRELSZ"; case DT_PLTGOT: return "DT_PLTGOT"; case DT_HASH: return "DT_HASH"; case DT_STRTAB: return "DT_STRTAB"; case DT_SYMTAB: return "DT_SYMTAB"; case DT_RELA: return "DT_RELA"; case DT_RELASZ: return "DT_RELASZ"; case DT_RELAENT: return "DT_RELAENT"; case DT_STRSZ: return "DT_STRSZ"; case DT_SYMENT: return "DT_SYMENT"; case DT_INIT: return "DT_INIT"; case DT_FINI: return "DT_FINI"; case DT_SONAME: return "DT_SONAME"; case DT_RPATH: return "DT_RPATH"; case DT_SYMBOLIC: return "DT_SYMBOLIC"; case DT_REL: return "DT_REL"; case DT_RELSZ: return "DT_RELSZ"; case DT_RELENT: return "DT_RELENT"; case DT_PLTREL: return "DT_PLTREL"; case DT_DEBUG: return "DT_DEBUG"; case DT_TEXTREL: return "DT_TEXTREL"; case DT_JMPREL: return "DT_JMPREL"; case DT_BIND_NOW: return "DT_BIND_NOW"; case DT_INIT_ARRAY: return "DT_INIT_ARRAY"; case DT_FINI_ARRAY: return "DT_FINI_ARRAY"; case DT_INIT_ARRAYSZ: return "DT_INIT_ARRAYSZ"; case DT_FINI_ARRAYSZ: return "DT_FINI_ARRAYSZ"; case DT_RUNPATH: return "DT_RUNPATH"; case DT_FLAGS: return "DT_FLAGS"; case DT_PREINIT_ARRAY: return "DT_PREINIT_ARRAY"; /* XXX DT_ENCODING */ case DT_PREINIT_ARRAYSZ:return "DT_PREINIT_ARRAYSZ"; /* 0x6000000D - 0x6ffff000 operating system-specific semantics */ case 0x6ffffdf5: return "DT_GNU_PRELINKED"; case 0x6ffffdf6: return "DT_GNU_CONFLICTSZ"; case 0x6ffffdf7: return "DT_GNU_LIBLISTSZ"; case 0x6ffffdf8: return "DT_SUNW_CHECKSUM"; case DT_PLTPADSZ: return "DT_PLTPADSZ"; case DT_MOVEENT: return "DT_MOVEENT"; case DT_MOVESZ: return "DT_MOVESZ"; case 0x6ffffdfc: return "DT_FEATURE"; case DT_POSFLAG_1: return "DT_POSFLAG_1"; case DT_SYMINSZ: return "DT_SYMINSZ"; case DT_SYMINENT: return "DT_SYMINENT (DT_VALRNGHI)"; case DT_ADDRRNGLO: return "DT_ADDRRNGLO"; case DT_GNU_HASH: return "DT_GNU_HASH"; case 0x6ffffef8: return "DT_GNU_CONFLICT"; case 0x6ffffef9: return "DT_GNU_LIBLIST"; case 0x6ffffefa: return "DT_CONFIG"; case 0x6ffffefb: return "DT_DEPAUDIT"; case 0x6ffffefc: return "DT_AUDIT"; case 0x6ffffefd: return "DT_PLTPAD"; case 0x6ffffefe: return "DT_MOVETAB"; case DT_SYMINFO: return "DT_SYMINFO (DT_ADDRRNGHI)"; case DT_RELACOUNT: return "DT_RELACOUNT"; case DT_RELCOUNT: return "DT_RELCOUNT"; case DT_FLAGS_1: return "DT_FLAGS_1"; case DT_VERDEF: return "DT_VERDEF"; case DT_VERDEFNUM: return "DT_VERDEFNUM"; case DT_VERNEED: return "DT_VERNEED"; case DT_VERNEEDNUM: return "DT_VERNEEDNUM"; case 0x6ffffff0: return "DT_GNU_VERSYM"; /* 0x70000000 - 0x7fffffff processor-specific semantics */ case 0x70000000: return "DT_IA_64_PLT_RESERVE"; case DT_AUXILIARY: return "DT_AUXILIARY"; case DT_USED: return "DT_USED"; case DT_FILTER: return "DT_FILTER"; } snprintf(unknown_buf, sizeof(unknown_buf), "", (unsigned long long)tag); return (unknown_buf); } static const char * e_machines(unsigned int mach) { static char machdesc[64]; switch (mach) { case EM_NONE: return "EM_NONE"; case EM_M32: return "EM_M32"; case EM_SPARC: return "EM_SPARC"; case EM_386: return "EM_386"; case EM_68K: return "EM_68K"; case EM_88K: return "EM_88K"; case EM_IAMCU: return "EM_IAMCU"; case EM_860: return "EM_860"; case EM_MIPS: return "EM_MIPS"; case EM_PPC: return "EM_PPC"; case EM_PPC64: return "EM_PPC64"; case EM_ARM: return "EM_ARM"; case EM_ALPHA: return "EM_ALPHA (legacy)"; case EM_SPARCV9:return "EM_SPARCV9"; case EM_IA_64: return "EM_IA_64"; case EM_X86_64: return "EM_X86_64"; case EM_AARCH64:return "EM_AARCH64"; case EM_RISCV: return "EM_RISCV"; } snprintf(machdesc, sizeof(machdesc), "(unknown machine) -- type 0x%x", mach); return (machdesc); } static const char * elf_type_str(unsigned int type) { static char s_type[32]; switch (type) { case ET_NONE: return "ET_NONE"; case ET_REL: return "ET_REL"; case ET_EXEC: return "ET_EXEC"; case ET_DYN: return "ET_DYN"; case ET_CORE: return "ET_CORE"; } if (type >= ET_LOPROC) snprintf(s_type, sizeof(s_type), "", type); else if (type >= ET_LOOS && type <= ET_HIOS) snprintf(s_type, sizeof(s_type), "", type); else snprintf(s_type, sizeof(s_type), "", ver); return (s_ver); } static const char * elf_class_str(unsigned int class) { static char s_class[32]; switch (class) { case ELFCLASSNONE: return "ELFCLASSNONE"; case ELFCLASS32: return "ELFCLASS32"; case ELFCLASS64: return "ELFCLASS64"; } snprintf(s_class, sizeof(s_class), "", class); return (s_class); } static const char * elf_data_str(unsigned int data) { static char s_data[32]; switch (data) { case ELFDATANONE: return "ELFDATANONE"; case ELFDATA2LSB: return "ELFDATA2LSB"; case ELFDATA2MSB: return "ELFDATA2MSB"; } snprintf(s_data, sizeof(s_data), "", data); return (s_data); } static const char *ei_abis[256] = { "ELFOSABI_NONE", "ELFOSABI_HPUX", "ELFOSABI_NETBSD", "ELFOSABI_LINUX", "ELFOSABI_HURD", "ELFOSABI_86OPEN", "ELFOSABI_SOLARIS", "ELFOSABI_AIX", "ELFOSABI_IRIX", "ELFOSABI_FREEBSD", "ELFOSABI_TRU64", "ELFOSABI_MODESTO", "ELFOSABI_OPENBSD", [17] = "ELFOSABI_CLOUDABI", [64] = "ELFOSABI_ARM_AEABI", [97] = "ELFOSABI_ARM", [255] = "ELFOSABI_STANDALONE" }; static const char * elf_phdr_type_str(unsigned int type) { static char s_type[32]; switch (type) { - case PT_NULL: return "PT_NULL"; - case PT_LOAD: return "PT_LOAD"; - case PT_DYNAMIC: return "PT_DYNAMIC"; - case PT_INTERP: return "PT_INTERP"; - case PT_NOTE: return "PT_NOTE"; - case PT_SHLIB: return "PT_SHLIB"; - case PT_PHDR: return "PT_PHDR"; - case PT_TLS: return "PT_TLS"; - case PT_GNU_EH_FRAME: return "PT_GNU_EH_FRAME"; - case PT_GNU_STACK: return "PT_GNU_STACK"; - case PT_GNU_RELRO: return "PT_GNU_RELRO"; + case PT_NULL: return "PT_NULL"; + case PT_LOAD: return "PT_LOAD"; + case PT_DYNAMIC: return "PT_DYNAMIC"; + case PT_INTERP: return "PT_INTERP"; + case PT_NOTE: return "PT_NOTE"; + case PT_SHLIB: return "PT_SHLIB"; + case PT_PHDR: return "PT_PHDR"; + case PT_TLS: return "PT_TLS"; + case PT_GNU_EH_FRAME: return "PT_GNU_EH_FRAME"; + case PT_GNU_STACK: return "PT_GNU_STACK"; + case PT_GNU_RELRO: return "PT_GNU_RELRO"; + case PT_OPENBSD_RANDOMIZE: return "PT_OPENBSD_RANDOMIZE"; + case PT_OPENBSD_WXNEEDED: return "PT_OPENBSD_WXNEEDED"; + case PT_OPENBSD_BOOTDATA: return "PT_OPENBSD_BOOTDATA"; } snprintf(s_type, sizeof(s_type), "", type); return (s_type); } static const char *p_flags[] = { "", "PF_X", "PF_W", "PF_X|PF_W", "PF_R", "PF_X|PF_R", "PF_W|PF_R", "PF_X|PF_W|PF_R" }; static const char * sh_name(struct elfdump *ed, int ndx) { static char num[10]; switch (ndx) { case SHN_UNDEF: return "UNDEF"; case SHN_ABS: return "ABS"; case SHN_COMMON: return "COMMON"; default: if ((uint64_t)ndx < ed->shnum) return (ed->sl[ndx].name); else { snprintf(num, sizeof(num), "%d", ndx); return (num); } } } /* http://www.sco.com/developers/gabi/latest/ch4.sheader.html#sh_type */ static const char * sh_types(uint64_t mach, uint64_t sht) { static char unknown_buf[64]; if (sht < 0x60000000) { switch (sht) { case SHT_NULL: return "SHT_NULL"; case SHT_PROGBITS: return "SHT_PROGBITS"; case SHT_SYMTAB: return "SHT_SYMTAB"; case SHT_STRTAB: return "SHT_STRTAB"; case SHT_RELA: return "SHT_RELA"; case SHT_HASH: return "SHT_HASH"; case SHT_DYNAMIC: return "SHT_DYNAMIC"; case SHT_NOTE: return "SHT_NOTE"; case SHT_NOBITS: return "SHT_NOBITS"; case SHT_REL: return "SHT_REL"; case SHT_SHLIB: return "SHT_SHLIB"; case SHT_DYNSYM: return "SHT_DYNSYM"; case SHT_INIT_ARRAY: return "SHT_INIT_ARRAY"; case SHT_FINI_ARRAY: return "SHT_FINI_ARRAY"; case SHT_PREINIT_ARRAY: return "SHT_PREINIT_ARRAY"; case SHT_GROUP: return "SHT_GROUP"; case SHT_SYMTAB_SHNDX: return "SHT_SYMTAB_SHNDX"; } } else if (sht < 0x70000000) { /* 0x60000000-0x6fffffff operating system-specific semantics */ switch (sht) { case 0x6ffffff0: return "XXX:VERSYM"; case SHT_SUNW_dof: return "SHT_SUNW_dof"; case SHT_GNU_HASH: return "SHT_GNU_HASH"; case 0x6ffffff7: return "SHT_GNU_LIBLIST"; case 0x6ffffffc: return "XXX:VERDEF"; case SHT_SUNW_verdef: return "SHT_SUNW(GNU)_verdef"; case SHT_SUNW_verneed: return "SHT_SUNW(GNU)_verneed"; case SHT_SUNW_versym: return "SHT_SUNW(GNU)_versym"; } } else if (sht < 0x80000000) { /* 0x70000000 - 0x7fffffff processor-specific semantics */ switch (mach) { case EM_ARM: switch (sht) { case SHT_ARM_EXIDX: return "SHT_ARM_EXIDX"; case SHT_ARM_PREEMPTMAP: return "SHT_ARM_PREEMPTMAP"; case SHT_ARM_ATTRIBUTES: return "SHT_ARM_ATTRIBUTES"; case SHT_ARM_DEBUGOVERLAY: return "SHT_ARM_DEBUGOVERLAY"; case SHT_ARM_OVERLAYSECTION: return "SHT_ARM_OVERLAYSECTION"; } break; case EM_IA_64: switch (sht) { case 0x70000000: return "SHT_IA_64_EXT"; case 0x70000001: return "SHT_IA_64_UNWIND"; } break; case EM_MIPS: switch (sht) { case SHT_MIPS_REGINFO: return "SHT_MIPS_REGINFO"; case SHT_MIPS_OPTIONS: return "SHT_MIPS_OPTIONS"; case SHT_MIPS_ABIFLAGS: return "SHT_MIPS_ABIFLAGS"; } break; } switch (sht) { case 0x7ffffffd: return "XXX:AUXILIARY"; case 0x7fffffff: return "XXX:FILTER"; } } /* 0x80000000 - 0xffffffff application programs */ snprintf(unknown_buf, sizeof(unknown_buf), "", (unsigned long long)sht); return (unknown_buf); } /* * Define known section flags. These flags are defined in the order * they are to be printed out. */ #define DEFINE_SHFLAGS() \ DEFINE_SHF(WRITE) \ DEFINE_SHF(ALLOC) \ DEFINE_SHF(EXECINSTR) \ DEFINE_SHF(MERGE) \ DEFINE_SHF(STRINGS) \ DEFINE_SHF(INFO_LINK) \ DEFINE_SHF(LINK_ORDER) \ DEFINE_SHF(OS_NONCONFORMING) \ DEFINE_SHF(GROUP) \ DEFINE_SHF(TLS) \ DEFINE_SHF(COMPRESSED) #undef DEFINE_SHF #define DEFINE_SHF(F) "SHF_" #F "|" #define ALLSHFLAGS DEFINE_SHFLAGS() static const char * sh_flags(uint64_t shf) { static char flg[sizeof(ALLSHFLAGS)+1]; flg[0] = '\0'; #undef DEFINE_SHF #define DEFINE_SHF(N) \ if (shf & SHF_##N) \ strcat(flg, "SHF_" #N "|"); \ DEFINE_SHFLAGS() flg[strlen(flg) - 1] = '\0'; /* Remove the trailing "|". */ return (flg); } static const char * st_type(unsigned int mach, unsigned int type) { static char s_type[32]; switch (type) { case STT_NOTYPE: return "STT_NOTYPE"; case STT_OBJECT: return "STT_OBJECT"; case STT_FUNC: return "STT_FUNC"; case STT_SECTION: return "STT_SECTION"; case STT_FILE: return "STT_FILE"; case STT_COMMON: return "STT_COMMON"; case STT_TLS: return "STT_TLS"; case 13: if (mach == EM_SPARCV9) return "STT_SPARC_REGISTER"; break; } snprintf(s_type, sizeof(s_type), "", type); return (s_type); } static const char * st_type_S(unsigned int type) { static char s_type[32]; switch (type) { case STT_NOTYPE: return "NOTY"; case STT_OBJECT: return "OBJT"; case STT_FUNC: return "FUNC"; case STT_SECTION: return "SECT"; case STT_FILE: return "FILE"; } snprintf(s_type, sizeof(s_type), "", type); return (s_type); } static const char * st_bindings(unsigned int sbind) { static char s_sbind[32]; switch (sbind) { case STB_LOCAL: return "STB_LOCAL"; case STB_GLOBAL: return "STB_GLOBAL"; case STB_WEAK: return "STB_WEAK"; case STB_GNU_UNIQUE: return "STB_GNU_UNIQUE"; default: if (sbind >= STB_LOOS && sbind <= STB_HIOS) return "OS"; else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) return "PROC"; else snprintf(s_sbind, sizeof(s_sbind), "", sbind); return (s_sbind); } } static const char * st_bindings_S(unsigned int sbind) { static char s_sbind[32]; switch (sbind) { case STB_LOCAL: return "LOCL"; case STB_GLOBAL: return "GLOB"; case STB_WEAK: return "WEAK"; case STB_GNU_UNIQUE: return "UNIQ"; default: if (sbind >= STB_LOOS && sbind <= STB_HIOS) return "OS"; else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) return "PROC"; else snprintf(s_sbind, sizeof(s_sbind), "<%#x>", sbind); return (s_sbind); } } static unsigned char st_others[] = { 'D', 'I', 'H', 'P' }; static void add_name(struct elfdump *ed, const char *name); static void elf_print_object(struct elfdump *ed); static void elf_print_elf(struct elfdump *ed); static void elf_print_ehdr(struct elfdump *ed); static void elf_print_phdr(struct elfdump *ed); static void elf_print_shdr(struct elfdump *ed); static void elf_print_symtab(struct elfdump *ed, int i); static void elf_print_symtabs(struct elfdump *ed); static void elf_print_symver(struct elfdump *ed); static void elf_print_verdef(struct elfdump *ed, struct section *s); static void elf_print_verneed(struct elfdump *ed, struct section *s); static void elf_print_interp(struct elfdump *ed); static void elf_print_dynamic(struct elfdump *ed); static void elf_print_rel_entry(struct elfdump *ed, struct section *s, int j, struct rel_entry *r); static void elf_print_rela(struct elfdump *ed, struct section *s, Elf_Data *data); static void elf_print_rel(struct elfdump *ed, struct section *s, Elf_Data *data); static void elf_print_reloc(struct elfdump *ed); static void elf_print_got(struct elfdump *ed); static void elf_print_got_section(struct elfdump *ed, struct section *s); static void elf_print_note(struct elfdump *ed); static void elf_print_svr4_hash(struct elfdump *ed, struct section *s); static void elf_print_svr4_hash64(struct elfdump *ed, struct section *s); static void elf_print_gnu_hash(struct elfdump *ed, struct section *s); static void elf_print_hash(struct elfdump *ed); static void elf_print_checksum(struct elfdump *ed); static void find_gotrel(struct elfdump *ed, struct section *gs, struct rel_entry *got); static struct spec_name *find_name(struct elfdump *ed, const char *name); static int get_ent_count(const struct section *s, int *ent_count); static const char *get_symbol_name(struct elfdump *ed, uint32_t symtab, int i); static const char *get_string(struct elfdump *ed, int strtab, size_t off); static void get_versym(struct elfdump *ed, int i, uint16_t **vs, int *nvs); static void load_sections(struct elfdump *ed); static void unload_sections(struct elfdump *ed); static void usage(void); #ifdef USE_LIBARCHIVE_AR static int ac_detect_ar(int fd); static void ac_print_ar(struct elfdump *ed, int fd); #else static void elf_print_ar(struct elfdump *ed, int fd); #endif /* USE_LIBARCHIVE_AR */ static struct option elfdump_longopts[] = { { "help", no_argument, NULL, 'H' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; int main(int ac, char **av) { struct elfdump *ed, ed_storage; struct spec_name *sn; int ch, i; ed = &ed_storage; memset(ed, 0, sizeof(*ed)); STAILQ_INIT(&ed->snl); ed->out = stdout; while ((ch = getopt_long(ac, av, "acdeiGHhknN:prsSvVw:", elfdump_longopts, NULL)) != -1) switch (ch) { case 'a': ed->options = ED_ALL; break; case 'c': ed->options |= ED_SHDR; break; case 'd': ed->options |= ED_DYN; break; case 'e': ed->options |= ED_EHDR; break; case 'i': ed->options |= ED_INTERP; break; case 'G': ed->options |= ED_GOT; break; case 'h': ed->options |= ED_HASH; break; case 'k': ed->options |= ED_CHECKSUM; break; case 'n': ed->options |= ED_NOTE; break; case 'N': add_name(ed, optarg); break; case 'p': ed->options |= ED_PHDR; break; case 'r': ed->options |= ED_REL; break; case 's': ed->options |= ED_SYMTAB; break; case 'S': ed->flags |= SOLARIS_FMT; break; case 'v': ed->options |= ED_SYMVER; break; case 'V': (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); exit(EXIT_SUCCESS); break; case 'w': if ((ed->out = fopen(optarg, "w")) == NULL) err(EXIT_FAILURE, "%s", optarg); break; case '?': case 'H': default: usage(); } ac -= optind; av += optind; if (ed->options == 0) ed->options = ED_ALL; sn = NULL; if (ed->options & ED_SYMTAB && (STAILQ_EMPTY(&ed->snl) || (sn = find_name(ed, "ARSYM")) != NULL)) { ed->flags |= PRINT_ARSYM; if (sn != NULL) { STAILQ_REMOVE(&ed->snl, sn, spec_name, sn_list); if (STAILQ_EMPTY(&ed->snl)) ed->flags |= ONLY_ARSYM; } } if (ac == 0) usage(); if (ac > 1) ed->flags |= PRINT_FILENAME; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "ELF library initialization failed: %s", elf_errmsg(-1)); for (i = 0; i < ac; i++) { ed->filename = av[i]; ed->archive = NULL; elf_print_object(ed); } exit(EXIT_SUCCESS); } #ifdef USE_LIBARCHIVE_AR /* Archive symbol table entry. */ struct arsym_entry { char *sym_name; size_t off; }; /* * Convenient wrapper for general libarchive error handling. */ #define AC(CALL) do { \ if ((CALL)) { \ warnx("%s", archive_error_string(a)); \ return; \ } \ } while (0) /* * Detect an ar(1) archive using libarchive(3). */ static int ac_detect_ar(int fd) { struct archive *a; struct archive_entry *entry; int r; r = -1; if ((a = archive_read_new()) == NULL) return (0); archive_read_support_format_ar(a); if (archive_read_open_fd(a, fd, 10240) == ARCHIVE_OK) r = archive_read_next_header(a, &entry); archive_read_close(a); archive_read_free(a); return (r == ARCHIVE_OK); } /* * Dump an ar(1) archive using libarchive(3). */ static void ac_print_ar(struct elfdump *ed, int fd) { struct archive *a; struct archive_entry *entry; struct arsym_entry *arsym; const char *name; char idx[10], *b; void *buff; size_t size; uint32_t cnt, i; int r; if (lseek(fd, 0, SEEK_SET) == -1) err(EXIT_FAILURE, "lseek failed"); if ((a = archive_read_new()) == NULL) errx(EXIT_FAILURE, "%s", archive_error_string(a)); archive_read_support_format_ar(a); AC(archive_read_open_fd(a, fd, 10240)); for(;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_FATAL) errx(EXIT_FAILURE, "%s", archive_error_string(a)); if (r == ARCHIVE_EOF) break; if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY) warnx("%s", archive_error_string(a)); if (r == ARCHIVE_RETRY) continue; name = archive_entry_pathname(entry); size = archive_entry_size(entry); if (size == 0) continue; if ((buff = malloc(size)) == NULL) { warn("malloc failed"); continue; } if (archive_read_data(a, buff, size) != (ssize_t)size) { warnx("%s", archive_error_string(a)); free(buff); continue; } /* * Note that when processing arsym via libarchive, there is * no way to tell which member a certain symbol belongs to, * since we can not just "lseek" to a member offset and read * the member header. */ if (!strcmp(name, "/") && ed->flags & PRINT_ARSYM) { b = buff; cnt = be32dec(b); if (cnt == 0) { free(buff); continue; } arsym = calloc(cnt, sizeof(*arsym)); if (arsym == NULL) err(EXIT_FAILURE, "calloc failed"); b += sizeof(uint32_t); for (i = 0; i < cnt; i++) { arsym[i].off = be32dec(b); b += sizeof(uint32_t); } for (i = 0; i < cnt; i++) { arsym[i].sym_name = b; b += strlen(b) + 1; } if (ed->flags & SOLARIS_FMT) { PRT("\nSymbol Table: (archive)\n"); PRT(" index offset symbol\n"); } else PRT("\nsymbol table (archive):\n"); for (i = 0; i < cnt; i++) { if (ed->flags & SOLARIS_FMT) { snprintf(idx, sizeof(idx), "[%d]", i); PRT("%10s ", idx); PRT("0x%8.8jx ", (uintmax_t)arsym[i].off); PRT("%s\n", arsym[i].sym_name); } else { PRT("\nentry: %d\n", i); PRT("\toffset: %#jx\n", (uintmax_t)arsym[i].off); PRT("\tsymbol: %s\n", arsym[i].sym_name); } } free(arsym); free(buff); /* No need to continue if we only dump ARSYM. */ if (ed->flags & ONLY_ARSYM) { AC(archive_read_close(a)); AC(archive_read_free(a)); return; } continue; } if ((ed->elf = elf_memory(buff, size)) == NULL) { warnx("elf_memroy() failed: %s", elf_errmsg(-1)); free(buff); continue; } /* Skip non-ELF member. */ if (elf_kind(ed->elf) == ELF_K_ELF) { printf("\n%s(%s):\n", ed->archive, name); elf_print_elf(ed); } elf_end(ed->elf); free(buff); } AC(archive_read_close(a)); AC(archive_read_free(a)); } #else /* USE_LIBARCHIVE_AR */ /* * Dump an ar(1) archive. */ static void elf_print_ar(struct elfdump *ed, int fd) { Elf *e; Elf_Arhdr *arh; Elf_Arsym *arsym; Elf_Cmd cmd; char idx[21]; size_t cnt, i; ed->ar = ed->elf; if (ed->flags & PRINT_ARSYM) { cnt = 0; if ((arsym = elf_getarsym(ed->ar, &cnt)) == NULL) { warnx("elf_getarsym failed: %s", elf_errmsg(-1)); goto print_members; } if (cnt == 0) goto print_members; if (ed->flags & SOLARIS_FMT) { PRT("\nSymbol Table: (archive)\n"); PRT(" index offset member name and symbol\n"); } else PRT("\nsymbol table (archive):\n"); for (i = 0; i < cnt - 1; i++) { if (elf_rand(ed->ar, arsym[i].as_off) != arsym[i].as_off) { warnx("elf_rand failed: %s", elf_errmsg(-1)); break; } if ((e = elf_begin(fd, ELF_C_READ, ed->ar)) == NULL) { warnx("elf_begin failed: %s", elf_errmsg(-1)); break; } if ((arh = elf_getarhdr(e)) == NULL) { warnx("elf_getarhdr failed: %s", elf_errmsg(-1)); break; } if (ed->flags & SOLARIS_FMT) { snprintf(idx, sizeof(idx), "[%zu]", i); PRT("%10s ", idx); PRT("0x%8.8jx ", (uintmax_t)arsym[i].as_off); PRT("(%s):%s\n", arh->ar_name, arsym[i].as_name); } else { PRT("\nentry: %zu\n", i); PRT("\toffset: %#jx\n", (uintmax_t)arsym[i].as_off); PRT("\tmember: %s\n", arh->ar_name); PRT("\tsymbol: %s\n", arsym[i].as_name); } elf_end(e); } /* No need to continue if we only dump ARSYM. */ if (ed->flags & ONLY_ARSYM) return; } print_members: /* Rewind the archive. */ if (elf_rand(ed->ar, SARMAG) != SARMAG) { warnx("elf_rand failed: %s", elf_errmsg(-1)); return; } /* Dump each member of the archive. */ cmd = ELF_C_READ; while ((ed->elf = elf_begin(fd, cmd, ed->ar)) != NULL) { /* Skip non-ELF member. */ if (elf_kind(ed->elf) == ELF_K_ELF) { if ((arh = elf_getarhdr(ed->elf)) == NULL) { warnx("elf_getarhdr failed: %s", elf_errmsg(-1)); break; } printf("\n%s(%s):\n", ed->archive, arh->ar_name); elf_print_elf(ed); } cmd = elf_next(ed->elf); elf_end(ed->elf); } } #endif /* USE_LIBARCHIVE_AR */ /* * Dump an object. (ELF object or ar(1) archive) */ static void elf_print_object(struct elfdump *ed) { int fd; if ((fd = open(ed->filename, O_RDONLY)) == -1) { warn("open %s failed", ed->filename); return; } #ifdef USE_LIBARCHIVE_AR if (ac_detect_ar(fd)) { ed->archive = ed->filename; ac_print_ar(ed, fd); return; } #endif /* USE_LIBARCHIVE_AR */ if ((ed->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { warnx("elf_begin() failed: %s", elf_errmsg(-1)); return; } switch (elf_kind(ed->elf)) { case ELF_K_NONE: warnx("Not an ELF file."); return; case ELF_K_ELF: if (ed->flags & PRINT_FILENAME) printf("\n%s:\n", ed->filename); elf_print_elf(ed); break; case ELF_K_AR: #ifndef USE_LIBARCHIVE_AR ed->archive = ed->filename; elf_print_ar(ed, fd); #endif break; default: warnx("Internal: libelf returned unknown elf kind."); return; } elf_end(ed->elf); } /* * Dump an ELF object. */ static void elf_print_elf(struct elfdump *ed) { if (gelf_getehdr(ed->elf, &ed->ehdr) == NULL) { warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); return; } if ((ed->ec = gelf_getclass(ed->elf)) == ELFCLASSNONE) { warnx("gelf_getclass failed: %s", elf_errmsg(-1)); return; } if (ed->options & (ED_SHDR | ED_DYN | ED_REL | ED_GOT | ED_SYMTAB | ED_SYMVER | ED_NOTE | ED_HASH)) load_sections(ed); if (ed->options & ED_EHDR) elf_print_ehdr(ed); if (ed->options & ED_PHDR) elf_print_phdr(ed); if (ed->options & ED_INTERP) elf_print_interp(ed); if (ed->options & ED_SHDR) elf_print_shdr(ed); if (ed->options & ED_DYN) elf_print_dynamic(ed); if (ed->options & ED_REL) elf_print_reloc(ed); if (ed->options & ED_GOT) elf_print_got(ed); if (ed->options & ED_SYMTAB) elf_print_symtabs(ed); if (ed->options & ED_SYMVER) elf_print_symver(ed); if (ed->options & ED_NOTE) elf_print_note(ed); if (ed->options & ED_HASH) elf_print_hash(ed); if (ed->options & ED_CHECKSUM) elf_print_checksum(ed); unload_sections(ed); } /* * Read the section headers from ELF object and store them in the * internal cache. */ static void load_sections(struct elfdump *ed) { struct section *s; const char *name; Elf_Scn *scn; GElf_Shdr sh; size_t shstrndx, ndx; int elferr; assert(ed->sl == NULL); if (!elf_getshnum(ed->elf, &ed->shnum)) { warnx("elf_getshnum failed: %s", elf_errmsg(-1)); return; } if (ed->shnum == 0) return; if ((ed->sl = calloc(ed->shnum, sizeof(*ed->sl))) == NULL) err(EXIT_FAILURE, "calloc failed"); if (!elf_getshstrndx(ed->elf, &shstrndx)) { warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); return; } if ((scn = elf_getscn(ed->elf, 0)) == NULL) { warnx("elf_getscn failed: %s", elf_errmsg(-1)); return; } (void) elf_errno(); do { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((name = elf_strptr(ed->elf, shstrndx, sh.sh_name)) == NULL) { (void) elf_errno(); name = "ERROR"; } if ((ndx = elf_ndxscn(scn)) == SHN_UNDEF) if ((elferr = elf_errno()) != 0) { warnx("elf_ndxscn failed: %s", elf_errmsg(elferr)); continue; } if (ndx >= ed->shnum) { warnx("section index of '%s' out of range", name); continue; } s = &ed->sl[ndx]; s->name = name; s->scn = scn; s->off = sh.sh_offset; s->sz = sh.sh_size; s->entsize = sh.sh_entsize; s->align = sh.sh_addralign; s->type = sh.sh_type; s->flags = sh.sh_flags; s->addr = sh.sh_addr; s->link = sh.sh_link; s->info = sh.sh_info; } while ((scn = elf_nextscn(ed->elf, scn)) != NULL); elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); } /* * Release section related resources. */ static void unload_sections(struct elfdump *ed) { if (ed->sl != NULL) { free(ed->sl); ed->sl = NULL; } } /* * Add a name to the '-N' name list. */ static void add_name(struct elfdump *ed, const char *name) { struct spec_name *sn; if (find_name(ed, name)) return; if ((sn = malloc(sizeof(*sn))) == NULL) { warn("malloc failed"); return; } sn->name = name; STAILQ_INSERT_TAIL(&ed->snl, sn, sn_list); } /* * Lookup a name in the '-N' name list. */ static struct spec_name * find_name(struct elfdump *ed, const char *name) { struct spec_name *sn; STAILQ_FOREACH(sn, &ed->snl, sn_list) { if (!strcmp(sn->name, name)) return (sn); } return (NULL); } /* * Retrieve the name of a symbol using the section index of the symbol * table and the index of the symbol within that table. */ static const char * get_symbol_name(struct elfdump *ed, uint32_t symtab, int i) { static char sname[64]; struct section *s; const char *name; GElf_Sym sym; Elf_Data *data; int elferr; if (symtab >= ed->shnum) return (""); s = &ed->sl[symtab]; if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) return (""); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return (""); } if (gelf_getsym(data, i, &sym) != &sym) return (""); if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) { if (sym.st_shndx < ed->shnum) { snprintf(sname, sizeof(sname), "%s (section)", ed->sl[sym.st_shndx].name); return (sname); } else return (""); } if ((name = elf_strptr(ed->elf, s->link, sym.st_name)) == NULL) return (""); return (name); } /* * Retrieve a string using string table section index and the string offset. */ static const char* get_string(struct elfdump *ed, int strtab, size_t off) { const char *name; if ((name = elf_strptr(ed->elf, strtab, off)) == NULL) return (""); return (name); } /* * Dump the ELF Executable Header. */ static void elf_print_ehdr(struct elfdump *ed) { if (!STAILQ_EMPTY(&ed->snl)) return; if (ed->flags & SOLARIS_FMT) { PRT("\nELF Header\n"); PRT(" ei_magic: { %#x, %c, %c, %c }\n", ed->ehdr.e_ident[0], ed->ehdr.e_ident[1], ed->ehdr.e_ident[2], ed->ehdr.e_ident[3]); PRT(" ei_class: %-18s", elf_class_str(ed->ehdr.e_ident[EI_CLASS])); PRT(" ei_data: %s\n", elf_data_str(ed->ehdr.e_ident[EI_DATA])); PRT(" e_machine: %-18s", e_machines(ed->ehdr.e_machine)); PRT(" e_version: %s\n", elf_version_str(ed->ehdr.e_version)); PRT(" e_type: %s\n", elf_type_str(ed->ehdr.e_type)); PRT(" e_flags: %18d\n", ed->ehdr.e_flags); PRT(" e_entry: %#18jx", (uintmax_t)ed->ehdr.e_entry); PRT(" e_ehsize: %6d", ed->ehdr.e_ehsize); PRT(" e_shstrndx:%5d\n", ed->ehdr.e_shstrndx); PRT(" e_shoff: %#18jx", (uintmax_t)ed->ehdr.e_shoff); PRT(" e_shentsize: %3d", ed->ehdr.e_shentsize); PRT(" e_shnum: %5d\n", ed->ehdr.e_shnum); PRT(" e_phoff: %#18jx", (uintmax_t)ed->ehdr.e_phoff); PRT(" e_phentsize: %3d", ed->ehdr.e_phentsize); PRT(" e_phnum: %5d\n", ed->ehdr.e_phnum); } else { PRT("\nelf header:\n"); PRT("\n"); PRT("\te_ident: %s %s %s\n", elf_class_str(ed->ehdr.e_ident[EI_CLASS]), elf_data_str(ed->ehdr.e_ident[EI_DATA]), ei_abis[ed->ehdr.e_ident[EI_OSABI]]); PRT("\te_type: %s\n", elf_type_str(ed->ehdr.e_type)); PRT("\te_machine: %s\n", e_machines(ed->ehdr.e_machine)); PRT("\te_version: %s\n", elf_version_str(ed->ehdr.e_version)); PRT("\te_entry: %#jx\n", (uintmax_t)ed->ehdr.e_entry); PRT("\te_phoff: %ju\n", (uintmax_t)ed->ehdr.e_phoff); PRT("\te_shoff: %ju\n", (uintmax_t) ed->ehdr.e_shoff); PRT("\te_flags: %u\n", ed->ehdr.e_flags); PRT("\te_ehsize: %u\n", ed->ehdr.e_ehsize); PRT("\te_phentsize: %u\n", ed->ehdr.e_phentsize); PRT("\te_phnum: %u\n", ed->ehdr.e_phnum); PRT("\te_shentsize: %u\n", ed->ehdr.e_shentsize); PRT("\te_shnum: %u\n", ed->ehdr.e_shnum); PRT("\te_shstrndx: %u\n", ed->ehdr.e_shstrndx); } } /* * Dump the ELF Program Header Table. */ static void elf_print_phdr(struct elfdump *ed) { GElf_Phdr ph; size_t phnum, i; int header; if (elf_getphnum(ed->elf, &phnum) == 0) { warnx("elf_getphnum failed: %s", elf_errmsg(-1)); return; } header = 0; for (i = 0; i < phnum; i++) { if (gelf_getphdr(ed->elf, i, &ph) != &ph) { warnx("elf_getphdr failed: %s", elf_errmsg(-1)); continue; } if (!STAILQ_EMPTY(&ed->snl) && find_name(ed, elf_phdr_type_str(ph.p_type)) == NULL) continue; if (ed->flags & SOLARIS_FMT) { PRT("\nProgram Header[%zu]:\n", i); PRT(" p_vaddr: %#-14jx", (uintmax_t)ph.p_vaddr); PRT(" p_flags: [ %s ]\n", p_flags[ph.p_flags & 0x7]); PRT(" p_paddr: %#-14jx", (uintmax_t)ph.p_paddr); PRT(" p_type: [ %s ]\n", elf_phdr_type_str(ph.p_type)); PRT(" p_filesz: %#-14jx", (uintmax_t)ph.p_filesz); PRT(" p_memsz: %#jx\n", (uintmax_t)ph.p_memsz); PRT(" p_offset: %#-14jx", (uintmax_t)ph.p_offset); PRT(" p_align: %#jx\n", (uintmax_t)ph.p_align); } else { if (!header) { PRT("\nprogram header:\n"); header = 1; } PRT("\n"); PRT("entry: %zu\n", i); PRT("\tp_type: %s\n", elf_phdr_type_str(ph.p_type)); PRT("\tp_offset: %ju\n", (uintmax_t)ph.p_offset); PRT("\tp_vaddr: %#jx\n", (uintmax_t)ph.p_vaddr); PRT("\tp_paddr: %#jx\n", (uintmax_t)ph.p_paddr); PRT("\tp_filesz: %ju\n", (uintmax_t)ph.p_filesz); PRT("\tp_memsz: %ju\n", (uintmax_t)ph.p_memsz); PRT("\tp_flags: %s\n", p_flags[ph.p_flags & 0x7]); PRT("\tp_align: %ju\n", (uintmax_t)ph.p_align); } } } /* * Dump the ELF Section Header Table. */ static void elf_print_shdr(struct elfdump *ed) { struct section *s; size_t i; if (!STAILQ_EMPTY(&ed->snl)) return; if ((ed->flags & SOLARIS_FMT) == 0) PRT("\nsection header:\n"); for (i = 0; i < ed->shnum; i++) { s = &ed->sl[i]; if (ed->flags & SOLARIS_FMT) { if (i == 0) continue; PRT("\nSection Header[%zu]:", i); PRT(" sh_name: %s\n", s->name); PRT(" sh_addr: %#-14jx", (uintmax_t)s->addr); if (s->flags != 0) PRT(" sh_flags: [ %s ]\n", sh_flags(s->flags)); else PRT(" sh_flags: 0\n"); PRT(" sh_size: %#-14jx", (uintmax_t)s->sz); PRT(" sh_type: [ %s ]\n", sh_types(ed->ehdr.e_machine, s->type)); PRT(" sh_offset: %#-14jx", (uintmax_t)s->off); PRT(" sh_entsize: %#jx\n", (uintmax_t)s->entsize); PRT(" sh_link: %-14u", s->link); PRT(" sh_info: %u\n", s->info); PRT(" sh_addralign: %#jx\n", (uintmax_t)s->align); } else { PRT("\n"); PRT("entry: %ju\n", (uintmax_t)i); PRT("\tsh_name: %s\n", s->name); PRT("\tsh_type: %s\n", sh_types(ed->ehdr.e_machine, s->type)); PRT("\tsh_flags: %s\n", sh_flags(s->flags)); PRT("\tsh_addr: %#jx\n", (uintmax_t)s->addr); PRT("\tsh_offset: %ju\n", (uintmax_t)s->off); PRT("\tsh_size: %ju\n", (uintmax_t)s->sz); PRT("\tsh_link: %u\n", s->link); PRT("\tsh_info: %u\n", s->info); PRT("\tsh_addralign: %ju\n", (uintmax_t)s->align); PRT("\tsh_entsize: %ju\n", (uintmax_t)s->entsize); } } } /* * Return number of entries in the given section. We'd prefer ent_count be a * size_t, but libelf APIs already use int for section indices. */ static int get_ent_count(const struct section *s, int *ent_count) { if (s->entsize == 0) { warnx("section %s has entry size 0", s->name); return (0); } else if (s->sz / s->entsize > INT_MAX) { warnx("section %s has invalid section count", s->name); return (0); } *ent_count = (int)(s->sz / s->entsize); return (1); } /* * Retrieve the content of the corresponding SHT_SUNW_versym section for * a symbol table section. */ static void get_versym(struct elfdump *ed, int i, uint16_t **vs, int *nvs) { struct section *s; Elf_Data *data; size_t j; int elferr; s = NULL; for (j = 0; j < ed->shnum; j++) { s = &ed->sl[j]; if (s->type == SHT_SUNW_versym && s->link == (uint32_t)i) break; } if (j >= ed->shnum) { *vs = NULL; return; } (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); *vs = NULL; return; } *vs = data->d_buf; assert(data->d_size == s->sz); if (!get_ent_count(s, nvs)) *nvs = 0; } /* * Dump the symbol table section. */ static void elf_print_symtab(struct elfdump *ed, int i) { struct section *s; const char *name; uint16_t *vs; char idx[13]; Elf_Data *data; GElf_Sym sym; int len, j, elferr, nvs; s = &ed->sl[i]; if (ed->flags & SOLARIS_FMT) PRT("\nSymbol Table Section: %s\n", s->name); else PRT("\nsymbol table (%s):\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } vs = NULL; nvs = 0; assert(data->d_size == s->sz); if (!get_ent_count(s, &len)) return; if (ed->flags & SOLARIS_FMT) { if (ed->ec == ELFCLASS32) PRT(" index value "); else PRT(" index value "); PRT("size type bind oth ver shndx name\n"); get_versym(ed, i, &vs, &nvs); if (vs != NULL && nvs != len) { warnx("#symbol not equal to #versym"); vs = NULL; } } for (j = 0; j < len; j++) { if (gelf_getsym(data, j, &sym) != &sym) { warnx("gelf_getsym failed: %s", elf_errmsg(-1)); continue; } name = get_string(ed, s->link, sym.st_name); if (ed->flags & SOLARIS_FMT) { snprintf(idx, sizeof(idx), "[%d]", j); if (ed->ec == ELFCLASS32) PRT("%10s ", idx); else PRT("%10s ", idx); PRT("0x%8.8jx ", (uintmax_t)sym.st_value); if (ed->ec == ELFCLASS32) PRT("0x%8.8jx ", (uintmax_t)sym.st_size); else PRT("0x%12.12jx ", (uintmax_t)sym.st_size); PRT("%s ", st_type_S(GELF_ST_TYPE(sym.st_info))); PRT("%s ", st_bindings_S(GELF_ST_BIND(sym.st_info))); PRT("%c ", st_others[sym.st_other]); PRT("%3u ", (vs == NULL ? 0 : vs[j])); PRT("%-11.11s ", sh_name(ed, sym.st_shndx)); PRT("%s\n", name); } else { PRT("\nentry: %d\n", j); PRT("\tst_name: %s\n", name); PRT("\tst_value: %#jx\n", (uintmax_t)sym.st_value); PRT("\tst_size: %ju\n", (uintmax_t)sym.st_size); PRT("\tst_info: %s %s\n", st_type(ed->ehdr.e_machine, GELF_ST_TYPE(sym.st_info)), st_bindings(GELF_ST_BIND(sym.st_info))); PRT("\tst_shndx: %ju\n", (uintmax_t)sym.st_shndx); } } } /* * Dump the symbol tables. (.dynsym and .symtab) */ static void elf_print_symtabs(struct elfdump *ed) { size_t i; for (i = 0; i < ed->shnum; i++) if ((ed->sl[i].type == SHT_SYMTAB || ed->sl[i].type == SHT_DYNSYM) && (STAILQ_EMPTY(&ed->snl) || find_name(ed, ed->sl[i].name))) elf_print_symtab(ed, i); } /* * Dump the content of .dynamic section. */ static void elf_print_dynamic(struct elfdump *ed) { struct section *s; const char *name; char idx[13]; Elf_Data *data; GElf_Dyn dyn; int elferr, i, len; s = NULL; for (i = 0; (size_t)i < ed->shnum; i++) { s = &ed->sl[i]; if (s->type == SHT_DYNAMIC && (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) break; } if ((size_t)i >= ed->shnum) return; if (ed->flags & SOLARIS_FMT) { PRT("Dynamic Section: %s\n", s->name); PRT(" index tag value\n"); } else PRT("\ndynamic:\n"); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } assert(data->d_size == s->sz); if (!get_ent_count(s, &len)) return; for (i = 0; i < len; i++) { if (gelf_getdyn(data, i, &dyn) != &dyn) { warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); continue; } if (ed->flags & SOLARIS_FMT) { snprintf(idx, sizeof(idx), "[%d]", i); PRT("%10s %-16s ", idx, d_tags(dyn.d_tag)); } else { PRT("\n"); PRT("entry: %d\n", i); PRT("\td_tag: %s\n", d_tags(dyn.d_tag)); } switch(dyn.d_tag) { case DT_NEEDED: case DT_SONAME: case DT_RPATH: case DT_RUNPATH: if ((name = elf_strptr(ed->elf, s->link, dyn.d_un.d_val)) == NULL) name = ""; if (ed->flags & SOLARIS_FMT) PRT("%#-16jx %s\n", (uintmax_t)dyn.d_un.d_val, name); else PRT("\td_val: %s\n", name); break; case DT_PLTRELSZ: case DT_RELA: case DT_RELASZ: case DT_RELAENT: case DT_RELACOUNT: case DT_STRSZ: case DT_SYMENT: case DT_RELSZ: case DT_RELENT: case DT_PLTREL: case DT_VERDEF: case DT_VERDEFNUM: case DT_VERNEED: case DT_VERNEEDNUM: case DT_VERSYM: if (ed->flags & SOLARIS_FMT) PRT("%#jx\n", (uintmax_t)dyn.d_un.d_val); else PRT("\td_val: %ju\n", (uintmax_t)dyn.d_un.d_val); break; case DT_PLTGOT: case DT_HASH: case DT_GNU_HASH: case DT_STRTAB: case DT_SYMTAB: case DT_INIT: case DT_FINI: case DT_REL: case DT_JMPREL: case DT_DEBUG: if (ed->flags & SOLARIS_FMT) PRT("%#jx\n", (uintmax_t)dyn.d_un.d_ptr); else PRT("\td_ptr: %#jx\n", (uintmax_t)dyn.d_un.d_ptr); break; case DT_NULL: case DT_SYMBOLIC: case DT_TEXTREL: default: if (ed->flags & SOLARIS_FMT) PRT("\n"); break; } } } /* * Dump a .rel/.rela section entry. */ static void elf_print_rel_entry(struct elfdump *ed, struct section *s, int j, struct rel_entry *r) { if (ed->flags & SOLARIS_FMT) { PRT(" %-23s ", elftc_reloc_type_str(ed->ehdr.e_machine, GELF_R_TYPE(r->u_r.rel.r_info))); PRT("%#12jx ", (uintmax_t)r->u_r.rel.r_offset); if (r->type == SHT_RELA) PRT("%10jd ", (intmax_t)r->u_r.rela.r_addend); else PRT(" "); PRT("%-14s ", s->name); PRT("%s\n", r->symn); } else { PRT("\n"); PRT("entry: %d\n", j); PRT("\tr_offset: %#jx\n", (uintmax_t)r->u_r.rel.r_offset); if (ed->ec == ELFCLASS32) PRT("\tr_info: %#jx\n", (uintmax_t) ELF32_R_INFO(ELF64_R_SYM(r->u_r.rel.r_info), ELF64_R_TYPE(r->u_r.rel.r_info))); else PRT("\tr_info: %#jx\n", (uintmax_t)r->u_r.rel.r_info); if (r->type == SHT_RELA) PRT("\tr_addend: %jd\n", (intmax_t)r->u_r.rela.r_addend); } } /* * Dump a relocation section of type SHT_RELA. */ static void elf_print_rela(struct elfdump *ed, struct section *s, Elf_Data *data) { struct rel_entry r; int j, len; if (ed->flags & SOLARIS_FMT) { PRT("\nRelocation Section: %s\n", s->name); PRT(" type offset " "addend section with respect to\n"); } else PRT("\nrelocation with addend (%s):\n", s->name); r.type = SHT_RELA; assert(data->d_size == s->sz); if (!get_ent_count(s, &len)) return; for (j = 0; j < len; j++) { if (gelf_getrela(data, j, &r.u_r.rela) != &r.u_r.rela) { warnx("gelf_getrela failed: %s", elf_errmsg(-1)); continue; } r.symn = get_symbol_name(ed, s->link, GELF_R_SYM(r.u_r.rela.r_info)); elf_print_rel_entry(ed, s, j, &r); } } /* * Dump a relocation section of type SHT_REL. */ static void elf_print_rel(struct elfdump *ed, struct section *s, Elf_Data *data) { struct rel_entry r; int j, len; if (ed->flags & SOLARIS_FMT) { PRT("\nRelocation Section: %s\n", s->name); PRT(" type offset " "section with respect to\n"); } else PRT("\nrelocation (%s):\n", s->name); r.type = SHT_REL; assert(data->d_size == s->sz); if (!get_ent_count(s, &len)) return; for (j = 0; j < len; j++) { if (gelf_getrel(data, j, &r.u_r.rel) != &r.u_r.rel) { warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } r.symn = get_symbol_name(ed, s->link, GELF_R_SYM(r.u_r.rel.r_info)); elf_print_rel_entry(ed, s, j, &r); } } /* * Dump relocation sections. */ static void elf_print_reloc(struct elfdump *ed) { struct section *s; Elf_Data *data; size_t i; int elferr; for (i = 0; i < ed->shnum; i++) { s = &ed->sl[i]; if ((s->type == SHT_REL || s->type == SHT_RELA) && (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) { (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } if (s->type == SHT_REL) elf_print_rel(ed, s, data); else elf_print_rela(ed, s, data); } } } /* * Dump the content of PT_INTERP segment. */ static void elf_print_interp(struct elfdump *ed) { const char *s; GElf_Phdr phdr; size_t filesize, i, phnum; if (!STAILQ_EMPTY(&ed->snl) && find_name(ed, "PT_INTERP") == NULL) return; if ((s = elf_rawfile(ed->elf, &filesize)) == NULL) { warnx("elf_rawfile failed: %s", elf_errmsg(-1)); return; } if (!elf_getphnum(ed->elf, &phnum)) { warnx("elf_getphnum failed: %s", elf_errmsg(-1)); return; } for (i = 0; i < phnum; i++) { if (gelf_getphdr(ed->elf, i, &phdr) != &phdr) { warnx("elf_getphdr failed: %s", elf_errmsg(-1)); continue; } if (phdr.p_type == PT_INTERP) { if (phdr.p_offset >= filesize) { warnx("invalid phdr offset"); continue; } PRT("\ninterp:\n"); PRT("\t%s\n", s + phdr.p_offset); } } } /* * Search the relocation sections for entries referring to the .got section. */ static void find_gotrel(struct elfdump *ed, struct section *gs, struct rel_entry *got) { struct section *s; struct rel_entry r; Elf_Data *data; size_t i; int elferr, j, k, len; for(i = 0; i < ed->shnum; i++) { s = &ed->sl[i]; if (s->type != SHT_REL && s->type != SHT_RELA) continue; (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } memset(&r, 0, sizeof(struct rel_entry)); r.type = s->type; assert(data->d_size == s->sz); if (!get_ent_count(s, &len)) return; for (j = 0; j < len; j++) { if (s->type == SHT_REL) { if (gelf_getrel(data, j, &r.u_r.rel) != &r.u_r.rel) { warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } } else { if (gelf_getrela(data, j, &r.u_r.rela) != &r.u_r.rela) { warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } } if (r.u_r.rel.r_offset >= gs->addr && r.u_r.rel.r_offset < gs->addr + gs->sz) { r.symn = get_symbol_name(ed, s->link, GELF_R_SYM(r.u_r.rel.r_info)); k = (r.u_r.rel.r_offset - gs->addr) / gs->entsize; memcpy(&got[k], &r, sizeof(struct rel_entry)); } } } } static void elf_print_got_section(struct elfdump *ed, struct section *s) { struct rel_entry *got; Elf_Data *data, dst; int elferr, i, len; if (s->entsize == 0) { /* XXX IA64 GOT section generated by gcc has entry size 0. */ if (s->align != 0) s->entsize = s->align; else return; } if (!get_ent_count(s, &len)) return; if (ed->flags & SOLARIS_FMT) PRT("\nGlobal Offset Table Section: %s (%d entries)\n", s->name, len); else PRT("\nglobal offset table: %s\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } /* * GOT section has section type SHT_PROGBITS, thus libelf treats it as * byte stream and will not perform any translation on it. As a result, * an exlicit call to gelf_xlatetom is needed here. Depends on arch, * GOT section should be translated to either WORD or XWORD. */ if (ed->ec == ELFCLASS32) data->d_type = ELF_T_WORD; else data->d_type = ELF_T_XWORD; memcpy(&dst, data, sizeof(Elf_Data)); if (gelf_xlatetom(ed->elf, &dst, data, ed->ehdr.e_ident[EI_DATA]) != &dst) { warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); return; } assert(dst.d_size == s->sz); if (ed->flags & SOLARIS_FMT) { /* * In verbose/Solaris mode, we search the relocation sections * and try to find the corresponding reloc entry for each GOT * section entry. */ if ((got = calloc(len, sizeof(struct rel_entry))) == NULL) err(EXIT_FAILURE, "calloc failed"); find_gotrel(ed, s, got); if (ed->ec == ELFCLASS32) { PRT(" ndx addr value reloc "); PRT("addend symbol\n"); } else { PRT(" ndx addr value "); PRT("reloc addend symbol\n"); } for(i = 0; i < len; i++) { PRT("[%5.5d] ", i); if (ed->ec == ELFCLASS32) { PRT("%-8.8jx ", (uintmax_t) (s->addr + i * s->entsize)); PRT("%-8.8x ", *((uint32_t *)dst.d_buf + i)); } else { PRT("%-16.16jx ", (uintmax_t) (s->addr + i * s->entsize)); PRT("%-16.16jx ", (uintmax_t) *((uint64_t *)dst.d_buf + i)); } PRT("%-18s ", elftc_reloc_type_str(ed->ehdr.e_machine, GELF_R_TYPE(got[i].u_r.rel.r_info))); if (ed->ec == ELFCLASS32) PRT("%-8.8jd ", (intmax_t)got[i].u_r.rela.r_addend); else PRT("%-12.12jd ", (intmax_t)got[i].u_r.rela.r_addend); if (got[i].symn == NULL) got[i].symn = ""; PRT("%s\n", got[i].symn); } free(got); } else { for(i = 0; i < len; i++) { PRT("\nentry: %d\n", i); if (ed->ec == ELFCLASS32) PRT("\t%#x\n", *((uint32_t *)dst.d_buf + i)); else PRT("\t%#jx\n", (uintmax_t) *((uint64_t *)dst.d_buf + i)); } } } /* * Dump the content of Global Offset Table section. */ static void elf_print_got(struct elfdump *ed) { struct section *s; size_t i; if (!STAILQ_EMPTY(&ed->snl)) return; s = NULL; for (i = 0; i < ed->shnum; i++) { s = &ed->sl[i]; if (s->name && !strncmp(s->name, ".got", 4) && (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) elf_print_got_section(ed, s); } } /* * Dump the content of .note.ABI-tag section. */ static void elf_print_note(struct elfdump *ed) { struct section *s; Elf_Data *data; Elf_Note *en; uint32_t namesz; uint32_t descsz; uint32_t desc; size_t count; int elferr, i; uint8_t *src; char idx[17]; s = NULL; for (i = 0; (size_t)i < ed->shnum; i++) { s = &ed->sl[i]; if (s->type == SHT_NOTE && s->name && !strcmp(s->name, ".note.ABI-tag") && (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) break; } if ((size_t)i >= ed->shnum) return; if (ed->flags & SOLARIS_FMT) PRT("\nNote Section: %s\n", s->name); else PRT("\nnote (%s):\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } src = data->d_buf; count = data->d_size; while (count > sizeof(Elf_Note)) { en = (Elf_Note *) (uintptr_t) src; namesz = en->n_namesz; descsz = en->n_descsz; src += sizeof(Elf_Note); count -= sizeof(Elf_Note); if (roundup2(namesz, 4) + roundup2(descsz, 4) > count) { warnx("truncated note section"); return; } if (ed->flags & SOLARIS_FMT) { PRT("\n type %#x\n", en->n_type); PRT(" namesz %#x:\n", en->n_namesz); PRT("%s\n", src); } else PRT("\t%s ", src); src += roundup2(namesz, 4); count -= roundup2(namesz, 4); /* * Note that we dump the whole desc part if we're in * "Solaris mode", while in the normal mode, we only look * at the first 4 bytes (a 32bit word) of the desc, i.e, * we assume that it's always a FreeBSD version number. */ if (ed->flags & SOLARIS_FMT) { PRT(" descsz %#x:", en->n_descsz); for (i = 0; (uint32_t)i < descsz; i++) { if ((i & 0xF) == 0) { snprintf(idx, sizeof(idx), "desc[%d]", i); PRT("\n %-9s", idx); } else if ((i & 0x3) == 0) PRT(" "); PRT(" %2.2x", src[i]); } PRT("\n"); } else { if (ed->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) desc = be32dec(src); else desc = le32dec(src); PRT("%d\n", desc); } src += roundup2(descsz, 4); count -= roundup2(descsz, 4); } } /* * Dump a hash table. */ static void elf_print_svr4_hash(struct elfdump *ed, struct section *s) { Elf_Data *data; uint32_t *buf; uint32_t *bucket, *chain; uint32_t nbucket, nchain; uint32_t *bl, *c, maxl, total; uint32_t i, j; int first, elferr; char idx[10]; if (ed->flags & SOLARIS_FMT) PRT("\nHash Section: %s\n", s->name); else PRT("\nhash table (%s):\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (data->d_size < 2 * sizeof(uint32_t)) { warnx(".hash section too small"); return; } buf = data->d_buf; nbucket = buf[0]; nchain = buf[1]; if (nbucket <= 0 || nchain <= 0) { warnx("Malformed .hash section"); return; } if (data->d_size != ((uint64_t)nbucket + (uint64_t)nchain + 2) * sizeof(uint32_t)) { warnx("Malformed .hash section"); return; } bucket = &buf[2]; chain = &buf[2 + nbucket]; if (ed->flags & SOLARIS_FMT) { maxl = 0; if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) err(EXIT_FAILURE, "calloc failed"); for (i = 0; i < nbucket; i++) for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) if (++bl[i] > maxl) maxl = bl[i]; if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) err(EXIT_FAILURE, "calloc failed"); for (i = 0; i < nbucket; i++) c[bl[i]]++; PRT(" bucket symndx name\n"); for (i = 0; i < nbucket; i++) { first = 1; for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) { if (first) { PRT("%10d ", i); first = 0; } else PRT(" "); snprintf(idx, sizeof(idx), "[%d]", j); PRT("%-10s ", idx); PRT("%s\n", get_symbol_name(ed, s->link, j)); } } PRT("\n"); total = 0; for (i = 0; i <= maxl; i++) { total += c[i] * i; PRT("%10u buckets contain %8d symbols\n", c[i], i); } PRT("%10u buckets %8u symbols (globals)\n", nbucket, total); } else { PRT("\nnbucket: %u\n", nbucket); PRT("nchain: %u\n\n", nchain); for (i = 0; i < nbucket; i++) PRT("bucket[%d]:\n\t%u\n\n", i, bucket[i]); for (i = 0; i < nchain; i++) PRT("chain[%d]:\n\t%u\n\n", i, chain[i]); } } /* * Dump a 64bit hash table. */ static void elf_print_svr4_hash64(struct elfdump *ed, struct section *s) { Elf_Data *data, dst; uint64_t *buf; uint64_t *bucket, *chain; uint64_t nbucket, nchain; uint64_t *bl, *c, j, maxl, total; size_t i; int elferr, first; char idx[10]; if (ed->flags & SOLARIS_FMT) PRT("\nHash Section: %s\n", s->name); else PRT("\nhash table (%s):\n", s->name); /* * ALPHA uses 64-bit hash entries. Since libelf assumes that * .hash section contains only 32-bit entry, an explicit * gelf_xlatetom is needed here. */ (void) elf_errno(); if ((data = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(elferr)); return; } data->d_type = ELF_T_XWORD; memcpy(&dst, data, sizeof(Elf_Data)); if (gelf_xlatetom(ed->elf, &dst, data, ed->ehdr.e_ident[EI_DATA]) != &dst) { warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); return; } if (dst.d_size < 2 * sizeof(uint64_t)) { warnx(".hash section too small"); return; } buf = dst.d_buf; nbucket = buf[0]; nchain = buf[1]; if (nbucket <= 0 || nchain <= 0) { warnx("Malformed .hash section"); return; } if (dst.d_size != (nbucket + nchain + 2) * sizeof(uint64_t)) { warnx("Malformed .hash section"); return; } bucket = &buf[2]; chain = &buf[2 + nbucket]; if (ed->flags & SOLARIS_FMT) { maxl = 0; if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) err(EXIT_FAILURE, "calloc failed"); for (i = 0; i < nbucket; i++) for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) if (++bl[i] > maxl) maxl = bl[i]; if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) err(EXIT_FAILURE, "calloc failed"); for (i = 0; i < nbucket; i++) c[bl[i]]++; PRT(" bucket symndx name\n"); for (i = 0; i < nbucket; i++) { first = 1; for (j = bucket[i]; j > 0 && j < nchain; j = chain[j]) { if (first) { PRT("%10zu ", i); first = 0; } else PRT(" "); snprintf(idx, sizeof(idx), "[%zu]", (size_t)j); PRT("%-10s ", idx); PRT("%s\n", get_symbol_name(ed, s->link, j)); } } PRT("\n"); total = 0; for (i = 0; i <= maxl; i++) { total += c[i] * i; PRT("%10ju buckets contain %8zu symbols\n", (uintmax_t)c[i], i); } PRT("%10ju buckets %8ju symbols (globals)\n", (uintmax_t)nbucket, (uintmax_t)total); } else { PRT("\nnbucket: %ju\n", (uintmax_t)nbucket); PRT("nchain: %ju\n\n", (uintmax_t)nchain); for (i = 0; i < nbucket; i++) PRT("bucket[%zu]:\n\t%ju\n\n", i, (uintmax_t)bucket[i]); for (i = 0; i < nchain; i++) PRT("chain[%zu]:\n\t%ju\n\n", i, (uintmax_t)chain[i]); } } /* * Dump a GNU hash table. */ static void elf_print_gnu_hash(struct elfdump *ed, struct section *s) { struct section *ds; Elf_Data *data; uint32_t *buf; uint32_t *bucket, *chain; uint32_t nbucket, nchain, symndx, maskwords, shift2; uint32_t *bl, *c, maxl, total; uint32_t i, j; int first, elferr, dynsymcount; char idx[10]; if (ed->flags & SOLARIS_FMT) PRT("\nGNU Hash Section: %s\n", s->name); else PRT("\ngnu hash table (%s):\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (data->d_size < 4 * sizeof(uint32_t)) { warnx(".gnu.hash section too small"); return; } buf = data->d_buf; nbucket = buf[0]; symndx = buf[1]; maskwords = buf[2]; shift2 = buf[3]; buf += 4; if (s->link >= ed->shnum) { warnx("Malformed .gnu.hash section"); return; } ds = &ed->sl[s->link]; if (!get_ent_count(ds, &dynsymcount)) return; if (symndx >= (uint32_t)dynsymcount) { warnx("Malformed .gnu.hash section"); return; } nchain = dynsymcount - symndx; if (data->d_size != 4 * sizeof(uint32_t) + maskwords * (ed->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) + ((uint64_t)nbucket + (uint64_t)nchain) * sizeof(uint32_t)) { warnx("Malformed .gnu.hash section"); return; } bucket = buf + (ed->ec == ELFCLASS32 ? maskwords : maskwords * 2); chain = bucket + nbucket; if (ed->flags & SOLARIS_FMT) { maxl = 0; if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) err(EXIT_FAILURE, "calloc failed"); for (i = 0; i < nbucket; i++) for (j = bucket[i]; j > 0 && j - symndx < nchain; j++) { if (++bl[i] > maxl) maxl = bl[i]; if (chain[j - symndx] & 1) break; } if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) err(EXIT_FAILURE, "calloc failed"); for (i = 0; i < nbucket; i++) c[bl[i]]++; PRT(" bucket symndx name\n"); for (i = 0; i < nbucket; i++) { first = 1; for (j = bucket[i]; j > 0 && j - symndx < nchain; j++) { if (first) { PRT("%10d ", i); first = 0; } else PRT(" "); snprintf(idx, sizeof(idx), "[%d]", j ); PRT("%-10s ", idx); PRT("%s\n", get_symbol_name(ed, s->link, j)); if (chain[j - symndx] & 1) break; } } PRT("\n"); total = 0; for (i = 0; i <= maxl; i++) { total += c[i] * i; PRT("%10u buckets contain %8d symbols\n", c[i], i); } PRT("%10u buckets %8u symbols (globals)\n", nbucket, total); } else { PRT("\nnbucket: %u\n", nbucket); PRT("symndx: %u\n", symndx); PRT("maskwords: %u\n", maskwords); PRT("shift2: %u\n", shift2); PRT("nchain: %u\n\n", nchain); for (i = 0; i < nbucket; i++) PRT("bucket[%d]:\n\t%u\n\n", i, bucket[i]); for (i = 0; i < nchain; i++) PRT("chain[%d]:\n\t%u\n\n", i, chain[i]); } } /* * Dump hash tables. */ static void elf_print_hash(struct elfdump *ed) { struct section *s; size_t i; for (i = 0; i < ed->shnum; i++) { s = &ed->sl[i]; if ((s->type == SHT_HASH || s->type == SHT_GNU_HASH) && (STAILQ_EMPTY(&ed->snl) || find_name(ed, s->name))) { if (s->type == SHT_GNU_HASH) elf_print_gnu_hash(ed, s); else if (ed->ehdr.e_machine == EM_ALPHA && s->entsize == 8) elf_print_svr4_hash64(ed, s); else elf_print_svr4_hash(ed, s); } } } /* * Dump the content of a Version Definition(SHT_SUNW_Verdef) Section. */ static void elf_print_verdef(struct elfdump *ed, struct section *s) { Elf_Data *data; Elf32_Verdef *vd; Elf32_Verdaux *vda; const char *str; char idx[10]; uint8_t *buf, *end, *buf2; int i, j, elferr, count; if (ed->flags & SOLARIS_FMT) PRT("Version Definition Section: %s\n", s->name); else PRT("\nversion definition section (%s):\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } buf = data->d_buf; end = buf + data->d_size; i = 0; if (ed->flags & SOLARIS_FMT) PRT(" index version dependency\n"); while (buf + sizeof(Elf32_Verdef) <= end) { vd = (Elf32_Verdef *) (uintptr_t) buf; if (ed->flags & SOLARIS_FMT) { snprintf(idx, sizeof(idx), "[%d]", vd->vd_ndx); PRT("%10s ", idx); } else { PRT("\nentry: %d\n", i++); PRT("\tvd_version: %u\n", vd->vd_version); PRT("\tvd_flags: %u\n", vd->vd_flags); PRT("\tvd_ndx: %u\n", vd->vd_ndx); PRT("\tvd_cnt: %u\n", vd->vd_cnt); PRT("\tvd_hash: %u\n", vd->vd_hash); PRT("\tvd_aux: %u\n", vd->vd_aux); PRT("\tvd_next: %u\n\n", vd->vd_next); } buf2 = buf + vd->vd_aux; j = 0; count = 0; while (buf2 + sizeof(Elf32_Verdaux) <= end && j < vd->vd_cnt) { vda = (Elf32_Verdaux *) (uintptr_t) buf2; str = get_string(ed, s->link, vda->vda_name); if (ed->flags & SOLARIS_FMT) { if (count == 0) PRT("%-26.26s", str); else if (count == 1) PRT(" %-20.20s", str); else { PRT("\n%40.40s", ""); PRT("%s", str); } } else { PRT("\t\tvda: %d\n", j++); PRT("\t\t\tvda_name: %s\n", str); PRT("\t\t\tvda_next: %u\n", vda->vda_next); } if (vda->vda_next == 0) { if (ed->flags & SOLARIS_FMT) { if (vd->vd_flags & VER_FLG_BASE) { if (count == 0) PRT("%-20.20s", ""); PRT("%s", "[ BASE ]"); } PRT("\n"); } break; } if (ed->flags & SOLARIS_FMT) count++; buf2 += vda->vda_next; } if (vd->vd_next == 0) break; buf += vd->vd_next; } } /* * Dump the content of a Version Needed(SHT_SUNW_Verneed) Section. */ static void elf_print_verneed(struct elfdump *ed, struct section *s) { Elf_Data *data; Elf32_Verneed *vn; Elf32_Vernaux *vna; uint8_t *buf, *end, *buf2; int i, j, elferr, first; if (ed->flags & SOLARIS_FMT) PRT("\nVersion Needed Section: %s\n", s->name); else PRT("\nversion need section (%s):\n", s->name); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } buf = data->d_buf; end = buf + data->d_size; if (ed->flags & SOLARIS_FMT) PRT(" file version\n"); i = 0; while (buf + sizeof(Elf32_Verneed) <= end) { vn = (Elf32_Verneed *) (uintptr_t) buf; if (ed->flags & SOLARIS_FMT) PRT(" %-26.26s ", get_string(ed, s->link, vn->vn_file)); else { PRT("\nentry: %d\n", i++); PRT("\tvn_version: %u\n", vn->vn_version); PRT("\tvn_cnt: %u\n", vn->vn_cnt); PRT("\tvn_file: %s\n", get_string(ed, s->link, vn->vn_file)); PRT("\tvn_aux: %u\n", vn->vn_aux); PRT("\tvn_next: %u\n\n", vn->vn_next); } buf2 = buf + vn->vn_aux; j = 0; first = 1; while (buf2 + sizeof(Elf32_Vernaux) <= end && j < vn->vn_cnt) { vna = (Elf32_Vernaux *) (uintptr_t) buf2; if (ed->flags & SOLARIS_FMT) { if (!first) PRT("%40.40s", ""); else first = 0; PRT("%s\n", get_string(ed, s->link, vna->vna_name)); } else { PRT("\t\tvna: %d\n", j++); PRT("\t\t\tvna_hash: %u\n", vna->vna_hash); PRT("\t\t\tvna_flags: %u\n", vna->vna_flags); PRT("\t\t\tvna_other: %u\n", vna->vna_other); PRT("\t\t\tvna_name: %s\n", get_string(ed, s->link, vna->vna_name)); PRT("\t\t\tvna_next: %u\n", vna->vna_next); } if (vna->vna_next == 0) break; buf2 += vna->vna_next; } if (vn->vn_next == 0) break; buf += vn->vn_next; } } /* * Dump the symbol-versioning sections. */ static void elf_print_symver(struct elfdump *ed) { struct section *s; size_t i; for (i = 0; i < ed->shnum; i++) { s = &ed->sl[i]; if (!STAILQ_EMPTY(&ed->snl) && !find_name(ed, s->name)) continue; if (s->type == SHT_SUNW_verdef) elf_print_verdef(ed, s); if (s->type == SHT_SUNW_verneed) elf_print_verneed(ed, s); } } /* * Dump the ELF checksum. See gelf_checksum(3) for details. */ static void elf_print_checksum(struct elfdump *ed) { if (!STAILQ_EMPTY(&ed->snl)) return; PRT("\nelf checksum: %#lx\n", gelf_checksum(ed->elf)); } #define USAGE_MESSAGE "\ Usage: %s [options] file...\n\ Display information about ELF objects and ar(1) archives.\n\n\ Options:\n\ -a Show all information.\n\ -c Show shared headers.\n\ -d Show dynamic symbols.\n\ -e Show the ELF header.\n\ -G Show the GOT.\n\ -H | --help Show a usage message and exit.\n\ -h Show hash values.\n\ -i Show the dynamic interpreter.\n\ -k Show the ELF checksum.\n\ -n Show the contents of note sections.\n\ -N NAME Show the section named \"NAME\".\n\ -p Show the program header.\n\ -r Show relocations.\n\ -s Show the symbol table.\n\ -S Use the Solaris elfdump format.\n\ -v Show symbol-versioning information.\n\ -V | --version Print a version identifier and exit.\n\ -w FILE Write output to \"FILE\".\n" static void usage(void) { fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } Index: stable/11/contrib/elftoolchain/libdwarf/dwarf.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf.3 (revision 367466) @@ -1,751 +1,751 @@ .\" Copyright (c) 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: dwarf.3 3295 2016-01-08 22:08:10Z jkoshy $ +.\" $Id: dwarf.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd December 21, 2014 -.Os .Dt DWARF 3 +.Os .Sh NAME .Nm dwarf .Nd access debugging information in object files .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Sh DESCRIPTION -.Pp The .Lb libdwarf provides functions that allow an application to read and write debugging information in object files. The format of debugging information accessible through this API is defined by the DWARF standard, see .Xr dwarf 4 . .Pp The .Xr DWARF 3 API has two parts: .Bl -bullet .It A consumer API set allows applications to read existing debug information in a program object. The functions that comprise the DWARF consumer API are described in the section .Sx "DWARF Consumer API" below. .It A producer API set that allows applications to add debug information to a program object. The functions that comprise the DWARF producer API are described in the section .Sx "DWARF Producer API" below. .El .Pp Each function referenced below is further described in its own manual page. .Ss Namespace use The DWARF library uses the following prefixes: .Pp .Bl -tag -width ".Li Dwarf_*" -compact .It Li DWARF_* Used for error numbers and constants. .It Li DW_* Used for constants. .It Li Dwarf_* Used for types. .It Li dwarf_* Used for functions and macros that make up the API. .El .Ss Data Types The DWARF(3) API uses the following data types: .Pp .Bl -tag -width ".Vt Dwarf_Unsigned" -compact .It Vt Dwarf_Abbrev Describes DWARF abbreviations. .It Vt Dwarf_Addr A program address in the target object. .It Vt Dwarf_Arange Describes address ranges. .It Vt Dwarf_Attribute , Vt Dwarf_P_Attribute Describes attributes of debugging information entries. .It Vt Dwarf_Bool Used for boolean states. .It Vt Dwarf_Cie , Vt Dwarf_P_Cie Describes call information that is common to several frames. .It Vt Dwarf_Debug , Vt Dwarf_P_Debug An opaque type describing a debug context. .It Vt Dwarf_Die , Vt Dwarf_P_Die A debugging information entry. .It Vt Dwarf_Fde , Vt Dwarf_P_Fde A frame descriptor. .It Vt Dwarf_Func A descriptor representing a function. .It Vt Dwarf_Global A descriptor representing a global name. .It Vt Dwarf_Half A 16-bit wide unsigned numeric type. .It Vt Dwarf_Handler A pointer to an error handling function. .It Vt Dwarf_Line A descriptor for a source line. .It Vt Dwarf_Off An unsigned file offset. .It Vt Dwarf_P_Expr A descriptor for a location expression. .It Vt Dwarf_Ptr A virtual address used by an application. .It Vt Dwarf_Signed A 64-bit wide signed numeric type. .It Vt Dwarf_Small An 8-bit wide unsigned numeric type. .It Vt Dwarf_Type A descriptor representing a user-specified type. .It Vt Dwarf_Unsigned A 64-bit wide unsigned numeric type. .It Vt Dwarf_Var A descriptor representing a static variable. .It Vt Dwarf_Weak A descriptor representing a weak name. .El .Ss Error Handling -.Pp Library functions that encounter an error will return with a value other than .Dv DW_DLV_OK . .Pp The .Lb libdwarf allows applications to specify three levels of error handling: .Bl -enum -compact .It Most library functions take a parameter of type .Vt Dwarf_Error that specifies a location to store an error descriptor in case of an error. If an error occurs during the execution on an API, and if this parameter is non-NULL, then an error descriptor is written to the location specified. .It Otherwise, if the error parameter was NULL, but if an error handler was defined for the debug context in use using .Xr dwarf_init 3 or .Xr dwarf_seterrhand 3 , then the library will invoke the specified error handler with an error descriptor as argument. .It Otherwise, if a library wide error handler was specified using .Xr dwarf_seterrhand 3 , it is called. .El .Pp Error descriptors may be used with .Xr dwarf_errmsg 3 or .Xr dwarf_errno 3 . .Sh The DWARF Consumer API The DWARF consumer API permits applications to read DWARF information in an object file. .Pp The major functional groups of functions in the consumer API are listed below. .Pp .Bl -tag -compact -width "CCCC" .It Abbreviations -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_abbrev Retrieve abbreviation information at a given offset. .It Fn dwarf_get_abbrev_children_flag Check if an abbreviation has child elements. .It Fn dwarf_get_abbrev_code Retrieve the abbreviation code for an abbreviation entry descriptor. .It Fn dwarf_get_abbrev_entry Retrieve abbreviation information for an abbreviation entry descriptor. .It Fn dwarf_get_abbrev_tag Retrieve the tag for an abbreviation entry. .El .It Addresses -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_address_size Return the number of bytes needed to represent an address. .It Fn dwarf_get_arange Search for an address range descriptor covering an address. .It Fn dwarf_get_arange_cu_header_offset Retrieve the offsets associated with an address range descriptor. .It Fn dwarf_get_arange_info Extract address range information from a descriptor. .It Fn dwarf_get_aranges Retrieve program address space mappings. .It Fn dwarf_get_cu_die_offset Retrieve the offset associated with a compilation unit for an address range descriptor. .It Fn dwarf_get_ranges , Fn dwarf_get_ranges_a Retrieve information about non-contiguous address ranges for a debugging information entry. .El .It Attributes -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_arrayorder Retrieve the value of a .Dv DW_AT_ordering attribute. .It Fn dwarf_attr Retrieve an attribute descriptor. .It Fn dwarf_attrlist Retrieve attribute descriptors for a debugging information entry. .It Fn dwarf_attroffset Retrieve the section-relative offset of an attribute descriptor. .It Fn dwarf_attrval_flag Retrieve a .Dv DW_AT_FORM_flag value. .It Fn dwarf_attrval_signed Retrieve an attribute's value as a signed integral quantity. .It Fn dwarf_attrval_string Retrieve an attribute's value as a NUL-terminated string. .It Fn dwarf_attrval_unsigned Retrieve an attribute's value as an unsigned integral quantity. .It Fn dwarf_bitoffset , Retrieve the value of a .Dv DW_AT_bit_offset attribute. .It Fn dwarf_bitsize , Retrieve the value of a .Dv DW_AT_bit_size attribute. .It Fn dwarf_bytesize Retrieve the value of a .Dv DW_AT_byte_size attribute. .It Fn dwarf_formaddr Return the value of an .Dv ADDRESS Ns - Ns class attribute. .It Fn dwarf_formblock Return the value of a .Dv BLOCK Ns - Ns class attribute .It Fn dwarf_formexprloc Return information about a location expression. .It Fn dwarf_formflag Retrieve information about a .Dv BOOLEAN Ns - Ns class attribute. .It Fn dwarf_formref , Fn dwarf_global_formref Retrieve offsets for .Dv REFERENCE Ns - Ns class attributes. .It Fn dwarf_formsdata , Fn dwarf_formudata Retrieve the value of a .Dv CONSTANT Ns - Ns class attribute. .It Fn dwarf_formsig8 Return the type signature for a DWARF type. .It Fn dwarf_formstring Retrieve information about a .Dv STRING Ns - Ns class attribute. .It Fn dwarf_get_form_class Retrieve the form class for an attribute. .It Fn dwarf_hasattr Check for the presence of an attribute. .It Fn dwarf_hasform Check if an attribute has the given form. .It Fn dwarf_whatattr Retrieve the attribute code for an attribute. .It Fn dwarf_whatform , Fn dwarf_whatform_direct Retrieve the form of an attribute. .El .It Call Information Entries and Frame Descriptor Entries -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_cie_index Retrieve the index for a CIE descriptor. .It Fn dwarf_get_cie_info Retrieve information from a CIE descriptor. .It Fn dwarf_get_cie_of_fde Retrieve a CIE descriptor. .It Fn dwarf_get_fde_at_pc Retrieve an FDE descriptor for an address. .It Fn dwarf_get_fde_info_for_all_regs Retrieve register rule row. .It Fn dwarf_get_fde_info_for_all_regs3 Retrieve register rule row (revised API). .It Fn dwarf_get_fde_info_for_cfa_reg3 Retrieve a CFA register rule. .It Fn dwarf_get_fde_info_for_reg Retrieve a register rule. .It Fn dwarf_get_fde_info_for_reg3 Retrieve a register rule (revised API). .It Fn dwarf_get_fde_instr_bytes Retrieve instructions from an FDE descriptor. .It Fn dwarf_get_fde_list , Fn dwarf_get_fde_list_eh Retrieve frame information. .It Fn dwarf_get_fde_n Retrieve an FDE descriptor. .It Fn dwarf_get_fde_range Retrieve range information from an FDE descriptor. .El .It Compilation Units -.Bl -tag -compact +.Bl -tag -compact -width indent .It Xo .Fn dwarf_get_cu_die_offset_given_cu_header_offset , .Fn dwarf_get_cu_die_offset_given_cu_header_offset_b .Xc Retrieve the offset of the debugging information entry for a compilation or type unit. .It Xo .Fn dwarf_next_cu_header , .Fn dwarf_next_cu_header_b , .Fn dwarf_next_cu_header_c .Xc Step through compilation units in a debug context. .El .It Debugging Information Entries -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_child Returns the child of a debugging information entry. .It Fn dwarf_die_abbrev_code Returns the abbreviation code for a debugging information entry. .It Fn dwarf_die_CU_offset , Fn dwarf_die_CU_offset_range Retrieve offsets and lengths for a compilation unit. .It Fn dwarf_diename Returns the .Dv DW_AT_name attribute for a debugging information entry. .It Fn dwarf_dieoffset Retrieves the offset for a debugging information entry. .It Fn dwarf_get_die_infotypes_flag Indicate the originating section for a debugging information entry. .It Fn dwarf_highpc , Fn dwarf_highpc_b Return the highest PC value for a debugging information entry. .It Fn dwarf_lowpc Return the lowest PC value for a debugging information entry. .It Fn dwarf_offdie , Fn dwarf_offdie_b Retrieve a debugging information entry given an offset. .It Fn dwarf_siblingof , Fn dwarf_siblingof_b Retrieve the sibling descriptor for a debugging information entry. .It Fn dwarf_srclang Retrieve the source language attribute for a debugging information entry. .It Fn dwarf_tag Retrieve the tag for a debugging information entry. .El .It Functions -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_func_cu_offset Retrieves the offset for the compilation unit for a function. .It Fn dwarf_func_die_offset Retrieves the offset for the debugging information entry for a function. .It Fn dwarf_funcname Retrieves the name of a function. .It Fn dwarf_func_name_offsets Retrieve both the name and offsets for a function. .It Fn dwarf_get_funcs Retrieve information about static functions. .El .It Globals -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_globals Retrieve a list of globals. .It Fn dwarf_global_cu_offset Return the offset for compilation unit for a global. .It Fn dwarf_global_die_offset Return the offset for the debugging information entry for a global. .It Fn dwarf_global_name_offsets Return the name and offsets for a global. .It Fn dwarf_globname Return the name for a global. .El .It Initialization and Finalization Functions .Fn dwarf_elf_init and .Fn dwarf_init may be used for initialization. The function .Fn dwarf_finish may be used to release resources. .Pp The functions .Fn dwarf_object_init and .Fn dwarf_object_finish allow an application to specify alternate low-level file access routines. .It Line Numbers -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_lineaddr Retrieve the program address for a source line. .It Fn dwarf_linebeginstatement Check if a source line corresponds to the beginning of a statement. .It Fn dwarf_lineblock Check if a source line corresponds to the start of a basic block. .It Fn dwarf_lineendsequence Check if the source line corresponds to the end of a sequence of instructions. .It Fn dwarf_lineno Retrieve the line number for a line descriptor. .It Fn dwarf_lineoff Retrieve the column number for a line descriptor. .It Fn dwarf_linesrc Retrieve the source file for a line descriptor. .It Fn dwarf_line_srcfileno Retrieve the index of the source file for a line descriptor. .It Fn dwarf_srcfiles Retrieve source files for a compilation unit. .It Fn dwarf_srclines Return line number information for a compilation unit. .El .It Location Lists -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_loclist_entry Retrieve a location list entry. .It Fn dwarf_loclist , Fn dwarf_loclist_n Retrieve location expressions. .It Xo .Fn dwarf_loclist_from_expr , .Fn dwarf_loclist_from_expr_a , .Fn dwarf_loclist_from_expr_b .Xc Translate a location expression into a location descriptor. .El .It Error Handling -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_errmsg Retrieve a human-readable error message. .It Fn dwarf_errno Retrieve an error number from an error descriptor. .It Fn dwarf_seterrarg Set the argument passed to a callback error handler. .It Fn dwarf_seterrhand Set the callback handler to be called in case of an error. .El .It Frame Handling -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_expand_frame_instructions Translate frame instruction bytes. .It Fn dwarf_set_frame_cfa_value Set the CFA parameter for the internal register rule table. .It Fn dwarf_set_frame_rule_initial_value Set the initial value of the register rules in the internal register rule table. .It Fn dwarf_set_frame_rule_table_size Set the maximum number of columns in the register rule table. .It Fn dwarf_set_frame_same_value Set the register number representing the .Dq "same value" rule. .It Fn dwarf_set_frame_undefined_value Set the register number representing the .Dq "undefined" rule. .El .It Macros -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_find_macro_value_start Return the macro value part of a macro string. .It Fn dwarf_get_macro_details Retrieve macro information. .El .It Memory Management In the DWARF consumer API, the rules for memory management differ between functions. In some cases, the memory areas returned to the application by the library are freed by calling specific API functions. In others, the deallocation function .Fn dwarf_dealloc suffices. The individual manual pages for the API's functions document the specific memory management rules to be followed. .Pp The function .Fn dwarf_dealloc is used to mark memory arenas as unused. Additionally, the following functions release specific types of DWARF resources: .Fn dwarf_fde_cie_list_dealloc , .Fn dwarf_funcs_dealloc , .Fn dwarf_globals_dealloc , .Fn dwarf_pubtypes_dealloc , .Fn dwarf_ranges_dealloc , .Fn dwarf_srclines_dealloc , .Fn dwarf_types_dealloc , .Fn dwarf_vars_dealloc , and .Fn dwarf_weaks_dealloc . .It Symbol Constants The following functions may be used to return symbolic names for DWARF constants: .Fn dwarf_get_ACCESS_name , .Fn dwarf_get_AT_name , .Fn dwarf_get_ATE_name , .Fn dwarf_get_CC_name , .Fn dwarf_get_CFA_name , .Fn dwarf_get_CHILDREN_name , .Fn dwarf_get_DS_name , .Fn dwarf_get_DSC_name , .Fn dwarf_get_EH_name , .Fn dwarf_get_END_name , .Fn dwarf_get_FORM_name , .Fn dwarf_get_ID_name , .Fn dwarf_get_INL_name , .Fn dwarf_get_LANG_name , .Fn dwarf_get_LNE_name , .Fn dwarf_get_LNS_name , .Fn dwarf_get_MACINFO_name , .Fn dwarf_get_OP_name , .Fn dwarf_get_ORD_name , .Fn dwarf_get_TAG_name , .Fn dwarf_get_VIRTUALITY_name , and .Fn dwarf_get_VIS_name . .It Types -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_pubtypes , Fn dwarf_get_types Retrieve descriptors for user-defined types. .It Fn dwarf_next_types_section Step through .Dq \&.debug_types sections in a debug context. .It Fn dwarf_pubtype_cu_offset , Fn dwarf_type_cu_offset Return the offset for the compilation unit for a type. .It Fn dwarf_pubtype_die_offset , Fn dwarf_type_die_offset Return the offset for the debugging information entry for a type. .It Fn dwarf_pubtypename , Fn dwarf_typename Retrieve the name of a type. .It Fn dwarf_pubtype_name_offsets , Fn dwarf_type_name_offsets Retrieve the name and offsets for a type. .El .It Variables -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_vars Retrieve descriptors for static variables. .It Fn dwarf_var_cu_offset Return the offset for the compilation unit for a variable. .It Fn dwarf_var_die_offset Return the offset for the debugging information entry for a variable. .It Fn dwarf_varname Retrieve the name of a variable. .It Fn dwarf_var_name_offsets Retrieve the name and offsets for a variable. .El .It Weak Symbols -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_weaks Retrieve information about weak symbols. .It Fn dwarf_weak_cu_offset Return the offset for the compilation unit for a weak symbol. .It Fn dwarf_weak_die_offset Return the offset for the debugging information entry for a weak symbol. .It Fn dwarf_weakname Retrieve the name of a weak symbol. .It Fn dwarf_weak_name_offsets Retrieve the name and offsets for a weak symbol. .El .It Miscellaneous -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_elf Retrieve the ELF descriptor for a debug context, see .Xr elf 3 . .It Fn dwarf_get_str Retrieve a NUL-terminated string from the DWARF string section. .It Fn dwarf_set_reloc_application Control whether relocations are to be handled by .Lb libdwarf . .El .El .Sh The DWARF Producer API The DWARF producer API permits applications to add DWARF information to an object file. .Pp The major functional groups of functions in the producer API are listed below. .Bl -tag -width "CCCC" .It Attribute Management The following functions are used to attach attributes to a debugging information entry: .Fn dwarf_add_AT_comp_dir , .Fn dwarf_add_AT_const_value_signedint , .Fn dwarf_add_AT_const_value_string , .Fn dwarf_add_AT_const_value_unsignedint , .Fn dwarf_add_AT_dataref , .Fn dwarf_add_AT_flag , .Fn dwarf_add_AT_location_expr , .Fn dwarf_add_AT_name , .Fn dwarf_add_AT_producer , .Fn dwarf_add_AT_ref_address , .Fn dwarf_add_AT_reference , .Fn dwarf_add_AT_signed_const , .Fn dwarf_add_AT_string , .Fn dwarf_add_AT_targ_address , .Fn dwarf_add_AT_targ_address_b and .Fn dwarf_add_AT_unsigned_const . .It Debugging Information Entry Management -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_add_die_to_debug Set the root debugging information entry for a DWARF producer instance. .It Fn dwarf_die_link Links debugging information entries. .It Fn dwarf_new_die Allocate a new debugging information entry. .El .It Initialization and Finalization The functions .Fn dwarf_producer_init and .Fn dwarf_producer_init_b are used to initialize a producer instance. .Pp When done, applications release resources using the function .Fn dwarf_producer_finish . .It Relocations and Sections -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_get_relocation_info Retrieve a relocation array from a producer instance. .It Fn dwarf_get_relocation_info_count Return the number of relocation arrays for a producer instance. .It Fn dwarf_get_section_bytes Retrieve the ELF byte stream for a section. .It Fn dwarf_reset_section_bytes Reset internal state for a producer instance. .It Fn dwarf_transform_to_disk_form Prepare byte streams for writing out. .El .It Macros -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_def_macro Add a macro definition. .It Fn dwarf_end_macro_file , Fn dwarf_start_macro_file Record macro file related information. .It Fn dwarf_undef_macro Note the removal of a macro definition. .It Fn dwarf_vendor_ext Enables storing macro information as specified in the DWARF standard. .El .It Symbols, Expressions, Addresses and Offsets -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn dwarf_add_arange , Fn dwarf_add_arange_b Add address range information. .It Fn dwarf_add_directory_decl Add information about an include directory to a producer instance. .It Fn dwarf_add_fde_inst Add an operation to a frame descriptor entry. .It Fn dwarf_add_file_decl Add information about a source file to a producer instance. .It Fn dwarf_add_frame_cie Add call information to a frame descriptor. .It Fn dwarf_add_frame_fde , Fn dwarf_add_frame_fde_b Link a frame descriptor to a producer instance. .It Fn dwarf_add_funcname Add information about a function to a producer instance. .It Fn dwarf_add_line_entry Record mapping information between machine addresses and a source line. .It Fn dwarf_add_expr_addr , Fn dwarf_add_expr_addr_b Add a .Dv DW_OP_addr opcode to a location expression. .It Fn dwarf_add_expr_gen Add an operator to a location expression. .It Fn dwarf_add_pubname Add information about a global name to a producer instance. .It Fn dwarf_add_typename Add information about a type to a producer instance. .It Fn dwarf_add_varname Add information about a static variable to a producer instance. .It Fn dwarf_add_weakname Add information about a weak symbol to a producer instance. .It Fn dwarf_expr_current_offset Retrieve the current size of a location expression. .It Fn dwarf_expr_into_block Convert a location expression into a byte stream. .It Fn dwarf_fde_cfa_offset Append a .Dv DW_CFA_offset operation to a frame descriptor. .It Fn dwarf_lne_end_sequence , Fn dwarf_lne_set_address Note address ranges for source lines. .It Fn dwarf_new_expr Allocate a location expression descriptor. .It Fn dwarf_new_fde Allocate a frame descriptor. .El .It Miscellaneous The function .Fn dwarf_producer_set_isa sets the instruction set architecture for the producer instance. .El .Sh COMPATIBILITY This implementation is believed to be source compatible with the SGI/GNU DWARF(3) library, version 20110113. .Pp Known differences with the SGI/GNU library include: .Bl -bullet -compact .It The memory management scheme used differs, in a backward-compatible way. See .Sx Memory Management above, for coding guidelines for portable applications. .It There is provision for setting a library-wide error handler in addition to the per-debug context handlers supported by the SGI/GNU API, see the subsection .Sx Error Handling above. .El .Ss Extensions The following APIs are extensions specific to this implementation: .Bl -bullet -compact .It .Fn dwarf_attroffset .It .Fn dwarf_next_types_section .It .Fn dwarf_producer_set_isa .El .Sh SEE ALSO .Xr elf 3 .Sh STANDARDS The DWARF standard is defined by .Rs .%T "The DWARF Debugging Information Format" .%V "Version 4" .%O "http://www.dwarfstd.org/" .Re .Sh HISTORY The DWARF(3) API originated at Silicon Graphics Inc. .Pp A BSD-licensed implementation of a subset of the API was written by .An John Birrell Aq Mt jb@FreeBSD.org -for the FreeBSD project. +for the +.Fx +project. The implementation was subsequently revised and completed by .An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . .Pp Manual pages for this implementation were written by .An Joseph Koshy Aq Mt jkoshy@users.sourceforge.net and .An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . Index: stable/11/contrib/elftoolchain/libdwarf/dwarf.h =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf.h (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf.h (revision 367466) @@ -1,652 +1,652 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) * 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: dwarf.h 3494 2016-09-20 17:16:13Z emaste $ + * $Id: dwarf.h 3749 2019-06-28 01:10:44Z emaste $ */ #ifndef _DWARF_H_ #define _DWARF_H_ #define DW_TAG_array_type 0x01 #define DW_TAG_class_type 0x02 #define DW_TAG_entry_point 0x03 #define DW_TAG_enumeration_type 0x04 #define DW_TAG_formal_parameter 0x05 #define DW_TAG_imported_declaration 0x08 #define DW_TAG_label 0x0a #define DW_TAG_lexical_block 0x0b #define DW_TAG_member 0x0d #define DW_TAG_pointer_type 0x0f #define DW_TAG_reference_type 0x10 #define DW_TAG_compile_unit 0x11 #define DW_TAG_string_type 0x12 #define DW_TAG_structure_type 0x13 #define DW_TAG_subroutine_type 0x15 #define DW_TAG_typedef 0x16 #define DW_TAG_union_type 0x17 #define DW_TAG_unspecified_parameters 0x18 #define DW_TAG_variant 0x19 #define DW_TAG_common_block 0x1a #define DW_TAG_common_inclusion 0x1b #define DW_TAG_inheritance 0x1c #define DW_TAG_inlined_subroutine 0x1d #define DW_TAG_module 0x1e #define DW_TAG_ptr_to_member_type 0x1f #define DW_TAG_set_type 0x20 #define DW_TAG_subrange_type 0x21 #define DW_TAG_with_stmt 0x22 #define DW_TAG_access_declaration 0x23 #define DW_TAG_base_type 0x24 #define DW_TAG_catch_block 0x25 #define DW_TAG_const_type 0x26 #define DW_TAG_constant 0x27 #define DW_TAG_enumerator 0x28 #define DW_TAG_friend 0x2a #define DW_TAG_namelist 0x2b #define DW_TAG_namelist_item 0x2c #define DW_TAG_packed_type 0x2d #define DW_TAG_subprogram 0x2e #define DW_TAG_template_type_parameter 0x2f #define DW_TAG_template_type_param 0x2f #define DW_TAG_template_value_parameter 0x30 #define DW_TAG_template_value_param 0x30 #define DW_TAG_thrown_type 0x31 #define DW_TAG_try_block 0x32 #define DW_TAG_variant_part 0x33 #define DW_TAG_variable 0x34 #define DW_TAG_volatile_type 0x35 #define DW_TAG_dwarf_procedure 0x36 #define DW_TAG_restrict_type 0x37 #define DW_TAG_interface_type 0x38 #define DW_TAG_namespace 0x39 #define DW_TAG_imported_module 0x3a #define DW_TAG_unspecified_type 0x3b #define DW_TAG_partial_unit 0x3c #define DW_TAG_imported_unit 0x3d #define DW_TAG_condition 0x3f #define DW_TAG_shared_type 0x40 #define DW_TAG_type_unit 0x41 #define DW_TAG_rvalue_reference_type 0x42 #define DW_TAG_template_alias 0x43 #define DW_TAG_lo_user 0x4080 #define DW_TAG_hi_user 0xffff /* GNU extensions. */ #define DW_TAG_format_label 0x4101 #define DW_TAG_function_template 0x4102 #define DW_TAG_class_template 0x4103 #define DW_TAG_GNU_BINCL 0x4104 #define DW_TAG_GNU_EINCL 0x4105 #define DW_TAG_GNU_template_template_parameter 0x4106 #define DW_TAG_GNU_template_template_param 0x4106 #define DW_TAG_GNU_template_parameter_pack 0x4107 #define DW_TAG_GNU_formal_parameter_pack 0x4108 #define DW_TAG_GNU_call_site 0x4109 #define DW_TAG_GNU_call_site_parameter 0x410a #define DW_CHILDREN_no 0x00 #define DW_CHILDREN_yes 0x01 #define DW_AT_sibling 0x01 #define DW_AT_location 0x02 #define DW_AT_name 0x03 #define DW_AT_ordering 0x09 #define DW_AT_subscr_data 0x0a #define DW_AT_byte_size 0x0b #define DW_AT_bit_offset 0x0c #define DW_AT_bit_size 0x0d #define DW_AT_element_list 0x0f #define DW_AT_stmt_list 0x10 #define DW_AT_low_pc 0x11 #define DW_AT_high_pc 0x12 #define DW_AT_language 0x13 #define DW_AT_member 0x14 #define DW_AT_discr 0x15 #define DW_AT_discr_value 0x16 #define DW_AT_visibility 0x17 #define DW_AT_import 0x18 #define DW_AT_string_length 0x19 #define DW_AT_common_reference 0x1a #define DW_AT_comp_dir 0x1b #define DW_AT_const_value 0x1c #define DW_AT_containing_type 0x1d #define DW_AT_default_value 0x1e #define DW_AT_inline 0x20 #define DW_AT_is_optional 0x21 #define DW_AT_lower_bound 0x22 #define DW_AT_producer 0x25 #define DW_AT_prototyped 0x27 #define DW_AT_return_addr 0x2a #define DW_AT_start_scope 0x2c #define DW_AT_bit_stride 0x2e #define DW_AT_stride_size 0x2e #define DW_AT_upper_bound 0x2f #define DW_AT_abstract_origin 0x31 #define DW_AT_accessibility 0x32 #define DW_AT_address_class 0x33 #define DW_AT_artificial 0x34 #define DW_AT_base_types 0x35 #define DW_AT_calling_convention 0x36 #define DW_AT_count 0x37 #define DW_AT_data_member_location 0x38 #define DW_AT_decl_column 0x39 #define DW_AT_decl_file 0x3a #define DW_AT_decl_line 0x3b #define DW_AT_declaration 0x3c #define DW_AT_discr_list 0x3d #define DW_AT_encoding 0x3e #define DW_AT_external 0x3f #define DW_AT_frame_base 0x40 #define DW_AT_friend 0x41 #define DW_AT_identifier_case 0x42 #define DW_AT_macro_info 0x43 #define DW_AT_namelist_item 0x44 #define DW_AT_priority 0x45 #define DW_AT_segment 0x46 #define DW_AT_specification 0x47 #define DW_AT_static_link 0x48 #define DW_AT_type 0x49 #define DW_AT_use_location 0x4a #define DW_AT_variable_parameter 0x4b #define DW_AT_virtuality 0x4c #define DW_AT_vtable_elem_location 0x4d #define DW_AT_allocated 0x4e #define DW_AT_associated 0x4f #define DW_AT_data_location 0x50 #define DW_AT_byte_stride 0x51 #define DW_AT_entry_pc 0x52 #define DW_AT_use_UTF8 0x53 #define DW_AT_extension 0x54 #define DW_AT_ranges 0x55 #define DW_AT_trampoline 0x56 #define DW_AT_call_column 0x57 #define DW_AT_call_file 0x58 #define DW_AT_call_line 0x59 #define DW_AT_description 0x5a #define DW_AT_binary_scale 0x5b #define DW_AT_decimal_scale 0x5c #define DW_AT_small 0x5d #define DW_AT_decimal_sign 0x5e #define DW_AT_digit_count 0x5f #define DW_AT_picture_string 0x60 #define DW_AT_mutable 0x61 #define DW_AT_threads_scaled 0x62 #define DW_AT_explicit 0x63 #define DW_AT_object_pointer 0x64 #define DW_AT_endianity 0x65 #define DW_AT_elemental 0x66 #define DW_AT_pure 0x67 #define DW_AT_recursive 0x68 #define DW_AT_signature 0x69 #define DW_AT_main_subprogram 0x6a #define DW_AT_data_bit_offset 0x6b #define DW_AT_const_expr 0x6c #define DW_AT_enum_class 0x6d #define DW_AT_linkage_name 0x6e #define DW_AT_lo_user 0x2000 #define DW_AT_hi_user 0x3fff /* SGI/MIPS extensions. */ #define DW_AT_MIPS_fde 0x2001 #define DW_AT_MIPS_loop_begin 0x2002 #define DW_AT_MIPS_tail_loop_begin 0x2003 #define DW_AT_MIPS_epilog_begin 0x2004 #define DW_AT_MIPS_loop_unroll_factor 0x2005 #define DW_AT_MIPS_software_pipeline_depth 0x2006 #define DW_AT_MIPS_linkage_name 0x2007 #define DW_AT_MIPS_stride 0x2008 #define DW_AT_MIPS_abstract_name 0x2009 #define DW_AT_MIPS_clone_origin 0x200a #define DW_AT_MIPS_has_inlines 0x200b #define DW_AT_MIPS_stride_byte 0x200c #define DW_AT_MIPS_stride_elem 0x200d #define DW_AT_MIPS_ptr_dopetype 0x200e #define DW_AT_MIPS_allocatable_dopetype 0x200f #define DW_AT_MIPS_assumed_shape_dopetype 0x2010 #define DW_AT_MIPS_assumed_size 0x2011 /* GNU extensions. */ #define DW_AT_sf_names 0x2101 #define DW_AT_src_info 0x2102 #define DW_AT_mac_info 0x2103 #define DW_AT_src_coords 0x2104 #define DW_AT_body_begin 0x2105 #define DW_AT_body_end 0x2106 #define DW_AT_GNU_vector 0x2107 #define DW_AT_GNU_guarded_by 0x2108 #define DW_AT_GNU_pt_guarded_by 0x2109 #define DW_AT_GNU_guarded 0x210a #define DW_AT_GNU_pt_guarded 0x210b #define DW_AT_GNU_locks_excluded 0x210c #define DW_AT_GNU_exclusive_locks_required 0x210d #define DW_AT_GNU_shared_locks_required 0x210e #define DW_AT_GNU_odr_signature 0x210f #define DW_AT_GNU_template_name 0x2110 #define DW_AT_GNU_call_site_value 0x2111 #define DW_AT_GNU_call_site_data_value 0x2112 #define DW_AT_GNU_call_site_target 0x2113 #define DW_AT_GNU_call_site_target_clobbered 0x2114 #define DW_AT_GNU_tail_call 0x2115 #define DW_AT_GNU_all_tail_call_sites 0x2116 #define DW_AT_GNU_all_call_sites 0x2117 #define DW_AT_GNU_all_source_call_sites 0x2118 /* Apple extensions. */ #define DW_AT_APPLE_optimized 0x3fe1 #define DW_AT_APPLE_flags 0x3fe2 #define DW_AT_APPLE_isa 0x3fe3 #define DW_AT_APPLE_block 0x3fe4 #define DW_AT_APPLE_major_runtime_vers 0x3fe5 #define DW_AT_APPLE_runtime_class 0x3fe6 #define DW_AT_APPLE_omit_frame_ptr 0x3fe7 #define DW_AT_APPLE_property_name 0x3fe8 #define DW_AT_APPLE_property_getter 0x3fe9 #define DW_AT_APPLE_property_setter 0x3fea #define DW_AT_APPLE_property_attribute 0x3feb #define DW_AT_APPLE_objc_complete_type 0x3fec #define DW_AT_APPLE_property 0x3fed #define DW_FORM_addr 0x01 #define DW_FORM_block2 0x03 #define DW_FORM_block4 0x04 #define DW_FORM_data2 0x05 #define DW_FORM_data4 0x06 #define DW_FORM_data8 0x07 #define DW_FORM_string 0x08 #define DW_FORM_block 0x09 #define DW_FORM_block1 0x0a #define DW_FORM_data1 0x0b #define DW_FORM_flag 0x0c #define DW_FORM_sdata 0x0d #define DW_FORM_strp 0x0e #define DW_FORM_udata 0x0f #define DW_FORM_ref_addr 0x10 #define DW_FORM_ref1 0x11 #define DW_FORM_ref2 0x12 #define DW_FORM_ref4 0x13 #define DW_FORM_ref8 0x14 #define DW_FORM_ref_udata 0x15 #define DW_FORM_indirect 0x16 #define DW_FORM_sec_offset 0x17 #define DW_FORM_exprloc 0x18 #define DW_FORM_flag_present 0x19 #define DW_FORM_ref_sig8 0x20 #define DW_FORM_GNU_ref_alt 0x1f20 #define DW_FORM_GNU_strp_alt 0x1f21 #define DW_OP_addr 0x03 #define DW_OP_deref 0x06 #define DW_OP_const1u 0x08 #define DW_OP_const1s 0x09 #define DW_OP_const2u 0x0a #define DW_OP_const2s 0x0b #define DW_OP_const4u 0x0c #define DW_OP_const4s 0x0d #define DW_OP_const8u 0x0e #define DW_OP_const8s 0x0f #define DW_OP_constu 0x10 #define DW_OP_consts 0x11 #define DW_OP_dup 0x12 #define DW_OP_drop 0x13 #define DW_OP_over 0x14 #define DW_OP_pick 0x15 #define DW_OP_swap 0x16 #define DW_OP_rot 0x17 #define DW_OP_xderef 0x18 #define DW_OP_abs 0x19 #define DW_OP_and 0x1a #define DW_OP_div 0x1b #define DW_OP_minus 0x1c #define DW_OP_mod 0x1d #define DW_OP_mul 0x1e #define DW_OP_neg 0x1f #define DW_OP_not 0x20 #define DW_OP_or 0x21 #define DW_OP_plus 0x22 #define DW_OP_plus_uconst 0x23 #define DW_OP_shl 0x24 #define DW_OP_shr 0x25 #define DW_OP_shra 0x26 #define DW_OP_xor 0x27 #define DW_OP_bra 0x28 #define DW_OP_eq 0x29 #define DW_OP_ge 0x2a #define DW_OP_gt 0x2b #define DW_OP_le 0x2c #define DW_OP_lt 0x2d #define DW_OP_ne 0x2e #define DW_OP_skip 0x2f #define DW_OP_lit0 0x30 #define DW_OP_lit1 0x31 #define DW_OP_lit2 0x32 #define DW_OP_lit3 0x33 #define DW_OP_lit4 0x34 #define DW_OP_lit5 0x35 #define DW_OP_lit6 0x36 #define DW_OP_lit7 0x37 #define DW_OP_lit8 0x38 #define DW_OP_lit9 0x39 #define DW_OP_lit10 0x3a #define DW_OP_lit11 0x3b #define DW_OP_lit12 0x3c #define DW_OP_lit13 0x3d #define DW_OP_lit14 0x3e #define DW_OP_lit15 0x3f #define DW_OP_lit16 0x40 #define DW_OP_lit17 0x41 #define DW_OP_lit18 0x42 #define DW_OP_lit19 0x43 #define DW_OP_lit20 0x44 #define DW_OP_lit21 0x45 #define DW_OP_lit22 0x46 #define DW_OP_lit23 0x47 #define DW_OP_lit24 0x48 #define DW_OP_lit25 0x49 #define DW_OP_lit26 0x4a #define DW_OP_lit27 0x4b #define DW_OP_lit28 0x4c #define DW_OP_lit29 0x4d #define DW_OP_lit30 0x4e #define DW_OP_lit31 0x4f #define DW_OP_reg0 0x50 #define DW_OP_reg1 0x51 #define DW_OP_reg2 0x52 #define DW_OP_reg3 0x53 #define DW_OP_reg4 0x54 #define DW_OP_reg5 0x55 #define DW_OP_reg6 0x56 #define DW_OP_reg7 0x57 #define DW_OP_reg8 0x58 #define DW_OP_reg9 0x59 #define DW_OP_reg10 0x5a #define DW_OP_reg11 0x5b #define DW_OP_reg12 0x5c #define DW_OP_reg13 0x5d #define DW_OP_reg14 0x5e #define DW_OP_reg15 0x5f #define DW_OP_reg16 0x60 #define DW_OP_reg17 0x61 #define DW_OP_reg18 0x62 #define DW_OP_reg19 0x63 #define DW_OP_reg20 0x64 #define DW_OP_reg21 0x65 #define DW_OP_reg22 0x66 #define DW_OP_reg23 0x67 #define DW_OP_reg24 0x68 #define DW_OP_reg25 0x69 #define DW_OP_reg26 0x6a #define DW_OP_reg27 0x6b #define DW_OP_reg28 0x6c #define DW_OP_reg29 0x6d #define DW_OP_reg30 0x6e #define DW_OP_reg31 0x6f #define DW_OP_breg0 0x70 #define DW_OP_breg1 0x71 #define DW_OP_breg2 0x72 #define DW_OP_breg3 0x73 #define DW_OP_breg4 0x74 #define DW_OP_breg5 0x75 #define DW_OP_breg6 0x76 #define DW_OP_breg7 0x77 #define DW_OP_breg8 0x78 #define DW_OP_breg9 0x79 #define DW_OP_breg10 0x7a #define DW_OP_breg11 0x7b #define DW_OP_breg12 0x7c #define DW_OP_breg13 0x7d #define DW_OP_breg14 0x7e #define DW_OP_breg15 0x7f #define DW_OP_breg16 0x80 #define DW_OP_breg17 0x81 #define DW_OP_breg18 0x82 #define DW_OP_breg19 0x83 #define DW_OP_breg20 0x84 #define DW_OP_breg21 0x85 #define DW_OP_breg22 0x86 #define DW_OP_breg23 0x87 #define DW_OP_breg24 0x88 #define DW_OP_breg25 0x89 #define DW_OP_breg26 0x8a #define DW_OP_breg27 0x8b #define DW_OP_breg28 0x8c #define DW_OP_breg29 0x8d #define DW_OP_breg30 0x8e #define DW_OP_breg31 0x8f #define DW_OP_regx 0x90 #define DW_OP_fbreg 0x91 #define DW_OP_bregx 0x92 #define DW_OP_piece 0x93 #define DW_OP_deref_size 0x94 #define DW_OP_xderef_size 0x95 #define DW_OP_nop 0x96 #define DW_OP_push_object_address 0x97 #define DW_OP_call2 0x98 #define DW_OP_call4 0x99 #define DW_OP_call_ref 0x9a #define DW_OP_form_tls_address 0x9b #define DW_OP_call_frame_cfa 0x9c #define DW_OP_bit_piece 0x9d #define DW_OP_implicit_value 0x9e #define DW_OP_stack_value 0x9f #define DW_OP_lo_user 0xe0 #define DW_OP_hi_user 0xff /* GNU extensions. */ #define DW_OP_GNU_push_tls_address 0xe0 #define DW_OP_GNU_uninit 0xf0 #define DW_OP_GNU_encoded_addr 0xf1 #define DW_OP_GNU_implicit_pointer 0xf2 #define DW_OP_GNU_entry_value 0xf3 #define DW_OP_GNU_const_type 0xf4 #define DW_OP_GNU_regval_type 0xf5 #define DW_OP_GNU_deref_type 0xf6 #define DW_OP_GNU_convert 0xf7 #define DW_OP_GNU_reinterpret 0xf9 #define DW_OP_GNU_parameter_ref 0xfa #define DW_OP_GNU_addr_index 0xfb #define DW_OP_GNU_const_index 0xfc #define DW_ATE_address 0x1 #define DW_ATE_boolean 0x2 #define DW_ATE_complex_float 0x3 #define DW_ATE_float 0x4 #define DW_ATE_signed 0x5 #define DW_ATE_signed_char 0x6 #define DW_ATE_unsigned 0x7 #define DW_ATE_unsigned_char 0x8 #define DW_ATE_imaginary_float 0x9 #define DW_ATE_packed_decimal 0xa #define DW_ATE_numeric_string 0xb #define DW_ATE_edited 0xc #define DW_ATE_signed_fixed 0xd #define DW_ATE_unsigned_fixed 0xe #define DW_ATE_decimal_float 0xf #define DW_ATE_lo_user 0x80 #define DW_ATE_hi_user 0xff #define DW_ACCESS_public 0x01 #define DW_ACCESS_protected 0x02 #define DW_ACCESS_private 0x03 #define DW_END_default 0x00 #define DW_END_big 0x01 #define DW_END_little 0x02 #define DW_END_lo_user 0x40 #define DW_END_high_user 0xff #define DW_VIS_local 0x01 #define DW_VIS_exported 0x02 #define DW_VIS_qualified 0x03 #define DW_VIRTUALITY_none 0x00 #define DW_VIRTUALITY_virtual 0x01 #define DW_VIRTUALITY_pure_virtual 0x02 #define DW_LANG_C89 0x0001 #define DW_LANG_C 0x0002 #define DW_LANG_Ada83 0x0003 #define DW_LANG_C_plus_plus 0x0004 #define DW_LANG_Cobol74 0x0005 #define DW_LANG_Cobol85 0x0006 #define DW_LANG_Fortran77 0x0007 #define DW_LANG_Fortran90 0x0008 #define DW_LANG_Pascal83 0x0009 #define DW_LANG_Modula2 0x000a #define DW_LANG_Java 0x000b #define DW_LANG_C99 0x000c #define DW_LANG_Ada95 0x000d #define DW_LANG_Fortran95 0x000e #define DW_LANG_PLI 0x000f #define DW_LANG_ObjC 0x0010 #define DW_LANG_ObjC_plus_plus 0x0011 #define DW_LANG_UPC 0x0012 #define DW_LANG_D 0x0013 #define DW_LANG_Python 0x0014 #define DW_LANG_OpenCL 0x0015 #define DW_LANG_Go 0x0016 #define DW_LANG_Modula3 0x0017 #define DW_LANG_Haskell 0x0018 #define DW_LANG_C_plus_plus_03 0x0019 #define DW_LANG_C_plus_plus_11 0x001a #define DW_LANG_OCaml 0x001b #define DW_LANG_Rust 0x001c #define DW_LANG_C11 0x001d #define DW_LANG_Swift 0x001e #define DW_LANG_Julia 0x001f #define DW_LANG_Dylan 0x0020 #define DW_LANG_C_plus_plus_14 0x0021 #define DW_LANG_Fortran03 0x0022 #define DW_LANG_Fortran08 0x0023 #define DW_LANG_RenderScript 0x0024 #define DW_LANG_BLISS 0x0025 #define DW_LANG_lo_user 0x8000 #define DW_LANG_Mips_Assembler 0x8001 #define DW_LANG_hi_user 0xffff #define DW_ID_case_sensitive 0x00 #define DW_ID_up_case 0x01 #define DW_ID_down_case 0x02 #define DW_ID_case_insensitive 0x03 #define DW_CC_normal 0x01 #define DW_CC_program 0x02 #define DW_CC_nocall 0x03 #define DW_CC_lo_user 0x40 #define DW_CC_hi_user 0xff #define DW_INL_not_inlined 0x00 #define DW_INL_inlined 0x01 #define DW_INL_declared_not_inlined 0x02 #define DW_INL_declared_inlined 0x03 #define DW_ORD_row_major 0x00 #define DW_ORD_col_major 0x01 #define DW_DS_unsigned 0x01 #define DW_DS_leading_overpunch 0x02 #define DW_DS_trailing_overpunch 0x03 #define DW_DS_leading_separate 0x04 #define DW_DS_trailing_separate 0x05 #define DW_DSC_label 0x00 #define DW_DSC_range 0x01 #define DW_LNS_copy 0x01 #define DW_LNS_advance_pc 0x02 #define DW_LNS_advance_line 0x03 #define DW_LNS_set_file 0x04 #define DW_LNS_set_column 0x05 #define DW_LNS_negate_stmt 0x06 #define DW_LNS_set_basic_block 0x07 #define DW_LNS_const_add_pc 0x08 #define DW_LNS_fixed_advance_pc 0x09 #define DW_LNS_set_prologue_end 0x0a #define DW_LNS_set_epilogue_begin 0x0b #define DW_LNS_set_isa 0x0c #define DW_LNE_end_sequence 0x01 #define DW_LNE_set_address 0x02 #define DW_LNE_define_file 0x03 #define DW_LNE_lo_user 0x80 #define DW_LNE_hi_user 0xff #define DW_MACINFO_define 0x01 #define DW_MACINFO_undef 0x02 #define DW_MACINFO_start_file 0x03 #define DW_MACINFO_end_file 0x04 #define DW_MACINFO_vendor_ext 0xff #define DW_CFA_advance_loc 0x40 #define DW_CFA_offset 0x80 #define DW_CFA_restore 0xc0 #define DW_CFA_extended 0 #define DW_CFA_nop 0x00 #define DW_CFA_set_loc 0x01 #define DW_CFA_advance_loc1 0x02 #define DW_CFA_advance_loc2 0x03 #define DW_CFA_advance_loc4 0x04 #define DW_CFA_offset_extended 0x05 #define DW_CFA_restore_extended 0x06 #define DW_CFA_undefined 0x07 #define DW_CFA_same_value 0x08 #define DW_CFA_register 0x09 #define DW_CFA_remember_state 0x0a #define DW_CFA_restore_state 0x0b #define DW_CFA_def_cfa 0x0c #define DW_CFA_def_cfa_register 0x0d #define DW_CFA_def_cfa_offset 0x0e #define DW_CFA_def_cfa_expression 0x0f #define DW_CFA_expression 0x10 #define DW_CFA_offset_extended_sf 0x11 #define DW_CFA_def_cfa_sf 0x12 #define DW_CFA_def_cfa_offset_sf 0x13 #define DW_CFA_val_offset 0x14 #define DW_CFA_val_offset_sf 0x15 #define DW_CFA_val_expression 0x16 #define DW_CFA_lo_user 0x1c #define DW_CFA_high_user 0x3f /* * LSB(Linux Standard Base) extension to DWARF2. */ #define DW_EH_PE_absptr 0x00 #define DW_EH_PE_uleb128 0x01 #define DW_EH_PE_udata2 0x02 #define DW_EH_PE_udata4 0x03 #define DW_EH_PE_udata8 0x04 #define DW_EH_PE_sleb128 0x09 #define DW_EH_PE_sdata2 0x0a #define DW_EH_PE_sdata4 0x0b #define DW_EH_PE_sdata8 0x0c #define DW_EH_PE_pcrel 0x10 #define DW_EH_PE_textrel 0x20 #define DW_EH_PE_datarel 0x30 #define DW_EH_PE_funcrel 0x40 #define DW_EH_PE_aligned 0x50 #define DW_EH_PE_omit 0xff #endif /* !_DWARF_H_ */ Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_comp_dir.3 (revision 367466) @@ -1,99 +1,99 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_comp_dir.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_comp_dir.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_COMP_DIR 3 +.Os .Sh NAME .Nm dwarf_add_AT_comp_dir .Nd create and attach a DW_AT_comp_dir attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_comp_dir .Fa "Dwarf_P_Die die" .Fa "char *dir" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_comp_dir creates a .Dv DW_AT_comp_dir attribute descriptor and attaches it to the debugging information entry referenced by argument .Ar die . The created attribute will have DWARF form .Dv DW_FORM_strp . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar dir should point to a NUL-terminated string which will become the value of the created attribute. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_comp_dir returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_comp_dir returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_comp_dir can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar die or .Ar dir was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_const_value_string 3 , .Xr dwarf_add_AT_name 3 , .Xr dwarf_add_AT_producer 3 , .Xr dwarf_add_AT_string 3 , .Xr dwarf_new_die 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_const_value_string.3 (revision 367466) @@ -1,126 +1,126 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_const_value_string.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_const_value_string.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_CONST_VALUE_STRING 3 +.Os .Sh NAME .Nm dwarf_add_AT_const_value_signedint , .Nm dwarf_add_AT_const_value_string , .Nm dwarf_add_AT_const_value_unsignedint .Nd create and attach a DW_AT_const_value attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_const_value_signedint .Fa "Dwarf_P_Die die" .Fa "Dwarf_Signed value" .Fa "Dwarf_Error *err" .Fc .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_const_value_string .Fa "Dwarf_P_Die die" .Fa "char *str" .Fa "Dwarf_Error *err" .Fc .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_const_value_unsignedint .Fa "Dwarf_P_Die die" .Fa "Dwarf_Unsigned value" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions create a .Dv DW_AT_const_value attribute descriptor and attach it to the debugging information entry referenced by argument .Ar die . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Function .Fn dwarf_add_AT_const_value_signedint creates a .Dv DW_AT_const_value attribute descriptor containing the signed value specified by argument .Ar value . The created attribute descriptor will have DWARF form .Dv DW_FORM_sdata . .Pp Function .Fn dwarf_add_AT_const_value_unsignedint creates a .Dv DW_AT_const_value attribute descriptor containing the unsigned value specified by argument .Ar value . The created attribute descriptor will have DWARF form .Dv DW_FORM_udata . .Pp Function .Fn dwarf_add_AT_const_value_string creates a .Dv DW_AT_const_value attribute descriptor containing the string pointed to by the NUL-terminated argument .Ar str . The created attribute descriptor will have DWARF form .Dv DW_FORM_strp . .Pp If argument .Ar err is not NULL, it will be used by these functions to store error information in case of an error. .Sh RETURN VALUES On success, these functions return the created attribute descriptor. In case of an error, these functions return .Dv DW_DLV_BADADDR and set the argument .Ar err . .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar die or .Ar str was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during execution. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_name 3 , .Xr dwarf_add_AT_signed_const 3 , .Xr dwarf_add_AT_string 3 , .Xr dwarf_add_AT_unsigned_const 3 , .Xr dwarf_new_die 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_dataref.3 (revision 367466) @@ -1,122 +1,122 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_dataref.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_dataref.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_DATAREF 3 +.Os .Sh NAME .Nm dwarf_add_AT_dataref .Nd create an attribute descriptor for a relocatable address .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Attribute" .Fo dwarf_add_AT_dataref .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Unsigned pc_value" .Fa "Dwarf_Unsigned sym_index" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_dataref creates an attribute descriptor for a relocatable address and attaches it to the debugging information entry referenced by argument .Ar die . .Pp If flag .Dv DW_DLC_SIZE_64 is set, the address value will be 8 bytes in size and of the DWARF form .Dv DW_FORM_data8 . Otherwise, the address value will be 4 bytes in size and of the DWARF form .Dv DW_FORM_data4 . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr specifies the attribute code of the created attribute descriptor. .Pp Argument .Ar pc_value specifies the value of the relocatable address. .Pp Argument .Ar sym_index specifies the ELF symbol index of the symbol to be used for relocation. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_dataref returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_dataref returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_dataref can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar die was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_add_AT_reference 3 , .Xr dwarf_add_AT_ref_address 3 , +.Xr dwarf_add_AT_reference 3 , .Xr dwarf_add_AT_signed_const 3 , .Xr dwarf_add_AT_unsigned_const 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_flag.3 (revision 367466) @@ -1,115 +1,115 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_flag.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_flag.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_FLAG 3 +.Os .Sh NAME .Nm dwarf_add_AT_flag .Nd create and attach a flag attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_flag .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Small flag" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_flag creates an attribute descriptor belonging to the .Sq flag class, and attaches it to the debugging information entry referenced by argument .Ar die . The created attribute descriptor will have DWARF form .Dv DW_FORM_flag . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr should specify the attribute code for the new attribute descriptor. .Pp Argument .Ar flag should specify the value of the new attribute descriptor. A zero value is treated as .Sq false and a non-zero value as .Sq true . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_flag returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_flag returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_flag can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar die was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_signed_const 3 , .Xr dwarf_add_AT_unsigned_const 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_location_expr.3 (revision 367466) @@ -1,120 +1,120 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_location_expr.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_location_expr.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 5, 2011 -.Os .Dt DWARF_ADD_AT_LOCATION_EXPR 3 +.Os .Sh NAME .Nm dwarf_add_AT_location_expr .Nd create an attribute descriptor for a location expression .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Attribute" .Fo dwarf_add_AT_location_expr .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_P_Expr loc_expr" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_location_expr creates an attribute descriptor for a location expression and attaches it to the debugging information entry referenced by argument .Ar die . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr specifies the attribute code of the created attribute descriptor. .Pp Argument .Ar loc_expr should reference a location expression descriptor allocated using .Xr dwarf_new_expr 3 . .Pp The attribute created by function .Fn dwarf_add_AT_location_expr will have one of the DWARF forms .Dv DW_FORM_block , .Dv DW_FORM_block1 , .Dv DW_FORM_block2 or .Dv DW_FORM_block4 , depending on the size of the byte stream generated by the location expression descriptor referenced by argument .Ar loc_expr . .Pp If argument .Ar err is not NULL, it will be used by to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_location_expr returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_location_expr returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_location_expr can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar loc_expr was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_new_die 3 , .Xr dwarf_new_expr 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_name.3 (revision 367466) @@ -1,99 +1,99 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_name.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_name.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_NAME 3 +.Os .Sh NAME .Nm dwarf_add_AT_name .Nd create and attach a DW_AT_name attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_name .Fa "Dwarf_P_Die die" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_name creates a .Dv DW_AT_name attribute descriptor and attaches it to the debugging information entry referenced by argument .Ar die . The created attribute will have DWARF form .Dv DW_FORM_strp . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar name should point to a NUL-terminated string which will become the value of the created attribute. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_name returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_name returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_name can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar die or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of this function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_comp_dir 3 , .Xr dwarf_add_AT_const_value_string 3 , .Xr dwarf_add_AT_producer 3 , .Xr dwarf_add_AT_string 3 , .Xr dwarf_new_die 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_producer.3 (revision 367466) @@ -1,99 +1,99 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_producer.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_producer.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_PRODUCER 3 +.Os .Sh NAME .Nm dwarf_add_AT_producer .Nd create and attach a DW_AT_producer attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_producer .Fa "Dwarf_P_Die die" .Fa "char *producer" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_producer creates a .Dv DW_AT_producer attribute descriptor and attaches it to the debugging information entry referenced by argument .Ar die . The created attribute will have DWARF form .Dv DW_FORM_strp . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar producer should point to a NUL-terminated string which will become the value of the created attribute. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_producer returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_producer returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_producer can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar die or .Ar producer was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_comp_dir 3 , .Xr dwarf_add_AT_const_value_string 3 , .Xr dwarf_add_AT_name 3 , .Xr dwarf_add_AT_string 3 , .Xr dwarf_new_die 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_ref_address.3 (revision 367466) @@ -1,117 +1,117 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_ref_address.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_ref_address.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 7, 2011 -.Os .Dt DWARF_ADD_AT_REF_ADDRESS 3 +.Os .Sh NAME .Nm dwarf_add_AT_ref_address .Nd create a reference class attribute descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Attribute" .Fo dwarf_add_AT_ref_address .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Unsigned pc_value" .Fa "Dwarf_Unsigned sym_index" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_ref_address creates a .Sq reference class attribute descriptor containing a relocatable address value. The created attribute will use DWARF form .Dv DW_FORM_ref_addr . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr specifies the attribute code of the created attribute. .Pp Argument .Ar pc_value contains a relocatable address which will become the value of the created attribute. .Pp Argument .Ar sym_index should specify the ELF symbol index of the symbol to be used when relocating the address value. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_ref_address returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_ref_address returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_ref_address can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar die was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during execution. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_dataref 3 , .Xr dwarf_add_AT_reference 3 , .Xr dwarf_add_AT_signed_const 3 , .Xr dwarf_add_AT_unsigned_const 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_reference.3 (revision 367466) @@ -1,117 +1,117 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_reference.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_reference.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_REFERENCE 3 +.Os .Sh NAME .Nm dwarf_add_AT_reference .Nd create and attach an attribute that references another DIE .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Attribute" .Fo dwarf_add_AT_reference .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_P_Die ref_die" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_reference creates an attribute descriptor that references another debugging information entry in the same compilation unit. The attribute will be of DWARF form .Dv DW_FORM_ref4 or .Dv DW_FORM_ref8 depending on the target address size, and will contain the section-relative offset of the referenced debugging information entry as its value. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr should specify the attribute code of the created attribute descriptor. .Pp Argument .Ar ref_die should hold the debugging information entry descriptor that the attribute should refer to. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_reference returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_reference returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_reference can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar ref_die was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_dataref 3 , .Xr dwarf_add_AT_ref_address 3 , .Xr dwarf_add_AT_signed_const 3 , .Xr dwarf_add_AT_unsigned_const 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_signed_const.3 (revision 367466) @@ -1,131 +1,131 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_signed_const.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_signed_const.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_SIGNED_CONST 3 +.Os .Sh NAME .Nm dwarf_add_AT_signed_const , .Nm dwarf_add_AT_unsigned_const .Nd create and attach constant class attributes .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_signed_const .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Signed value" .Fa "Dwarf_Error *err" .Fc .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_unsigned_const .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Unsigned value" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions create attribute descriptors belonging to the .Sq constant class and attach them to the debugging information entry referenced by argument .Ar die . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr specifies the attribute code of the created attribute descriptor. .Pp Function .Fn dwarf_add_AT_signed_const creates an attribute descriptor with the signed value specified in argument .Ar value . .Pp Function .Fn dwarf_add_AT_unsigned_const creates an attribute descriptor with the unsigned value specified in argument .Ar value . .Pp The attribute created by these function will have one of the DWARF forms .Dv DW_FORM_data1 , .Dv DW_FORM_data2 , .Dv DW_FORM_data4 or .Dv DW_FORM_data8 , depending on the size of the value specified in argument .Ar value . .Pp If argument .Ar err is not NULL, it will be used by these functions to store error information in case of an error. .Sh RETURN VALUES On success, these functions return the created attribute descriptor. In case of an error, these functions return .Dv DW_DLV_BADADDR and set the argument .Ar err . .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar die was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during execution. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_const_value_signedint 3 , .Xr dwarf_add_AT_const_value_unsignedint 3 , .Xr dwarf_add_AT_dataref 3 , .Xr dwarf_add_AT_ref_address 3 , .Xr dwarf_add_AT_targ_address_b 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_string.3 (revision 367466) @@ -1,114 +1,114 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_string.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_string.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_STRING 3 +.Os .Sh NAME .Nm dwarf_add_AT_string .Nd create and attach a string class attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_string .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "char *str" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_string creates an attribute descriptor belonging to the .Sq string class and attaches it to the debugging information entry referenced by argument .Ar die . The created attribute descriptor will have DWARF form .Dv DW_FORM_strp . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr should specify the attribute code for the created attribute descriptor. .Pp Argument .Ar str should hold a pointer to a NUL-terminated string which will become the value of the created attribute descriptor. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_AT_string returns the created attribute descriptor. In case of an error, function .Fn dwarf_add_AT_string returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_AT_string can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar str was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_const_value_string 3 , .Xr dwarf_add_AT_name 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_AT_targ_address.3 (revision 367466) @@ -1,137 +1,137 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_AT_targ_address.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_AT_targ_address.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_ADD_AT_TARG_ADDRESS 3 +.Os .Sh NAME .Nm dwarf_add_AT_targ_address , .Nm dwarf_add_AT_targ_address_b .Nd create and attach address class attributes .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_targ_address .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Unsigned pc_value" .Fa "Dwarf_Signed sym_index" .Fa "Dwarf_Error *err" .Fc .Ft Dwarf_P_Attribute .Fo dwarf_add_AT_targ_address_b .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Unsigned pc_value" .Fa "Dwarf_Unsigned sym_index" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_AT_targ_address_b creates an attribute descriptor belonging to the .Sq address class and attaches it to the debugging information entry referenced by argument .Ar die . .Pp The created attribute descriptor will have DWARF form .Dv DW_FORM_addr . If flag .Dv DW_DLC_SIZE_64 is set on the producer instance, the attribute value will be 8 bytes in size. Otherwise the attribute value will be 4 bytes in size. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die should reference a debugging information entry allocated using .Xr dwarf_new_die 3 . .Pp Argument .Ar attr should specify the attribute code of the created attribute descriptor. .Pp Argument .Ar pc_value should hold a relocatable address value which will become the value of the created attribute descriptor. .Pp Argument .Ar sym_index should specify the ELF symbol index of the symbol to be used for relocating the address value. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_add_AT_targ_address is deprecated. It is similar to function .Fn dwarf_add_AT_targ_address_b except that it cannot handle all possible symbol index values. .Sh RETURN VALUES On success, these functions return the created attribute descriptor. In case of an error, these functions return .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar die was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during execution. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_const_value_unsignedint 3 , .Xr dwarf_add_AT_dataref 3 , .Xr dwarf_add_AT_ref_address 3 , .Xr dwarf_add_AT_signed_const 3 , .Xr dwarf_add_AT_unsigned_const 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_arange.3 (revision 367466) @@ -1,151 +1,151 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_arange.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_arange.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 18, 2011 -.Os .Dt DWARF_ADD_ARANGE 3 +.Os .Sh NAME .Nm dwarf_add_arange , .Nm dwarf_add_arange_b .Nd add address range information to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_arange .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Addr start" .Fa "Dwarf_Unsigned length" .Fa "Dwarf_Signed symbol_index" .Fa "Dwarf_Error *err" .Fc .Ft "Dwarf_Unsigned" .Fo dwarf_add_arange_b .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Addr start" .Fa "Dwarf_Unsigned length" .Fa "Dwarf_Unsigned symbol_index" .Fa "Dwarf_Unsigned end_symbol_index" .Fa "Dwarf_Addr offset_from_end_symbol" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_arange_b adds an address range entry to a producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar start specifies the relocatable start address of the address range. .Pp Argument .Ar length specifies the length of the address range. .Pp Argument .Ar symbol_index specifies the ELF symbol index of the first symbol to be used for relocation. .Pp Argument .Ar end_symbol_index specifies the ELF symbol index of the second symbol to be used for relocation. .Bl -bullet .It If argument .Ar end_symbol_index is not 0, the .Dv DW_DLC_SYMBOLIC_RELOCATIONS flag should have been set on the DWARF producer instance. The address value specified by argument .Ar start will be treated as an offset value from the first symbol, and the argument .Ar offset_from_end_symbol should hold an offset value from the second symbol. Application code can retrieve the relocation entries for the symbol pair by calling function .Xr dwarf_get_relocation_info 3 . The relocation entry for the first symbol will have type .Dv dwarf_drt_first_of_length_pair and the relocation entry for the second symbol will have type .Dv dwarf_drt_second_of_length_pair . .It If argument .Ar end_symbol_index is 0, argument .Ar offset_from_end_symbol will be ignored and only one symbol is used for relocation. .El .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_add_arange is deprecated. It is similar to function .Fn dwarf_add_arange_b except that it cannot handle all possible symbol index values and supports only one relocation symbol. .Sh RETURN VALUES On success, these functions return a non-zero value. In case of an error, these functions return 0 and set the argument .Ar err . .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_ARGUMENT Argument .Ar end_symbol_index was non-zero, but the flag .Dv DW_DLC_SYMBOLIC_RELOCATIONS was not set on the producer instance. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_relocation_info 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_die_to_debug.3 (revision 367466) @@ -1,95 +1,95 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_die_to_debug.3 2938 2013-04-27 05:09:17Z jkoshy $ +.\" $Id: dwarf_add_die_to_debug.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd August 21, 2011 -.Os .Dt DWARF_ADD_DIE_TO_DEBUG 3 +.Os .Sh NAME .Nm dwarf_add_die_to_debug .Nd set the root debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_Unsigned .Fo dwarf_add_die_to_debug .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die first_die" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_die_to_debug sets the root debugging information entry of a DWARF producer instance. All debugging information entries linked to the root entry will also be added to the producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar first_die should hold the debugging information entry which will become the root DIE. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_die_to_debug returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_add_die_to_debug returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_die_to_debug can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar first_die was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_die_link 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_directory_decl.3 (revision 367466) @@ -1,97 +1,97 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_directory_decl.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_directory_decl.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 17, 2011 -.Os .Dt DWARF_ADD_DIRECTORY_DECL 3 +.Os .Sh NAME .Nm dwarf_add_directory_decl .Nd add a directory name to a producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_directory_decl .Fa "Dwarf_P_Debug dbg" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_directory_decl adds a source directory name to a producer instance and returns the index value generated for the directory name. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar name should point a NUL-terminated string containing the name of the directory. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_directory_decl returns the index value generated for the directory. In case of an error, function .Fn dwarf_add_directory_decl returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_directory_decl can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar dbg or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_file_decl 3 , .Xr dwarf_add_line_entry 3 , .Xr dwarf_lne_end_sequence 3 , .Xr dwarf_lne_set_address 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_expr_addr.3 (revision 367466) @@ -1,111 +1,111 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_expr_addr.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_expr_addr.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 9, 2011 -.Os .Dt DWARF_ADD_EXPR_ADDR 3 +.Os .Sh NAME .Nm dwarf_add_expr_addr , .Nm dwarf_add_expr_addr_b .Nd add a DW_OP_addr location expression .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_expr_addr .Fa "Dwarf_P_Expr expr" .Fa "Dwarf_Unsigned address" .Fa "Dwarf_Signed sym_index" .Fa "Dwarf_Error *err" .Fc .Ft "Dwarf_Unsigned" .Fo dwarf_add_expr_addr_b .Fa "Dwarf_P_Expr expr" .Fa "Dwarf_Unsigned address" .Fa "Dwarf_Unsigned sym_index" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_expr_addr_b adds a .Dv DW_OP_addr location expression to the location expression descriptor referenced by argument .Ar expr . .Pp Argument .Ar expr should reference a location expression descriptor allocated using the function .Xr dwarf_new_expr 3 . .Pp Argument .Ar address specifies the operand, a relocatable address value. .Pp Argument .Ar sym_index specifies the ELF symbol index of the symbol to be used for relocation. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_add_expr_addr is deprecated. It is similar to function .Fn dwarf_add_expr_addr_b except that it cannot handle all possible symbol index values. .Sh RETURN VALUES On success, these functions return the size in bytes of the location expression byte stream generated. In case of an error, these functions return .Dv DW_DLV_NOCOUNT and set the argument .Ar err . .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar expr was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_location_expr 3 , .Xr dwarf_add_expr_gen 3 , .Xr dwarf_expr_current_offset 3 , .Xr dwarf_expr_into_block 3 , .Xr dwarf_new_expr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_expr_gen.3 (revision 367466) @@ -1,118 +1,118 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_expr_gen.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_expr_gen.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 9, 2011 -.Os .Dt DWARF_ADD_EXPR_GEN 3 +.Os .Sh NAME .Nm dwarf_add_expr_gen .Nd add an operator to a location expression descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_expr_gen .Fa "Dwarf_P_Expr expr" .Fa "Dwarf_Small opcode" .Fa "Dwarf_Unsigned val1" .Fa "Dwarf_Unsigned val2" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_expr_gen adds a location expression operator to the location expression descriptor referenced by argument .Ar expr . .Pp Argument .Ar expr should reference a location expression descriptor allocated using the function .Xr dwarf_new_expr 3 . .Pp Argument .Ar opcode specifies the operation code of the location expression operator. Valid values for this argument are those denoted by the .Dv DW_OP_ Ns * constants defined in .In libdwarf.h . .Pp To generate a .Dv DW_OP_addr operation, application code should instead use .Xr dwarf_add_expr_addr_b 3 . .Pp Argument .Ar val1 specifies the first operand of the location expression operator. .Pp Argument .Ar val2 specifies the second operand of the location expression operator. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_expr_gen returns the size in bytes of the location expression byte stream generated. In case of an error, function .Fn dwarf_add_expr_gen returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_expr_gen can fail with: .Bl -tag -width ".Bq Er DW_DLE_LOC_EXPR_BAD" .It Bq Er DW_DLE_ARGUMENT Argument .Ar expr was NULL. .It Bq Er DW_DLE_LOC_EXPR_BAD The operation code specified in argument .Ar opcode was invalid. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_location_expr 3 , .Xr dwarf_add_expr_addr 3 , .Xr dwarf_add_expr_addr_b 3 , .Xr dwarf_expr_current_offset 3 , .Xr dwarf_expr_into_block 3 , .Xr dwarf_new_expr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_fde_inst.3 (revision 367466) @@ -1,113 +1,113 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_fde_inst.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_fde_inst.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 26, 2011 -.Os .Dt DWARF_ADD_FDE_INST 3 +.Os .Sh NAME .Nm dwarf_add_fde_inst .Nd add a call frame instruction to a DWARF frame descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Fde" .Fo dwarf_add_fde_inst .Fa "Dwarf_P_Fde fde" .Fa "Dwarf_Small op" .Fa "Dwarf_Unsigned val1" .Fa "Dwarf_Unsigned val2" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_fde_inst adds a call frame instruction to the DWARF frame descriptor referenced by argument .Ar fde . .Pp Argument .Ar fde should reference a frame descriptor allocated using .Xr dwarf_new_fde 3 . .Pp Argument .Ar op specifies the operator for the frame instruction. The DWARF standard defines the set of legal values for this argument. .Pp Argument .Ar val1 specifies the first operand of the frame instruction. .Pp Argument .Ar val2 specifies the second operand of the frame instruction. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_fde_inst returns the frame descriptor given in argument .Ar fde . In case of an error, function .Fn dwarf_add_fde_inst returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_fde_inst can fail with: .Bl -tag -width ".Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR" .It Bq Er DW_DLE_ARGUMENT Argument .Ar fde was NULL. .It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR The frame instruction operator specified in argument .Ar op was invalid. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , +.Xr dwarf_add_frame_cie 3 , .Xr dwarf_add_frame_fde 3 , .Xr dwarf_add_frame_fde_b 3 , -.Xr dwarf_add_frame_cie 3 , .Xr dwarf_fde_cfa_offset 3 , .Xr dwarf_new_fde 3 .Rs .%T "The DWARF Debugging Information Format" .%V "Version 4" .%O "http://www.dwarfstd.org/" .Re Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_file_decl.3 (revision 367466) @@ -1,122 +1,122 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_file_decl.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_file_decl.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 17, 2011 -.Os .Dt DWARF_ADD_FILE_DECL 3 +.Os .Sh NAME .Nm dwarf_add_file_decl .Nd add a source file entry to a producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_file_decl .Fa "Dwarf_P_Debug dbg" .Fa "char *name" .Fa "Dwarf_Unsigned dirndx" .Fa "Dwarf_Unsigned mtime" .Fa "Dwarf_Unsigned size" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_file_decl adds a source file entry to a producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the source file. .Pp If the file name in argument .Ar name is not a fully qualified pathname, argument .Ar dirndx should specify the index of the directory where the source file resides. Otherwise, argument .Ar dirndx should be 0. Valid directory indices are those returned by the function .Xr dwarf_add_directory_decl 3 . .Pp Argument .Ar mtime specifies the time when the file was last modified. .Pp Argument .Ar size specifies the size of the file in bytes. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_file_decl returns the index value generated for the source file. In case of an error, function .Fn dwarf_add_file_decl returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_file_decl can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either arguments .Ar dbg or .Ar name was NULL. .It Bq Er DW_DLE_ARGUMENT The length of the NUL-teminated string pointed to by argument .Ar name was 0. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_directory_decl 3 , .Xr dwarf_add_line_entry 3 , .Xr dwarf_lne_end_sequence 3 , .Xr dwarf_lne_set_address 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_frame_cie.3 (revision 367466) @@ -1,124 +1,124 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_frame_cie.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_frame_cie.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 26, 2011 -.Os .Dt DWARF_ADD_FRAME_CIE 3 +.Os .Sh NAME .Nm dwarf_add_frame_cie .Nd add a call frame common information entry to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_frame_cie .Fa "Dwarf_P_Debug dbg" .Fa "char *augmenter" .Fa "Dwarf_Small caf" .Fa "Dwarf_Small daf" .Fa "Dwarf_Small ra" .Fa "Dwarf_Ptr initinst" .Fa "Dwarf_Unsigned initlen" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_frame_cie adds a DWARF call frame common information entry (CIE) to a producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar augmenter should point to a NUL-terminated augmentation string for the common information entry. .Pp Argument .Ar caf specifies the code alignment factor. .Pp Argument .Ar daf specifies the data alignment factor. .Pp Argument .Ar ra specifies the column number used for the return address register. .Pp Argument .Ar initinst should point to a byte stream containing the initial instructions for the common information entry. .Pp Argument .Ar initlen should hold the length in bytes of the byte stream pointed to by argument .Ar initinst . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_frame_cie returns the index value of the created common information entry. In case of an error, function .Fn dwarf_add_frame_cie returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_frame_cie can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_fde_inst 3 , .Xr dwarf_add_frame_fde 3 , .Xr dwarf_add_frame_fde_b 3 , .Xr dwarf_fde_cfa_offset 3 , .Xr dwarf_new_fde 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_frame_fde.3 (revision 367466) @@ -1,201 +1,201 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_frame_fde.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_frame_fde.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 26, 2011 -.Os .Dt DWARF_ADD_FRAME_FDE 3 +.Os .Sh NAME .Nm dwarf_add_frame_fde .Nd add a call frame descriptor to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_frame_fde .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Fde fde" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Unsigned cie" .Fa "Dwarf_Addr virt_addr" .Fa "Dwarf_Unsigned code_len" .Fa "Dwarf_Unsigned symbol_index" .Fa "Dwarf_Error *err" .Fc .Ft "Dwarf_Unsigned" .Fo dwarf_add_frame_fde_b .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Fde fde" .Fa "Dwarf_P_Die die" .Fa "Dwarf_Unsigned cie" .Fa "Dwarf_Addr virt_addr" .Fa "Dwarf_Unsigned code_len" .Fa "Dwarf_Unsigned symbol_index" .Fa "Dwarf_Unsigned end_symbol_index" .Fa "Dwarf_Addr offset_from_end_sym" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_frame_fde_b adds the call frame descriptor referenced by argument .Ar fde to a producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar fde should reference a frame descriptor allocated using .Xr dwarf_new_fde 3 . .Pp Argument .Ar die is ignored by this implementation of the .Lb libdwarf . .Pp Argument .Ar cie specifies the index of call frame common information entry for the frame descriptor. Valid indices are those returned by the function .Xr dwarf_add_frame_cie 3 . .Pp Argument .Ar symbol_index specifies the ELF symbol index of the first symbol to be used for relocation. .Pp The meaning of the arguments .Ar virt_addr , .Ar code_len and .Ar offset_from_end_sym depend on the value of argument .Ar end_symbol_index : .Bl -bullet .It If the argument .Ar end_symbol_index is zero, the argument .Ar virt_addr specifies the relocatable address of the start of the function associated with the frame descriptor, the argument .Ar code_len specifies the size in bytes of the machine instructions for this function, the argument .Ar symbol_index specifies the ELF symbol to be used for relocating the address in argument .Ar virt_addr , and the argument .Ar offset_from_end_symbol is ignored. .It If the argument .Ar end_symbol_index is non-zero, it specifies the ELF symbol index of the second symbol to be used for relocation. In this case, the argument .Ar virt_addr specifies an offset from the relocatable symbol specified by argument .Ar symbol_index , the argument .Ar offset_from_end_symbol should specify an offset from the symbol named by the argument .Ar end_symbol_index , and the argument .Ar code_len will be ignored. The .Dv DW_DLC_SYMBOLIC_RELOCATIONS flag should also have been set on the DWARF producer instance. .Pp Application code can retrieve the relocation entries for the symbol pair by calling function .Xr dwarf_get_relocation_info 3 . The relocation entry for the first symbol will have type .Dv dwarf_drt_first_of_length_pair and the relocation entry for the second symbol will have type .Dv dwarf_drt_second_of_length_pair . .El .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_add_frame_fde is similar to function .Fn dwarf_add_frame_fde_b except that it supports only one relocation symbol. .Sh RETURN VALUES On success, these functions return the index value for the added frame descriptor. In case of an error, these functions return .Dv DW_DLV_NOCOUNT and set the argument .Ar err . .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg or .Ar fde was NULL. .It Bq Er DW_DLE_ARGUMENT The frame descriptor referenced by argument .Ar fde did not belong to the producer instance referenced by argument .Ar dbg . .It Bq Er DW_DLE_ARGUMENT The common information entry index specified by argument .Ar cie was invalid. .It Bq Er DW_DLE_ARGUMENT Argument .Ar end_symbol_index was non-zero, but the flag .Dv DW_DLC_SYMBOLIC_RELOCATIONS was not set on the producer instance. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_fde_inst 3 , .Xr dwarf_add_frame_cie 3 , .Xr dwarf_fde_cfa_offset 3 , .Xr dwarf_get_relocation_info 3 , .Xr dwarf_new_fde 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_funcname.3 (revision 367466) @@ -1,103 +1,103 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_funcname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_funcname.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 24, 2011 -.Os .Dt DWARF_ADD_FUNCNAME 3 +.Os .Sh NAME .Nm dwarf_add_funcname .Nd add information about a static function to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_funcname .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_funcname adds information about a static function to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die specifies the debugging information entry associated with the static function. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the static function. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_funcname returns a non-zero value. In case of an error, function .Fn dwarf_add_funcname returns 0 and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_funcname can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_pubname 3 , .Xr dwarf_add_typename 3 , .Xr dwarf_add_varname 3 , .Xr dwarf_add_weakname 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_line_entry.3 (revision 367466) @@ -1,164 +1,164 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_line_entry.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_add_line_entry.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd June 30, 2013 -.Os .Dt DWARF_ADD_LINE_ENTRY 3 +.Os .Sh NAME .Nm dwarf_add_line_entry .Nd add a line number information entry to a producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_line_entry .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Unsigned filendx" .Fa "Dwarf_Addr off" .Fa "Dwarf_Unsigned lineno" .Fa "Dwarf_Signed column" .Fa "Dwarf_Bool is_stmt" .Fa "Dwarf_Bool basic_block" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_line_entry adds a line number information entry to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar filendx specifies the index of the source file that contains the source line in question. Valid source file indices are those returned by the function .Xr dwarf_add_file_decl 3 . .Pp Argument .Ar off specifies a relocatable program address. The ELF symbol to be used for relocation is set by a prior call to the function .Xr dwarf_lne_set_address 3 . .Pp Argument .Ar lineno specifies the line number of the source line. .Pp Argument .Ar column specifies the column number within the source line. .Pp If the argument .Ar is_stmt is set to true, it indicates that the instruction at the address specified by argument .Ar off is a recommended breakpoint location, i.e., the first instruction in the instruction sequence generated by the source line. .Pp If the argument .Ar basic_block is set to true, it indicates that the instruction at the address specified by argument .Ar off is the first instruction of a basic block. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_line_entry returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_add_line_entry returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_add_line_entry -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -Argument -.Ar dbg -was NULL. -.It Bq Er DW_DLE_ARGUMENT -The function -.Xr dwarf_lne_set_address 3 -was not called before calling this function. -.It Bq Er DW_DLE_MEMORY -An out of memory condition was encountered during the execution of the -function. -.El -.Sh EXAMPLE +.Sh EXAMPLES To add line number information to the producer instance, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_Error de; Dwarf_Unsigned dir, filendx; /* ... assume dbg refers to a DWARF producer instance ... */ dir = dwarf_add_directory_decl(dbg, "/home/foo", &de); if (dir == DW_DLV_NOCOUNT) errx(EXIT_FAILURE, "dwarf_add_directory_decl failed: %s", dwarf_errmsg(-1)); filendx = dwarf_add_file_decl(dbg, "bar.c", dir, 0, 1234, &de); if (filendx == DW_DLV_NOCOUNT) errx(EXIT_FAILURE, "dwarf_add_file_decl failed: %s", dwarf_errmsg(-1)); if (dwarf_lne_set_address(dbg, 0x4012b0, 12, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_lne_set_address failed: %s", dwarf_errmsg(-1)); if (dwarf_add_line_entry(dbg, filendx, 10, 258, 0, 1, 1, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_add_line_entry failed: %s", dwarf_errmsg(-1)); .Ed +.Sh ERRORS +Function +.Fn dwarf_add_line_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The function +.Xr dwarf_lne_set_address 3 +was not called before calling this function. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_directory_decl 3 , .Xr dwarf_add_file_decl 3 , .Xr dwarf_lne_end_sequence 3 , .Xr dwarf_lne_set_address 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_pubname.3 (revision 367466) @@ -1,103 +1,103 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_pubname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_pubname.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 24, 2011 -.Os .Dt DWARF_ADD_PUBNAME 3 +.Os .Sh NAME .Nm dwarf_add_pubname .Nd add information about a global object to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_pubname .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_pubname adds information about a global object to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die specifies the debugging information entry associated with the global object. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the global object. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_pubname returns a non-zero value. In case of an error, function .Fn dwarf_add_pubname returns 0 and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_pubname can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_funcname 3 , .Xr dwarf_add_typename 3 , .Xr dwarf_add_varname 3 , .Xr dwarf_add_weakname 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_typename.3 (revision 367466) @@ -1,103 +1,103 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_typename.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_typename.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 24, 2011 -.Os .Dt DWARF_ADD_TYPENAME 3 +.Os .Sh NAME .Nm dwarf_add_typename .Nd add information about a user-defined type to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_typename .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_typename adds information about a user-defined type to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die specifies the debugging information entry associated with the user-defined type. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the user-defined type. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_typename returns a non-zero value. In case of an error, function .Fn dwarf_add_typename returns 0 and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_typename can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_funcname 3 , .Xr dwarf_add_pubname 3 , .Xr dwarf_add_varname 3 , .Xr dwarf_add_weakname 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_varname.3 (revision 367466) @@ -1,103 +1,103 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_varname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_varname.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 24, 2011 -.Os .Dt DWARF_ADD_VARNAME 3 +.Os .Sh NAME .Nm dwarf_add_varname .Nd add information about a static variable to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_varname .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_varname adds information about a static variable to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die specifies the debugging information entry associated with the static variable. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the static variable. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_varname returns a non-zero value. In case of an error, function .Fn dwarf_add_varname returns 0 and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_varname can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_funcname 3 , .Xr dwarf_add_pubname 3 , .Xr dwarf_add_typename 3 , .Xr dwarf_add_weakname 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_add_weakname.3 (revision 367466) @@ -1,103 +1,103 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_add_weakname.3 2072 2011-10-27 03:26:49Z jkoshy $ +.\" $Id: dwarf_add_weakname.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 24, 2011 -.Os .Dt DWARF_ADD_WEAKNAME 3 +.Os .Sh NAME .Nm dwarf_add_weakname .Nd add information about a weak object to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_add_weakname .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_P_Die die" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_add_weakname adds information about a weak object to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar die specifies the debugging information entry associated with the weak object. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the weak object. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_add_weakname returns a non-zero value. In case of an error, function .Fn dwarf_add_weakname returns 0 and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_add_weakname can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar die or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_funcname 3 , .Xr dwarf_add_pubname 3 , .Xr dwarf_add_typename 3 , .Xr dwarf_add_varname 3 , .Xr dwarf_new_die 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_attr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_attr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_attr.3 (revision 367466) @@ -1,120 +1,121 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_attr.3 3093 2014-09-02 22:09:40Z kaiwang27 $ +.\" $Id: dwarf_attr.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 8, 2010 -.Os .Dt DWARF_ATTR 3 +.Os .Sh NAME .Nm dwarf_attr .Nd retrieve an attribute descriptor associated with a DWARF debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_attr .Fa "Dwarf_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Attribute *atp" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_attr retrieves the attribute descriptor for an attribute associated with the DWARF debugging information entry descriptor in argument .Ar die . .Pp DWARF attribute descriptors are represented by value of the opaque type .Vt Dwarf_Attribute , see .Xr dwarf 3 . .Pp Argument .Ar attr names the desired DWARF attribute. Legal values for argument .Ar attr are those denoted by the .Dv DW_AT_* constants in the DWARF specification. .Pp Argument .Ar atp points to a location into which the returned attribute descriptor will be written. The returned descriptor may then be passed to the form query functions in the .Xr dwarf 3 API set to access the data associated with the attribute. .Pp If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_attr returns -.Dv DW_DLV_OK on success. +.Dv DW_DLV_OK +on success. .Pp If the debugging information entry descriptor denoted by argument .Ar die does not contain the named attribute, the function returns .Dv DW_DLV_NO_ENTRY and sets argument .Ar err . For other errors, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_attr can fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar die or .Ar atp was NULL. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar die had no attribute corresponding to the value in argument .Ar attr . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attrlist 3 , .Xr dwarf_attroffset 3 , .Xr dwarf_hasattr 3 , .Xr dwarf_hasform 3 , .Xr dwarf_whatattr 3 , .Xr dwarf_whatform 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_attrlist.3 (revision 367466) @@ -1,146 +1,147 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_attrlist.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_attrlist.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_ATTRLIST 3 +.Os .Sh NAME .Nm dwarf_attrlist .Nd retrieve DWARF attribute descriptors .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_attrlist .Fa "Dwarf_Die die" .Fa "Dwarf_Attribute **attrbuf" .Fa "Dwarf_Signed *attrcount" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_attrlist retrieves the DWARF attribute descriptors associated with a debugging information entry descriptor in argument .Ar die . The descriptors are returned as an array of values of the opaque type .Vt Dwarf_Attribute . The data associated with each returned attribute descriptor may be queried using the form query functions in the .Xr dwarf 3 API set. .Pp Argument .Ar attrbuf points to a location that will hold a pointer to the returned array of DWARF attribute descriptors. Argument .Ar attrcount points to a location that will hold the number of descriptors in the returned array. .Pp If argument .Ar err is non-NULL, it is used to return an error descriptor in case of an error. .Ss Memory Management In the current implementation, the memory allocated for each DWARF attribute descriptor and for the returned array of descriptors is managed by the library and the application does not need to explicitly free the returned pointers. However, for compatibility with other implementations of the .Xr dwarf 3 API, the application is permitted to pass the pointers returned by to the .Fn dwarf_dealloc function. .Sh RETURN VALUES Function .Fn dwarf_attrlist returns -.Dv DW_DLV_OK on success. +.Dv DW_DLV_OK +on success. .Pp If the debugging information entry descriptor denoted by argument .Ar die does not contain any attribute, the function returns .Dv DW_DLV_NO_ENTRY and sets argument .Ar err . For other errors, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh EXAMPLES To retrieve the attribute list for a DWARF debugging information entry use: .Bd -literal -offset indent Dwarf_Die dw_die; Dwarf_Error dw_e; Dwarf_Unsigned dw_count; Dwarf_Attribute *dw_attributes; int error, i; \&... variable dw_die contains a reference to the DIE of interest ... /* Retrieve the attribute list from the DIE. */ if ((error = dwarf_attrlist(dw_die, &dw_attributes, &dw_count, &dw_e)) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_attrlist: %s", dwarf_errmsg(dw_e)); /* Process the attribute list. */ for (i = 0; i < dw_count; ++i) { /* Use the returned pointers in dw_attributes[i] here. */ } .Ed .Sh ERRORS Function .Fn dwarf_diename can fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Arguments .Ar die , .Ar attrbuf , or .Ar attrcount were NULL. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar die had no attributes. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_hasattr 3 , .Xr dwarf_hasform 3 , .Xr dwarf_whatattr 3 , .Xr dwarf_whatform 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_attroffset.3 (revision 367466) @@ -1,86 +1,86 @@ .\" Copyright (c) 2014 Kai Wang .\" 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: dwarf_attroffset.3 3115 2014-12-20 18:26:46Z jkoshy $ +.\" $Id: dwarf_attroffset.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd December 20, 2014 -.Os .Dt DWARF_ATTROFFSET 3 +.Os .Sh NAME .Nm dwarf_attroffset .Nd retrieve the section-relative offset of an attribute descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_attroffset .Fa "Dwarf_Attribute at" .Fa "Dwarf_Off *ret_off" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_attroffset retrieves the section-relative offset of the attribute descriptor referenced by argument .Ar at . .Pp Argument .Ar ret_off should point to a location that is to hold the returned section-relative offset. If argument .Ar err is non-NULL, it is used to return an error descriptor in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_attroffset returns .Dv DW_DLV_OK . .Pp In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh COMPATIBILITY This function is an extension to the .Xr DWARF 3 API. .Sh ERRORS The .Fn dwarf_attroffset function may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar at or .Ar ret_off was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_attrval_signed.3 (revision 367466) @@ -1,225 +1,225 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_attrval_signed.3 3509 2016-12-29 03:58:41Z emaste $ +.\" $Id: dwarf_attrval_signed.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd December 26, 2016 -.Os .Dt DWARF_ATTRVAL_SIGNED 3 +.Os .Sh NAME .Nm dwarf_attrval_flag , .Nm dwarf_attrval_signed , .Nm dwarf_attrval_string , .Nm dwarf_attrval_unsigned .Nd retrieve the value of an attribute within a DWARF debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_attrval_flag .Fa "Dwarf_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Bool *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_attrval_signed .Fa "Dwarf_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Signed *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_attrval_string .Fa "Dwarf_Die die" .Fa "Dwarf_Half attr" .Fa "const char **ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_attrval_unsigned .Fa "Dwarf_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Unsigned *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions search the debugging information entry referenced by argument .Ar die for the attribute named by argument .Ar attr . If the named attribute is found, the functions set the location pointed to by argument .Ar ret to the value of the attribute. The argument .Ar err , if non NULL, will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_attrval_flag sets the location pointed to by argument .Ar ret to either 0 or 1. If the form of the attribute named by argument .Ar attr is .Dv DW_FORM_flag , function .Fn dwarf_attrval_flag sets the location pointed to by argument .Ar ret to 1 if the attribute has a non-zero value, or to 0 otherwise. If the form of the attribute named by argument .Ar attr is .Dv DW_FORM_flag_present , function .Fn dwarf_attrval_flag unconditionally sets the location pointed to by argument .Ar ret to 1. The form of the attribute must be one of .Dv DW_FORM_flag or .Dv DW_FORM_flag_present . .Pp Function .Fn dwarf_attrval_signed stores the value for the attribute named by argument .Ar attr , into the location pointed to by argument .Ar ret . The attribute's value is treated as a signed integral quantity and is sign-extended as needed. The attribute named by the argument .Ar attr must belong to the .Dv CONSTANT class and must have one of the following forms: .Dv DW_FORM_data1 , .Dv DW_FORM_data2 , .Dv DW_FORM_data4 , .Dv DW_FORM_data8 or .Dv DW_FORM_sdata . .Pp Function .Fn dwarf_attrval_string sets the location pointed to by argument .Ar ret to a pointer to a NUL-terminated string that is the value of the attribute named by argument .Ar attr . The form of the attribute must be one of .Dv DW_FORM_string or .Dv DW_FORM_strp . .Pp Function .Fn dwarf_attrval_unsigned stores the value for the attribute named by argument .Ar attr into the location pointed to by argument .Ar ret . The attribute's value is treated as an unsigned integral quantity, and is zero-extended as needed. The named attribute must belong to one of the .Dv CONSTANT , .Dv ADDRESS or .Dv REFERENCE classes and must have one of the following forms: .Dv DW_FORM_addr , .Dv DW_FORM_data1 , .Dv DW_FORM_data2 , .Dv DW_FORM_data4 , .Dv DW_FORM_data8 , .Dv DW_FORM_udata , .Dv DW_FORM_ref1 , .Dv DW_FORM_ref2 , .Dv DW_FORM_ref4 , .Dv DW_FORM_ref8 , or .Dv DW_FORM_ref_udata . .Pp If the attribute named by argument .Ar attr is .Dv DW_AT_type and is not present in the debugging information entry referenced by argument .Ar die , and if a .Dv DW_AT_abstract_origin or .Dv DW_AT_specification attribute is present in the debugging information entry, function .Fn dwarf_attrval_unsigned will search for the named attribute in the debugging information entry referenced by the .Dv DW_AT_abstract_origin or .Dv DW_AT_specification attribute. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . If the named attribute was not found in the specified debugging information entry descriptor these functions return .Dv DW_DLV_NO_ENTRY and set argument .Ar err . For other errors, these functions return .Dv DW_DLV_ERROR and set argument .Ar err . .Sh COMPATIBILITY These functions are extensions added by this implementation of the DWARF(3) API. .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Va die or .Va ret was NULL. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar die did not contain an attribute corresponding to the value in argument .Ar attr . .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute named by argument .Ar attr was not of a permitted form. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_child.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_child.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_child.3 (revision 367466) @@ -1,278 +1,278 @@ .\" Copyright (c) 2010,2014 Kai Wang .\" 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: dwarf_child.3 3127 2014-12-21 19:09:19Z jkoshy $ +.\" $Id: dwarf_child.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd December 21, 2014 -.Os .Dt DWARF_CHILD 3 +.Os .Sh NAME .Nm dwarf_child , .Nm dwarf_offdie , .Nm dwarf_offdie_b , .Nm dwarf_siblingof , .Nm dwarf_siblingof_b .Nd retrieve DWARF Debugging Information Entry descriptors .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fn dwarf_child "Dwarf_Die die" "Dwarf_Die *ret_die" "Dwarf_Error *err" .Ft int .Fo dwarf_offdie .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off offset" .Fa "Dwarf_Die *ret_die" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_offdie_b .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off offset" .Fa "Dwarf_Bool is_info" .Fa "Dwarf_Die *ret_die" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_siblingof .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Die die" .Fa "Dwarf_Die *ret_die" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_siblingof_b .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Die die" .Fa "Dwarf_Die *ret_die" .Fa "Dwarf_Bool is_info" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions are used to retrieve and traverse DWARF Debugging Information Entry (DIE) descriptors associated with a compilation unit. These descriptors are arranged in the form of a tree, traversable using .Dq child and .Dq sibling links; see .Xr dwarf 3 for more information. DWARF Debugging Information Entry descriptors are represented by the .Vt Dwarf_Die opaque type. .Pp Function .Fn dwarf_child retrieves the child of descriptor denoted by argument .Ar die , and stores it in the location pointed to by argument .Ar ret_die . .Pp Function .Fn dwarf_siblingof retrieves the sibling of the descriptor denoted by argument .Ar die , and stores it in the location pointed to by argument .Ar ret_die . If argument .Ar die is NULL, the first debugging information entry descriptor for the current compilation unit will be returned. This function and function .Fn dwarf_child may be used together to traverse the tree of debugging information entry descriptors for a compilation unit. .Pp Function .Fn dwarf_siblingof_b is identical to the function .Fn dwarf_siblingof except that it can retrieve the sibling descriptor from either the current compilation unit or type unit. If argument .Ar is_info is non-zero, the function behaves identically to function .Fn dwarf_siblingof . If argument .Ar is_info is zero, the descriptor referred by argument .Ar die should be associated with a debugging information entry in the type unit. The function will store the sibling of the descriptor in the location pointed to by argument .Ar ret_die . If argument .Ar is_info is zero and argument .Ar die is .Dv NULL , the first debugging information entry descriptor for the current type unit will be returned. .Pp Function .Fn dwarf_offdie retrieves the debugging information entry descriptor at global offset .Ar offset in the .Dq .debug_info section of the object associated with argument .Ar dbg . The returned descriptor is written to the location pointed to by argument .Ar ret_die . .Pp Function .Fn dwarf_offdie_b is identical to the function .Fn dwarf_offdie except that it can retrieve the debugging information entry descriptor at global offset .Ar offset from either of the .Dq .debug_info and .Dq .debug_types sections of the object associated with argument .Ar dbg . If argument .Ar is_info is non-zero, the function will retrieve the debugging information entry from the .Dq .debug_info section, otherwise the function will retrieve the debugging information entry from the .Dq .debug_types section. The returned descriptor is written to the location pointed to by argument .Ar ret_die . .Ss Memory Management The memory area used for the .Vt Dwarf_Die descriptor returned in argument .Ar ret_die is allocated by the .Lb libdwarf . Application code should use function .Fn dwarf_dealloc with the allocation type .Dv DW_DLA_DIE to free the memory area when the .Vt Dwarf_Die descriptor is no longer needed. .Sh RETURN VALUES These functions return the following values: .Bl -tag -width ".Bq Er DW_DLV_NO_ENTRY" .It Bq Er DW_DLV_OK The call succeeded. .It Bq Er DW_DLV_ERROR The requested operation failed. Additional information about the error encountered will be recorded in argument .Ar err , if it is not NULL. .It Bq Er DW_DLV_NO_ENTRY For functions .Fn dwarf_child , .Fn dwarf_siblingof and .Fn dwarf_siblingof_b , the descriptor denoted by argument .Ar die did not have a child or sibling. .Pp For functions .Fn dwarf_offdie and .Fn dwarf_offdie_b , there was no debugging information entry at the offset specified by argument .Ar offset . .El -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width ".Bq Er DW_DLE_DIE_NO_CU_CONTEXT" -.It Bq Er DW_DLE_ARGUMENT -Arguments -.Ar dbg , -.Ar die -or -.Ar ret_die -were NULL. -.It Bq Er DW_DLE_DIE_NO_CU_CONTEXT -Argument -.Ar dbg -was not associated with a compilation unit. -.It Bq Er DW_DLE_NO_ENTRY -The descriptor denoted by argument -.Ar die -had no child or sibling, or there was no DWARF debugging information -entry at the offset specified by argument -.Va offset . -.El .Sh EXAMPLES To retrieve the first DWARF Debugging Information Entry descriptor for the first compilation unit associated with a .Vt Dwarf_Debug instance, and to traverse all its children, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Die die, die0; Dwarf_Error de; \&... allocate dbg using dwarf_init() etc ... if (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_next_cu_header: %s", dwarf_errmsg(de)); /* Get the first DIE for the current compilation unit. */ die = NULL; if (dwarf_siblingof(dbg, die, &die0, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_siblingof: %s", dwarf_errmsg(de)); /* Get the first child of this DIE. */ die = die0; if (dwarf_child(die, &die0, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_child: %s", dwarf_errmsg(de)); /* Get the rest of children. */ do { die = die0; if (dwarf_siblingof(dbg, die, &die0, &de) == DW_DLV_ERROR) errx(EXIT_FAILURE, "dwarf_siblingof: %s", dwarf_errmsg(de)); } while (die0 != NULL); .Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_DIE_NO_CU_CONTEXT" +.It Bq Er DW_DLE_ARGUMENT +Arguments +.Ar dbg , +.Ar die +or +.Ar ret_die +were NULL. +.It Bq Er DW_DLE_DIE_NO_CU_CONTEXT +Argument +.Ar dbg +was not associated with a compilation unit. +.It Bq Er DW_DLE_NO_ENTRY +The descriptor denoted by argument +.Ar die +had no child or sibling, or there was no DWARF debugging information +entry at the offset specified by argument +.Va offset . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 , -.Xr dwarf_get_die_infotypes_flag.3 , +.Xr dwarf_get_die_infotypes_flag 3 , .Xr dwarf_next_cu_header 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_dealloc.3 (revision 367466) @@ -1,203 +1,203 @@ .\" Copyright (c) 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 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: dwarf_dealloc.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_dealloc.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd July 23, 2011 -.Os .Dt DWARF_DEALLOC 3 +.Os .Sh NAME .Nm dwarf_dealloc , .Nm dwarf_fde_cie_list_dealloc , .Nm dwarf_funcs_dealloc , .Nm dwarf_globals_dealloc , .Nm dwarf_pubtypes_dealloc , .Nm dwarf_ranges_dealloc , .Nm dwarf_srclines_dealloc , .Nm dwarf_types_dealloc , .Nm dwarf_vars_dealloc , .Nm dwarf_weaks_dealloc .Nd release resources .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft void .Fo dwarf_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Ptr ptr" .Fa "Dwarf_Unsigned type" .Fc .Fo dwarf_fde_cie_list_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Cie *cie_list" .Fa "Dwarf_Signed cie_count" .Fa "Dwarf_Fde *fde_list" .Fa "Dwarf_Signed fde_count" .Fc .Ft void .Fo dwarf_funcs_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Func *funcs" .Fa "Dwarf_Signed funccount" .Fc .Ft void .Fo dwarf_globals_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Global *globals" .Fa "Dwarf_Signed globalcount" .Fc .Ft void .Fo dwarf_pubtypes_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Type *pubtypes" .Fa "Dwarf_Signed pubtypecount" .Fc .Ft void .Fo dwarf_ranges_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Ranges *ranges" .Fa "Dwarf_Signed rangecount" .Fc .Ft void .Fo dwarf_srclines_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Line *lines" .Fa "Dwarf_Signed linecount" .Fc .Ft void .Fo dwarf_types_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Type *types" .Fa "Dwarf_Signed typecount" .Fc .Ft void .Fo dwarf_vars_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Var *vars" .Fa "Dwarf_Signed varcount" .Fc .Ft void .Fo dwarf_weaks_dealloc .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Weak *weaks" .Fa "Dwarf_Signed weakcount" .Fc .Sh DESCRIPTION The function .Fn dwarf_dealloc is used by applications to indicate that memory areas returned by .Lb libdwarf may be safely disposed off. Due to the way memory is managed in the current implementation, the use of .Fn dwarf_dealloc is only necessary for a small set of DWARF types. .Pp Argument .Ar dbg should reference a valid debugging context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar ptr should point to an object or memory area obtained by a prior call to a DWARF(3) function. .Pp Argument .Ar type indicates the type of object being deallocated. The indicated type must match that of the object being passed in argument .Ar ptr . Valid values for the .Ar type argument are: .Bl -tag -width ".Dv DW_DLA_FRAME_BLOCK" .It Dv DW_DLA_ABBREV An object of type .Vt Dwarf_Abbrev , as returned by a call to the function .Xr dwarf_get_abbrev 3 . .It Dv DW_DLA_DIE An object of type .Vt Dwarf_Die , as returned by calls to the functions .Xr dwarf_child 3 , .Xr dwarf_offdie 3 or .Xr dwarf_siblingof 3 . .It Dv DW_DLA_FRAME_BLOCK An array of objects of type .Vt Dwarf_Frame_op , as returned by a call to the function .Xr dwarf_expand_frame_instructions 3 . .El .Pp Calls to .Fn dwarf_dealloc with other values for argument .Ar type are no-ops in this implementation. .Pp The functions .Fn dwarf_fde_cie_list_dealloc , .Fn dwarf_funcs_dealloc , .Fn dwarf_globals_dealloc , .Fn dwarf_pubtypes_dealloc , .Fn dwarf_ranges_dealloc , .Fn dwarf_srclines_dealloc , .Fn dwarf_types_dealloc , .Fn dwarf_vars_dealloc and .Fn dwarf_weaks_dealloc are provided for compatibility with other implementations of the DWARF(3) API. Due to the way memory is managed in the current implementation, these functions are effectively no-ops. .Pp See .Xr dwarf 3 for more information about the memory management scheme in this implementation of the DWARF(3) API. .Sh RETURN VALUES Functions .Fn dwarf_dealloc , .Fn dwarf_fde_cie_list_dealloc , .Fn dwarf_funcs_dealloc , .Fn dwarf_globals_dealloc , .Fn dwarf_pubtypes_dealloc , .Fn dwarf_ranges_dealloc , .Fn dwarf_srclines_dealloc , .Fn dwarf_types_dealloc , .Fn dwarf_vars_dealloc and .Fn dwarf_weaks_dealloc have no return value. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_child 3 , .Xr dwarf_expand_frame_instructions 3 , .Xr dwarf_get_abbrev 3 , .Xr dwarf_offdie 3 , .Xr dwarf_siblingof 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_def_macro.3 (revision 367466) @@ -1,129 +1,129 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_def_macro.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_def_macro.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_DEF_MACRO 3 +.Os .Sh NAME .Nm dwarf_def_macro .Nd add a macro definition to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "int" .Fo dwarf_def_macro .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Unsigned lineno" .Fa "char *name" .Fa "char *value" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_def_macro adds a macro definition to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar lineno specifies the line number of the source line where the macro is defined. A line number of zero is used for macros that are defined before any source file is read. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the macro. For function-like macros this parameter should also include parentheses and parameter names if any. .Pp Argument .Ar value should point to a NUL-terminated string containing the value of the macro. If the macro does not have a value, argument .Ar value should be set to NULL. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_def_macro returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_def_macro returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh EXAMPLE +.Sh EXAMPLES To record the fact that a macro named .Dv _STDIO_H_ was defined at line 20 of the current macro file, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_Error de; /* ... Assume 'dbg' refers to a DWARF producer instance... */ if (dwarf_def_macro(dbg, 20, "_STDIO_H_", NULL, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_def_macro failed: %s", dwarf_errmsg(-1)); .Ed .Sh ERRORS Function .Fn dwarf_def_macro can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either arguments .Ar dbg or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_end_macro_file 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_start_macro_file 3 , .Xr dwarf_undef_macro 3 , .Xr dwarf_vendor_ext 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_die_abbrev_code.3 (revision 367466) @@ -1,55 +1,55 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_die_abbrev_code.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_die_abbrev_code.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 14, 2010 -.Os .Dt DWARF_DIE_ABBREV_CODE 3 +.Os .Sh NAME .Nm dwarf_die_abbrev_code .Nd retrieve the abbreviation code for a DWARF debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fn dwarf_die_abbrev_code "Dwarf_Die die" .Sh DESCRIPTION Function .Fn dwarf_die_abbrev_code returns the abbreviation code for the debugging information entry descriptor referenced by argument .Ar die . Argument .Ar die should be a valid pointer to a value of type .Vt Dwarf_Die . .Sh RETURN VALUES The function returns an integral value. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_diename 3 , .Xr dwarf_dieoffset 3 , .Xr dwarf_tag 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_die_link.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_die_link.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_die_link.3 (revision 367466) @@ -1,118 +1,118 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_die_link.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_die_link.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_DIE_LINK 3 +.Os .Sh NAME .Nm dwarf_die_link .Nd link a debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Die .Fo dwarf_die_link .Fa "Dwarf_P_Die die" .Fa "Dwarf_P_Die parent" .Fa "Dwarf_P_Die child" .Fa "Dwarf_P_Die left" .Fa "Dwarf_P_Die right" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_die_link links debugging information entries together. .Pp Argument .Ar die should specify the debugging information entry to be updated. .Pp Argument .Ar parent specifies the new parent link for the debugging information entry. .Pp Argument .Ar child specifies the new first child link for the debugging information entry. .Pp Argument .Ar left specifies the new left sibling link for the debugging information entry. .Pp Argument .Ar right specifies the new right sibling link for the debugging information entry. .Pp Only one of arguments .Ar parent , .Ar child , .Ar left and .Ar right is allowed to be non-NULL. Existing links to parent, child, left or right debugging information entries, if any, will be unlinked before the specified link is established. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_die_link returns the debugging information entry provided in argument .Ar die . In case of an error, function .Fn dwarf_die_link returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS The function .Fn dwarf_die_link can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar die was NULL. .It Bq Er DW_DLE_ARGUMENT More than one of the arguments .Ar parent , .Ar child , .Ar left and .Ar right were non-NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_die_to_debug 3 , .Xr dwarf_new_die 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_diename.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_diename.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_diename.3 (revision 367466) @@ -1,90 +1,91 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_diename.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_diename.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd March 31, 2010 -.Os .Dt DWARF_DIENAME 3 +.Os .Sh NAME .Nm dwarf_diename .Nd retrieve the name associated with a debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fn dwarf_diename "Dwarf_Die die" "char **ret_name" "Dwarf_Error *err" .Sh DESCRIPTION Function .Fn dwarf_diename retrieves a pointer to the NUL-terminated string associated with the .Dv DW_AT_name attribute of the debugging information entry descriptor referenced by argument .Ar die . If the pointer was successfully retrieved, it is stored in the location pointed to by argument .Ar ret_name . .Sh RETURN VALUES Function .Fn dwarf_diename returns -.Dv DW_DLV_OK on success. +.Dv DW_DLV_OK +on success. .Pp If the debugging information entry descriptor denoted by argument .Ar die does not contain a .Dv DW_AT_name attribute, the function returns .Dv DW_DLV_NO_ENTRY and sets argument .Ar err . For other errors, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_diename can fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar die or .Ar ret_name was NULL. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar die had no .Dv DW_AT_name attribute. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_tag 3 , +.Xr dwarf_die_abbrev_code 3 , .Xr dwarf_dieoffset 3 , -.Xr dwarf_die_abbrev_code 3 +.Xr dwarf_tag 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_dieoffset.3 (revision 367466) @@ -1,206 +1,206 @@ .\" Copyright (c) 2010,2014 Kai Wang .\" 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: dwarf_dieoffset.3 3129 2014-12-21 20:06:26Z jkoshy $ +.\" $Id: dwarf_dieoffset.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd December 21, 2014 -.Os .Dt DWARF_DIEOFFSET 3 +.Os .Sh NAME .Nm dwarf_die_CU_offset , .Nm dwarf_die_CU_offset_range , .Nm dwarf_dieoffset , .Nm dwarf_get_cu_die_offset_given_cu_header_offset , .Nm dwarf_get_cu_die_offset_given_cu_header_offset_b .Nd return offsets of DWARF debugging information entries .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_die_CU_offset .Fa "Dwarf_Die die" .Fa "Dwarf_Off *ret_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_die_CU_offset_range .Fa "Dwarf_Die die" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Off *cu_length" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_dieoffset .Fa "Dwarf_Die die" .Fa "Dwarf_Off *ret_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_get_cu_die_offset_given_cu_header_offset .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off in_cu_header_offset" .Fa "Dwarf_Off *out_cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_get_cu_die_offset_given_cu_header_offset_b .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off in_cu_header_offset" .Fa "Dwarf_Bool is_info" .Fa "Dwarf_Off *out_cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions are used to retrieve offsets for DWARF debugging information entries. .Pp Function .Fn dwarf_die_CU_offset returns the offset of the debugging information entry referenced by argument .Ar die relative to the start of its containing compilation unit. Argument .Ar ret_offset should point to the location that is to hold the returned offset. If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_die_CU_offset_range returns the section-relative offset and length of the compilation unit containing the debugging information entry referenced by argument .Ar die . Argument .Ar cu_offset should point to a location that will hold the returned offset. Argument .Ar cu_length should point to a location that will hold the returned length of the compilation unit. If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_dieoffset retrieves the section-relative offset of the debugging information entry referenced by argument .Ar die . Argument .Ar ret_offset should point to a location that is to hold the returned section-relative offset. If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset returns the offset for the first debugging information entry for a compilation unit, given an offset to the header of the compilation unit. Argument .Ar dbg should reference a valid debugging context allocated using .Xr dwarf_init 3 . Argument .Ar in_cu_header_offset contains the offset to the start of a compilation unit. Argument .Ar out_cu_die_offset points to a location that will hold the returned offset. If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset_b behaves identically to the function .Fn dwarf_get_cu_die_offset_given_cu_header_offset when the argument .Ar is_info is non-zero. When the argument .Ar is_info is zero, function .Fn dwarf_get_cu_die_offset_given_cu_header_offset_b returns the offset for the first debugging information entry for a type unit, given an offset to the header of the type unit in argument .Ar in_cu_header_offset . Argument .Ar out_cu_die_offset points to a location that will hold the returned offset. If the argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES On success, these functions return .Dv DW_DLV_OK . In case of an error, these functions return .Dv DW_DLV_ERROR and set argument .Ar err . .Pp Function .Fn dwarf_get_cu_die_offset_given_cu_header_offset and .Fn dwarf_get_cu_die_offset_given_cu_header_offset_b returns .Dv DW_DLV_NO_ENTRY and sets argument .Ar err if there is no compilation or type unit located at the offset specified in argument .Ar in_cu_header_offset . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_length , .Va cu_offset , .Va dbg , .Va die , .Va out_cu_die_offset or .Va ret_offset was NULL. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar in_cu_header_offset specified an unknown offset. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_next_cu_header 3 , .Xr dwarf_offdie 3 , .Xr dwarf_offdie_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_dump.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_dump.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_dump.c (revision 367466) @@ -1,1482 +1,1482 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) * Copyright (c) 2009 Kai Wang * 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 "_libdwarf.h" -ELFTC_VCSID("$Id: dwarf_dump.c 3494 2016-09-20 17:16:13Z emaste $"); +ELFTC_VCSID("$Id: dwarf_dump.c 3749 2019-06-28 01:10:44Z emaste $"); int dwarf_get_ACCESS_name(unsigned access, const char **s) { assert(s != NULL); switch (access) { case DW_ACCESS_public: *s = "DW_ACCESS_public"; break; case DW_ACCESS_protected: *s = "DW_ACCESS_protected"; break; case DW_ACCESS_private: *s = "DW_ACCESS_private"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_AT_name(unsigned attr, const char **s) { assert(s != NULL); switch (attr) { case DW_AT_abstract_origin: *s = "DW_AT_abstract_origin"; break; case DW_AT_accessibility: *s = "DW_AT_accessibility"; break; case DW_AT_address_class: *s = "DW_AT_address_class"; break; case DW_AT_artificial: *s = "DW_AT_artificial"; break; case DW_AT_allocated: *s = "DW_AT_allocated"; break; case DW_AT_associated: *s = "DW_AT_associated"; break; case DW_AT_base_types: *s = "DW_AT_base_types"; break; case DW_AT_binary_scale: *s = "DW_AT_binary_scale"; break; case DW_AT_bit_offset: *s = "DW_AT_bit_offset"; break; case DW_AT_bit_size: *s = "DW_AT_bit_size"; break; case DW_AT_bit_stride: *s = "DW_AT_bit_stride"; break; case DW_AT_byte_size: *s = "DW_AT_byte_size"; break; case DW_AT_byte_stride: *s = "DW_AT_byte_stride"; break; case DW_AT_calling_convention: *s = "DW_AT_calling_convention"; break; case DW_AT_common_reference: *s = "DW_AT_common_reference"; break; case DW_AT_comp_dir: *s = "DW_AT_comp_dir"; break; case DW_AT_const_expr: *s = "DW_AT_const_expr"; break; case DW_AT_const_value: *s = "DW_AT_const_value"; break; case DW_AT_containing_type: *s = "DW_AT_containing_type"; break; case DW_AT_count: *s = "DW_AT_count"; break; case DW_AT_call_column: *s = "DW_AT_call_column"; break; case DW_AT_call_file: *s = "DW_AT_call_file"; break; case DW_AT_call_line: *s = "DW_AT_call_line"; break; case DW_AT_data_bit_offset: *s = "DW_AT_data_bit_offset"; break; case DW_AT_data_location: *s = "DW_AT_data_location"; break; case DW_AT_data_member_location: *s = "DW_AT_data_member_location"; break; case DW_AT_decl_column: *s = "DW_AT_decl_column"; break; case DW_AT_decl_file: *s = "DW_AT_decl_file"; break; case DW_AT_decl_line: *s = "DW_AT_decl_line"; break; case DW_AT_declaration: *s = "DW_AT_declaration"; break; case DW_AT_default_value: *s = "DW_AT_default_value"; break; case DW_AT_decimal_scale: *s = "DW_AT_decimal_scale"; break; case DW_AT_decimal_sign: *s = "DW_AT_decimal_sign"; break; case DW_AT_description: *s = "DW_AT_description"; break; case DW_AT_digit_count: *s = "DW_AT_digit_count"; break; case DW_AT_discr: *s = "DW_AT_discr"; break; case DW_AT_discr_list: *s = "DW_AT_discr_list"; break; case DW_AT_discr_value: *s = "DW_AT_discr_value"; break; case DW_AT_element_list: *s = "DW_AT_element_list"; break; case DW_AT_encoding: *s = "DW_AT_encoding"; break; case DW_AT_enum_class: *s = "DW_AT_enum_class"; break; case DW_AT_external: *s = "DW_AT_external"; break; case DW_AT_entry_pc: *s = "DW_AT_entry_pc"; break; case DW_AT_extension: *s = "DW_AT_extension"; break; case DW_AT_explicit: *s = "DW_AT_explicit"; break; case DW_AT_endianity: *s = "DW_AT_endianity"; break; case DW_AT_elemental: *s = "DW_AT_elemental"; break; case DW_AT_frame_base: *s = "DW_AT_frame_base"; break; case DW_AT_friend: *s = "DW_AT_friend"; break; case DW_AT_high_pc: *s = "DW_AT_high_pc"; break; case DW_AT_hi_user: *s = "DW_AT_hi_user"; break; case DW_AT_identifier_case: *s = "DW_AT_identifier_case"; break; case DW_AT_import: *s = "DW_AT_import"; break; case DW_AT_inline: *s = "DW_AT_inline"; break; case DW_AT_is_optional: *s = "DW_AT_is_optional"; break; case DW_AT_language: *s = "DW_AT_language"; break; case DW_AT_linkage_name: *s = "DW_AT_linkage_name"; break; case DW_AT_lo_user: *s = "DW_AT_lo_user"; break; case DW_AT_location: *s = "DW_AT_location"; break; case DW_AT_low_pc: *s = "DW_AT_low_pc"; break; case DW_AT_lower_bound: *s = "DW_AT_lower_bound"; break; case DW_AT_macro_info: *s = "DW_AT_macro_info"; break; case DW_AT_main_subprogram: *s = "DW_AT_main_subprogram"; break; case DW_AT_mutable: *s = "DW_AT_mutable"; break; case DW_AT_member: *s = "DW_AT_member"; break; case DW_AT_name: *s = "DW_AT_name"; break; case DW_AT_namelist_item: *s = "DW_AT_namelist_item"; break; case DW_AT_ordering: *s = "DW_AT_ordering"; break; case DW_AT_object_pointer: *s = "DW_AT_object_pointer"; break; case DW_AT_priority: *s = "DW_AT_priority"; break; case DW_AT_producer: *s = "DW_AT_producer"; break; case DW_AT_prototyped: *s = "DW_AT_prototyped"; break; case DW_AT_picture_string: *s = "DW_AT_picture_string"; break; case DW_AT_pure: *s = "DW_AT_pure"; break; case DW_AT_return_addr: *s = "DW_AT_return_addr"; break; case DW_AT_ranges: *s = "DW_AT_ranges"; break; case DW_AT_recursive: *s = "DW_AT_recursive"; break; case DW_AT_segment: *s = "DW_AT_segment"; break; case DW_AT_sibling: *s = "DW_AT_sibling"; break; case DW_AT_signature: *s = "DW_AT_signature"; break; case DW_AT_specification: *s = "DW_AT_specification"; break; case DW_AT_start_scope: *s = "DW_AT_start_scope"; break; case DW_AT_static_link: *s = "DW_AT_static_link"; break; case DW_AT_stmt_list: *s = "DW_AT_stmt_list"; break; case DW_AT_string_length: *s = "DW_AT_string_length"; break; case DW_AT_subscr_data: *s = "DW_AT_subscr_data"; break; case DW_AT_small: *s = "DW_AT_small"; break; case DW_AT_type: *s = "DW_AT_type"; break; case DW_AT_trampoline: *s = "DW_AT_trampoline"; break; case DW_AT_threads_scaled: *s = "DW_AT_threads_scaled"; break; case DW_AT_upper_bound: *s = "DW_AT_upper_bound"; break; case DW_AT_use_location: *s = "DW_AT_use_location"; break; case DW_AT_use_UTF8: *s = "DW_AT_use_UTF8"; break; case DW_AT_variable_parameter: *s = "DW_AT_variable_parameter"; break; case DW_AT_virtuality: *s = "DW_AT_virtuality"; break; case DW_AT_visibility: *s = "DW_AT_visibility"; break; case DW_AT_vtable_elem_location: *s = "DW_AT_vtable_elem_location"; break; case DW_AT_sf_names: *s = "DW_AT_sf_names"; break; case DW_AT_src_info: *s = "DW_AT_src_info"; break; case DW_AT_mac_info: *s = "DW_AT_mac_info"; break; case DW_AT_src_coords: *s = "DW_AT_src_coords"; break; case DW_AT_body_begin: *s = "DW_AT_body_begin"; break; case DW_AT_body_end: *s = "DW_AT_body_end"; break; case DW_AT_MIPS_fde: *s = "DW_AT_MIPS_fde"; break; case DW_AT_MIPS_loop_begin: *s = "DW_AT_MIPS_loop_begin"; break; case DW_AT_MIPS_tail_loop_begin: *s = "DW_AT_MIPS_tail_loop_begin"; break; case DW_AT_MIPS_epilog_begin: *s = "DW_AT_MIPS_epilog_begin"; break; case DW_AT_MIPS_loop_unroll_factor: *s = "DW_AT_MIPS_loop_unroll_factor"; break; case DW_AT_MIPS_software_pipeline_depth: *s = "DW_AT_MIPS_software_pipeline_depth"; break; case DW_AT_MIPS_linkage_name: *s = "DW_AT_MIPS_linkage_name"; break; case DW_AT_MIPS_stride: *s = "DW_AT_MIPS_stride"; break; case DW_AT_MIPS_abstract_name: *s = "DW_AT_MIPS_abstract_name"; break; case DW_AT_MIPS_clone_origin: *s = "DW_AT_MIPS_clone_origin"; break; case DW_AT_MIPS_has_inlines: *s = "DW_AT_MIPS_has_inlines"; break; case DW_AT_MIPS_stride_byte: *s = "DW_AT_MIPS_stride_byte"; break; case DW_AT_MIPS_stride_elem: *s = "DW_AT_MIPS_stride_elem"; break; case DW_AT_MIPS_ptr_dopetype: *s = "DW_AT_MIPS_ptr_dopetype"; break; case DW_AT_MIPS_allocatable_dopetype: *s = "DW_AT_MIPS_allocatable_dopetype"; break; case DW_AT_MIPS_assumed_shape_dopetype: *s = "DW_AT_MIPS_assumed_shape_dopetype"; break; case DW_AT_MIPS_assumed_size: *s = "DW_AT_MIPS_assumed_size"; break; case DW_AT_GNU_vector: *s = "DW_AT_GNU_vector"; break; case DW_AT_GNU_guarded_by: *s = "DW_AT_GNU_guarded_by"; break; case DW_AT_GNU_pt_guarded_by: *s = "DW_AT_GNU_pt_guarded_by"; break; case DW_AT_GNU_guarded: *s = "DW_AT_GNU_guarded"; break; case DW_AT_GNU_pt_guarded: *s = "DW_AT_GNU_pt_guarded"; break; case DW_AT_GNU_locks_excluded: *s = "DW_AT_GNU_locks_excluded"; break; case DW_AT_GNU_exclusive_locks_required: *s = "DW_AT_GNU_exclusive_locks_required"; break; case DW_AT_GNU_shared_locks_required: *s = "DW_AT_GNU_shared_locks_required"; break; case DW_AT_GNU_odr_signature: *s = "DW_AT_GNU_odr_signature"; break; case DW_AT_GNU_template_name: *s = "DW_AT_GNU_template_name"; break; case DW_AT_GNU_call_site_value: *s = "DW_AT_GNU_call_site_value"; break; case DW_AT_GNU_call_site_data_value: *s = "DW_AT_GNU_call_site_data_value"; break; case DW_AT_GNU_call_site_target: *s = "DW_AT_GNU_call_site_target"; break; case DW_AT_GNU_call_site_target_clobbered: *s = "DW_AT_GNU_call_site_target_clobbered"; break; case DW_AT_GNU_tail_call: *s = "DW_AT_GNU_tail_call"; break; case DW_AT_GNU_all_tail_call_sites: *s = "DW_AT_GNU_all_tail_call_sites"; break; case DW_AT_GNU_all_call_sites: *s = "DW_AT_GNU_all_call_sites"; break; case DW_AT_GNU_all_source_call_sites: *s = "DW_AT_GNU_all_source_call_sites"; break; case DW_AT_APPLE_optimized: *s = "DW_AT_APPLE_optimized"; break; case DW_AT_APPLE_flags: *s = "DW_AT_APPLE_flags"; break; case DW_AT_APPLE_isa: *s = "DW_AT_APPLE_isa"; break; case DW_AT_APPLE_block: *s = "DW_AT_APPLE_block"; break; case DW_AT_APPLE_major_runtime_vers: *s = "DW_AT_APPLE_major_runtime_vers"; break; case DW_AT_APPLE_runtime_class: *s = "DW_AT_APPLE_runtime_class"; break; case DW_AT_APPLE_omit_frame_ptr: *s = "DW_AT_APPLE_omit_frame_ptr"; break; case DW_AT_APPLE_property_name: *s = "DW_AT_APPLE_property_name"; break; case DW_AT_APPLE_property_getter: *s = "DW_AT_APPLE_property_getter"; break; case DW_AT_APPLE_property_setter: *s = "DW_AT_APPLE_property_setter"; break; case DW_AT_APPLE_property_attribute: *s = "DW_AT_APPLE_property_attribute"; break; case DW_AT_APPLE_objc_complete_type: *s = "DW_AT_APPLE_objc_complete_type"; break; case DW_AT_APPLE_property: *s = "DW_AT_APPLE_property"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_ATE_name(unsigned ate, const char **s) { assert(s != NULL); switch(ate) { case DW_ATE_address: *s = "DW_ATE_address"; break; case DW_ATE_boolean: *s = "DW_ATE_boolean"; break; case DW_ATE_complex_float: *s = "DW_ATE_complex_float"; break; case DW_ATE_float: *s = "DW_ATE_float"; break; case DW_ATE_signed: *s = "DW_ATE_signed"; break; case DW_ATE_signed_char: *s = "DW_ATE_signed_char"; break; case DW_ATE_unsigned: *s = "DW_ATE_unsigned"; break; case DW_ATE_unsigned_char: *s = "DW_ATE_unsigned_char"; break; case DW_ATE_imaginary_float: *s = "DW_ATE_imaginary_float"; break; case DW_ATE_packed_decimal: *s = "DW_ATE_packed_decimal"; break; case DW_ATE_numeric_string: *s = "DW_ATE_numeric_string"; break; case DW_ATE_edited: *s = "DW_ATE_edited"; break; case DW_ATE_signed_fixed: *s = "DW_ATE_signed_fixed"; break; case DW_ATE_unsigned_fixed: *s = "DW_ATE_unsigned_fixed"; break; case DW_ATE_decimal_float: *s = "DW_ATE_decimal_float"; break; case DW_ATE_lo_user: *s = "DW_ATE_lo_user"; break; case DW_ATE_hi_user: *s = "DW_ATE_hi_user"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_CC_name(unsigned cc, const char **s) { assert(s != NULL); switch (cc) { case DW_CC_normal: *s = "DW_CC_normal"; break; case DW_CC_program: *s = "DW_CC_program"; break; case DW_CC_nocall: *s = "DW_CC_nocall"; break; case DW_CC_lo_user: *s = "DW_CC_lo_user"; break; case DW_CC_hi_user: *s = "DW_CC_hi_user"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_CFA_name(unsigned cfa, const char **s) { assert(s != NULL); switch (cfa) { case DW_CFA_advance_loc: *s = "DW_CFA_advance_loc"; break; case DW_CFA_offset: *s = "DW_CFA_offset"; break; case DW_CFA_restore: *s = "DW_CFA_restore"; break; case DW_CFA_nop: *s = "DW_CFA_nop"; break; case DW_CFA_set_loc: *s = "DW_CFA_set_loc"; break; case DW_CFA_advance_loc1: *s = "DW_CFA_advance_loc1"; break; case DW_CFA_advance_loc2: *s = "DW_CFA_advance_loc2"; break; case DW_CFA_advance_loc4: *s = "DW_CFA_advance_loc4"; break; case DW_CFA_offset_extended: *s = "DW_CFA_offset_extended"; break; case DW_CFA_restore_extended: *s = "DW_CFA_restore_extended"; break; case DW_CFA_undefined: *s = "DW_CFA_undefined"; break; case DW_CFA_same_value: *s = "DW_CFA_same_value"; break; case DW_CFA_register: *s = "DW_CFA_register"; break; case DW_CFA_remember_state: *s = "DW_CFA_remember_state"; break; case DW_CFA_restore_state: *s = "DW_CFA_restore_state"; break; case DW_CFA_def_cfa: *s = "DW_CFA_def_cfa"; break; case DW_CFA_def_cfa_register: *s = "DW_CFA_def_cfa_register"; break; case DW_CFA_def_cfa_offset: *s = "DW_CFA_def_cfa_offset"; break; case DW_CFA_def_cfa_expression: *s = "DW_CFA_def_cfa_expression"; break; case DW_CFA_expression: *s = "DW_CFA_expression"; break; case DW_CFA_offset_extended_sf: *s = "DW_CFA_offset_extended_sf"; break; case DW_CFA_def_cfa_sf: *s = "DW_CFA_def_cfa_sf"; break; case DW_CFA_def_cfa_offset_sf: *s = "DW_CFA_def_cfa_offset_sf"; break; case DW_CFA_val_offset: *s = "DW_CFA_val_offset"; break; case DW_CFA_val_offset_sf: *s = "DW_CFA_val_offset_sf"; break; case DW_CFA_val_expression: *s = "DW_CFA_val_expression"; break; case DW_CFA_lo_user: *s = "DW_CFA_lo_user"; break; case DW_CFA_high_user: *s = "DW_CFA_high_user"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_CHILDREN_name(unsigned children, const char **s) { assert(s != NULL); switch (children) { case DW_CHILDREN_no: *s = "DW_CHILDREN_no"; break; case DW_CHILDREN_yes: *s = "DW_CHILDREN_yes"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_FORM_name(unsigned form, const char **s) { assert(s != NULL); switch (form) { case DW_FORM_addr: *s = "DW_FORM_addr"; break; case DW_FORM_block: *s = "DW_FORM_block"; break; case DW_FORM_block1: *s = "DW_FORM_block1"; break; case DW_FORM_block2: *s = "DW_FORM_block2"; break; case DW_FORM_block4: *s = "DW_FORM_block4"; break; case DW_FORM_data1: *s = "DW_FORM_data1"; break; case DW_FORM_data2: *s = "DW_FORM_data2"; break; case DW_FORM_data4: *s = "DW_FORM_data4"; break; case DW_FORM_data8: *s = "DW_FORM_data8"; break; case DW_FORM_exprloc: *s = "DW_FORM_exprloc"; break; case DW_FORM_flag: *s = "DW_FORM_flag"; break; case DW_FORM_flag_present: *s = "DW_FORM_flag_present"; break; case DW_FORM_indirect: *s = "DW_FORM_indirect"; break; case DW_FORM_ref1: *s = "DW_FORM_ref1"; break; case DW_FORM_ref2: *s = "DW_FORM_ref2"; break; case DW_FORM_ref4: *s = "DW_FORM_ref4"; break; case DW_FORM_ref8: *s = "DW_FORM_ref8"; break; case DW_FORM_ref_addr: *s = "DW_FORM_ref_addr"; break; case DW_FORM_ref_sig8: *s = "DW_FORM_ref_sig8"; break; case DW_FORM_ref_udata: *s = "DW_FORM_ref_udata"; break; case DW_FORM_sdata: *s = "DW_FORM_sdata"; break; case DW_FORM_sec_offset: *s = "DW_FORM_sec_offset"; break; case DW_FORM_string: *s = "DW_FORM_string"; break; case DW_FORM_strp: *s = "DW_FORM_strp"; break; case DW_FORM_udata: *s = "DW_FORM_udata"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_DS_name(unsigned ds, const char **s) { assert(s != NULL); switch (ds) { case DW_DS_unsigned: *s = "DW_DS_unsigned"; break; case DW_DS_leading_overpunch: *s = "DW_DS_leading_overpunch"; break; case DW_DS_trailing_overpunch: *s = "DW_DS_trailing_overpunch"; break; case DW_DS_leading_separate: *s = "DW_DS_leading_separate"; break; case DW_DS_trailing_separate: - *s = "DW_DS_trailing_separate"; + *s = "DW_DS_trailing_separate"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_DSC_name(unsigned dsc, const char **s) { assert(s != NULL); switch (dsc) { case DW_DSC_label: *s = "DW_DSC_label"; break; case DW_DSC_range: *s = "DW_DSC_range"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_EH_name(unsigned eh, const char **s) { assert(s != NULL); switch (eh) { case DW_EH_PE_absptr: *s = "DW_EH_PE_absptr"; break; case DW_EH_PE_uleb128: *s = "DW_EH_PE_uleb128"; break; case DW_EH_PE_udata2: *s = "DW_EH_PE_udata2"; break; case DW_EH_PE_udata4: *s = "DW_EH_PE_udata4"; break; case DW_EH_PE_udata8: *s = "DW_EH_PE_udata8"; break; case DW_EH_PE_sleb128: *s = "DW_EH_PE_sleb128"; break; case DW_EH_PE_sdata2: *s = "DW_EH_PE_sdata2"; break; case DW_EH_PE_sdata4: *s = "DW_EH_PE_sdata4"; break; case DW_EH_PE_sdata8: *s = "DW_EH_PE_sdata8"; break; case DW_EH_PE_pcrel: *s = "DW_EH_PE_pcrel"; break; case DW_EH_PE_textrel: *s = "DW_EH_PE_textrel"; break; case DW_EH_PE_datarel: *s = "DW_EH_PE_datarel"; break; case DW_EH_PE_funcrel: *s = "DW_EH_PE_funcrel"; break; case DW_EH_PE_aligned: *s = "DW_EH_PE_aligned"; break; case DW_EH_PE_omit: *s = "DW_EH_PE_omit"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_END_name(unsigned end, const char **s) { assert(s != NULL); switch (end) { case DW_END_default: *s = "DW_END_default"; break; case DW_END_big: *s = "DW_END_big"; break; case DW_END_little: *s = "DW_END_little"; break; case DW_END_lo_user: *s = "DW_END_lo_user"; break; case DW_END_high_user: *s = "DW_END_high_user"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_ID_name(unsigned id, const char **s) { assert(s != NULL); switch (id) { case DW_ID_case_sensitive: *s = "DW_ID_case_sensitive"; break; case DW_ID_up_case: *s = "DW_ID_up_case"; break; case DW_ID_down_case: *s = "DW_ID_down_case"; break; case DW_ID_case_insensitive: *s = "DW_ID_case_insensitive"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_INL_name(unsigned inl, const char **s) { assert(s != NULL); switch (inl) { case DW_INL_not_inlined: *s = "DW_INL_not_inlined"; break; case DW_INL_inlined: *s = "DW_INL_inlined"; break; case DW_INL_declared_not_inlined: *s = "DW_INL_declared_not_inlined"; break; case DW_INL_declared_inlined: *s = "DW_INL_declared_inlined"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_LANG_name(unsigned lang, const char **s) { assert(s != NULL); switch (lang) { case DW_LANG_C89: *s = "DW_LANG_C89"; break; case DW_LANG_C: *s = "DW_LANG_C"; break; case DW_LANG_Ada83: *s = "DW_LANG_Ada83"; break; case DW_LANG_C_plus_plus: *s = "DW_LANG_C_plus_plus"; break; case DW_LANG_Cobol74: *s = "DW_LANG_Cobol74"; break; case DW_LANG_Cobol85: *s = "DW_LANG_Cobol85"; break; case DW_LANG_Fortran77: *s = "DW_LANG_Fortran77"; break; case DW_LANG_Fortran90: *s = "DW_LANG_Fortran90"; break; case DW_LANG_Pascal83: *s = "DW_LANG_Pascal83"; break; case DW_LANG_Modula2: *s = "DW_LANG_Modula2"; break; case DW_LANG_Java: *s = "DW_LANG_Java"; break; case DW_LANG_C99: *s = "DW_LANG_C99"; break; case DW_LANG_Ada95: *s = "DW_LANG_Ada95"; break; case DW_LANG_Fortran95: *s = "DW_LANG_Fortran95"; break; case DW_LANG_PLI: *s = "DW_LANG_PLI"; break; case DW_LANG_ObjC: *s = "DW_LANG_ObjC"; break; case DW_LANG_ObjC_plus_plus: *s = "DW_LANG_ObjC_plus_plus"; break; case DW_LANG_UPC: *s = "DW_LANG_UPC"; break; case DW_LANG_D: *s = "DW_LANG_D"; break; case DW_LANG_Python: *s = "DW_LANG_Python"; break; case DW_LANG_OpenCL: *s = "DW_LANG_OpenCL"; break; case DW_LANG_Go: *s = "DW_LANG_Go"; break; case DW_LANG_Modula3: *s = "DW_LANG_Modula3"; break; case DW_LANG_Haskell: *s = "DW_LANG_Haskell"; break; case DW_LANG_C_plus_plus_03: *s = "DW_LANG_C_plus_plus_03"; break; case DW_LANG_C_plus_plus_11: *s = "DW_LANG_C_plus_plus_11"; break; case DW_LANG_OCaml: *s = "DW_LANG_OCaml"; break; case DW_LANG_Rust: *s = "DW_LANG_Rust"; break; case DW_LANG_C11: *s = "DW_LANG_C11"; break; case DW_LANG_Swift: *s = "DW_LANG_Swift"; break; case DW_LANG_Julia: *s = "DW_LANG_Julia"; break; case DW_LANG_Dylan: *s = "DW_LANG_Dylan"; break; case DW_LANG_C_plus_plus_14: *s = "DW_LANG_C_plus_plus_14"; break; case DW_LANG_Fortran03: *s = "DW_LANG_Fortran03"; break; case DW_LANG_Fortran08: *s = "DW_LANG_Fortran08"; break; case DW_LANG_RenderScript: *s = "DW_LANG_RenderScript"; break; case DW_LANG_BLISS: *s = "DW_LANG_BLISS"; break; case DW_LANG_lo_user: *s = "DW_LANG_lo_user"; break; case DW_LANG_Mips_Assembler: *s = "DW_LANG_Mips_Assembler"; break; case DW_LANG_hi_user: *s = "DW_LANG_hi_user"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_LNE_name(unsigned lne, const char **s) { assert(s != NULL); switch (lne) { case DW_LNE_end_sequence: *s = "DW_LNE_end_sequence"; break; case DW_LNE_set_address: *s = "DW_LNE_set_address"; break; case DW_LNE_define_file: *s = "DW_LNE_define_file"; break; case DW_LNE_lo_user: *s = "DW_LNE_lo_user"; break; case DW_LNE_hi_user: *s = "DW_LNE_hi_user"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_LNS_name(unsigned lns, const char **s) { assert(s != NULL); switch (lns) { case DW_LNS_copy: *s = "DW_LNS_copy"; break; case DW_LNS_advance_pc: *s = "DW_LNS_advance_pc"; break; case DW_LNS_advance_line: *s = "DW_LNS_advance_line"; break; case DW_LNS_set_file: *s = "DW_LNS_set_file"; break; case DW_LNS_set_column: *s = "DW_LNS_set_column"; break; case DW_LNS_negate_stmt: *s = "DW_LNS_negate_stmt"; break; case DW_LNS_set_basic_block: *s = "DW_LNS_set_basic_block"; break; case DW_LNS_const_add_pc: *s = "DW_LNS_const_add_pc"; break; case DW_LNS_fixed_advance_pc: *s = "DW_LNS_fixed_advance_pc"; break; case DW_LNS_set_prologue_end: *s = "DW_LNS_set_prologue_end"; break; case DW_LNS_set_epilogue_begin: *s = "DW_LNS_set_epilogue_begin"; break; case DW_LNS_set_isa: *s = "DW_LNS_set_isa"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_MACINFO_name(unsigned mi, const char **s) { assert(s != NULL); switch (mi) { case DW_MACINFO_define: *s = "DW_MACINFO_define"; break; case DW_MACINFO_undef: *s = "DW_MACINFO_undef"; break; case DW_MACINFO_start_file: *s = "DW_MACINFO_start_file"; break; case DW_MACINFO_end_file: *s = "DW_MACINFO_end_file"; break; case DW_MACINFO_vendor_ext: *s = "DW_MACINFO_vendor_ext"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_OP_name(unsigned op, const char **s) { assert(s != NULL); switch (op) { case DW_OP_deref: *s = "DW_OP_deref"; break; case DW_OP_reg0: *s = "DW_OP_reg0"; break; case DW_OP_reg1: *s = "DW_OP_reg1"; break; case DW_OP_reg2: *s = "DW_OP_reg2"; break; case DW_OP_reg3: *s = "DW_OP_reg3"; break; case DW_OP_reg4: *s = "DW_OP_reg4"; break; case DW_OP_reg5: *s = "DW_OP_reg5"; break; case DW_OP_reg6: *s = "DW_OP_reg6"; break; case DW_OP_reg7: *s = "DW_OP_reg7"; break; case DW_OP_reg8: *s = "DW_OP_reg8"; break; case DW_OP_reg9: *s = "DW_OP_reg9"; break; case DW_OP_reg10: *s = "DW_OP_reg10"; break; case DW_OP_reg11: *s = "DW_OP_reg11"; break; case DW_OP_reg12: *s = "DW_OP_reg12"; break; case DW_OP_reg13: *s = "DW_OP_reg13"; break; case DW_OP_reg14: *s = "DW_OP_reg14"; break; case DW_OP_reg15: *s = "DW_OP_reg15"; break; case DW_OP_reg16: *s = "DW_OP_reg16"; break; case DW_OP_reg17: *s = "DW_OP_reg17"; break; case DW_OP_reg18: *s = "DW_OP_reg18"; break; case DW_OP_reg19: *s = "DW_OP_reg19"; break; case DW_OP_reg20: *s = "DW_OP_reg20"; break; case DW_OP_reg21: *s = "DW_OP_reg21"; break; case DW_OP_reg22: *s = "DW_OP_reg22"; break; case DW_OP_reg23: *s = "DW_OP_reg23"; break; case DW_OP_reg24: *s = "DW_OP_reg24"; break; case DW_OP_reg25: *s = "DW_OP_reg25"; break; case DW_OP_reg26: *s = "DW_OP_reg26"; break; case DW_OP_reg27: *s = "DW_OP_reg27"; break; case DW_OP_reg28: *s = "DW_OP_reg28"; break; case DW_OP_reg29: *s = "DW_OP_reg29"; break; case DW_OP_reg30: *s = "DW_OP_reg30"; break; case DW_OP_reg31: *s = "DW_OP_reg31"; break; case DW_OP_lit0: *s = "DW_OP_lit0"; break; case DW_OP_lit1: *s = "DW_OP_lit1"; break; case DW_OP_lit2: *s = "DW_OP_lit2"; break; case DW_OP_lit3: *s = "DW_OP_lit3"; break; case DW_OP_lit4: *s = "DW_OP_lit4"; break; case DW_OP_lit5: *s = "DW_OP_lit5"; break; case DW_OP_lit6: *s = "DW_OP_lit6"; break; case DW_OP_lit7: *s = "DW_OP_lit7"; break; case DW_OP_lit8: *s = "DW_OP_lit8"; break; case DW_OP_lit9: *s = "DW_OP_lit9"; break; case DW_OP_lit10: *s = "DW_OP_lit10"; break; case DW_OP_lit11: *s = "DW_OP_lit11"; break; case DW_OP_lit12: *s = "DW_OP_lit12"; break; case DW_OP_lit13: *s = "DW_OP_lit13"; break; case DW_OP_lit14: *s = "DW_OP_lit14"; break; case DW_OP_lit15: *s = "DW_OP_lit15"; break; case DW_OP_lit16: *s = "DW_OP_lit16"; break; case DW_OP_lit17: *s = "DW_OP_lit17"; break; case DW_OP_lit18: *s = "DW_OP_lit18"; break; case DW_OP_lit19: *s = "DW_OP_lit19"; break; case DW_OP_lit20: *s = "DW_OP_lit20"; break; case DW_OP_lit21: *s = "DW_OP_lit21"; break; case DW_OP_lit22: *s = "DW_OP_lit22"; break; case DW_OP_lit23: *s = "DW_OP_lit23"; break; case DW_OP_lit24: *s = "DW_OP_lit24"; break; case DW_OP_lit25: *s = "DW_OP_lit25"; break; case DW_OP_lit26: *s = "DW_OP_lit26"; break; case DW_OP_lit27: *s = "DW_OP_lit27"; break; case DW_OP_lit28: *s = "DW_OP_lit28"; break; case DW_OP_lit29: *s = "DW_OP_lit29"; break; case DW_OP_lit30: *s = "DW_OP_lit30"; break; case DW_OP_lit31: *s = "DW_OP_lit31"; break; case DW_OP_dup: *s = "DW_OP_dup"; break; case DW_OP_drop: *s = "DW_OP_drop"; break; case DW_OP_over: *s = "DW_OP_over"; break; case DW_OP_swap: *s = "DW_OP_swap"; break; case DW_OP_rot: *s = "DW_OP_rot"; break; case DW_OP_xderef: *s = "DW_OP_xderef"; break; case DW_OP_abs: *s = "DW_OP_abs"; break; case DW_OP_and: *s = "DW_OP_and"; break; case DW_OP_div: *s = "DW_OP_div"; break; case DW_OP_minus: *s = "DW_OP_minus"; break; case DW_OP_mod: *s = "DW_OP_mod"; break; case DW_OP_mul: *s = "DW_OP_mul"; break; case DW_OP_neg: *s = "DW_OP_neg"; break; case DW_OP_not: *s = "DW_OP_not"; break; case DW_OP_or: *s = "DW_OP_or"; break; case DW_OP_plus: *s = "DW_OP_plus"; break; case DW_OP_shl: *s = "DW_OP_shl"; break; case DW_OP_shr: *s = "DW_OP_shr"; break; case DW_OP_shra: *s = "DW_OP_shra"; break; case DW_OP_xor: *s = "DW_OP_xor"; break; case DW_OP_eq: *s = "DW_OP_eq"; break; case DW_OP_ge: *s = "DW_OP_ge"; break; case DW_OP_gt: *s = "DW_OP_gt"; break; case DW_OP_le: *s = "DW_OP_le"; break; case DW_OP_lt: *s = "DW_OP_lt"; break; case DW_OP_ne: *s = "DW_OP_ne"; break; case DW_OP_nop: *s = "DW_OP_nop"; break; case DW_OP_const1u: *s = "DW_OP_const1u"; break; case DW_OP_const1s: *s = "DW_OP_const1s"; break; case DW_OP_pick: *s = "DW_OP_pick"; break; case DW_OP_deref_size: *s = "DW_OP_deref_size"; break; case DW_OP_xderef_size: *s = "DW_OP_xderef_size"; break; case DW_OP_const2u: *s = "DW_OP_const2u"; break; case DW_OP_const2s: *s = "DW_OP_const2s"; break; case DW_OP_bra: *s = "DW_OP_bra"; break; case DW_OP_skip: *s = "DW_OP_skip"; break; case DW_OP_const4u: *s = "DW_OP_const4u"; break; case DW_OP_const4s: *s = "DW_OP_const4s"; break; case DW_OP_const8u: *s = "DW_OP_const8u"; break; case DW_OP_const8s: *s = "DW_OP_const8s"; break; case DW_OP_constu: *s = "DW_OP_constu"; break; case DW_OP_plus_uconst: *s = "DW_OP_plus_uconst"; break; case DW_OP_regx: *s = "DW_OP_regx"; break; case DW_OP_piece: *s = "DW_OP_piece"; break; case DW_OP_consts: *s = "DW_OP_consts"; break; case DW_OP_breg0: *s = "DW_OP_breg0"; break; case DW_OP_breg1: *s = "DW_OP_breg1"; break; case DW_OP_breg2: *s = "DW_OP_breg2"; break; case DW_OP_breg3: *s = "DW_OP_breg3"; break; case DW_OP_breg4: *s = "DW_OP_breg4"; break; case DW_OP_breg5: *s = "DW_OP_breg5"; break; case DW_OP_breg6: *s = "DW_OP_breg6"; break; case DW_OP_breg7: *s = "DW_OP_breg7"; break; case DW_OP_breg8: *s = "DW_OP_breg8"; break; case DW_OP_breg9: *s = "DW_OP_breg9"; break; case DW_OP_breg10: *s = "DW_OP_breg10"; break; case DW_OP_breg11: *s = "DW_OP_breg11"; break; case DW_OP_breg12: *s = "DW_OP_breg12"; break; case DW_OP_breg13: *s = "DW_OP_breg13"; break; case DW_OP_breg14: *s = "DW_OP_breg14"; break; case DW_OP_breg15: *s = "DW_OP_breg15"; break; case DW_OP_breg16: *s = "DW_OP_breg16"; break; case DW_OP_breg17: *s = "DW_OP_breg17"; break; case DW_OP_breg18: *s = "DW_OP_breg18"; break; case DW_OP_breg19: *s = "DW_OP_breg19"; break; case DW_OP_breg20: *s = "DW_OP_breg20"; break; case DW_OP_breg21: *s = "DW_OP_breg21"; break; case DW_OP_breg22: *s = "DW_OP_breg22"; break; case DW_OP_breg23: *s = "DW_OP_breg23"; break; case DW_OP_breg24: *s = "DW_OP_breg24"; break; case DW_OP_breg25: *s = "DW_OP_breg25"; break; case DW_OP_breg26: *s = "DW_OP_breg26"; break; case DW_OP_breg27: *s = "DW_OP_breg27"; break; case DW_OP_breg28: *s = "DW_OP_breg28"; break; case DW_OP_breg29: *s = "DW_OP_breg29"; break; case DW_OP_breg30: *s = "DW_OP_breg30"; break; case DW_OP_breg31: *s = "DW_OP_breg31"; break; case DW_OP_fbreg: *s = "DW_OP_fbreg"; break; case DW_OP_bregx: *s = "DW_OP_bregx"; break; case DW_OP_addr: *s = "DW_OP_addr"; break; case DW_OP_push_object_address: *s = "DW_OP_push_object_address"; break; case DW_OP_call2: *s = "DW_OP_call2"; break; case DW_OP_call4: *s = "DW_OP_call4"; break; case DW_OP_call_ref: *s = "DW_OP_call_ref"; break; case DW_OP_form_tls_address: *s = "DW_OP_form_tls_address"; break; case DW_OP_call_frame_cfa: *s = "DW_OP_call_frame_cfa"; break; case DW_OP_bit_piece: *s = "DW_OP_bit_piece"; break; case DW_OP_implicit_value: *s = "DW_OP_implicit_value"; break; case DW_OP_stack_value: *s = "DW_OP_stack_value"; break; case DW_OP_GNU_push_tls_address: *s = "DW_OP_GNU_push_tls_address"; break; case DW_OP_GNU_uninit: *s = "DW_OP_GNU_uninit"; break; case DW_OP_GNU_encoded_addr: *s = "DW_OP_GNU_encoded_addr"; break; case DW_OP_GNU_implicit_pointer: *s = "DW_OP_GNU_implicit_pointer"; break; case DW_OP_GNU_entry_value: *s = "DW_OP_GNU_entry_value"; break; case DW_OP_GNU_const_type: *s = "DW_OP_GNU_const_type"; break; case DW_OP_GNU_regval_type: *s = "DW_OP_GNU_regval_type"; break; case DW_OP_GNU_deref_type: *s = "DW_OP_GNU_deref_type"; break; case DW_OP_GNU_convert: *s = "DW_OP_GNU_convert"; break; case DW_OP_GNU_reinterpret: *s = "DW_OP_GNU_reinterpret"; break; case DW_OP_GNU_parameter_ref: *s = "DW_OP_GNU_parameter_ref"; break; case DW_OP_GNU_addr_index: *s = "DW_OP_GNU_addr_index"; break; case DW_OP_GNU_const_index: *s = "DW_OP_GNU_const_index"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_ORD_name(unsigned ord, const char **s) { assert(s != NULL); switch (ord) { case DW_ORD_row_major: *s = "DW_ORD_row_major"; break; case DW_ORD_col_major: *s = "DW_ORD_col_major"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_TAG_name(unsigned tag, const char **s) { assert(s != NULL); switch (tag) { case DW_TAG_access_declaration: *s = "DW_TAG_access_declaration"; break; case DW_TAG_array_type: *s = "DW_TAG_array_type"; break; case DW_TAG_base_type: *s = "DW_TAG_base_type"; break; case DW_TAG_catch_block: *s = "DW_TAG_catch_block"; break; case DW_TAG_class_type: *s = "DW_TAG_class_type"; break; case DW_TAG_common_block: *s = "DW_TAG_common_block"; break; case DW_TAG_common_inclusion: *s = "DW_TAG_common_inclusion"; break; case DW_TAG_compile_unit: *s = "DW_TAG_compile_unit"; break; case DW_TAG_condition: *s = "DW_TAG_condition"; break; case DW_TAG_const_type: *s = "DW_TAG_const_type"; break; case DW_TAG_constant: *s = "DW_TAG_constant"; break; case DW_TAG_dwarf_procedure: *s = "DW_TAG_dwarf_procedure"; break; case DW_TAG_entry_point: *s = "DW_TAG_entry_point"; break; case DW_TAG_enumeration_type: *s = "DW_TAG_enumeration_type"; break; case DW_TAG_enumerator: *s = "DW_TAG_enumerator"; break; case DW_TAG_formal_parameter: *s = "DW_TAG_formal_parameter"; break; case DW_TAG_friend: *s = "DW_TAG_friend"; break; case DW_TAG_imported_declaration: *s = "DW_TAG_imported_declaration"; break; case DW_TAG_imported_module: *s = "DW_TAG_imported_module"; break; case DW_TAG_imported_unit: *s = "DW_TAG_imported_unit"; break; case DW_TAG_inheritance: *s = "DW_TAG_inheritance"; break; case DW_TAG_inlined_subroutine: *s = "DW_TAG_inlined_subroutine"; break; case DW_TAG_interface_type: *s = "DW_TAG_interface_type"; break; case DW_TAG_label: *s = "DW_TAG_label"; break; case DW_TAG_lexical_block: *s = "DW_TAG_lexical_block"; break; case DW_TAG_member: *s = "DW_TAG_member"; break; case DW_TAG_module: *s = "DW_TAG_module"; break; case DW_TAG_namelist: *s = "DW_TAG_namelist"; break; case DW_TAG_namelist_item: *s = "DW_TAG_namelist_item"; break; case DW_TAG_namespace: *s = "DW_TAG_namespace"; break; case DW_TAG_packed_type: *s = "DW_TAG_packed_type"; break; case DW_TAG_partial_unit: *s = "DW_TAG_partial_unit"; break; case DW_TAG_pointer_type: *s = "DW_TAG_pointer_type"; break; case DW_TAG_ptr_to_member_type: *s = "DW_TAG_ptr_to_member_type"; break; case DW_TAG_reference_type: *s = "DW_TAG_reference_type"; break; case DW_TAG_restrict_type: *s = "DW_TAG_restrict_type"; break; case DW_TAG_rvalue_reference_type: *s = "DW_TAG_rvalue_reference_type"; break; case DW_TAG_set_type: *s = "DW_TAG_set_type"; break; case DW_TAG_shared_type: *s = "DW_TAG_shared_type"; break; case DW_TAG_string_type: *s = "DW_TAG_string_type"; break; case DW_TAG_structure_type: *s = "DW_TAG_structure_type"; break; case DW_TAG_subprogram: *s = "DW_TAG_subprogram"; break; case DW_TAG_subrange_type: *s = "DW_TAG_subrange_type"; break; case DW_TAG_subroutine_type: *s = "DW_TAG_subroutine_type"; break; case DW_TAG_template_alias: *s = "DW_TAG_template_alias"; break; case DW_TAG_template_type_parameter: *s = "DW_TAG_template_type_parameter"; break; case DW_TAG_template_value_parameter: *s = "DW_TAG_template_value_parameter"; break; case DW_TAG_thrown_type: *s = "DW_TAG_thrown_type"; break; case DW_TAG_try_block: *s = "DW_TAG_try_block"; break; case DW_TAG_type_unit: *s = "DW_TAG_type_unit"; break; case DW_TAG_typedef: *s = "DW_TAG_typedef"; break; case DW_TAG_union_type: *s = "DW_TAG_union_type"; break; case DW_TAG_unspecified_parameters: *s = "DW_TAG_unspecified_parameters"; break; case DW_TAG_unspecified_type: *s = "DW_TAG_unspecified_type"; break; case DW_TAG_variable: *s = "DW_TAG_variable"; break; case DW_TAG_variant: *s = "DW_TAG_variant"; break; case DW_TAG_variant_part: *s = "DW_TAG_variant_part"; break; case DW_TAG_volatile_type: *s = "DW_TAG_volatile_type"; break; case DW_TAG_with_stmt: *s = "DW_TAG_with_stmt"; break; case DW_TAG_format_label: *s = "DW_TAG_format_label"; break; case DW_TAG_function_template: *s = "DW_TAG_function_template"; break; case DW_TAG_class_template: *s = "DW_TAG_class_template"; break; case DW_TAG_GNU_BINCL: *s = "DW_TAG_GNU_BINCL"; break; case DW_TAG_GNU_EINCL: *s = "DW_TAG_GNU_EINCL"; break; case DW_TAG_GNU_template_template_param: *s = "DW_TAG_GNU_template_template_param"; break; case DW_TAG_GNU_template_parameter_pack: *s = "DW_TAG_GNU_template_parameter_pack"; break; case DW_TAG_GNU_formal_parameter_pack: *s = "DW_TAG_GNU_formal_parameter_pack"; break; case DW_TAG_GNU_call_site: *s = "DW_TAG_GNU_call_site"; break; case DW_TAG_GNU_call_site_parameter: *s = "DW_TAG_GNU_call_site_parameter"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_VIRTUALITY_name(unsigned vir, const char **s) { assert(s != NULL); switch (vir) { case DW_VIRTUALITY_none: *s = "DW_VIRTUALITY_none"; break; case DW_VIRTUALITY_virtual: *s = "DW_VIRTUALITY_virtual"; break; case DW_VIRTUALITY_pure_virtual: *s = "DW_VIRTUALITY_pure_virtual"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } int dwarf_get_VIS_name(unsigned vis, const char **s) { assert(s != NULL); switch (vis) { case DW_VIS_local: *s = "DW_VIS_local"; break; case DW_VIS_exported: *s = "DW_VIS_exported"; break; case DW_VIS_qualified: *s = "DW_VIS_qualified"; break; default: return (DW_DLV_NO_ENTRY); } return (DW_DLV_OK); } Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_end_macro_file.3 (revision 367466) @@ -1,90 +1,89 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_end_macro_file.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_end_macro_file.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 25, 2011 -.Os .Dt DWARF_END_MACRO_FILE 3 +.Os .Sh NAME .Nm dwarf_end_macro_file .Nd mark the end of the current source file inclusion .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "int" .Fo dwarf_end_macro_file .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Error *err" -.Fa .Fc .Sh DESCRIPTION Function .Fn dwarf_end_macro_file marks the end of the current source file inclusion. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_end_macro_file returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_end_macro_file returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_end_macro_file can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_def_macro 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_start_macro_file 3 , .Xr dwarf_undef_macro 3 , .Xr dwarf_vendor_ext 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_errmsg.3 (revision 367466) @@ -1,67 +1,67 @@ .\" 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 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: dwarf_errmsg.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_errmsg.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd December 12, 2009 -.Os .Dt DWARF_ERRMSG 3 +.Os .Sh NAME .Nm dwarf_errmsg .Nd retrieve a human-readable string corresponding to a .Vt Dwarf_Error instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "const char *" .Fn dwarf_errmsg "Dwarf_Error err" .Sh DESCRIPTION Function .Fn dwarf_errmsg returns a .Dv NUL Ns - Ns terminated string for the error denoted by argument .Ar err . .Pp Argument .Ar err should be a valid handle to a .Vt Dwarf_Error instance. .Sh Memory Management The returned pointer should not be freed using .Xr free 3 or .Xr dwarf_dealloc 3 . .Sh RETURN VALUES Function .Fn dwarf_errmsg returns a pointer to a .Dv NUL Ns - Ns terminated string. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errno 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_errno.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_errno.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_errno.3 (revision 367466) @@ -1,58 +1,58 @@ .\" Copyright (c) 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 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: dwarf_errno.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_errno.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd March 25, 2010 -.Os .Dt DWARF_ERRNO 3 +.Os .Sh NAME .Nm dwarf_errno .Nd retrieve the error number corresponding to a .Vt Dwarf_Error instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fn dwarf_errno "Dwarf_Error err" .Sh DESCRIPTION Function .Fn dwarf_errno returns the error number associated with a .Vt Dwarf_Error instance. .Pp Argument .Ar err should be a valid handle to a .Vt Dwarf_Error instance. .Sh RETURN VALUES Function .Fn dwarf_errno returns an integral value. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_expand_frame_instructions.3 (revision 367466) @@ -1,182 +1,182 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_expand_frame_instructions.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_expand_frame_instructions.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_EXPAND_FRAME_INSTRUCTIONS 3 +.Os .Sh NAME .Nm dwarf_expand_frame_instructions .Nd expand frame instructions .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_expand_frame_instructions .Fa "Dwarf_Cie cie" .Fa "Dwarf_Ptr instructions" .Fa "Dwarf_Unsigned len" .Fa "Dwarf_Frame_Op **ret_ops" .Fa "Dwarf_Signed *ret_opcnt" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION Function .Fn dwarf_expand_frame_instructions translates DWARF frame instruction bytes into an array of .Vt Dwarf_Frame_Op descriptors. .Pp Argument .Ar cie should reference the CIE descriptor associated with the instructions to be translated. .Pp Arugment .Ar instructions should point to an array of frame instruction bytes, as returned by the functions .Xr dwarf_get_cie_info 3 or .Xr dwarf_get_fde_instr_bytes 3 . .Pp Argument .Ar len should specify the number of the frame instruction bytes to be translated. .Pp Argument .Ar ret_ops should point to a location that will be set to a pointer to an array of translated .Vt Dwarf_Frame_Op descriptors. .Pp Argument .Ar ret_opcnt should point to a location that will hold the total number of the returned descriptors. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Ss Memory Management The memory area used for the descriptor array returned in argument .Ar ret_ops is allocated by .Lb libdwarf . Application code should use function .Xr dwarf_dealloc 3 with type .Dv DW_DLA_FRAME_BLOCK to free the memory area when the descriptor array is no longer needed. .Sh RETURN VALUES Function .Fn dwarf_expand_frame_instructions returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_expand_frame_instructions -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar cie , -.Ar instructions , -.Ar ret_ops -or -.Ar ret_opcnt -was NULL. -.It Bq Er DW_DLE_ARGUMENT -Argument -.Ar len -was 0. -.It Bq Er DW_DLE_MEMORY -An out of memory condition was encountered during the execution of -this function. -.It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR -An unknown instruction was found in the instruction bytes provided -in argument -.Ar instructions . -.El -.Sh EXAMPLE +.Sh EXAMPLES To retrieve and expand the frame instructions for a given FDE descriptor, use: .Bd -literal -offset indent Dwarf_Dbg dbg; Dwarf_Cie cie; Dwarf_Fde fde; Dwarf_Ptr fde_inst; Dwarf_Unsigned fde_instlen; Dwarf_Frame_Op *ops; Dwarf_Signed opcnt; Dwarf_Error de; /* ... assuming `dbg` references a valid DWARF debugging context, `fde` references a valid FDE descriptor and `cie` holds the CIE descriptor associated with the FDE descriptor ... */ if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_fde_instr_bytes failed: %s", dwarf_errmsg(de)); if (dwarf_expand_frame_instructions(cie, fde_inst, fde_instlen, &ops, &opcnt, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_expand_frame_instructions failed: %s", dwarf_errmsg(de)); for (i = 0; i < opcnt; i++) { /* ... use ops[i] ... */ } /* Free the memory area when no longer needed. */ dwarf_dealloc(dbg, ops, DW_DLA_FRAME_BLOCK); .Ed +.Sh ERRORS +Function +.Fn dwarf_expand_frame_instructions +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar cie , +.Ar instructions , +.Ar ret_ops +or +.Ar ret_opcnt +was NULL. +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar len +was 0. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.It Bq Er DW_DLE_FRAME_INSTR_EXEC_ERROR +An unknown instruction was found in the instruction bytes provided +in argument +.Ar instructions . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_frame_instructions_dealloc 3 , -.Xr dwarf_get_cie_info 3 , .Xr dwarf_get_cie_index 3 , -.Xr dwarf_get_cie_of_fde , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_instr_bytes 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 , .Xr dwarf_get_fde_n 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_expr_current_offset.3 (revision 367466) @@ -1,84 +1,84 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_expr_current_offset.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_expr_current_offset.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 13, 2011 -.Os .Dt DWARF_EXPR_CURRENT_OFFSET 3 +.Os .Sh NAME .Nm dwarf_expr_current_offset .Nd retrieve the number of bytes in a location expression stream .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_expr_current_offset .Fa "Dwarf_P_Expr expr" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_expr_current_offset returns the size in bytes of the stream representation of a location expression. .Pp Argument .Ar expr should reference a location expression descriptor allocated using .Xr dwarf_new_expr 3 . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_expr_current_offset returns the size in bytes of the location descriptor's stream representation. In case of an error, function .Fn dwarf_expr_current_offset returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_expr_current_offset can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar expr was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_expr_addr 3 , .Xr dwarf_add_expr_addr_b 3 , .Xr dwarf_add_expr_gen 3 , .Xr dwarf_expr_into_block 3 , .Xr dwarf_new_expr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_expr_into_block.3 (revision 367466) @@ -1,94 +1,94 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_expr_into_block.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_expr_into_block.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 13, 2011 -.Os .Dt DWARF_EXPR_INTO_BLOCK 3 +.Os .Sh NAME .Nm dwarf_expr_into_block .Nd retrieve the byte stream for a location expression .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Addr" .Fo dwarf_expr_into_block .Fa "Dwarf_P_Expr expr" .Fa "Dwarf_Unsigned *length" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_expr_into_block retrieves the byte stream representation of a location expression. .Pp Argument .Ar expr should reference a location expression descriptor allocated using .Xr dwarf_new_expr 3 . .Pp Argument .Ar length should point to a location which will hold the size in bytes of the retrieved byte stream. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_expr_into_block returns the address of the first byte of the generated byte stream. In case of an error, function .Fn dwarf_expr_into_block returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_expr_into_block can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar expr or .Ar length was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_location_expr 3 , .Xr dwarf_add_expr_addr 3 , .Xr dwarf_add_expr_addr_b 3 , .Xr dwarf_add_expr_gen 3 , .Xr dwarf_expr_current_offset 3 , .Xr dwarf_new_expr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_fde_cfa_offset.3 (revision 367466) @@ -1,99 +1,99 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_fde_cfa_offset.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_fde_cfa_offset.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 26, 2011 -.Os .Dt DWARF_FDE_CFA_OFFSET 3 +.Os .Sh NAME .Nm dwarf_fde_cfa_offset .Nd add a DW_CFA_offset frame instruction to a DWARF frame descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Fde" .Fo dwarf_fde_cfa_offset .Fa "Dwarf_P_Fde fde" .Fa "Dwarf_Unsigned reg" .Fa "Dwarf_Signed offset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_fde_cfa_offset appends a .Dv DW_CFA_offset frame instruction to the frame descriptor referenced by argument .Ar fde . .Pp Argument .Ar fde should reference a frame descriptor allocated using .Xr dwarf_new_fde 3 . .Pp Argument .Ar reg specifies the register operand for the frame instruction. .Pp Argument .Ar offset specifies the offset operand for the frame instruction. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_fde_cfa_offset returns the frame descriptor given in argument .Ar fde . In case of an error, function .Fn dwarf_fde_cfa_offset returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_fde_cfa_offset can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar fde was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_cie 3 , .Xr dwarf_add_frame_fde 3 , .Xr dwarf_add_frame_fde_b 3 , -.Xr dwarf_add_frame_cie 3 , .Xr dwarf_new_fde 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_find_macro_value_start.3 (revision 367466) @@ -1,68 +1,68 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_find_macro_value_start.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_find_macro_value_start.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd March 26, 2011 -.Os .Dt DWARF_FIND_MACRO_VALUE_START 3 +.Os .Sh NAME .Nm dwarf_find_macro_value_start .Nd return the address of the first byte of a macro value .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft char * .Fo dwarf_find_macro_value_start .Fa "char *macro_string" .Fc .Sh DESCRIPTION Given a DWARF macro string, function .Fn dwarf_find_macro_value_start returns a pointer to the first byte of the macro value part of the macro string. .Pp Argument .Ar macro_string should be a NUL-terminated string conforming to the macro format defined in the DWARF standard; see .Xr dwarf 4 . .Sh RETURN VALUES On success, function .Fn dwarf_find_macro_value_start returns a pointer to the first byte of the macro value. If the macro value part was not found, function .Fn dwarf_find_macro_value_start returns a pointer to the NUL-byte terminating argument .Ar macro_string . .Pp Function .Fn dwarf_find_macro_value_start returns NULL if argument .Ar macro_string was NULL. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_macro_details 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_finish.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_finish.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_finish.3 (revision 367466) @@ -1,140 +1,140 @@ .\" Copyright (c) 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 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: dwarf_finish.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_finish.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_FINISH 3 +.Os .Sh NAME .Nm dwarf_finish , .Nm dwarf_object_finish .Nd free resources associated with a debug descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fn dwarf_finish "Dwarf_Debug dbg" "Dwarf_Error *err" .Ft int .Fn dwarf_object_finish "Dwarf_Debug dbg" "Dwarf_Error *err" .Sh DESCRIPTION The .Fn dwarf_finish and .Fn dwarf_object_finish functions are used to release the resources associated with a debug descriptor allocated by a prior call to .Xr dwarf_init 3 and .Xr dwarf_object_init 3 respectively. .Pp Argument .Ar dbg denotes a valid .Vt Dwarf_Debug instance. Argument .Ar err will be used to record error information in case of an error. .Pp After a call to .Fn dwarf_finish or .Fn dwarf_object_finish , the argument .Ar dbg will be invalid and should not be used further. .Pp For .Vt Dwarf_Debug descriptors opened using .Xr dwarf_init 3 , the application would need to explicitly release the .Vt Elf instance associated with the descriptor by first retrieving the instance using .Xr dwarf_get_elf 3 and closing it using .Xr elf_end 3 . .Sh RETURN VALUES These functions return .Dv DW_DLV_OK if successful. In case of an error, the functions return .Dv DW_DLV_ERROR and record additional information in argument .Ar err . .Sh EXAMPLES To deallocate a .Vt Dwarf_Debug instance allocated using .Xr dwarf_elf_init 3 use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Error de; if (dwarf_finish(dbg, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_finish: %s", dwarf_errmsg(de)); .Ed .Pp To deallocate a .Vt Dwarf_Debug instance allocated using .Xr dwarf_object_init 3 use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Error de; if (dwarf_object_finish(dbg, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_object_finish: %s", dwarf_errmsg(de)); .Ed .Pp To deallocate a .Vt Dwarf_Debug instance allocated using .Xr dwarf_init 3 use: .Bd -literal -offset indent Dwarf_Debug dbg; Dward_Error de; Elf *e; if (dwarf_get_elf(dbg, &e, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(&de)); if (dwarf_finish(dbg, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_finish: %s", dwarf_errmsg(de)); (void) elf_end(e); .Ed .Sh SEE ALSO -.Xr elf_end 3 , .Xr dwarf_elf_init 3 , .Xr dwarf_get_elf 3 , .Xr dwarf_init 3 , -.Xr dwarf_object_init 3 +.Xr dwarf_object_init 3 , +.Xr elf_end 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formaddr.3 (revision 367466) @@ -1,97 +1,97 @@ .\" 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: dwarf_formaddr.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_formaddr.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd July 23, 2010 -.Os .Dt DWARF_FORMADDR 3 +.Os .Sh NAME .Nm dwarf_formaddr .Nd return the value of an ADDRESS class attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formaddr .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Addr *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_formaddr sets the location pointed to by argument .Ar ret to the address represented by the attribute referenced by argument .Ar attr . The form of argument .Ar attr must be .Dv DW_FORM_addr . .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_formaddr returns .Dv DW_DLV_OK on success. In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_formblock may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar ret was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of form .Dv DW_FORM_addr . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formblock 3 , .Xr dwarf_formflag 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formstring 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formblock.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formblock.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formblock.3 (revision 367466) @@ -1,109 +1,109 @@ .\" 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: dwarf_formblock.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_formblock.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd July 23, 2010 -.Os .Dt DWARF_FORMBLOCK 3 +.Os .Sh NAME .Nm dwarf_formblock .Nd return the value of a BLOCK attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formblock .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Block **ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_formblock sets the location pointed to by argument .Ar ret to a pointer to a .Vt Dwarf_Block structure containing the value of the attribute referenced by argument .Ar attr . The form of argument .Ar attr must be one of .Dv DW_FORM_block , .Dv DW_FORM_block1 , .Dv DW_FORM_block2 or .Dv DW_FORM_block4 . .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Ss Memory Management The memory area referenced by the returned pointer is managed by the DWARF(3) library. The application should not attempt to free this memory area. Portable code may indicate that the memory area is to be freed by using .Xr dwarf_dealloc 3 . .Sh RETURN VALUES Function .Fn dwarf_formblock returns .Dv DW_DLV_OK on success. In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_formblock may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar ret was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of a permitted kind. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formflag 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formstring 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formexprloc.3 (revision 367466) @@ -1,109 +1,109 @@ .\" 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: dwarf_formexprloc.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_formexprloc.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd July 25, 2010 -.Os .Dt DWARF_FORMEXPRLOC 3 +.Os .Sh NAME .Nm dwarf_formexprloc .Nd return information about a location expression .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formexprloc .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Unsigned *retlen" .Fa "Dwarf_Ptr *retexpr" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_formexprloc allows an application to retrieve the length and the bytes of a DWARF location expression. .Pp Argument .Ar attr should reference a DWARF attribute of the form .Dv DW_FORM_exprloc . Argument .Ar retlen should point to a location that will be set to the length of the location expression. Argument .Ar retexpr should point to a location that will be set to a pointer to the content of the location expression itself. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Ss Memory Management The application should not attempt to free the memory area referenced by the pointer returned in argument .Ar retexpr . .Sh RETURN VALUES Function .Fn dwarf_formexprloc returns .Dv DW_DLV_OK on success. In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_formexprloc may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT One of arguments .Ar attr , .Ar retlen or .Ar retexpr was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of form .Dv DW_FORM_exprloc . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formblock 3 , .Xr dwarf_formflag 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formstring 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formflag.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formflag.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formflag.3 (revision 367466) @@ -1,97 +1,97 @@ .\" 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: dwarf_formflag.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_formflag.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd June 21, 2010 -.Os .Dt DWARF_FORMFLAG 3 +.Os .Sh NAME .Nm dwarf_formflag .Nd return the value of a BOOLEAN class attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formflag .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Bool *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_formflag sets the location pointed to by argument .Ar ret to 1 if the attribute referenced by argument .Ar attr has a non-zero value, or 0 otherwise. The form of argument .Ar attr must be one of .Dv DW_FORM_flag or .Dv DW_FORM_flag_present . .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_formflag returns .Dv DW_DLV_OK on success. In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_formflag may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar ret was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of a permitted kind. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formblock 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formstring 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formref.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formref.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formref.3 (revision 367466) @@ -1,136 +1,136 @@ .\" 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: dwarf_formref.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_formref.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd June 21, 2010 -.Os .Dt DWARF_FORMREF 3 +.Os .Sh NAME .Nm dwarf_formref , .Nm dwarf_global_formref .Nd retrieve offsets for REFERENCE class attributes .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formref .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Off *retoffset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_global_formref .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Off *retoffset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions return the offsets associated with a DWARF attribute descriptor. .Pp Function .Fn dwarf_formref returns the compilation unit relative offset of the descriptor referenced by argument .Ar attr in the location pointed to by argument .Ar retoffset . Argument .Ar attr must be a reference that is local to a compilation unit. Permitted forms for argument .Ar attr are .Dv DW_FORM_ref1 , .Dv DW_FORM_ref2 , .Dv DW_FORM_ref4 , .Dv DW_FORM_ref8 and .Dv DW_FORM_ref_udata . .Pp Function .Fn dwarf_global_formref returns the section-relative offset of the descriptor referenced by argument .Ar attr in the location pointed to by argument .Ar retoffset . Argument .Ar attr should be a legal .Sy REFERENCE class form. Permitted forms for argument .Ar attr are: .Dv DW_FORM_ref_addr , .Dv DW_FORM_ref_udata , .Dv DW_FORM_ref1 , .Dv DW_FORM_ref2 , .Dv DW_FORM_ref4 , .Dv DW_FORM_ref8 and .Dv DW_FORM_sec_offset . The returned offset is relative to the start of the .Dq .debug_info ELF section. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES These functions return .Dv DW_DLV_OK on success. In case of an error, these functions return .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar retoffset was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of a permitted kind. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formblock 3 , .Xr dwarf_formflag 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formstring 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formsig8.3 (revision 367466) @@ -1,96 +1,96 @@ .\" 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: dwarf_formsig8.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_formsig8.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd July 24, 2010 -.Os .Dt DWARF_FORMSIG8 3 +.Os .Sh NAME .Nm dwarf_formsig8 .Nd return the 64-bit type signature for a DWARF type .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formsig8 .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Sig8 *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_formsig8 sets the location pointed to by argument .Ar ret to the 64-bit type signature that is the value of the attribute referenced by argument .Ar attr . The form of argument .Ar attr must be .Dv DW_FORM_ref_sig8 . .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_formsig8 returns .Dv DW_DLV_OK on success. In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_formsig8 may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar ret was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of a permitted kind. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formflag 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formstring 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 .Sh HISTORY Type signatures were added in version 4 of the DWARF specification. Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formstring.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formstring.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formstring.3 (revision 367466) @@ -1,101 +1,101 @@ .\" 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: dwarf_formstring.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_formstring.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd July 24, 2010 -.Os .Dt DWARF_FORMSTRING 3 +.Os .Sh NAME .Nm dwarf_formstring .Nd return the value of a STRING class attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formstring .Fa "Dwarf_Attribute attr" .Fa "char **ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_formstring sets the location pointed to by argument .Ar ret to a pointer to a NUL-terminated string containing the value of the attribute referenced by argument .Ar attr . The form of argument .Ar attr must be one of .Dv DW_FORM_string or .Dv DW_FORM_strp . .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Ss Memory Management The memory area referenced by the returned pointer is managed by the DWARF(3) library. The application should not attempt to directly free this memory area. .Sh RETURN VALUES Function .Fn dwarf_formstring returns .Dv DW_DLV_OK on success. In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_formstring may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar ret was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of a permitted kind. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formblock 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsdata 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formudata 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_formudata.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_formudata.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_formudata.3 (revision 367466) @@ -1,122 +1,122 @@ .\" 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: dwarf_formudata.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_formudata.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd June 21, 2010 -.Os .Dt DWARF_FORMUDATA 3 +.Os .Sh NAME .Nm dwarf_formudata , .Nm dwarf_formsdata .Nd return the value of a CONSTANT class attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_formudata .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Unsigned *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_formsdata .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Signed *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions return the value associated with a DWARF attribute describing a constant. .Pp Function .Fn dwarf_formudata sets the location pointed to by argument .Ar ret to the value of the attribute referenced by argument .Ar attr , treating the value as an unsigned quantity. Argument .Ar attr must have one of the following forms: .Dv DW_FORM_data1 , .Dv DW_FORM_data2 , .Dv DW_FORM_data4 , .Dv DW_FORM_data8 and .Dv DW_FORM_udata . .Pp Function .Fn dwarf_formsdata sets the location pointed to by argument .Ar ret to the value of the attribute referenced by argument .Ar attr , appropriately sign extended. Argument .Ar attr must have one of the following forms: .Dv DW_FORM_data1 , .Dv DW_FORM_data2 , .Dv DW_FORM_data4 , .Dv DW_FORM_data8 and .Dv DW_FORM_sdata . .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES These functions return .Dv DW_DLV_OK on success. In case of an error, they return .Dv DW_DLV_ERROR and set argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ATTR_FORM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar attr or .Ar ret was NULL. .It Bq Er DW_DLE_ATTR_FORM_BAD The attribute referenced by argument .Ar attr was not of a permitted kind. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_formblock 3 , .Xr dwarf_formflag 3 , .Xr dwarf_formref 3 , .Xr dwarf_formsig8 3 , .Xr dwarf_formstring 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 (revision 367466) @@ -1,259 +1,260 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_AT_name.3 3142 2015-01-29 23:11:14Z jkoshy $ +.\" $Id: dwarf_get_AT_name.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 22, 2011 -.Os .Dt DWARF_GET_AT_NAME 3 +.Os .Sh NAME .Nm dwarf_get_ACCESS_name , .Nm dwarf_get_AT_name , .Nm dwarf_get_ATE_name , .Nm dwarf_get_CC_name , .Nm dwarf_get_CFA_name , .Nm dwarf_get_CHILDREN_name , .Nm dwarf_get_DS_name , .Nm dwarf_get_DSC_name , .Nm dwarf_get_EH_name , .Nm dwarf_get_END_name , .Nm dwarf_get_FORM_name , .Nm dwarf_get_ID_name , .Nm dwarf_get_INL_name , .Nm dwarf_get_LANG_name , .Nm dwarf_get_LNE_name , .Nm dwarf_get_LNS_name , .Nm dwarf_get_MACINFO_name , .Nm dwarf_get_OP_name , .Nm dwarf_get_ORD_name , .Nm dwarf_get_TAG_name , .Nm dwarf_get_VIRTUALITY_name , .Nm dwarf_get_VIS_name .Nd retrieve the symbolic names of DWARF constants .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_ACCESS_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_AT_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_ATE_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_CC_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_CFA_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_CHILDREN_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_DS_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_DSC_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_EH_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_END_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_FORM_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_ID_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_INL_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_LANG_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_LNE_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_LNS_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_MACINFO_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_OP_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_ORD_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_TAG_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_VIRTUALITY_name .Fa "unsigned val" .Fa "char **str" .Fc .Ft int .Fo dwarf_get_VIS_name .Fa "unsigned val" .Fa "char **str" .Fc .Sh DESCRIPTION These functions return the symbolic name of a numeric DWARF constant. .Pp Argument .Ar val specifies the numeric value whose symbolic name is desired. .Pp Argument .Ar str should point to a location which will hold the returned NUL-terminated string containing the symbolic name of the specified value. .Pp The list of functions and the DWARF constants that they accept are: .Pp .Bl -tag -width ".Fn dwarf_get_VIRTUALITY_name" -compact .It Fn dwarf_get_ACCESS_name .Dv DW_ACCESS_* constants. .It Fn dwarf_get_AT_name .Dv DW_AT_* constants. .It Fn dwarf_get_ATE_name .Dv DW_ATE_* constants. .It Fn dwarf_get_CC_name .Dv DW_CC_* constants. .It Fn dwarf_get_CFA_name .Dv DW_CFA_* constants. .It Fn dwarf_get_CHILDREN_name .Dv DW_CHILDREN_* constants. .It Fn dwarf_get_DS_name .Dv DW_DS_* constants. .It Fn dwarf_get_DSC_name .Dv DW_DSC_* constants. .It Fn dwarf_get_EH_name .Dv DW_EH_PE_* constants. .It Fn dwarf_get_END_name .Dv DW_END_* constants. .It Fn dwarf_get_FORM_name .Dv DW_FORM_* constants. .It Fn dwarf_get_ID_name .Dv DW_ID_* constants. .It Fn dwarf_get_INL_name .Dv DW_INL_* constants. .It Fn dwarf_get_LANG_name .Dv DW_LANG_* constants. .It Fn dwarf_get_LNE_name .Dv DW_LNE_* constants. .It Fn dwarf_get_LNS_name .Dv DW_LNS_* constants. .It Fn dwarf_get_MACINFO_name .Dv DW_MACINFO_* constants. .It Fn dwarf_get_OP_name .Dv DW_OP_* constants. .It Fn dwarf_get_ORD_name .Dv DW_ORD_* constants. .It Fn dwarf_get_TAG_name .Dv DW_TAG_* constants. .It Fn dwarf_get_VIRTUALITY_name .Dv DW_VIRTUALITY_* constants. .It Fn dwarf_get_VIS_name .Dv DW_VIS_* constants. .El .Sh RETURN VALUES These functions return -.Dv DW_DLV_OK on success. +.Dv DW_DLV_OK +on success. If the DWARF constant denoted by argument .Ar val is not recognized, these function return .Dv DW_DLV_NO_ENTRY . .Sh SEE ALSO .Xr dwarf 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev.3 (revision 367466) @@ -1,179 +1,179 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_abbrev.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_abbrev.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd March 27, 2011 -.Os .Dt DWARF_GET_ABBREV 3 +.Os .Sh NAME .Nm dwarf_get_abbrev .Nd retrieve abbreviation information .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_abbrev .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Unsigned offset" .Fa "Dwarf_Abbrev *ret_abbrev" .Fa "Dwarf_Unsigned *length" .Fa "Dwarf_Unsigned *attr_count" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_abbrev retrieves information about an abbreviation from the DWARF abbreviations section, .Dq ".debug_abbrev" . Abbreviation information is returned using an opaque descriptor of type .Vt Dwarf_Abbrev . The returned .Vt Dwarf_Abbrev descriptor may then be passed to the other abbreviation related APIs in the DWARF(3) API to retrieve specific information about the abbreviation. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar offset should be an offset, relative to the .Dq ".debug_abbrev" section, to the start of an abbreviation entry. .Pp Argument .Ar ret_abbrev should point to a location that will hold a pointer to the returned .Vt Dwarf_Abbrev descriptor. .Pp Argument .Ar length should point to a location that will hold the number of bytes used by the abbrevation in the DWARF .Dq ".debug_abbrev" section. .Pp Argument .Ar attr_count should point to a location that will hold the number of attributes in the abbrevation. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Ss Memory Management The memory area used for the .Vt Dwarf_Abbrev descriptor returned in argument .Ar ret_abbrev is allocated by the .Lb libdwarf . Application code should use function .Fn dwarf_dealloc with the allocation type .Dv DW_DLA_ABBREV to free the memory area when the .Vt Dwarf_Abbrev descriptor is no longer needed. .Ss Application Programming Notes The last abbreviation entry in a standard DWARF abbreviation section will have a special length value of 1. .Sh RETURN VALUES Function .Fn dwarf_get_abbrev returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if there is no abbreviation information at offset .Ar offset . In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_abbrev -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar ret_abbrev , -.Ar length -or -.Ar attr_count -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There is no abbreviation information at offset -.Ar offset . -.El -.Sh EXAMPLE +.Sh EXAMPLES To loop through all the abbreviation information associated with a DWARF debug context, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Abbrev ab; Dwarf_Off aboff; Dwarf_Unsigned length, attr_count; Dwarf_Half tag; Dwarf_Error de; int ret; while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, &aboff, NULL, NULL, &de)) == DW_DLV_OK) { while ((ret = dwarf_get_abbrev(re->dbg, aboff, &ab, &length, &attr_count, &de)) == DW_DLV_OK) { if (length == 1) /* Last entry. */ break; aboff += length; if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { warnx("dwarf_get_abbrev_tag failed: %s", dwarf_errmsg(de)); continue; } if (ret != DW_DLV_OK) warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); .Ed +.Sh ERRORS +Function +.Fn dwarf_get_abbrev +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ret_abbrev , +.Ar length +or +.Ar attr_count +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no abbreviation information at offset +.Ar offset . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , -.Xr dwarf_get_abbrev_tag 3 , -.Xr dwarf_get_abbrev_code 3 , .Xr dwarf_get_abbrev_children_flag 3 , -.Xr dwarf_get_abbrev_entry 3 +.Xr dwarf_get_abbrev_code 3 , +.Xr dwarf_get_abbrev_entry 3 , +.Xr dwarf_get_abbrev_tag 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_children_flag.3 (revision 367466) @@ -1,100 +1,99 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_abbrev_children_flag.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_abbrev_children_flag.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd March 14, 2011 -.Os .Dt DWARF_GET_ABBREV_CHILDREN_FLAG 3 +.Os .Sh NAME .Nm dwarf_get_abbrev_children_flag .Nd return a flag indicating the presence of children .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_abbrev_children_flag .Fa "Dwarf_Abbrev abbrev" .Fa "Dwarf_Signed *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_abbrev_children_flag retrieves a flag indicating whether the DWARF debug information entry associated with a DWARF abbreviation descriptor has child entries. .Pp Argument .Ar abbrev should be a valid DWARF abbreviation descriptor, as returned by .Xr dwarf_get_abbrev 3 . .Pp Argument .Ar ret should point to a location which will hold the returned flag. The value returned will be one of the following: .Bl -tag -width ".Dv DW_CHILDREN_yes" -compact .It Dv DW_CHILDREN_yes The debugging information entry associated with the specified abbreviation descriptor has children. .It Dv DW_CHILDREN_no The debugging information entry associated with the specified abbreviation descriptor has no children. .El .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. -.Pp .Sh RETURN VALUES Function .Fn dwarf_get_abbrev_children_flag returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_abbrev_children_flag can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar abbrev or .Ar ret was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_abbrev 3 , .Xr dwarf_get_abbrev_code 3 , -.Xr dwarf_get_abbrev_tag 3 , -.Xr dwarf_get_abbrev_entry 3 +.Xr dwarf_get_abbrev_entry 3 , +.Xr dwarf_get_abbrev_tag 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_code.3 (revision 367466) @@ -1,86 +1,86 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_abbrev_code.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_abbrev_code.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd March 13, 2011 -.Os .Dt DWARF_GET_ABBREV_CODE 3 +.Os .Sh NAME .Nm dwarf_get_abbrev_code .Nd retrieve the abbreviation code for an abbreviation .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_abbrev_code .Fa "Dwarf_Abbrev abbrev" .Fa "Dwarf_Unsigned *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_abbrev_code retrieves the abbreviation code for the abbreviation entry descriptor referenced by argument .Ar abbrev . .Pp Argument .Ar ret should point to a location which will hold the returned abbreviation code. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_abbrev_code returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_abbrev_code can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar abbrev or .Ar ret was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_abbrev 3 , -.Xr dwarf_get_abbrev_tag 3 , .Xr dwarf_get_abbrev_children_flag 3 , -.Xr dwarf_get_abbrev_entry 3 +.Xr dwarf_get_abbrev_entry 3 , +.Xr dwarf_get_abbrev_tag 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_entry.3 (revision 367466) @@ -1,159 +1,159 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_abbrev_entry.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_abbrev_entry.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 02, 2011 -.Os .Dt DWARF_GET_ABBREV_ENTRY 3 +.Os .Sh NAME .Nm dwarf_get_abbrev_entry .Nd retrieve attribute information from an abbreviation descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_abbrev_entry .Fa "Dwarf_Abbrev abbrev" .Fa "Dwarf_Signed ndx" .Fa "Dwarf_Half *code" .Fa "Dwarf_Signed *form" .Fa "Dwarf_Off *offset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_abbrev_entry retrieves attribute information from a DWARF abbreviation descriptor. .Pp Argument .Ar abbrev should be a valid abbreviation descriptor, as returned by function .Xr dwarf_get_abbrev 3 . .Pp Argument .Ar ndx specifies the 0-based index of the attribute. The total count of the attributes contained in the abbreviation entry can be retrieved using the function .Xr dwarf_get_abbrev 3 . .Pp Argument .Ar code should point to a location which will hold a returned attribute code. .Pp Argument .Ar form should point to a location which will hold the returned form of the attribute. .Pp Argument .Ar offset should point to a location which will hold a returned offset, relative to the .Dq ".debug_abbrev" section, for the specified attribute. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_abbrev_entry returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if the attribute index specified by argument .Ar ndx is out of range. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_abbrev_entry -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar abbrev , -.Ar code , -.Ar form -or -.Ar offset -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -The attribute index specified by argument -.Ar ndx -was out of range. -.El -.Sh EXAMPLE +.Sh EXAMPLES To loop through all the attribute entries contained in the abbreviation section, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Abbrev ab; Dwarf_Off aboff, atoff; Dwarf_Signed form; Dwarf_Half attr; Dwarf_Unsigned length, attr_count; Dwarf_Error de; int i, ret; /* ...allocate 'dbg' using dwarf_init(3) ... */ while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, &aboff, NULL, NULL, &de)) == DW_DLV_OK) { while ((ret = dwarf_get_abbrev(dbg, aboff, &ab, &length, &attr_count, &de)) == DW_DLV_OK) { if (length == 1) /* Last entry. */ break; aboff += length; for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) { if (dwarf_get_abbrev_entry(ab, i, &attr, &form, &atoff, &de) != DW_DLV_OK) { warnx("dwarf_get_abbrev_entry failed:" " %s", dwarf_errmsg(de)); continue; } /* .. use the retrieved information ... */ } } if (ret != DW_DLV_OK) warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); .Ed +.Sh ERRORS +Function +.Fn dwarf_get_abbrev_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar abbrev , +.Ar code , +.Ar form +or +.Ar offset +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The attribute index specified by argument +.Ar ndx +was out of range. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_abbrev 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_abbrev_tag.3 (revision 367466) @@ -1,86 +1,86 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_abbrev_tag.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_abbrev_tag.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd March 13, 2011 -.Os .Dt DWARF_GET_ABBREV_TAG 3 +.Os .Sh NAME .Nm dwarf_get_abbrev_tag .Nd retrieve the tag for an abbreviation .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_abbrev_tag .Fa "Dwarf_Abbrev abbrev" .Fa "Dwarf_Half *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_abbrev_tag retrieves the tag for the abbreviation entry descriptor referenced by argument .Ar abbrev . .Pp Argument .Ar ret should point to a location which will hold the returned abbreviation tag. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_abbrev_tag returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_abbrev_tag can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar abbrev or .Ar ret was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_abbrev 3 , -.Xr dwarf_get_abbrev_code 3 , .Xr dwarf_get_abbrev_children_flag 3 , +.Xr dwarf_get_abbrev_code 3 , .Xr dwarf_get_abbrev_entry 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_address_size.3 (revision 367466) @@ -1,82 +1,82 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_get_address_size.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_address_size.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 14, 2010 -.Os .Dt DWARF_GET_ADDRESS_SIZE 3 +.Os .Sh NAME .Nm dwarf_get_address_size .Nd return the number of bytes needed to represent an address .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_address_size .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Half *addr_size" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_address_size returns the size in bytes of a native address for a program object. .Pp Argument .Ar dbg should denote a DWARF debug context created from a program object using .Xr dwarf_init 3 . Argument .Ar addr_size should point to a location that will hold the returned size. Argument .Ar err , if non-NULL, it will be used to return error information. .Sh RETURN VALUES On success, function .Fn dwarf_tag returns .Dv DW_DLV_OK . In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_address_size can fail with the following error: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arguments .Ar dbg or .Ar addr_size was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_init 3 , -.Xr dwarf_finish 3 +.Xr dwarf_finish 3 , +.Xr dwarf_init 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_arange.3 (revision 367466) @@ -1,121 +1,121 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_arange.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_arange.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 16, 2011 -.Os .Dt DWARF_GET_ARANGE 3 +.Os .Sh NAME .Nm dwarf_get_arange .Nd retrieve the address range descriptor for an address .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_arange .Fa "Dwarf_Arange *ar_list" .Fa "Dwarf_Unsigned ar_cnt" .Fa "Dwarf_Addr addr" .Fa "Dwarf_Arange *ret_ar" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_arange searches an array of .Vt Dwarf_Arange descriptors for one that covers a given address. .Pp Argument .Ar ar_list should point to an array of .Vt Dwarf_Arange descriptors. .Pp Argument .Ar ar_cnt specifies the number of .Vt Dwarf_Arange descriptors in the array pointed to by argument .Ar ar_list . .Pp Argument .Ar addr specifies the address being looked up. .Pp Argument .Ar ret_ar will be used to store the .Vt Dwarf_Arange descriptor that covers the given address. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_arange returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if there is no .Vt Dwarf_Arange descriptor that covers the provided address. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_arange can fail with: .Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar ar_list or .Ar ret_ar was NULL. .It Bq Er DW_DLE_ARGUMENT Value of argument .Ar ar_cnt equals to 0. .It Bq Er DW_DLE_NO_ENTRY A .Vt Dwarf_Arange descriptor that covers the given address was not found. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_get_aranges 3 , .Xr dwarf_get_arange_cu_header_offset 3 , .Xr dwarf_get_arange_info 3 , +.Xr dwarf_get_aranges 3 , .Xr dwarf_get_cu_die_offset 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 (revision 367466) @@ -1,135 +1,135 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_arange_info.3 3142 2015-01-29 23:11:14Z jkoshy $ +.\" $Id: dwarf_get_arange_info.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 16, 2011 -.Os .Dt DWARF_GET_ARANGE_INFO 3 +.Os .Sh NAME .Nm dwarf_get_arange_info .Nd extract address range information from a descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_arange_info .Fa "Dwarf_Arange ar" .Fa "Dwarf_Addr *start" .Fa "Dwarf_Unsigned *length" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_arange_info extracts address range information from a .Vt Dwarf_Arange descriptor. .Pp Argument .Ar ar should reference a valid .Vt Dwarf_Arange descriptor returned by function .Xr dwarf_get_aranges 3 . .Pp Argument .Ar start should point to a location which will hold the start value of the address range associated with the descriptor. .Pp Argument .Ar length should point to a location which will hold the length in bytes of the address range associated with the descriptor. .Pp Argument .Ar cu_die_offset should point to a location which will be set to an offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar ar . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_arange_info returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_arange_info -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar ar , -.Ar start , -.Ar length -or -.Ar cu_die_offset -was NULL. -.El -.Sh EXAMPLE +.Sh EXAMPLES To loop through all the address lookup table entries, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Addr start; Dwarf_Arange *aranges; Dwarf_Off die_off; Dwarf_Signed i, cnt; Dwarf_Unsigned length; Dwarf_Error de; if (dwarf_get_aranges(dbg, &aranges, &cnt, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_aranges: %s", dwarf_errmsg(de)); for (i = 0; i < cnt; i++) { if (dwarf_get_arange_info(aranges[i], &start, &length, &die_off, &de) != DW_DLV_OK) { warnx("dwarf_get_arange_info: %s", dwarf_errmsg(de)); continue; } /* Do something with the returned information. */ } .Ed +.Sh ERRORS +Function +.Fn dwarf_get_arange_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar ar , +.Ar start , +.Ar length +or +.Ar cu_die_offset +was NULL. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_arange 3 , -.Xr dwarf_get_aranges 3 , .Xr dwarf_get_arange_cu_header_offset 3 , +.Xr dwarf_get_aranges 3 , .Xr dwarf_get_cu_die_offset 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_aranges.3 (revision 367466) @@ -1,148 +1,148 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_aranges.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_get_aranges.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_GET_ARANGES 3 +.Os .Sh NAME .Nm dwarf_get_aranges .Nd retrieve program address space mappings .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_aranges .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Arange **ar_list" .Fa "Dwarf_Signed *ar_cnt" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION The function .Fn dwarf_get_aranges retrieves address range information from the .Dq ".debug_aranges" DWARF section. Information about address ranges is returned using opaque descriptors of type .Vt Dwarf_Arange , .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar ar_list should point to a location which will be set to a pointer to an array of .Vt Dwarf_Arange descriptors. .Pp Argument .Ar ar_cnt should point to a location which will be set to the number of descriptors returned. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Ss Memory Management The memory area used for the array returned in argument .Ar ar_list is owned by .Lb libdwarf . Application code should not attempt to directly free this area. Portable applications should instead use .Xr dwarf_dealloc 3 to indicate that the memory area may be freed. .Sh RETURN VALUES Function .Fn dwarf_get_aranges returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if there is no .Dq ".debug_aranges" section associated with the specified debugging context. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_aranges -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar ar_list -or -.Ar ar_cnt -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -The debugging context -.Ar dbg -did not contain a -.Dq ".debug_aranges" -string section. -.El -.Sh EXAMPLE +.Sh EXAMPLES To loop through all the address lookup table entries, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Addr start; Dwarf_Arange *aranges; Dwarf_Off die_off; Dwarf_Signed i, cnt; Dwarf_Unsigned length; Dwarf_Error de; if (dwarf_get_aranges(dbg, &aranges, &cnt, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_aranges: %s", dwarf_errmsg(de)); for (i = 0; i < cnt; i++) { if (dwarf_get_arange_info(aranges[i], &start, &length, &die_off, &de) != DW_DLV_OK) { warnx("dwarf_get_arange_info: %s", dwarf_errmsg(de)); continue; } /* Do something with the returned information. */ } .Ed +.Sh ERRORS +Function +.Fn dwarf_get_aranges +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ar_list +or +.Ar ar_cnt +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The debugging context +.Ar dbg +did not contain a +.Dq ".debug_aranges" +string section. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_arange 3 , .Xr dwarf_get_arange_cu_header_offset 3 , .Xr dwarf_get_arange_info 3 , .Xr dwarf_get_cu_die_offset 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_index.3 (revision 367466) @@ -1,86 +1,86 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_cie_index.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_cie_index.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd May 22, 2011 -.Os .Dt DWARF_GET_CIE_INDEX 3 +.Os .Sh NAME .Nm dwarf_get_cie_index .Nd retrieve the index of a CIE descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_cie_index .Fa "Dwarf_Cie cie" .Fa "Dwarf_Signed *cie_index" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_cie_index retrieves the zero-based index of a given CIE descriptor in the array of CIE descriptors returned by the functions .Xr dwarf_get_fde_list 3 and .Xr dwarf_get_fde_list_eh 3 . .Pp Argument .Ar cie should reference a valid DWARF CIE descriptor. .Pp Argument .Ar cie_index should point to a location that will hold the returned index. .Sh RETURN VALUES Function .Fn dwarf_get_cie_index returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_cie_index can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arugments .Ar cie or .Ar cie_index was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cie_info 3 , .Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_info.3 (revision 367466) @@ -1,150 +1,150 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_cie_info.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_cie_info.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd May 29, 2011 -.Os .Dt DWARF_GET_CIE_INFO 3 +.Os .Sh NAME .Nm dwarf_get_cie_info .Nd retrieve information associated with a CIE descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_cie_info .Fa "Dwarf_Cie cie" .Fa "Dwarf_Unsigned *cie_byte_len" .Fa "Dwarf_Small *version" .Fa "char **augmentation" .Fa "Dwarf_Unsigned *caf" .Fa "Dwarf_Unsigned *daf" .Fa "Dwarf_Half *ra" .Fa "Dwarf_Ptr *init_inst" .Fa "Dwarf_Unsigned *inst_len" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_cie_info retrieves the information associated with a given CIE descriptor. .Pp Argument .Ar cie should reference a valid DWARF CIE descriptor, such as would be returned by function .Xr dwarf_get_cie_of_fde 3 . .Pp Argument .Ar cie_byte_len should point to a location that will hold the length in bytes of the CIE descriptor itself. .Pp Argument .Ar version should point to a location that will hold the version number of the CIE descriptor. .Pp Arugment .Ar augmentation should point to a location that will be set to a pointer to a NUL-terminated string containing augmentation data encoded as UTF-8. .Pp Argument .Ar caf should point to a location that will hold the code alignment factor recorded in the CIE descriptor. .Pp Arugment .Ar daf should point to a location that will hold the data alignment factor recorded in the CIE descriptor. .Pp Argument .Ar ra should point to a location that will hold the return address recorded in the CIE descriptor. .Pp Argument .Ar init_inst should point to a location that will be set to a pointer to an array of bytes containing the initial instructions associated with the CIE descriptor. .Pp Argument .Ar inst_len should point to a location that will hold the length in bytes of the initial instructions returned in argument .Ar init_inst . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_cie_info returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_cie_info can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar cie , .Ar cie_byte_len , .Ar version , .Ar augmentation , .Ar caf , .Ar daf , .Ar ra , .Ar init_inst or .Ar inst_len was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cie_index 3 , .Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_instr_bytes 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_get_fde_range 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cie_of_fde.3 (revision 367466) @@ -1,88 +1,88 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_cie_of_fde.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_cie_of_fde.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd May 22, 2011 -.Os .Dt DWARF_GET_CIE_OF_FDE 3 +.Os .Sh NAME .Nm dwarf_get_cie_of_fde .Nd retrieve CIE descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_cie_of_fde .Fa "Dwarf_Fde fde" .Fa "Dwarf_Cie *ret_cie" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_cie_of_fde retrieves the CIE descriptor associated with a given FDE descriptor. .Pp Argument .Ar fde should reference a valid FDE descriptor. .Pp Argument .Ar ret_cie should point to a location that will hold the returned CIE descriptor. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_cie_of_fde returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_cie_of_fde can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of arugments .Ar fde or .Ar ret_cie was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_get_cie_info 3 , .Xr dwarf_get_cie_index 3 , +.Xr dwarf_get_cie_info 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_n 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_cu_die_offset.3 (revision 367466) @@ -1,103 +1,103 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_cu_die_offset.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_cu_die_offset.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 10, 2011 -.Os .Dt DWARF_GET_CU_DIE_OFFSET 3 +.Os .Sh NAME .Nm dwarf_get_arange_cu_header_offset , .Nm dwarf_get_cu_die_offset .Nd retrieve compilation unit offsets .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_arange_cu_header_offset .Fa "Dwarf_Arange ar" .Fa "Dwarf_Off *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_get_cu_die_offset .Fa "Dwarf_Arange ar" .Fa "Dwarf_Off *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve the offsets, relative to the .Dq ".debug_info" DWARF section, of the debugging information entries describing the compilation unit associated with a .Vt Dwarf_Arange descriptor. .Pp Function .Fn dwarf_get_arange_cu_header_offset retrieves the offset of the compilation unit header associated with argument .Ar ar , and stores it in the location pointed to by argument .Ar ret . .Pp Function .Fn dwarf_get_cu_die_offset retrieves the offset of the debugging information entry for the compilation unit associated with argument .Ar ar , and stores it in the location pointed to by argument .Ar ret . .Pp If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar ar was not a valid .Vt Dwarf_Arange descriptor. .It Bq Er DW_DLE_ARGUMENT Argument .Ar ret was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_arange 3 , .Xr dwarf_get_arange_info 3 , .Xr dwarf_get_aranges 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_die_infotypes_flag.3 (revision 367466) @@ -1,73 +1,73 @@ .\" Copyright (c) 2014 Kai Wang .\" 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: dwarf_get_die_infotypes_flag.3 3118 2014-12-20 20:30:06Z jkoshy $ +.\" $Id: dwarf_get_die_infotypes_flag.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd December 20, 2014 -.Os .Dt DWARF_GET_DIE_INFOTYPES_FLAG 3 +.Os .Sh NAME .Nm dwarf_get_die_infotypes_flag .Nd indicate the originating DWARF section for a DIE .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_Bool .Fo dwarf_get_die_infotypes_flag .Fa "Dwarf_Die die" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_die_infotypes_flag returns a flag indicating the originating DWARF section for the debugging information entry referenced by argument .Ar die . .Pp Argument .Ar die should reference a valid debugging information entry descriptor. .Sh RETURN VALUES Function .Fn dwarf_get_die_infotypes_flag returns a non-zero value if argument .Ar die originates in the .Dq .debug_info section. .Pp It returns zero if argument .Ar die originates in the .Dq .debug_types section. .Sh ERRORS Function .Fn dwarf_get_die_infotypes_flag always succeeds. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_next_cu_header_c 3 , .Xr dwarf_offdie_b 3 , .Xr dwarf_siblingof_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_elf.3 (revision 367466) @@ -1,103 +1,103 @@ .\" 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 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: dwarf_get_elf.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_get_elf.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_GET_ELF 3 +.Os .Sh NAME .Nm dwarf_get_elf .Nd retrieve the .Vt Elf descriptor associated with a .Vt Dwarf_Debug instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_elf .Fa "Dwarf_Debug dbg" .Fa "Elf **elf" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_elf returns the .Vt Elf descriptor associated with a .Vt Dwarf_Debug instance. .Pp Argument .Ar dbg should be a handle to a valid .Vt Dwarf_Debug instance returned by a prior call to .Xr dwarf_init 3 or .Xr dwarf_elf_init 3 . .Pp Argument .Ar elf points a location into which a handle to an .Vt Elf descriptor will be written. .Pp Argument .Ar err is used to record error information in case of failure. .Sh RETURN VALUES On success, function .Fn dwarf_get_elf returns .Dv DW_DLV_OK . In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh EXAMPLES To retrieve the .Vt Elf instance associated with a .Vt Dwarf_Debug instance use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Error de; Elf *elf; \&... allocate dbg using dwarf_init() etc ... if (dwarf_get_elf(dbg, &elf, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_elf: %s", dwarf_errmsg(de)); .Ed .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 , -.Xr dwarf_init 3 , .Xr dwarf_finish 3 , +.Xr dwarf_init 3 , .Xr elf 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_at_pc.3 (revision 367466) @@ -1,125 +1,125 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_at_pc.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_fde_at_pc.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd May 22, 2011 -.Os .Dt DWARF_GET_FDE_AT_PC 3 +.Os .Sh NAME .Nm dwarf_get_fde_at_pc .Nd retrieve the FDE descriptor for an address .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_at_pc .Fa "Dwarf_Fde *fdelist" .Fa "Dwarf_Addr pc" .Fa "Dwarf_Fde *ret_fde" .Fa "Dwarf_Addr *lopc" .Fa "Dwarf_Addr *hipc" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_at_pc searches the provided array of DWARF FDE descriptors for a descriptor covering a given program counter address. .Pp Argument .Ar fdelist should point to an array of FDE descriptors, as returned by the functions .Xr dwarf_get_fde_list 3 or .Xr dwarf_get_fde_list_eh 3 . .Pp Argument .Ar pc should contain the program counter address being looked up. .Pp Argument .Ar ret_fde should point to a location that will hold the returned FDE descriptor. .Pp Argument .Ar lopc should point to a location that will be set to the lowest address covered by the returned FDE descriptor. .Pp Argument .Ar hipc should point to a location that will be set to the highest address covered by the returned FDE descriptor. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_fde_at_pc returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if a FDE descriptor that covers the address specified by argument .Ar pc is not found. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_at_pc can fail with: .Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va fdelist , .Va ret_fde , .Va lopc , or .Va hipc was NULL. .It Bq Er DW_DLE_NO_ENTRY These was no FDE descriptor covering the address specified by argument .Ar pc . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_instr_bytes 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_get_fde_range 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs.3 (revision 367466) @@ -1,156 +1,156 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_info_for_all_regs.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_get_fde_info_for_all_regs.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd June 4, 2011 -.Os .Dt DWARF_GET_FDE_INFO_FOR_ALL_REGS 3 +.Os .Sh NAME .Nm dwarf_get_fde_info_for_all_regs .Nd retrieve register rule row .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_info_for_all_regs .Fa "Dwarf_Fde fde" .Fa "Dwarf_Addr pc" .Fa "Dwarf_Regtable *reg_table" .Fa "Dwarf_Addr *row_pc" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_info_for_all_regs retrieves a row from the register rule table associated with the given FDE descriptor. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Argument .Ar pc should hold the program counter address to be used to locate the desired table row. .Pp Argument .Ar reg_table should point to a .Vt Dwarf_Regtable descriptor which will hold the returned table row of register rules. .Pp Argument .Ar row_pc should point to a location which will be set to the lowest program counter address associated with the table row. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp The .Vt Dwarf_Regtable descriptor is defined in the header file .In libdwarf.h : .Bd -literal -offset indent typedef struct { struct { Dwarf_Small dw_offset_relevant; Dwarf_Half dw_regnum; Dwarf_Addr dw_offset; } rules[DW_REG_TABLE_SIZE]; } Dwarf_Regtable; .Ed .Pp For each of the register rules returned, the .Va dw_offset_relevant field is set to 1 if the register rule has a offset value. The .Va dw_regnum field is set to the register number associated with the regsiter rule. The .Va dw_offset field is set to the offset value associated with the register rule. .Pp The number of register columns returned is either the constant value .Dv DW_REG_TABLE_SIZE as defined in the header file .In libdwarf.h , or the value set by function .Xr dwarf_set_frame_rule_table_size 3 , whichever is smaller. .Ss COMPATIBILITY Function .Fn dwarf_get_fde_info_for_all_regs is deprecated since it only supports DWARF2 frame sections. Applications should instead use function .Xr dwarf_get_fde_info_for_all_regs3 3 which supports both DWARF2 and DWARF3 frame sections. .Sh RETURN VALUES Function .Fn dwarf_get_fde_info_for_all_regs returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_info_for_all_regs can fail with: .Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar fde , .Ar reg_table or .Ar row_pc was NULL. .It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE The program counter value provided in argument .Ar pc did not fall in the range covered by argument .Ar fde . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_set_frame_cfa_value 3 , -.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_same_value 3 , .Xr dwarf_set_frame_undefined_value 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_all_regs3.3 (revision 367466) @@ -1,183 +1,183 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_info_for_all_regs3.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_fde_info_for_all_regs3.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd June 26, 2011 -.Os .Dt DWARF_GET_FDE_INFO_FOR_ALL_REGS3 3 +.Os .Sh NAME .Nm dwarf_get_fde_info_for_all_regs3 .Nd retrieve register rule row .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_info_for_all_regs3 .Fa "Dwarf_Fde fde" .Fa "Dwarf_Addr pc" .Fa "Dwarf_Regtable3 *reg_table" .Fa "Dwarf_Addr *row_pc" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_info_for_all_regs3 retrieves a row from the register rule table associated with the given FDE descriptor. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Argument .Ar pc should hold the program counter address to be used to locate the desired table row. .Pp Argument .Ar reg_table should point to a .Vt Dwarf_Regtable3 descriptor which will hold the returned table row of register rules. The .Vt Dwarf_Regtable3 descriptor is defined in the header file .In libdwarf.h : .Bd -literal -offset indent typedef struct { Dwarf_Small dw_offset_relevant; Dwarf_Small dw_value_type; Dwarf_Half dw_regnum; Dwarf_Unsigned dw_offset_or_block_len; Dwarf_Ptr dw_block_ptr; } Dwarf_Regtable_Entry3; typedef struct { Dwarf_Regtable_Entry3 rt3_cfa_rule; Dwarf_Half rt3_reg_table_size; Dwarf_Regtable_Entry3 *rt3_rules; } Dwarf_Regtable3; .Ed .Pp The .Va rt3_reg_table_size field specifies the maximum number of register rule columns to be returned, and should be set by the application before calling the function. The .Va rt3_rules field should point to a memory arena allocated by the application with space for at least .Vt rt3_reg_table_size descriptors of type .Vt Dwarf_Regtable_Entry3 . .Pp On a successful execution of this function, the .Va rt3_cfa_rule field will be set to the CFA register rule associated with the table row, and the .Va rt3_rules array will hold the returned register rules contained in the table row. .Pp For each register rule descriptor returned, the .Va dw_offset_relevant field will be set to 1 if the register rule has a offset value, the .Va dw_value_type field will be set to the type code of the register rule and the .Va dw_regnum field will be set to the register number associated with the register rule. If the register rule is of type .Dv DW_EXPR_OFFSET or .Dv DW_EXPR_VAL_OFFSET , the .Va dw_offset_or_block_len field will be set to the offset value associated with the register rule. If the type is .Dv DW_EXPR_EXPRESSION or .Dv DW_EXPR_VAL_EXPRESSION , the .Va dw_offset_or_block_len field will be set to the length in bytes of the DWARF expression block associated with the register rule. The .Va dw_block_ptr field will be set to a pointer to the content of the DWARF expression block associated with the register rule. .Pp Argument .Ar row_pc should point to a location which will be set to the lowest program counter address associated with the table row. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_fde_info_for_all_regs3 returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_info_for_all_regs3 can fail with: .Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar fde , .Ar reg_table or .Ar row_pc was NULL. .It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE The program counter value provided in argument .Ar pc did not fall in the range covered by argument .Ar fde . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_set_frame_cfa_value 3 , -.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_same_value 3 , .Xr dwarf_set_frame_undefined_value 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_cfa_reg3.3 (revision 367466) @@ -1,171 +1,171 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_info_for_cfa_reg3.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_fde_info_for_cfa_reg3.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd June 12, 2011 -.Os .Dt DWARF_GET_FDE_INFO_FOR_CFA_REGS3 3 +.Os .Sh NAME .Nm dwarf_get_fde_info_for_cfa_regs3 .Nd retrieve a CFA register rule .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_info_for_cfa_regs3 .Fa "Dwarf_Fde fde" .Fa "Dwarf_Addr pc" .Fa "Dwarf_Small *type" .Fa "Dwarf_Signed *offset_relevant" .Fa "Dwarf_Signed *register_num" .Fa "Dwarf_Signed *offset_or_block_len" .Fa "Dwarf_Ptr *block_ptr" .Fa "Dwarf_Addr *row_pc" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_info_for_cfa_reg3 retrieves the CFA register rule for a given program counter address from the register rule table associated with an FDE descriptor. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Argument .Ar pc should hold the program counter address to be used to locate the desired register rule row. .Pp On successful execution, .Fn dwarf_get_fde_info_for_cfa_reg3 stores information about the CFA register rule found into the locations pointed to by the arguments .Ar type , .Ar offset_relevant , .Ar register_num , .Ar offset_or_block_len , .Ar block_ptr and .Ar row_pc . .Pp Argument .Ar type should point to a location which will hold the type code of the register rule found. The returned value is one of the .Dv DW_EXPR_* contants defined in the header file .In libdwarf.h . .Pp If there is an offset value associated with the CFA register rule, the location pointed to by argument .Ar offset_relevant will be set to 1. .Pp Argument .Ar register_num should point to a location which will hold the register number associated with the CFA register rule. .Pp If the CFA register rule is of type .Dv DW_EXPR_OFFSET or .Dv DW_EXPR_VAL_OFFSET , the location pointed to by argument .Ar offset_or_block_len will be set to the offset value associated with the register rule, or to 0 if the register rule does not have an offset value. If the type code is .Dv DW_EXPR_EXPRESSION or .Dv DW_EXPR_VAL_EXPRESSION , the location pointed to by argument .Ar offset_or_block_len will be set to the length in bytes of the DWARF expression block associated with the register rule. .Pp Argument .Ar block_ptr should point to a location which will be set to a pointer to the content of the DWARF expression block associated with the CFA register rule. .Pp Argument .Ar row_pc should point to a location which will be set to the lowest program counter address associated with the register rule found. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_fde_info_for_cfa_reg3 returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_info_for_cfa_reg3 can fail with: .Bl -tag -width ".Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar block_ptr , .Ar fde , .Ar offset_or_block_len , .Ar offset_relevant , .Ar register_num , .Ar row_pc , or .Ar type was NULL. .It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE The program counter value provided in argument .Ar pc did not fall in the range covered by argument .Ar fde . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_set_frame_cfa_value 3 , -.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_same_value 3 , .Xr dwarf_set_frame_undefined_value 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg.3 (revision 367466) @@ -1,156 +1,156 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_info_for_reg.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_get_fde_info_for_reg.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd June 4, 2011 -.Os .Dt DWARF_GET_FDE_INFO_FOR_REG 3 +.Os .Sh NAME .Nm dwarf_get_fde_info_for_reg .Nd retrieve register rule .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_info_for_reg .Fa "Dwarf_Fde fde" .Fa "Dwarf_Half table_column" .Fa "Dwarf_Addr pc" .Fa "Dwarf_Signed *offset_relevant" .Fa "Dwarf_Signed *register_num" .Fa "Dwarf_Signed *offset" .Fa "Dwarf_Addr *row_pc" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_info_for_reg retrieves a register rule from the register rule table associated with a given FDE descriptor, given a program counter address and rule column number. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Arugment .Ar table_column should hold the column number of the register rule desired. .Pp Argument .Ar pc should hold the program counter address to be used to locate the desired register rule row. .Pp On successful execution, .Fn dwarf_get_fde_info_for_reg stores information about the register rule found into the locations pointed to by the arguments .Ar offset_relevant , .Ar register_num , .Ar offset and .Ar row_pc . .Pp If there is an offset value associated with the register rule, the location pointed to by argument .Ar offset_relevant will be set to 1. .Pp Argument .Ar register_num should point to a location which will hold the register number associated with the register rule. .Pp Argument .Ar offset should point to a location which will be set to the offset value associated with the register rule, or to 0 if the register rule does not have an offset value. .Pp Argument .Ar row_pc should point to a location which will be set to the lowest program counter address associated with the register rule found. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Ss COMPATIBILITY Function .Fn dwarf_get_fde_info_for_reg is deprecated since it only supports DWARF2 frame sections. Applications should instead use function .Xr dwarf_get_fde_info_for_reg3 3 which supports both DWARF2 and DWARF3 frame sections. .Sh RETURN VALUES Function .Fn dwarf_get_fde_info_for_reg returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_info_for_reg can fail with: .Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar fde , .Ar offset_relevant , .Ar register_num , .Ar offset or .Ar row_pc was NULL. .It Bq Er DW_DLE_FRAME_TABLE_COL_BAD The column number provided in argument .Ar table_column was too large. .It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE The program counter value provided in argument .Ar pc did not fall in the range covered by argument .Ar fde . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_set_frame_cfa_value 3 , -.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_same_value 3 , .Xr dwarf_set_frame_undefined_value 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_info_for_reg3.3 (revision 367466) @@ -1,214 +1,214 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_info_for_reg3.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_get_fde_info_for_reg3.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_GET_FDE_INFO_FOR_REG3 3 +.Os .Sh NAME .Nm dwarf_get_fde_info_for_reg3 .Nd retrieve register rule .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_info_for_reg3 .Fa "Dwarf_Fde fde" .Fa "Dwarf_Half table_column" .Fa "Dwarf_Addr pc" .Fa "Dwarf_Small *type" .Fa "Dwarf_Signed *offset_relevant" .Fa "Dwarf_Signed *register_num" .Fa "Dwarf_Signed *offset_or_block_len" .Fa "Dwarf_Ptr *block_ptr" .Fa "Dwarf_Addr *row_pc" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_info_for_reg3 retrieves a register rule from the register rule table associated with a given FDE descriptor, given a program counter address and rule column number. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Arugment .Ar table_column should hold the column number of the register rule desired. .Pp Argument .Ar pc should hold the program counter address to be used to locate the desired register rule row. .Pp On successful execution, .Fn dwarf_get_fde_info_for_reg3 stores information about the register rule found into the locations pointed to by the arguments .Ar type , .Ar offset_relevant , .Ar register_num , .Ar offset_or_block_len , .Ar block_ptr and .Ar row_pc . .Pp Argument .Ar type should point to a location which will hold the type code of the register rule found. The returned value is one of the .Dv DW_EXPR_* contants defined in the header file .In libdwarf.h . .Pp If there is an offset value associated with the register rule, the location pointed to by argument .Ar offset_relevant will be set to 1. .Pp Argument .Ar register_num should point to a location which will hold the register number associated with the register rule. .Pp If the register rule is of type .Dv DW_EXPR_OFFSET or .Dv DW_EXPR_VAL_OFFSET , the location pointed to by argument .Ar offset_or_block_len will be set to the offset value associated with the register rule, or to 0 if the register rule does not have an offset value. If the type code is .Dv DW_EXPR_EXPRESSION or .Dv DW_EXPR_VAL_EXPRESSION , the location pointed to by argument .Ar offset_or_block_len will be set to the length in bytes of the DWARF expression block associated with the register rule. .Pp Argument .Ar block_ptr should point to a location which will be set to a pointer to the content of the DWARF expression block associated with the register rule. .Pp Argument .Ar row_pc should point to a location which will be set to the lowest program counter address associated with the register rule found. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_fde_info_for_reg3 returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_fde_info_for_reg3 -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar block_ptr , -.Ar fde , -.Ar offset_or_block_len , -.Ar offset_relevant , -.Ar register_num , -.Ar row_pc , -or -.Ar type -was NULL. -.It Bq Er DW_DLE_FRAME_TABLE_COL_BAD -The column number provided in argument -.Ar table_column -was too large. -.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE -The program counter value provided in argument -.Ar pc -did not fall in the range covered by argument -.Ar fde . -.El -.Sh EXAMPLE +.Sh EXAMPLES To retrieve the register rules at column 3 from a rule table associated with a FDE descriptor: .Bd -literal -offset indent Dwarf_Fde fde; Dwarf_Off fde_offset, cie_offset; Dwarf_Unsigned func_len, fde_length; Dwarf_Signed cie_index, offset_relevant, register_num; Dwarf_Signed offset_or_block_len; Dwarf_Addr low_pc, row_pc; Dwarf_Ptr fde_addr, block_ptr; Dwarf_Small type; Dwarf_Error de; /* ... assuming `fde` references a valid FDE descriptor... */ if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, &fde_length, &cie_offset, &cie_index, &fde_offset, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_get_fde_range failed: %s", dwarf_errmsg(de)); /* Iterate all the table rows. */ for (pc = low_pc; pc < low_pc + func_len; pc++) { if (dwarf_get_fde_info_for_reg3(fde, 3, pc, &type, &offset_relevant, ®ister_num, &offset_or_block_len, &block_ptr, &row_pc, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_info_for_reg3 failed: %s", dwarf_errmsg(de)); continue; } /* ... use the retrieved register rule ... */ } .Ed +.Sh ERRORS +Function +.Fn dwarf_get_fde_info_for_reg3 +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_FRAME_TABLE_COL_BAD" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar block_ptr , +.Ar fde , +.Ar offset_or_block_len , +.Ar offset_relevant , +.Ar register_num , +.Ar row_pc , +or +.Ar type +was NULL. +.It Bq Er DW_DLE_FRAME_TABLE_COL_BAD +The column number provided in argument +.Ar table_column +was too large. +.It Bq Er DW_DLE_PC_NOT_IN_FDE_RANGE +The program counter value provided in argument +.Ar pc +did not fall in the range covered by argument +.Ar fde . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_set_frame_cfa_value 3 , -.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_same_value 3 , .Xr dwarf_set_frame_undefined_value 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_instr_bytes.3 (revision 367466) @@ -1,113 +1,113 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_instr_bytes.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_fde_instr_bytes.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd May 23, 2011 -.Os .Dt DWARF_GET_FDE_INSTR_BYTES 3 +.Os .Sh NAME .Nm dwarf_get_fde_instr_bytes .Nd retrieve instructions from FDE descritpor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_instr_bytes .Fa "Dwarf_Fde fde" .Fa "Dwarf_Ptr *ret_inst" .Fa "Dwarf_Unsigned *ret_len" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_instr_bytes retrieves instruction bytes from a given FDE descriptor. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Argument .Ar ret_inst should point to a location that will be set to a pointer to an array of bytes containing the instructions of the FDE descriptor. .Pp Argument .Ar ret_len should point to a location that will hold the length in bytes of the instructions returned in argument .Ar ret_inst . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Applications can use the function .Xr dwarf_expand_frame_instructions 3 to parse and expand the returned instruction bytes into an array of .Vt Dwarf_Frame_Op descriptors. .Sh RETURN VALUES Function .Fn dwarf_get_fde_instr_bytes returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_instr_bytes can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar fde , .Ar ret_inst or .Ar ret_len was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_expand_frame_instructions 3 , -.Xr dwarf_get_cie_info 3 , .Xr dwarf_get_cie_index 3 , -.Xr dwarf_get_cie_of_fde , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_get_fde_range 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_list.3 (revision 367466) @@ -1,218 +1,218 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_list.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_get_fde_list.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_GET_FDE_LIST 3 +.Os .Sh NAME .Nm dwarf_get_fde_list .Nd retrieve frame information .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_list .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Cie **cie_list" .Fa "Dwarf_Signed *cie_count" .Fa "Dwarf_Fde **fde_list" .Fa "Dwarf_Signed *fde_count" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_get_fde_list_eh .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Cie **cie_list" .Fa "Dwarf_Signed *cie_count" .Fa "Dwarf_Fde **fde_list" .Fa "Dwarf_Signed *fde_count" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve frame related information for the specified DWARF debug context. .Pp Function .Fn dwarf_get_fde_list retrieves frame information from the DWARF section named .Dq ".debug_frame" . For objects containing GNU style C++ exception handling information, the function .Fn dwarf_get_fde_list_eh retrieves frame information from the section named .Dq ".eh_frame" . .Pp Frame information is returned using opaque descriptors of type .Vt Dwarf_Cie and .Vt Dwarf_Fde . Applications need to use the other frame related functions in the DWARF(3) API set to retrieve the information contained in these descriptors. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar cie_list should point to a location that will be set to a pointer to an array of .Vt Dwarf_Cie descriptors. .Pp Argument .Ar cie_count should point to a location that will be set to the number of .Vt Dwarf_Cie descriptors returned. .Pp Argument .Ar fde_list should point to a location that will be set to a pointer to an array of .Vt Dwarf_Fde descriptors. .Pp Argument .Ar fde_count should point to a location that will be set to the number of .Vt Dwarf_Fde descriptors returned. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Ss Memory Management The memory areas used for the arrays returned in arguments .Ar cie_list and .Ar fde_list are owned by the .Lb libdwarf . Application code should not attempt to directly free these areas. Portable applications should instead use the .Xr dwarf_fde_cie_list_dealloc 3 function to indicate that these memory areas may be freed. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . They return .Dv DW_DLV_NO_ENTRY if there is no frame information associated with the given DWARF debug context. In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . -.Sh ERRORS -These functions may fail with the following errors: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Va dbg , -.Va cie_list , -.Va cie_count , -.Va fde_list -or -.Va fde_count -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There is no frame information associated with the giving DWARF debug -context. -.El -.Sh EXAMPLE +.Sh EXAMPLES To obtain frame information from the .Dq ".debug_frame" section, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Cie *cie_list, cie; Dwarf_Fde *fde_list, fde; Dwarf_Off fde_offset, cie_offset; Dwarf_Unsigned func_len, fde_length, fde_instlen; Dwarf_Signed cie_count, fde_count, cie_index; Dwarf_Addr low_pc; Dwarf_Ptr fde_addr, fde_inst, cie_inst; Dwarf_Error de; int i; if (dwarf_get_fde_list(dbg, &cie_list, &cie_count, &fde_list, &fde_count, &de) != DW_DLV_OK) { errx(EXIT_FAILURE, "dwarf_get_fde_list failed: %s", dwarf_errmsg(de)); } for (i = 0; i < fde_count; i++) { if (dwarf_get_fde_n(fde_list, i, &fde, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, &fde_length, &cie_offset, &cie_index, &fde_offset, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_range failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_instr_bytes failed: %s", dwarf_errmsg(de)); continue; } /* ... Use the retrieved frame information ... */ } /* Indicate that the returned arrays may be freed. */ dwarf_fde_cie_list_dealloc(dbg, cie_list, cie_count, fde_list, fde_count); .Ed +.Sh ERRORS +These functions may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Va dbg , +.Va cie_list , +.Va cie_count , +.Va fde_list +or +.Va fde_count +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no frame information associated with the giving DWARF debug +context. +.El .Sh SEE ALSO .Xr dwarf 3 , +.Xr dwarf_fde_cie_list_dealloc 3 , .Xr dwarf_get_cie_index 3 , .Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_instr_bytes 3 , .Xr dwarf_get_fde_n 3 , .Xr dwarf_get_fde_range 3 , -.Xr dwarf_fde_cie_list_dealloc 3 , .Xr dwarf_set_frame_cfa_value 3 , -.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_rule_initial_value 3 , +.Xr dwarf_set_frame_rule_table_size 3 , .Xr dwarf_set_frame_same_value 3 , .Xr dwarf_set_frame_undefined_value 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_n.3 (revision 367466) @@ -1,111 +1,111 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_n.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_fde_n.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd May 14, 2011 -.Os .Dt DWARF_GET_FDE_N 3 +.Os .Sh NAME .Nm dwarf_get_fde_n .Nd retrieve FDE descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_n .Fa "Dwarf_Fde *fdelist" .Fa "Dwarf_Unsigned fde_index" .Fa "Dwarf_Fde *ret_fde" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_n retrieves an FDE descriptor from an array of FDE descriptors. .Pp Argument .Ar fdelist should point to an array of FDE descriptors, as returned by the functions .Xr dwarf_get_fde_list 3 or .Xr dwarf_get_fde_list_eh 3 . .Pp Argument .Ar fde_index specifies the 0-based index of the desired FDE descriptor. .Pp Argument .Ar ret_fde should point to a location that will hold the returned FDE descriptor. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_fde_n returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if the FDE descriptor index specified by argument .Ar fde_index is out of range. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_n can fail with: .Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Ar fdelist or .Ar ret_fde was NULL. .It Bq Er DW_DLE_NO_ENTRY The FDE descriptor index specified by argument .Ar fde_index was out of range. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_instr_bytes 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 , .Xr dwarf_get_fde_range 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_fde_range.3 (revision 367466) @@ -1,149 +1,149 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_fde_range.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_fde_range.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd May 22, 2011 -.Os .Dt DWARF_GET_FDE_RANGE 3 +.Os .Sh NAME .Nm dwarf_get_fde_range .Nd retrieve range information from an FDE descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_fde_range .Fa "Dwarf_Fde fde" .Fa "Dwarf_Addr *low_pc" .Fa "Dwarf_Unsigned *func_len" .Fa "Dwarf_Ptr *fde_bytes" .Fa "Dwarf_Unsigned *fde_byte_len" .Fa "Dwarf_Off *cie_offset" .Fa "Dwarf_Signed *cie_index" .Fa "Dwarf_Off *fde_offset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_fde_range retrieves range and offset information from a given FDE descriptor. .Pp Argument .Ar fde should reference a valid DWARF FDE descriptor. .Pp Argument .Ar low_pc should point to a location that will be set to the lowest program counter address covered by the FDE descriptor. .Pp Argument .Ar func_len should point to a location that will hold the length in bytes of the address range covered by the FDE descriptor. .Pp Argument .Ar fde_bytes should point to a location that will be set to a pointer to the content of the FDE descriptor itself. .Pp Argument .Ar fde_byte_len should point to a location that will hold the length in bytes of the FDE descriptor itself. .Pp Argument .Ar cie_offset should point to a location that will be set to the offset, relative to the DWARF .Dq ".debug_frame" section, of the CIE descriptor associated with the given FDE descriptor. .Pp Argument .Ar cie_index should point to a location that will hold the index of the CIE descriptor associated with the FDE descriptor. The returned value is a zero-based index into the array of CIE descriptors returned by a prior call to functions .Xr dwarf_get_fde_list 3 or .Xr dwarf_get_fde_list_eh 3 . .Pp Argument .Ar fde_offset should point to a location that will be set to the offset, relative to the DWARF .Dq ".debug_frame" section, of the FDE descriptor. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_fde_range returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_fde_range can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar fde , .Ar low_pc , .Ar func_len , .Ar fde_bytes , .Ar fde_byte_len , .Ar cie_offset , .Ar cie_index or .Ar fde_offset was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_get_cie_info 3 , .Xr dwarf_get_cie_index 3 , -.Xr dwarf_get_cie_of_fde , +.Xr dwarf_get_cie_info 3 , +.Xr dwarf_get_cie_of_fde 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_instr_bytes 3 , .Xr dwarf_get_fde_list 3 , .Xr dwarf_get_fde_list_eh 3 , .Xr dwarf_get_fde_n 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_form_class.3 (revision 367466) @@ -1,87 +1,87 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_form_class.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_form_class.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd June 26, 2011 -.Os .Dt DWARF_GET_FORM_CLASS 3 +.Os .Sh NAME .Nm dwarf_get_form_class .Nd retrieve the form class of an attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft enum Dwarf_Form_Class .Fo dwarf_get_form_class .Fa "Dwarf_Half dwversion" .Fa "Dwarf_Half attr" .Fa "Dwarf_Half offset_size" .Fa "Dwarf_Half form" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_form_class returns the class of the form of a DWARF attribute. .Pp Argument .Ar dwversion should specify the version number of DWARF specification to use: 2 for DWARF2, 3 for DWARF3 and 4 for DWARF4. .Pp Argument .Ar attr should hold the attribute code of the attribute, i.e., one of the .Li DW_AT_* values defined in .In libdwarf.h . .Pp Argument .Ar offset_size should hold the size of a DWARF offset for the relevant compilation unit. .Pp Argument .Ar form should hold the form code of the attribute. .Sh RETURN VALUES On success, function .Fn dwarf_get_form_class returns the form class code, which is one of the .Dv DW_FORM_CLASS_* contants defined in header file .In libdwarf.h . If the function was not able to determine the form class of the attribute, it returns the special form class code .Dv DW_FORM_CLASS_UNKNOWN . .Sh ERRORS Function .Fn dwarf_get_form_class does not return an error. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_whatattr 3 , .Xr dwarf_whatform 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_funcs.3 (revision 367466) @@ -1,215 +1,215 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_funcs.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_funcs.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 10, 2011 -.Os .Dt DWARF_GET_FUNCS 3 +.Os .Sh NAME .Nm dwarf_get_funcs , .Nm dwarf_func_cu_offset , .Nm dwarf_func_die_offset , .Nm dwarf_func_name_offsets , .Nm dwarf_funcname .Nd retrieve information about static functions .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_funcs .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Func **funcs" .Fa "Dwarf_Signed *nfuncs" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_func_cu_offset .Fa "Dwarf_Func func" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_func_die_offset .Fa "Dwarf_Func func" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_func_name_offsets .Fa "Dwarf_Func func" .Fa "char **name" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_funcname .Fa "Dwarf_Func func" .Fa "char **name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve information about static functions from the lookup tables in the (SGI-specific) .Dq ".debug_funcnames" section. Information about these functions is returned using opaque descriptors of type .Vt Dwarf_Func . Applications need to use the functions described below to retrieve the name and offset information contained in these descriptors. .Pp Function .Fn dwarf_get_funcs retrieves descriptors for all the static functions associated with the DWARF debug context specified by argument .Ar dbg . The argument .Ar funcs should point to a location that will be set to a pointer to an array of .Vt Dwarf_Func descriptors. The argument .Ar nfuncs should point to a location that will be set to the number of descriptors returned. .Pp Function .Fn dwarf_func_cu_offset returns the offset, relative to the .Dq ".debug_info" section, of the compilation unit that contains the debugging information entry associated with the argument .Ar func . Argument .Ar cu_offset should point to a location that will hold the returned offset. .Pp Function .Fn dwarf_func_die_offset retrieves the offset, relative to the .Dq ".debug_info" section, of the debugging information entry associated with the argument .Ar func , and stores it into the location pointed to by the argument .Ar die_offset . .Pp Function .Fn dwarf_func_name_offsets retrieves the name and offsets for the debugging information entry for argument .Ar func . Argument .Ar name should point to a location which will be set to a pointer to a NUL-terminated string containing the name of the associated debugging information entry. Argument .Ar die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the associated debugging information entry. Argument .Ar cu_die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar func . .Pp Function .Fn dwarf_funcname sets the location pointed to by argument .Ar name to a pointer to a NUL-terminated string holding the name of the debugging information entry associated with the argument .Ar func . .Ss Memory Management The memory area used for the array of .Vt Dwarf_Func descriptors returned in argument .Ar funcs by function .Fn dwarf_get_funcs is owned by the .Lb libdwarf . Application code should not attempt to directly free this pointer. Portable code should instead use the function .Xr dwarf_funcs_dealloc 3 to indicate that the memory area may be freed. .Pp The memory area used for the string returned in the .Ar name argument to functions .Fn dwarf_func_name_offsets and .Fn dwarf_funcname is owned by the .Lb libdwarf . Portable code should indicate that the memory area can be freed using the .Xr dwarf_dealloc 3 function. .Ss Error Returns If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_die_offset , .Va cu_offset , .Va dbg , .Va die_offset , .Va func , .Va funcs , .Va name , or .Va nfuncs was NULL. .It Bq Er DW_DLE_NO_ENTRY The DWARF debugging context referenced by argument .Ar dbg did not contain information about static functions. .El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , -.Xr dwarf_funcs_dealloc 3 +.Xr dwarf_funcs_dealloc 3 , +.Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_globals.3 (revision 367466) @@ -1,211 +1,211 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_globals.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_globals.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 2, 2011 -.Os .Dt DWARF_GET_GLOBALS 3 +.Os .Sh NAME .Nm dwarf_get_globals , .Nm dwarf_global_cu_offset , .Nm dwarf_global_die_offset , .Nm dwarf_global_name_offsets , .Nm dwarf_globname .Nd retrieve information about global objects .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_globals .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Global **globals" .Fa "Dwarf_Signed *nglobals" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_global_cu_offset .Fa "Dwarf_Global global" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_global_die_offset .Fa "Dwarf_Global global" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_global_name_offsets .Fa "Dwarf_Global global" .Fa "char **name" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_globname .Fa "Dwarf_Global global" .Fa "char **name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve information about global symbols from the lookup tables in the .Dq ".debug_pubnames" DWARF section. Information about these global symbols is returned using opaque descriptors of type .Vt Dwarf_Global . Applications need to use the functions described below to retrieve the name and the offsets for these descriptors. .Pp Function .Fn dwarf_get_globals retrieves descriptors for all the global symbols associated with the DWARF debug context specified by argument .Ar dbg . The argument .Ar globals should point to a location that will be set to a pointer to an array of .Vt Dwarf_Global descriptors. The argument .Ar nglobals should point to a location that will be set to the number of descriptors returned. .Pp Function .Fn dwarf_global_cu_offset returns the section-relative offset, relative to the .Dq ".debug_info" section, of the compilation unit that contains the debugging information entry associated with the argument .Ar global . Argument .Ar cu_offset should point to a location that will hold the returned offset. .Pp Function .Fn dwarf_global_die_offset retrieves the section-relative offset, relative to the .Dq ".debug_info" section, of the debugging information entry associated with the argument .Ar global , and stores it into the location pointed to by the argument .Ar die_offset . .Pp Function .Fn dwarf_global_name_offsets retrieves the name and the offsets for the debugging information entry for argument .Ar global . Argument .Ar name should point to a location which will be set to a pointer to a NUL-terminated string containing the name of the associated debugging information entry. Argument .Ar die_offset should point to a location which will be set to a section-relative offset, relative to the .Dq ".debug_info" section, of the associated debugging information entry. Argument .Ar cu_die_offset should point to a location which will be set to a section-relative offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar global . .Pp Function .Fn dwarf_globname sets the location pointed to by argument .Ar name to a pointer to a NUL-terminated string holding the name of the debugging information entry associated with the argument .Ar global . .Ss Memory Management The memory area used for the array of .Vt Dwarf_Global descriptors returned in argument .Ar globals by function .Fn dwarf_get_globals is owned by the .Lb libdwarf . Application code should not attempt to directly free this pointer. Portable code should instead use the function .Xr dwarf_globals_dealloc 3 to indicate that the memory area may be freed. .Pp The memory area used for the string returned in the .Ar name argument to functions .Fn dwarf_globname and .Fn dwarf_global_name_offsets is owned by the .Lb libdwarf . Portable code should use the .Xr dwarf_dealloc 3 function to indicate that the memory area may be freed. .Ss Error Returns If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_die_offset , .Va cu_offset , .Va dbg , .Va die_offset , .Va global , .Va globals , .Va name , or .Va nglobals was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_globals_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_loclist_entry.3 (revision 367466) @@ -1,156 +1,156 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_loclist_entry.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_loclist_entry.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd July 6, 2011 -.Os .Dt DWARF_GET_LOCLIST_ENTRY 3 +.Os .Sh NAME .Nm dwarf_get_loclist_entry .Nd retrieve DWARF location list entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_loclist_entry .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Unsigned offset" .Fa "Dwarf_Addr *hipc" .Fa "Dwarf_Addr *lopc" .Fa "Dwarf_Ptr *data" .Fa "Dwarf_Unsigned *entry_len" .Fa "Dwarf_Unsigned *next_entry" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_loclist_entry retrieves a location list entry from the DWARF section .Dq ".debug_loc" . .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar offset is an offset, relative to the .Dq ".debug_loc" section, to the start of the desired location list entry. .Pp Argument .Ar hipc should point to a location which will hold the offset, relative to the base address of the location list entry, of the highest program counter value for the entry. .Pp Argument .Ar lowpc should point to a location which will hold the offset, relative to the base address of the location list entry, of the lowest program counter value for the entry. .Pp Argument .Ar data should point to a location which will be set to a pointer to the location list data. .Pp Argument .Ar entry_len should point to a location which will hold the length in bytes of the location list data returned in argument .Ar data . .Pp Argument .Ar next_entry should point to a location which will hold the offset of the next location list entry. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_loclist_entry returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if there is no location list at the specified offset .Ar offset . In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_loclist_entry -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar hipc , -.Ar lopc , -.Ar data , -.Ar entry_len -or -.Ar next_entry -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There is no location list at the specified offset -.Ar offset . -.El -.Sh EXAMPLE +.Sh EXAMPLES To iterate through all the location list entries in the .Dq ".debug_loc" section, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Unsigned off, len, next; Dwarf_Addr hipc, lopc; Dwarf_Ptr data; Dwarf_Error de; int ret; off = 0; while ((ret = dwarf_get_loclist_entry(dbg, off, &hipc, &lopc, &data, &len, &next, &de)) == DW_DLV_OK) { /* ... use loclist entry ... */ off = next; } if (ret == DW_DLV_ERROR) warnx("dwarf_get_loclist_entry failed: %s", dwarf_errmsg(de)); .Ed +.Sh ERRORS +Function +.Fn dwarf_get_loclist_entry +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar hipc , +.Ar lopc , +.Ar data , +.Ar entry_len +or +.Ar next_entry +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no location list at the specified offset +.Ar offset . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_loclist 3 , -.Xr dwarf_loclist_n 3 , .Xr dwarf_loclist_from_expr 3 , -.Xr dwarf_loclist_from_expr_a 3 +.Xr dwarf_loclist_from_expr_a 3 , +.Xr dwarf_loclist_n 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_macro_details.3 (revision 367466) @@ -1,192 +1,192 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_macro_details.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_macro_details.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd March 20, 2011 -.Os .Dt DWARF_GET_MACRO_DETAILS 3 +.Os .Sh NAME .Nm dwarf_get_macro_details .Nd retrieve macro information .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_macro_details .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off offset" .Fa "Dwarf_Unsigned max_count" .Fa "Dwarf_Signed *entry_cnt" .Fa "Dwarf_Macro_Details **details" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_macro_details retrieves information about macros associated with a DWARF debug context. Information about macro entries are returned as an array of descriptors of type .Vt Dwarf_Macro_Details , with each .Vt Dwarf_Macro_Details descriptor describing one macro information entry. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . Argument .Ar offset is an offset, relative to the .Dq ".debug_macinfo" section, to the start of the desired macro information. Argument .Ar max_count specifies the maximum number of macro information entries to be returned, or 0 if all entries are to be returned. Argument .Ar entry_cnt should point to a location that will be set to the number of entries actually returned. Argument .Ar details should point to a location that will be set to a pointer to an array of .Vt Dwarf_Macro_Details descriptors. If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp .Vt Dwarf_Macro_Details descriptors are defined in the header file .In libdwarf.h , and consist of the following fields: .Bl -tag -width ".Va dmd_fileindex" -compact .It Va dmd_offset The section-relative offset within the .Dq ".debug_macinfo" section of the macro information entry being described. .It Va dmd_type The type code of this macro information entry; one of the .Dv DW_MACINFO_* constants defined by the DWARF specification. .It Va dmd_lineno The line number associated with the macro information entry, or 0 if there is no applicable line number. .It Va dmd_fileindex The source file index for the macro information entry. This field is only meaningful when .Va dmd_type field is set to .Dv DW_MACINFO_start_file . .It Va dmd_macro The contents of this field is a pointer to a NUL-terminated string whose meaning depends on the value of the .Va dmd_type field: .Bl -tag -width ".Dv DW_MACINFO_vendor_ext" -compact .It Dv DW_MACINFO_define The returned string contains the macro name and value. .It Dv DW_MACINFO_undef The string holds the macro name. .It Dv DW_MACINFO_vendor_ext The .Va dmd_macro field points to a vendor defined string. .El The field is NULL for other values of .Va dmd_type . .El .Ss Memory Management The memory area used for the array of .Vt Dwarf_Macro_Details descriptors returned in argument .Ar details is owned by the .Lb libdwarf . The application should not attempt to directly free this pointer. Portable code should instead use .Fn dwarf_dealloc with the allocation type .Dv DW_DLA_STRING to indicate that the memory may be freed. .Sh RETURN VALUES Function .Fn dwarf_get_macro_details returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if there is no more macro information at the specified offset .Ar offset . In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_macro_details -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar entry_cnt -or -.Ar details -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There is no more macro information at the specified offset -.Ar offset . -.El -.Sh EXAMPLE +.Sh EXAMPLES To loop through all the macro information entries associated with a DWARF debug context: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Unsigned offset; Dwarf_Signed cnt; Dwarf_Macro_Details *md; Dwarf_Error de; offset = 0; while (dwarf_get_macro_details(dbg, offset, 0, &cnt, &md, &de) == DW_DLV_OK) { for (i = 0; i < cnt; i++) { /* Access fields of md[i] ... */ } offset = md[cnt - 1].dmd_offset + 1; } .Ed +.Sh ERRORS +Function +.Fn dwarf_get_macro_details +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar entry_cnt +or +.Ar details +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no more macro information at the specified offset +.Ar offset . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_find_macro_value_start 3 , .Xr dwarf_init 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_pubtypes.3 (revision 367466) @@ -1,243 +1,243 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_pubtypes.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_pubtypes.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 4, 2011 -.Os .Dt DWARF_GET_PUBTYPES 3 +.Os .Sh NAME .Nm dwarf_get_pubtypes , .Nm dwarf_pubtype_cu_offset , .Nm dwarf_pubtype_die_offset , .Nm dwarf_pubtype_name_offsets , .Nm dwarf_pubtypename .Nd retrieve information about user-defined types .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_pubtypes .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Type **types" .Fa "Dwarf_Signed *ntypes" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_pubtype_cu_offset .Fa "Dwarf_Type type" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_pubtype_die_offset .Fa "Dwarf_Type type" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_pubtype_name_offsets .Fa "Dwarf_Type type" .Fa "char **name" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_pubtypename .Fa "Dwarf_Type type" .Fa "char **name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve information about file-scope, user-defined types recorded in lookup tables in the .Dq ".debug_pubtypes" DWARF section. Information about these types is returned using opaque descriptors of type .Vt Dwarf_Type . Applications need to use the functions described below to retrieve the name and offset information contained in these descriptors. .Pp Function .Fn dwarf_get_pubtypes retrieves descriptors for all the user-defined types associated with the DWARF debug context specified by argument .Ar dbg . The argument .Ar types should point to a location that will be set to a pointer to an array of .Vt Dwarf_Type descriptors. The argument .Ar ntypes should point to a location that will be set to the number of descriptors returned. .Pp Function .Fn dwarf_pubtype_cu_offset returns the offset, relative to the .Dq ".debug_info" section, of the compilation unit that contains the debugging information entry associated with the argument .Ar type . Argument .Ar cu_offset should point to a location that will hold the returned offset. .Pp Function .Fn dwarf_pubtype_die_offset retrieves the offset, relative to the .Dq ".debug_info" section, of the debugging information entry associated with the argument .Ar type , and stores it into the location pointed to by the argument .Ar die_offset . .Pp Function .Fn dwarf_pubtype_name_offsets retrieves the name and offsets for the debugging information entry for argument .Ar type . Argument .Ar name should point to a location which will be set to a pointer to a NUL-terminated string containing the name of the associated debugging information entry. Argument .Ar die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the associated debugging information entry. Argument .Ar cu_die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar type . .Pp Function .Fn dwarf_pubtypename sets the location pointed to by argument .Ar name to a pointer to a NUL-terminated string holding the name of the debugging information entry associated with the argument .Ar type . .Ss Memory Management The memory area used for the array of .Vt Dwarf_Type descriptors returned in argument .Ar types by function .Fn dwarf_get_pubtypes is owned by the .Lb libdwarf . Application code should not attempt to directly free this pointer. Portable code should instead use the function .Xr dwarf_types_dealloc 3 to indicate that the memory area may be freed. .Pp The memory area used for the string returned in the .Ar name argument to functions .Fn dwarf_pubtype_name_offsets and .Fn dwarf_pubtypename is owned by the .Lb libdwarf . Portable code should indicate that the memory area can be freed using the .Xr dwarf_dealloc 3 function. .Ss Error Returns If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh EXAMPLES To retrieve the list of file scope user-defined types and print their names, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Signed ntypes; Dwarf_Type *types; Dwarf_Error err; int n, result; char *typename; /* Initialize dbg etc. */; result = dwarf_get_pubtypes(dbg, &types, &ntypes, &err); if (result != DW_DLV_OK) /* Handle the error. */ ; /* Iterate over the returned array of descriptors. */ for (n = 0; n < ntypes; n++) { result = dwarf_pubtypename(types[n], &typename, &err); if (result != DW_DLV_OK) /* Handle the error. */ ; printf("%s\en", typename); } /* Deallocate the returned array. */ dwarf_types_dealloc(dbg, types, ntypes); .Ed .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_die_offset , .Va cu_offset , .Va dbg , .Va die_offset , .Va type , .Va types , .Va name , or .Va ntypes was NULL. .It Bq Er DW_DLE_NO_ENTRY The DWARF debugging context referenced by argument .Ar dbg did not contain information about user-defined types. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_pubtypes_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_ranges.3 (revision 367466) @@ -1,258 +1,258 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_ranges.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_get_ranges.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_GET_RANGES 3 +.Os .Sh NAME .Nm dwarf_get_ranges .Nd retrieve non-contiguous address ranges .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_ranges .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off offset" .Fa "Dwarf_Ranges **ranges" .Fa "Dwarf_Signed *cnt" .Fa "Dwarf_Unsigned *byte_cnt" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_get_ranges_a .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off offset" .Fa "Dwarf_Die die" .Fa "Dwarf_Ranges **ranges" .Fa "Dwarf_Signed *cnt" .Fa "Dwarf_Unsigned *byte_cnt" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_ranges retrieves information about the non-contiguous address ranges associated with a DWARF debugging information entry. Information about address ranges is returned as an array of descriptors of type .Vt Dwarf_Ranges , with each .Vt Dwarf_Ranges descriptor describing one address range entry. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar offset is an offset, relative to the .Dq ".debug_ranges" section, to the start of the desired list of address ranges. The offset of an address ranges list is indicated by the .Dv DW_AT_ranges attribute of a debugging information entry. .Pp Argument .Ar die (function .Fn dwarf_get_ranges_a only) is ignored in this implementation; see the section .Sx "Compatibility Notes" below. .Pp Argument .Ar ranges should point to a location that will be set to a pointer to an array of .Vt Dwarf_Ranges descriptors. .Pp Argument .Ar cnt should point to a location that will be set to the number of entries returned. If argument .Ar byte_cnt is not NULL, it will be set to the number of bytes occupied by the returned entries in the .Dq ".debug_ranges" section. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp .Vt Dwarf_Ranges descriptors are defined in the header file .In libdwarf.h , and consists of the following fields: .Bl -tag -width ".Va dwr_addr1" .It Va dwr_addr1 The first address offset, whose meaning depends on the type of the entry. .It Va dwr_addr2 The second address offset, whose meaning depends on the type of the entry. .It Va dwr_type The type of this address range entry: .Bl -tag -width ".Dv DW_RANGES_ENTRY" -compact .It Dv DW_RANGES_ENTRY A range list entry. For this type of entry, the fields .Va dwr_addr1 and .Va dwr_addr2 hold the beginning and ending offsets of the address range, respectively. .It Dv DW_RANGES_ADDRESS_SELECTION A base address selection entry. For this type of entry, the field .Va dwr_addr1 is the value of the largest representable address offset, and .Va dwr_addr2 is a base address for the beginning and ending address offsets of subsequent address range entries in the list. .It Dv DW_RANGES_END An end of list mark. Both .Va dwr_addr1 and .Va dwr_addr2 are set to 0. .El .El .Ss Memory Management The memory area used for the array of .Vt Dwarf_Ranges descriptors returned in argument .Ar ranges is owned by the .Lb libdwarf . The application should not attempt to directly free this pointer. Portable code should instead use .Fn dwarf_ranges_dealloc to indicate that the memory may be freed. -.Sh COMPATIBILITY -Function -.Fn dwarf_get_ranges_a -is identical to -.Fn dwarf_get_ranges , -except that it requires one additional argument -.Ar die -denoting the debugging information entry associated with -the address range list. -In this implementation of the -.Lb libdwarf , -the argument -.Ar die -is ignored, and function -.Fn dwarf_get_ranges_a -is only provided for compatibility with other implementations of the -DWARF(3) API. .Sh RETURN VALUES These functions return .Dv DW_DLV_OK when they succeed. They return .Dv DW_DLV_NO_ENTRY if there is no address range list at the specified offset .Ar offset . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . -.Sh ERRORS -These function can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar ranges -or -.Ar cnt -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There is no address range list at the specified offset -.Ar offset . -.El -.Sh EXAMPLE +.Sh EXAMPLES To retrieve the address range list associated with a debugging information entry, use: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Die die; Dwarf_Error de; Dwarf_Addr base; Dwarf_Attribute *attr_list; Dwarf_Ranges *ranges; Dwarf_Signed cnt; Dwarf_Unsigned off, attr_count, bytecnt; int i, j; if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_attrlist failed: %s", dwarf_errmsg(de)); for (i = 0; (Dwarf_Unsigned) i < attr_count; i++) { if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); continue; } if (attr != DW_AT_ranges) continue; if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_ranges(dbg, (Dwarf_Off) off, &ranges, &cnt, &bytecnt, &de) != DW_DLV_OK) continue; for (j = 0; j < cnt; j++) { if (ranges[j].dwr_type == DW_RANGES_END) break; else if (ranges[j].dwr_type == DW_RANGES_ADDRESS_SELECTION) base = ranges[j].dwr_addr2; else { /* * DW_RANGES_ENTRY entry. * .. Use dwr_addr1 and dwr_addr2 .. */ } } } .Ed +.Sh COMPATIBILITY +Function +.Fn dwarf_get_ranges_a +is identical to +.Fn dwarf_get_ranges , +except that it requires one additional argument +.Ar die +denoting the debugging information entry associated with +the address range list. +In this implementation of the +.Lb libdwarf , +the argument +.Ar die +is ignored, and function +.Fn dwarf_get_ranges_a +is only provided for compatibility with other implementations of the +DWARF(3) API. +.Sh ERRORS +These function can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar ranges +or +.Ar cnt +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There is no address range list at the specified offset +.Ar offset . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_ranges_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info.3 (revision 367466) @@ -1,228 +1,228 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_relocation_info.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_relocation_info.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 3, 2011 -.Os .Dt DWARF_GET_RELOCATION_INFO 3 +.Os .Sh NAME .Nm dwarf_get_relocation_info .Nd retrieve generated relocation arrays .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_relocation_info .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Signed *elf_section_index" .Fa "Dwarf_Signed *elf_section_link" .Fa "Dwarf_Unsigned *reloc_entry_count" .Fa "Dwarf_Relocation_Data *reloc_buf" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION The function .Fn dwarf_get_relocation_info is used to retrieve the relocation arrays generated by a prior call to .Xr dwarf_transform_to_disk_form 3 . .Pp Each call to this function retrieves the next available relocation array. Application code should call this function repeatly to retrieve all the relocation arrays. The total number of generated relocation arrays retrievable by this function may be obtained by calling function .Xr dwarf_get_relocation_info_count 3 . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 in sequence. or .Xr dwarf_producer_init_b 3 . The .Dv DW_DLC_SYMBOLIC_RELOCATIONS flag should have been set on the DWARF producer instance. .Pp Argument .Ar elf_section_index should point to a location which will be set to the ELF section index of the relocation section to which the retrieved relocation array belongs. .Pp Argument .Ar elf_section_link should point to a location which will be set to the section index of the ELF section to which the retrieved relocation array applies. .Pp Argument .Ar reloc_entry_count should point to a location which will be set to the total number of relocation entries contained in the relocation array. .Pp Argument .Ar reloc_buf should point to a location which will be set to a pointer to the retrieved array of relocation entries. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp The retrieved relocation entries are described using structure .Vt Dwarf_Relocation_Data_s , defined in the header file .In libdwarf.h : .Bd -literal -offset indent typedef struct Dwarf_Relocation_Data_s { unsigned char drd_type; unsigned char drd_length; Dwarf_Unsigned drd_offset; Dwarf_Unsigned drd_symbol_index; } *Dwarf_Relocation_Data; .Ed .Pp Struct .Vt Dwarf_Relocation_Data_s consists of following fields: .Bl -tag -width ".Va drd_symbol_index" -compact -offset indent .It Va drd_type The type code of the relocation entry. The .Vt Dwarf_Rel_Type enumeration defined in the header file .In libdwarf.h specifies legal values for this field. .It Va drd_length The size in bytes of the field to be relocated. .It Va drd_offset The section-relative offset of the field to be relocated. .It Va drd_symbol_index The symbol index associated with the relocation entry. .El .Ss Memory Management The memory area used for the relocation arrays is managed by the .Lb libdwarf . The function .Fn dwarf_producer_finish may be used to release it, along with other resources associated with the producer instance. .Sh RETURN VALUES On success, function .Fn dwarf_get_relocation_info returns .Dv DW_DLV_OK . It returns .Dv DW_DLV_NO_ENTRY if there were no more relocation arrays to retrieve, or if the flag .Dv DW_DLC_SYMBOLIC_RELOCATIONS was not set on the producer instance. In case of an error, function .Fn dwarf_get_relocation_info returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_relocation_info -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar elf_section_index , -.Ar elf_section_link , -.Ar reloc_entry_count -or -.Ar reloc_buf -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There were no more ELF relocation arrays to retrieve. -.It Bq Er DW_DLE_NO_ENTRY -The flag -.Dv DW_DLC_SYMBOLIC_RELOCATIONS -was not set on the producer instance. -.It Bq Er DW_DLE_NO_ENTRY -Function -.Xr dwarf_transform_to_disk_form 3 -was not called prior to calling function -.Fn dwarf_get_relocation_info . -.El .Sh EXAMPLES To generate relocation entries and retrieve them, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_Relocation_Data buf; Dwarf_Signed count, index, link; Dwarf_Unsigned reloc_cnt, entry_cnt; Dwarf_Error de; int version, i, j; /* * Assume that dbg refers to a DWARF producer instance created * created with DW_DLC_SYMBOLIC_RELOCATIONS flag set and that * application code has added DWARF debugging information * to the producer instance. */ if ((count = dwarf_transform_to_disk_form(dbg, &de)) == DW_DLV_NOCOUNT) { warnx("dwarf_transform_to_disk_form failed: %s", dwarf_errmsg(-1)); return; } /* ... process generated section byte streams ... */ if (dwarf_get_relocation_info_count(dbg, &reloc_cnt, &version, &de) != DW_DLV_OK) { warnx("dwarf_get_relocation_info_count failed: %s", dwarf_errmsg(-1)); return; } for (i = 0; (Dwarf_Unsigned) i < reloc_cnt; i++) { if (dwarf_get_relocation_info(dbg, &index, &link, &entry_cnt, &buf, &de) != DW_DLV_OK) { warnx("dwarf_get_relocation_info failed: %s", dwarf_errmsg(-1)); continue; } for (j = 0; (Dwarf_Unsigned) j < entry_cnt; j++) { /* ...use each reloc data in buf[j]... */ } } dwarf_producer_finish(dbg, &de); .Ed +.Sh ERRORS +Function +.Fn dwarf_get_relocation_info +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar elf_section_index , +.Ar elf_section_link , +.Ar reloc_entry_count +or +.Ar reloc_buf +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There were no more ELF relocation arrays to retrieve. +.It Bq Er DW_DLE_NO_ENTRY +The flag +.Dv DW_DLC_SYMBOLIC_RELOCATIONS +was not set on the producer instance. +.It Bq Er DW_DLE_NO_ENTRY +Function +.Xr dwarf_transform_to_disk_form 3 +was not called prior to calling function +.Fn dwarf_get_relocation_info . +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_relocation_info_count 3 , -.Xr dwarf_reset_section_bytes 3 , .Xr dwarf_producer_finish 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , +.Xr dwarf_reset_section_bytes 3 , .Xr dwarf_transform_to_disk_form 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_relocation_info_count.3 (revision 367466) @@ -1,116 +1,116 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_relocation_info_count.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_relocation_info_count.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 3, 2011 -.Os .Dt DWARF_GET_RELOCATION_INFO_COUNT 3 +.Os .Sh NAME .Nm dwarf_get_relocation_info_count .Nd return the number of relocation arrays .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_relocation_info_count .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Unsigned *reloc_cnt" .Fa "int *drd_buffer_version" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_relocation_info_count retrieves the total number of relocation arrays generated by a prior call to .Xr dwarf_transform_to_disk_form 3 . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . The .Dv DW_DLC_SYMBOLIC_RELOCATIONS flag should have been set on the producer instance. .Pp Argument .Ar reloc_cnt should point to a location which will be set to the total number of relocation arrays generated. .Pp Argument .Ar drd_buffer_version should point to a location which will be set to the version number of the relocation structures returned (see the symbol .Dv DWARF_DRD_BUFFER_VERSION , defined in the header file .In libdwarf.h ) . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_get_relocation_info_count returns .Dv DW_DLV_OK . It returns .Dv DW_DLV_NO_ENTRY if the .Dv DW_DLC_SYMBOLIC_RELOCATIONS flag is not set on the producer instance. In case of an error, function .Fn dwarf_get_relocation_info_count returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_get_relocation_info_count can fail with: .Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar reloc_cnt or .Ar drd_buffer_version was NULL. .It Bq Er DW_DLE_NO_ENTRY The .Dv DW_DLC_SYMBOLIC_RELOCATIONS flag was not set. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_relocation_info 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_transform_to_disk_form 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_section_bytes.3 (revision 367466) @@ -1,157 +1,157 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_section_bytes.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_section_bytes.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd August 26, 2011 -.Os .Dt DWARF_GET_SECTION_BYTES 3 +.Os .Sh NAME .Nm dwarf_get_section_bytes .Nd retrieve ELF section byte streams .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_Ptr .Fo dwarf_get_section_bytes .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Signed dwarf_section" .Fa "Dwarf_Signed *elf_section_index" .Fa "Dwarf_Unsigned *length" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_section_bytes returns the ELF section byte streams generated by a prior call to function .Xr dwarf_transform_to_disk_form 3 . .Pp Each call to function .Fn dwarf_get_section_bytes will return the byte stream for one ELF section. The first call to this function will always return the first ELF section, and the subsequent calls will return the rest of sections in the order when they were generated, until the last one. The total number of sections generated is returned by the function .Xr dwarf_transform_to_disk_form 3 . .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using the functions .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar dwarf_section is currently ignored. .Pp Argument .Ar elf_section_index should point to a location which will be set to the section index value of the returned ELF section. .Pp Argument .Ar length should point to a location which will hold the length in bytes of the returned ELF section. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Ss Memory Management The memory areas used for the returned ELF section byte streams should be freed using the function .Fn dwarf_producer_finish . .Sh RETURN VALUES On success, function .Fn dwarf_get_section_bytes returns a pointer to a ELF section byte stream. In case of an error, function .Fn dwarf_get_section_bytes will return NULL and set the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_get_section_bytes -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar dbg , -.Ar elf_section_index , -or -.Ar length -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -There were no more ELF sections to retrieve, or the function was -called before a call to -.Xr dwarf_transform_to_disk_form 3 . -.El .Sh EXAMPLES To generate and retrieve ELF section byte streams, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_Signed count, i, sec_index; Dwarf_Unsigned len; Dwarf_Ptr bytes; Dwarf_Error de; /* ... Assume that `dbg' refers to a DWARF producer instance, * and that application code has added DWARF debugging * information to the producer instance. ... */ if ((count = dwarf_transform_to_disk_form(dbg, &de)) == DW_DLV_NOCOUNT) { warnx("dwarf_transform_to_disk_form failed: %s", dwarf_errmsg(-1)); return; } /* Retrieve section data. */ for (i = 0; i < count; i++) { bytes = dwarf_get_section_bytes(dbg, i, &sec_index, &len, &de); if (bytes == NULL) { warnx("dwarf_get_section_bytes failed: %s", dwarf_errmsg(-1)); continue; } /* ... use the returned byte stream ... */ } /* Release resources. */ dwarf_producer_finish(dbg, &de); .Ed +.Sh ERRORS +Function +.Fn dwarf_get_section_bytes +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar dbg , +.Ar elf_section_index , +or +.Ar length +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +There were no more ELF sections to retrieve, or the function was +called before a call to +.Xr dwarf_transform_to_disk_form 3 . +.El .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_reset_section_bytes 3 , .Xr dwarf_producer_finish 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , +.Xr dwarf_reset_section_bytes 3 , .Xr dwarf_transform_to_disk_form 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_section_max_offsets.3 (revision 367466) @@ -1,116 +1,116 @@ .\" Copyright (c) 2014 Kai Wang .\" 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: dwarf_get_section_max_offsets.3 3141 2015-01-29 23:11:10Z jkoshy $ +.\" $Id: dwarf_get_section_max_offsets.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd December 21, 2014 +.Dt DWARF_GET_SECTION_MAX_OFFSETS 3 .Os -.Dt DWARF_GET_SECTION_MAX_OFFSETS .Sh NAME .Nm dwarf_get_section_max_offsets , .Nm dwarf_get_section_max_offsets_b .Nd return the size of DWARF sections .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_section_max_offsets .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Unsigned *debug_info" .Fa "Dwarf_Unsigned *debug_abbrev" .Fa "Dwarf_Unsigned *debug_line" .Fa "Dwarf_Unsigned *debug_loc" .Fa "Dwarf_Unsigned *debug_aranges" .Fa "Dwarf_Unsigned *debug_macinfo" .Fa "Dwarf_Unsigned *debug_pubnames" .Fa "Dwarf_Unsigned *debug_str" .Fa "Dwarf_Unsigned *debug_frame" .Fa "Dwarf_Unsigned *debug_ranges" .Fa "Dwarf_Unsigned *debug_pubtypes" .Fc .Ft int .Fo dwarf_get_section_max_offsets_b .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Unsigned *debug_info" .Fa "Dwarf_Unsigned *debug_abbrev" .Fa "Dwarf_Unsigned *debug_line" .Fa "Dwarf_Unsigned *debug_loc" .Fa "Dwarf_Unsigned *debug_aranges" .Fa "Dwarf_Unsigned *debug_macinfo" .Fa "Dwarf_Unsigned *debug_pubnames" .Fa "Dwarf_Unsigned *debug_str" .Fa "Dwarf_Unsigned *debug_frame" .Fa "Dwarf_Unsigned *debug_ranges" .Fa "Dwarf_Unsigned *debug_pubtypes" .Fa "Dwarf_Unsigned *debug_types" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_section_max_offsets_b retrieves the sizes of the DWARF sections in a DWARF debug context. Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . The function stores the size of each DWARF section to the location pointed to by the argument corresponding to the section name. If a DWARF section does not exist, the location pointed to by the argument corresponding to that section will be set to zero. .Pp A value of NULL may be used for any of the arguments .Ar debug_info , .Ar debug_abbrev , .Ar debug_line , .Ar debug_loc , .Ar debug_aranges , .Ar debug_macinfo , .Ar debug_pubnames , .Ar debug_str , .Ar debug_frame , .Ar debug_ranges , .Ar debug_pubtypes and .Ar debug_types if the caller is not interested in the respective section size. .Pp Function .Fn dwarf_get_section_max_offsets is identical to function .Fn dwarf_get_section_max_offsets_b except that it does not provide argument .Ar debug_types , and thus cannot return the size of the .Dq \&.debug_types section. .Sh RETURN VALUES On success, these functions return .Dv DW_DLV_OK . If argument .Ar dbg is NULL, they return .Dv DW_DLV_ERROR . .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_init 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_str.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_str.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_str.3 (revision 367466) @@ -1,149 +1,149 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_str.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_str.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd April 3, 2011 -.Os .Dt DWARF_GET_STR 3 +.Os .Sh NAME .Nm dwarf_get_str .Nd retrieve a string from the DWARF string section .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_str .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Off offset" .Fa "char **string" .Fa "Dwarf_Signed *len" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_get_str retrieves a NUL-terminated string from the DWARF string section .Dq ".debug_str" . .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar offset should be an offset, relative to the .Dq ".debug_str" section, specifying the start of the desired string. .Pp Argument .Ar string should point to a location which will hold a returned pointer to a NUL-terminated string. .Pp Argument .Ar len should point to a location which will hold the length of the returned string. The returned length does not include the space needed for the NUL-terminator. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES Function .Fn dwarf_get_str returns .Dv DW_DLV_OK when it succeeds. It returns .Dv DW_DLV_NO_ENTRY if there is no .Dq ".debug_str" section associated with the specified debugging context, or if the provided offset .Ar offset is at the very end of .Dq ".debug_str" section. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . +.Sh EXAMPLES +To retrieve all the strings in the DWARF string section, use: +.Bd -literal -offset indent +Dwarf_Debug dbg; +Dwarf_Off offset; +Dwarf_Signed len; +Dwarf_Error de; +char *str; +int ret + +offset = 0; +while ((ret = dwarf_get_str(dbg, offset, &str, &len, &de)) == + DW_DLV_OK) { + /* .. Use the retrieved string. .. */ + offset += len + 1; /* Account for the terminating NUL. */ +} + +if (ret == DW_DLV_ERROR) + warnx("dwarf_get_str: %s", dwarf_errmsg(de)); +.Ed .Sh ERRORS Function .Fn dwarf_get_str can fail with: .Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar dbg , .Ar string or .Ar len was NULL. .It Bq Er DW_DLE_ARGUMENT Argument .Ar offset was out of range. .It Bq Er DW_DLE_NO_ENTRY The debugging context .Ar dbg did not contain a .Dq ".debug_str" string section. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar offset was at the very end of the .Dq ".debug_str" section. .El -.Sh EXAMPLE -To retrieve all the strings in the DWARF string section, use: -.Bd -literal -offset indent -Dwarf_Debug dbg; -Dwarf_Off offset; -Dwarf_Signed len; -Dwarf_Error de; -char *str; -int ret - -offset = 0; -while ((ret = dwarf_get_str(dbg, offset, &str, &len, &de)) == - DW_DLV_OK) { - /* .. Use the retrieved string. .. */ - offset += len + 1; /* Account for the terminating NUL. */ -} - -if (ret == DW_DLV_ERROR) - warnx("dwarf_get_str: %s", dwarf_errmsg(de)); -.Ed .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_init 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_types.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_types.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_types.3 (revision 367466) @@ -1,232 +1,232 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_types.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_types.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 10, 2011 -.Os .Dt DWARF_GET_TYPES 3 +.Os .Sh NAME .Nm dwarf_get_types , .Nm dwarf_type_cu_offset , .Nm dwarf_type_die_offset , .Nm dwarf_type_name_offsets , .Nm dwarf_typename .Nd retrieve information about user-defined types .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_types .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Type **types" .Fa "Dwarf_Signed *ntypes" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_type_cu_offset .Fa "Dwarf_Type type" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_type_die_offset .Fa "Dwarf_Type type" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_type_name_offsets .Fa "Dwarf_Type type" .Fa "char **name" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_typename .Fa "Dwarf_Type type" .Fa "char **name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These APIs retrieve information about user-defined types from the SGI-specific .Dq ".debug_typenames" section. .Pp Standards-conformant applications should use the functions .Xr dwarf_get_pubtypes 3 , .Xr dwarf_pubtype_cu_offset 3 , .Xr dwarf_pubtype_die_offset 3 , .Xr dwarf_pubtype_name_offsets 3 and .Xr dwarf_pubtypename 3 , which operate on the equivalent .Dq ".debug_pubtypes" section defined by the DWARF3 standard. .Pp Information about user-defined types is returned using opaque descriptors of type .Vt Dwarf_Type . Applications need to use the functions described below to retrieve the name and offset information contained in these descriptors. .Pp Function .Fn dwarf_get_types retrieves descriptors for all user-defined types associated with the DWARF debug context specified by argument .Ar dbg . The argument .Ar types should point to a location that will be set to a pointer to an array of .Vt Dwarf_Type descriptors. The argument .Ar ntypes should point to a location that will be set to the number of descriptors returned. .Pp Function .Fn dwarf_type_cu_offset returns the offset, relative to the .Dq ".debug_info" section, of the compilation unit that contains the debugging information entry associated with the argument .Ar type . Argument .Ar cu_offset should point to a location that will hold the returned offset. .Pp Function .Fn dwarf_type_die_offset retrieves the offset, relative to the .Dq ".debug_info" section, of the debugging information entry associated with the argument .Ar type , and stores it into the location pointed to by the argument .Ar die_offset . .Pp Function .Fn dwarf_type_name_offsets retrieves the name and offsets for the debugging information entry for argument .Ar type . Argument .Ar name should point to a location which will be set to a pointer to a NUL-terminated string containing the name of the associated debugging information entry. Argument .Ar die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the associated debugging information entry. Argument .Ar cu_die_offset should point to a location which will be set to a offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar type . .Pp Function .Fn dwarf_typename sets the location pointed to by argument .Ar name to a pointer to a NUL-terminated string holding the name of the debugging information entry associated with the argument .Ar type . .Ss Memory Management The memory area used for the array of .Vt Dwarf_Type descriptors returned in argument .Ar types by function .Fn dwarf_get_types is owned by the .Lb libdwarf . Application code should not attempt to directly free this pointer. Portable code should instead use the function .Xr dwarf_types_dealloc 3 to indicate that the memory area may be freed. .Pp The memory area used for the string returned in the .Ar name argument to functions .Fn dwarf_type_name_offsets and .Fn dwarf_typename is owned by the .Lb libdwarf . Portable code should indicate that the memory area can be freed using the .Xr dwarf_dealloc 3 function. .Ss Error Returns If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_die_offset , .Va cu_offset , .Va dbg , .Va die_offset , .Va type , .Va types , .Va name , or .Va ntypes was NULL. .It Bq Er DW_DLE_NO_ENTRY The DWARF debugging context referenced by argument .Ar dbg did not contain information about user-defined types. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_get_pubtypes 3 , .Xr dwarf_pubtype_cu_offset 3 , .Xr dwarf_pubtype_die_offset 3 , .Xr dwarf_pubtype_name_offsets 3 , .Xr dwarf_pubtypename 3 , .Xr dwarf_types_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_vars.3 (revision 367466) @@ -1,210 +1,210 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_vars.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_vars.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 2, 2011 -.Os .Dt DWARF_GET_VARS 3 +.Os .Sh NAME .Nm dwarf_get_vars , .Nm dwarf_var_cu_offset , .Nm dwarf_var_die_offset , .Nm dwarf_var_name_offsets , .Nm dwarf_varname .Nd retrieve information about static variables .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_vars .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Var **vars" .Fa "Dwarf_Signed *nvars" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_var_cu_offset .Fa "Dwarf_Var var" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_var_die_offset .Fa "Dwarf_Var var" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_var_name_offsets .Fa "Dwarf_Var var" .Fa "char **name" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_varname .Fa "Dwarf_Var var" .Fa "char **name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve information about the file scope static variables associated with a DWARF debug context. Information about these static variables is returned using opaque descriptors of type .Vt Dwarf_Var . Applications need to use the functions described below to retrieve the name and offset information contained in these descriptors. .Pp Function .Fn dwarf_get_vars retrieves descriptors for all the static variables associated with the DWARF debug context specified by argument .Ar dbg . The argument .Ar vars should point to a location that will be set to a pointer to an array of .Vt Dwarf_Var descriptors. The argument .Ar nvars should point to a location that will be set to the number of descriptors returned. .Pp Function .Fn dwarf_var_cu_offset returns the section-relative offset, relative to the .Dq ".debug_info" section, of the compilation unit that contains the debugging information entry associated with the argument .Ar var . Argument .Ar cu_offset should point to a location that will hold the returned offset. .Pp Function .Fn dwarf_var_die_offset retrieves the section-relative offset, relative to the .Dq ".debug_info" section, of the debugging information entry associated with the argument .Ar var , and stores it into the location pointed to by the argument .Ar die_offset . .Pp Function .Fn dwarf_var_name_offsets retrieves both the name and the associated offsets for the debugging information entry for argument .Ar var . Argument .Ar name should point to a location which will be set to a pointer to a NUL-terminated string containing the name of the associated debugging information entry. Argument .Ar die_offset should point to a location which will be set to a section-relative offset, relative to the .Dq ".debug_info" section, of the associated debugging information entry. Argument .Ar cu_die_offset should point to a location which will be set to a section-relative offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar var . .Pp Function .Fn dwarf_varname sets the location pointed to by argument .Ar name to a pointer to a NUL-terminated string holding the name of the debugging information entry associated with the argument .Ar var . .Ss Memory Management The memory area used for the array of .Vt Dwarf_Var descriptors returned in argument .Ar vars by function .Fn dwarf_get_vars is owned by the .Lb libdwarf . Application code should not attempt to directly free this pointer. Portable code should instead use the function .Xr dwarf_vars_dealloc 3 to indicate that the memory area may be freed. .Pp The memory area used for the string returned in the .Ar name argument to functions .Fn dwarf_var_name_offsets and .Fn dwarf_varname is owned by the .Lb libdwarf . Portable code should indicate that the memory area can be freed using the .Xr dwarf_dealloc 3 function. .Ss Error Returns If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_die_offset , .Va cu_offset , .Va dbg , .Va die_offset , .Va var , .Va vars , .Va name , or .Va nvars was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_vars_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_get_weaks.3 (revision 367466) @@ -1,215 +1,215 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_get_weaks.3 2071 2011-10-27 03:20:00Z jkoshy $ +.\" $Id: dwarf_get_weaks.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 10, 2011 -.Os .Dt DWARF_GET_WEAKS 3 +.Os .Sh NAME .Nm dwarf_get_weaks , .Nm dwarf_weak_cu_offset , .Nm dwarf_weak_die_offset , .Nm dwarf_weak_name_offsets , .Nm dwarf_weakname .Nd retrieve information about weak symbols .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_get_weaks .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Weak **weaks" .Fa "Dwarf_Signed *nweaks" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_weak_cu_offset .Fa "Dwarf_Weak weak" .Fa "Dwarf_Off *cu_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_weak_die_offset .Fa "Dwarf_Weak weak" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_weak_name_offsets .Fa "Dwarf_Weak weak" .Fa "char **name" .Fa "Dwarf_Off *die_offset" .Fa "Dwarf_Off *cu_die_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_weakname .Fa "Dwarf_Weak weak" .Fa "char **name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve information about weak symbols from the lookup tables in the (SGI-specific) .Dq ".debug_weaknames" section. Information about weak symbols is returned using opaque descriptors of type .Vt Dwarf_Weak . Applications need to use the functions described below to retrieve the name and offset information contained in these descriptors. .Pp Function .Fn dwarf_get_weaks retrieves descriptors for all the weak symbols associated with the DWARF debug context specified by argument .Ar dbg . The argument .Ar weaks should point to a location that will be set to a pointer to an array of .Vt Dwarf_Weak descriptors. The argument .Ar nweaks should point to a location that will be set to the number of descriptors returned. .Pp Function .Fn dwarf_weak_cu_offset returns the offset, relative to the .Dq ".debug_info" section, of the compilation unit that contains the debugging information entry associated with the argument .Ar weak . Argument .Ar cu_offset should point to a location that will hold the returned offset. .Pp Function .Fn dwarf_weak_die_offset retrieves the offset, relative to the .Dq ".debug_info" section, of the debugging information entry associated with the argument .Ar weak , and stores it into the location pointed to by the argument .Ar die_offset . .Pp Function .Fn dwarf_weak_name_offsets retrieves the name and offsets for the debugging information entry for argument .Ar weak . Argument .Ar name should point to a location which will be set to a pointer to a NUL-terminated string containing the name of the associated debugging information entry. Argument .Ar die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the associated debugging information entry. Argument .Ar cu_die_offset should point to a location which will be set to the offset, relative to the .Dq ".debug_info" section, of the first debugging information entry in the compilation unit associated with argument .Ar weak . .Pp Function .Fn dwarf_weakname sets the location pointed to by argument .Ar name to a pointer to a NUL-terminated string holding the name of the debugging information entry associated with the argument .Ar weak . .Ss Memory Management The memory area used for the array of .Vt Dwarf_Weak descriptors returned in argument .Ar weaks by function .Fn dwarf_get_weaks is owned by the .Lb libdwarf . Application code should not attempt to directly free this pointer. Portable code should instead use the function .Xr dwarf_weaks_dealloc 3 to indicate that the memory area may be freed. .Pp The memory area used for the string returned in the .Ar name argument to functions .Fn dwarf_weak_name_offsets and .Fn dwarf_weakname is owned by the .Lb libdwarf . Portable code should indicate that the memory area can be freed using the .Xr dwarf_dealloc 3 function. .Ss Error Returns If argument .Ar err is not NULL, these functions will use it to store error information, in case of an error. .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va cu_die_offset , .Va cu_offset , .Va dbg , .Va die_offset , .Va weak , .Va weaks , .Va name , or .Va nweaks was NULL. .It Bq Er DW_DLE_NO_ENTRY The DWARF debugging context referenced by argument .Ar dbg did not contain information about weak symbols. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_weaks_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 (revision 367466) @@ -1,92 +1,92 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_hasattr.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_hasattr.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 17, 2010 -.Os .Dt DWARF_HASATTR 3 +.Os .Sh NAME .Nm dwarf_hasattr .Nd check for the presence of an attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_hasattr .Fa "Dwarf_Die die" .Fa "Dwarf_Half attr" .Fa "Dwarf_Bool *ret_bool" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_hasattr tests whether the debugging information entry referenced in argument .Ar die contains the attribute named by argument .Ar attr . Legal values for argument .Ar attr are those denoted by the .Dv DW_AT_* constants in the DWARF specification. .Pp If the named attribute is present in the debugging information entry, function .Fn dwarf_hasattr returns a non-zero value in the location pointed to by argument .Ar ret_bool . If the named attribute is not present, a zero is written instead. .Pp If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_hasattr returns .Dv DW_DLV_OK . In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_hasattr can fail with the following error: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of argument .Va die or .Va ret_bool was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_whatattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_hasform.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_hasform.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_hasform.3 (revision 367466) @@ -1,127 +1,127 @@ .\" 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 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: dwarf_hasform.3 2073 2011-10-27 03:30:47Z jkoshy $ +.\" $Id: dwarf_hasform.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd May 22, 2010 -.Os .Dt DWARF_HASFORM 3 +.Os .Sh NAME .Nm dwarf_hasform , .Nm dwarf_whatform , .Nm dwarf_whatform_direct .Nd query attribute forms .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_hasform .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Half form" .Fa "Dwarf_Bool *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_whatform .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Half *retform" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_whatform_direct .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Half *retform" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_hasform indicates whether the DWARF attribute denoted by argument .Ar attr has the attribute form specified by argument .Ar form . If the attribute has the specified form, then argument .Ar ret is set to a non-zero value, otherwise it is set to zero. If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_whatform sets the location specified by argument .Ar retform to the attribute form code for the DWARF attribute referenced by argument .Ar attr . If the attribute referenced by argument .Ar attr has an indirect form attribute, this function will return the final form for the attribute. If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Pp Function .Fn dwarf_whatform_direct sets the location specified by argument .Ar retform to the attribute form code for the DWARF attribute referenced by argument .Ar attr . If the form is an indirect form, the function sets the location specified by argument .Ar retform to .Dv DW_FORM_indirect . If argument .Ar err is non-NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES These functions return .Dv DW_DLV_OK on success. In case of an error, these functions return .Dv DW_DLV_ERR and set argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Any of the arguments .Ar attr , .Ar ret , or .Ar retform was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_highpc.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_highpc.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_highpc.3 (revision 367466) @@ -1,193 +1,194 @@ .\" Copyright (c) 2010,2014 Kai Wang .\" 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: dwarf_highpc.3 3092 2014-09-02 22:09:30Z kaiwang27 $ +.\" $Id: dwarf_highpc.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd July 22, 2014 -.Os .Dt DWARF_HIGHPC 3 +.Os .Sh NAME .Nm dwarf_arrayorder , .Nm dwarf_bitoffset , .Nm dwarf_bitsize , .Nm dwarf_bytesize , .Nm dwarf_highpc , .Nm dwarf_highpc_b , .Nm dwarf_lowpc , .Nm dwarf_srclang .Nd retrieve the value of a DWARF attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_arrayorder .Fa "Dwarf_Die die" .Fa "Dwarf_Unsigned *ret_order" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_bitoffset .Fa "Dwarf_Die die" .Fa "Dwarf_Unsigned *ret_size" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_bitsize .Fa "Dwarf_Die die" .Fa "Dwarf_Unsigned *ret_size" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_bytesize .Fa "Dwarf_Die die" .Fa "Dwarf_Unsigned *ret_size" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_highpc .Fa "Dwarf_Die die" .Fa "Dwarf_Addr *ret_highpc" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_highpc_b .Fa "Dwarf_Die die" .Fa "Dwarf_Addr *ret_highpc" .Fa "Dwarf_Half *ret_form" .Fa "enum Dwarf_Form_Class *ret_class" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_lowpc .Fa "Dwarf_Die die" .Fa "Dwarf_Addr *ret_lowpc" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_srclang .Fa "Dwarf_Die die" .Fa "Dwarf_Unsigned *ret_lang" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These convenience functions are used to retrieve DWARF attribute values associated with a Debugging Information Entry (DIE) descriptor denoted by argument .Ar die . These functions store the value of the requested attribute into the location pointed to by their second argument, provided that the requested attribute exists in the debugging information entry. .Pp The list of functions and the DWARF attribute that they retrieve are: .Pp .Bl -tag -width ".Fn dwarf_arrayorder" -compact .It Fn dwarf_arrayorder Retrieve the .Dv DW_AT_ordering attribute value. .It Fn dwarf_bitoffset Retrieve the .Dv DW_AT_bit_offset attribute value. .It Fn dwarf_bitsize Retrieve the .Dv DW_AT_bit_size attribute value. .It Fn dwarf_bytesize Retrieve the .Dv DW_AT_byte_size attribute value. .It Fn dwarf_highpc Retrieve the .Dv DW_AT_high_pc attribute value. .It Fn dwarf_highpc_b Retrieve the .Dv DW_AT_high_pc attribute value. .It Fn dwarf_lowpc Retrieve the .Dv DW_AT_low_pc attribute value. .It Fn dwarf_srclang Retrieve the .Dv DW_AT_language attribute value. .El .Pp Function .Fn dwarf_highpc_b is an enhanced version of function .Fn dwarf_highpc . It sets the location specified by argument .Ar ret_form to the form code of the attribute .Dv DW_AT_high_pc , and sets the location specified by argument .Ar ret_class to the class of that form. A value of NULL may be used for either of the arguments .Ar ret_form or .Ar ret_class if the caller is not interested in the respective value. .Sh RETURN VALUES These functions return -.Dv DW_DLV_OK on success. +.Dv DW_DLV_OK +on success. .Pp If the debugging information entry descriptor denoted by argument .Ar die does not contain the requested attribute, these functions return .Dv DW_DLV_NO_ENTRY and set argument .Ar err . For other errors, they return .Dv DW_DLV_ERROR and set argument .Ar err . .Sh ERRORS These functions can fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Arguments .Ar die , .Ar ret_highpc , .Ar ret_lowpc , .Ar ret_size , .Ar ret_lang or .Ar ret_order were NULL. .It Bq Er DW_DLE_NO_ENTRY Argument .Ar die had no requested attribute. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_attrlist 3 , -.Xr dwarf_hasattr 3 , -.Xr dwarf_get_form_class 3 +.Xr dwarf_get_form_class 3 , +.Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_init.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_init.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_init.3 (revision 367466) @@ -1,178 +1,178 @@ .\" 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 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: dwarf_init.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_init.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_INIT 3 +.Os .Sh NAME .Nm dwarf_init , .Nm dwarf_elf_init .Nd allocate a DWARF debug descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_init .Fa "int fd" .Fa "int mode" .Fa "Dwarf_Handler errhand" .Fa "Dwarf_Ptr errarg" .Fa "Dwarf_Debug *ret" .Fa "Dwarf_Error *err" .Fc .Ft in .Fo dwarf_elf_init .Fa "Elf *elf" .Fa "int mode" .Fa "Dwarf_Handler errhand" .Fa "Dwarf_Ptr errarg" .Fa "Dwarf_Debug *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions allocate and return a .Vt Dwarf_Debug instance for the object denoted by argument .Ar fd or .Ar elf . This instance would be used for subsequent access to debugging information in the object by other functions in the DWARF(3) library. .Pp For function .Fn dwarf_init , argument .Ar fd denotes an open file descriptor referencing a compilation object. Function .Fn dwarf_init implicitly allocates an .Vt Elf descriptor for argument .Ar fd . .Pp For function .Fn dwarf_elf_init , argument .Ar elf denotes a descriptor returned by .Xr elf_begin 3 or .Xr elf_memory 3 . .Pp Argument .Ar mode specifies the access mode desired. It should be at least as permissive as the mode with which the file descriptor .Ar fd or the ELF descriptor .Ar elf was created with. Legal values for argument .Ar mode are: .Pp .Bl -tag -width "DW_DLC_WRITE" -compact .It DW_DLC_RDWR Permit reading and writing of DWARF information. .It DW_DLC_READ Operate in read-only mode. .It DW_DLC_WRITE Permit writing of DWARF information. .El .Pp Argument .Ar errhand denotes a function to be called in case of an error. If this argument is .Dv NULL then a default error handling scheme is used. See .Xr dwarf 3 for a description of the error handling scheme used by the DWARF(3) library. .Pp Argument .Ar errarg is passed to the error handler function denoted by argument .Ar errhand when it is invoked. .Pp Argument .Ar ret points to the memory location that will hold a .Vt Dwarf_Debug reference on a successful call these functions. .Pp Argument .Ar err references a memory location that would hold a .Vt Dwarf_Error descriptor in case of an error. .Ss Memory Management The .Vt Dwarf_Debug instance returned by these functions should be freed using .Fn dwarf_finish . +.Sh IMPLEMENTATION NOTES +The current implementation does not support access modes +.Dv DW_DLC_RDWR +and +.Dv DW_DLC_WRITE . .Sh RETURN VALUES These functions return the following values: .Bl -tag -width ".Bq Er DW_DLV_NO_ENTRY" .It Bq Er DW_DLV_OK This return value indicates a successful return. .It Bq Er DW_DLV_ERROR The operation failed. .It Bq Er DW_DLV_NO_ENTRY The object specified by arguments .Ar "fd" or .Ar "elf" did not contain debug information. .El -.Sh IMPLEMENTATION NOTES -The current implementation does not support access modes -.Dv DW_DLC_RDWR -and -.Dv DW_DLC_WRITE . .Sh EXAMPLES To initialize a .Vt Dwarf_Debug instance from a open file descriptor referencing an ELF object, and with the default error handler, use: .Bd -literal -offset indent Dwarf_Error err; Dwarf_Debug dbg; if (dwarf_init(fd, DW_DLC_READ, NULL, NULL, &dbg, &err) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_init: %s", dwarf_errmsg(err)); .Ed .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 , .Xr dwarf_finish 3 , .Xr dwarf_get_elf 3 , .Xr elf_begin 3 , .Xr elf_memory 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_lineno.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_lineno.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_lineno.3 (revision 367466) @@ -1,202 +1,202 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_lineno.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_lineno.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd February 5, 2011 -.Os .Dt DWARF_LINENO 3 +.Os .Sh NAME .Nm dwarf_lineaddr , .Nm dwarf_linebeginstatement , .Nm dwarf_lineblock , .Nm dwarf_lineendsequence , .Nm dwarf_lineno , .Nm dwarf_lineoff , .Nm dwarf_linesrc , .Nm dwarf_line_srcfileno .Nd retrieve information associated with a DWARF line descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_lineaddr .Fa "Dwarf_Line ln" .Fa "Dwarf_Addr *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_linebeginstatement .Fa "Dwarf_Line ln" .Fa "Dwarf_Bool *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_lineblock .Fa "Dwarf_Line ln" .Fa "Dwarf_Bool *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_lineendsequence .Fa "Dwarf_Line ln" .Fa "Dwarf_Bool *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_lineno .Fa "Dwarf_Line ln" .Fa "Dwarf_Unsigned *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_lineoff .Fa "Dwarf_Line ln" .Fa "Dwarf_Signed *ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_linesrc .Fa "Dwarf_Line ln" .Fa "char **ret" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_line_srcfileno .Fa "Dwarf_Line ln" .Fa "Dwarf_Unsigned *ret" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions retrieve specific line information associated with the line descriptor specified by argument .Ar ln , and stores it in the location pointed to by argument .Ar ret . If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_lineaddr stores the program address corresponding to the source line specified in argument .Ar ln into the location pointed to by argument .Ar ret . .Pp Function .Fn dwarf_linebeginstatement sets the location pointed to by argument .Ar ret to 1 if the source line specified by the line descriptor .Ar ln is the beginning of a statement, or to 0 otherwise. .Pp Function .Fn dwarf_lineblock sets the location pointed to by argument .Ar ret to 1 if the source line specified by the line descriptor .Ar ln is the beginning of a basic block, or to 0 otherwise. .Pp Function .Fn dwarf_lineendsequence sets the location pointed to by argument .Ar ret to 1 if the program address associated with the line descriptor .Ar ln is the address immediately following the end of a sequence of target machine instructions, or to 0 otherwise. .Pp Function .Fn dwarf_lineno stores the line number of the source line associated with the line descriptor .Ar ln into the location pointed to by argument .Ar ret . .Pp Function .Fn dwarf_lineoff stores the column number within a line associated with descriptor .Ar ln into the location pointed to by argument .Ar ret . The retrieved column numbers are 1-based, with the value -1 indicating that column number information was not available. .Pp Function .Fn dwarf_linesrc stores a pointer to a NUL-terminated string containing the source file name associated with line descriptor .Ar ln into the location pointed to by argument .Ar ret . The full path of the source file is returned if possible. The memory used for the source file name string is managed by the DWARF(3) library and should not be directly freed by application code. Instead, portable code should use .Xr dwarf_dealloc 3 to indicate that the string should be freed. .Pp Function .Fn dwarf_line_srcfileno stores the index of the source file associated with the line descriptor .Ar ln in the location pointed to by argument .Ar ret . The returned value is 1-based index into the array of source file names returned by .Xr dwarf_srcfiles 3 . .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_LINE_FILE_NUM_BAD" .It Bq Er DW_DLE_ARGUMENT Either of the arguments .Va ln or .Va ret was NULL. .It Bq Er DW_DLE_LINE_FILE_NUM_BAD The source file name associated with the line descriptor .Ar ln could not be retrieved by function .Fn dwarf_linesrc . .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_srcfiles 3 , .Xr dwarf_srclines 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_lne_end_sequence.3 (revision 367466) @@ -1,100 +1,100 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_lne_end_sequence.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_lne_end_sequence.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 15, 2011 -.Os .Dt DWARF_LNE_END_SEQUENCE 3 +.Os .Sh NAME .Nm dwarf_lne_end_sequence .Nd set the end of instruction sequence .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_lne_end_sequence .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Addr addr" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_lne_end_sequence sets the address that indicates the end of a sequence of target machine instructions. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar addr specifies an address value which is the first byte after the end of a instruction sequence. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_lne_end_sequence returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_lne_end_sequence returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_lne_end_sequence can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_ARGUMENT The value in argument .Ar addr overlapped an existing line information entry. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_directory_decl 3 , .Xr dwarf_add_file_decl 3 , .Xr dwarf_add_line_entry 3 , .Xr dwarf_lne_set_address 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_lne_set_address.3 (revision 367466) @@ -1,105 +1,105 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_lne_set_address.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_lne_set_address.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 14, 2011 -.Os .Dt DWARF_LNE_SET_ADDRESS 3 +.Os .Sh NAME .Nm dwarf_lne_set_address .Nd set the base address for line number information .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_Unsigned" .Fo dwarf_lne_set_address .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Addr off" .Fa "Dwarf_Unsigned symndx" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_lne_set_address sets the base address used by subsequent invocations of the .Xr dwarf_add_line_entry 3 function. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar off specifies a relocatable program address. .Pp Argument .Ar symndx specifies the index of the ELF symbol to be used for relocation. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_lne_set_address returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_lne_set_address returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_lne_set_address can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_ARGUMENT The argument .Ar symndx had an illegal value. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_directory_decl 3 , .Xr dwarf_add_file_decl 3 , .Xr dwarf_add_line_entry 3 , .Xr dwarf_lne_end_sequence 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_loclist.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_loclist.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_loclist.3 (revision 367466) @@ -1,230 +1,230 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_loclist.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_loclist.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_LOCLIST 3 +.Os .Sh NAME .Nm dwarf_loclist , .Nm dwarf_loclist_n .Nd retrieve DWARF location expression information .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_loclist .Fa "Dwarf_Attribute at" .Fa "Dwarf_Locdesc **llbuf" .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *error" .Fc .Ft int .Fo dwarf_loclist_n .Fa "Dwarf_Attribute at" .Fa "Dwarf_Locdesc ***llbuf" .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION These functions retrieve the location expressions associated with a DWARF attribute. .Pp Note: function .Fn dwarf_loclist is deprecated. New application code should instead use function .Fn dwarf_loclist_n .Pp Function .Fn dwarf_loclist_n retrieves the list of location expressions associated with a DWARF attribute. Argument .Ar at should reference a valid DWARF attribute. Argument .Ar llbuf should point to a location which will hold a returned array of pointers to .Vt Dwarf_Locdesc descriptors. Argument .Ar listlen should point to a location which will be set to the number of elements contained in the returned array. If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_loclist retrieves the first location expression associated with an attribute. Argument .Ar at should reference a valid DWARF attribute. Argument .Ar llbuf should point to a location which will hold the returned pointer to a .Vt Dwarf_Locdesc descriptor. Argument .Ar listlen should point to a location which will be always set to 1. If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp .Vt Dwarf_Locdesc descriptors are defined in the header file .In libdwarf.h , and consist of following fields: .Pp .Bl -tag -width ".Va ld_cents" -compact .It Va ld_lopc The lowest program counter address covered by the descriptor. This field will be set to 0 if the descriptor is not associated with an address range. .It Va ld_hipc The highest program counter address covered by the descriptor. This field will be set to 0 if the descriptor is not associated with an address range. .It Va ld_cents The number of entries returned in .Va ld_s field. .It Va ld_s Pointer to an array of .Vt Dwarf_Loc descriptors. .El .Pp Each .Vt Dwarf_Loc descriptor represents one operation of a location expression. These descriptors are defined in the header file .In libdwarf.h , and consist of following fields: .Pp .Bl -tag -width ".Va lr_number2" -compact .It Va lr_atom The operator name, one of the .Dv DW_OP_* constants defined in the header file .In dwarf.h . .It Va lr_number The first operand of this operation. .It Va lr_number2 The second operand of this operation. .It Va lr_offset The byte offset of this operation within the containing location expression. .El .Ss Memory Management The memory area used for the descriptor array returned in argument .Ar llbuf is allocated by the .Lb libdwarf . When the descriptor array is no longer needed, application code should use function .Xr dwarf_dealloc 3 to free the memory area in the following manner: .Bl -enum .It First, the .Ar ld_s field of each .Vt Dwarf_Locdesc descriptor should be deallocated using the allocation type .Dv DW_DLA_LOC_BLOCK . .It Then, the application should free each .Vt Dwarf_Locdesc descriptor using the allocation type .Dv DW_DLA_LOCDESC . .It Finally, the .Va llbuf pointer should be deallocated using the allocation type .Dv DW_DLA_LIST . .El .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . -.Sh ERRORS -These functions can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar at , -.Ar llbuf -or -.Ar listlen -was NULL. -.It Bq Er DW_DLE_ARGUMENT -The attribute provided by argument -.Ar at -does not contain a location expression or is not associated with a -location expression list. -.El -.Sh EXAMPLE +.Sh EXAMPLES To retrieve the location list associated with an attribute, use: .Bd -literal -offset indent Dwarf_Attribute at; Dwarf_Locdesc **llbuf; Dwarf_Signed lcnt; Dwarf_Loc *lr; Dwarf_Error de; int i; if (dwarf_loclist_n(at, &llbuf, &lcnt, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_loclist_n failed: %s", dwarf_errmsg(de)); for (i = 0; i < lcnt; i++) { /* ... Use llbuf[i] ... */ for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { lr = &llbuf[i]->ld_s[j]; /* ... Use each Dwarf_Loc descriptor ... */ } dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); .Ed +.Sh ERRORS +These functions can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar at , +.Ar llbuf +or +.Ar listlen +was NULL. +.It Bq Er DW_DLE_ARGUMENT +The attribute provided by argument +.Ar at +does not contain a location expression or is not associated with a +location expression list. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , +.Xr dwarf_get_loclist_entry 3 , .Xr dwarf_loclist_from_expr 3 , -.Xr dwarf_loclist_from_expr_a 3 , -.Xr dwarf_get_loclist_entry 3 +.Xr dwarf_loclist_from_expr_a 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_loclist_from_expr.3 (revision 367466) @@ -1,201 +1,201 @@ .\" Copyright (c) 2011,2014 Kai Wang .\" 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: dwarf_loclist_from_expr.3 3129 2014-12-21 20:06:26Z jkoshy $ +.\" $Id: dwarf_loclist_from_expr.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd December 21, 2014 -.Os .Dt DWARF_LOCLIST_FROM_EXPR 3 +.Os .Sh NAME .Nm dwarf_loclist_from_expr , .Nm dwarf_loclist_from_expr_a , .Nm dwarf_loclist_from_expr_b .Nd translate DWARF location expression bytes .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_loclist_from_expr .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Ptr bytes_in" .Fa "Dwarf_Unsigned bytes_len" .Fa "Dwarf_Locdesc **llbuf" .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_loclist_from_expr_a .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Ptr bytes_in" .Fa "Dwarf_Unsigned bytes_len" .Fa "Dwarf_Half addr_size" .Fa "Dwarf_Locdesc **llbuf" .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_loclist_from_expr_b .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Ptr bytes_in" .Fa "Dwarf_Unsigned bytes_len" .Fa "Dwarf_Half addr_size" .Fa "Dwarf_Half offset_size" .Fa "Dwarf_Small version" .Fa "Dwarf_Locdesc **llbuf" .Fa "Dwarf_Signed *listlen" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION Function .Fn dwarf_loclist_from_expr translates DWARF location expression bytes into a .Vt Dwarf_Locdesc descriptor. The size for address related data is taken to be the default address size for the object being read. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar bytes_in should point to an array of DWARF location expression bytes. .Pp Argument .Ar bytes_len should specify the number of the location expression bytes to be translated. .Pp Argument .Ar llbuf should point to a location which will be set to a pointer to a returned .Vt Dwarf_Locdesc descriptor. .Pp Argument .Ar listlen should point to a location which will hold the number of the .Vt Dwarf_Locdesc descriptors returned. In this case it is always set to 1. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp Function .Fn dwarf_loclist_from_expr_a is identical to function .Fn dwarf_loclist_from_expr , except that it requires one additional argument .Ar addr_size , which specifies the address size to use when translating the location expression bytes. .Pp Function .Fn dwarf_loclist_from_expr_b is identical to function .Fn dwarf_loclist_from_expr_a except that it requires two additional arguments for translating the location expression bytes. Argument .Ar offset_size specifies the offset size, and argument .Ar version specifies the DWARF version. These values are required to correctly translate the .Dv DW_OP_GNU_implicit_pointer opcode. .Ss Memory Management The memory area used for the descriptor returned in argument .Ar llbuf is allocated by .Lb libdwarf . When the descriptor is no longer needed, application code should use function .Xr dwarf_dealloc 3 to free the memory area in two steps: .Bl -enum -compact .It First, the array of .Vt Dwarf_Loc descriptors pointed to by the .Ar ld_s field of the .Vt Dwarf_Locdesc descriptor should be deallocated using the allocation type .Dv DW_DLA_LOC_BLOCK . .It Next, the application should free the .Ar llbuf pointer using the allocation type .Dv DW_DLA_LOCDESC . .El .Sh RETURN VALUES On success, these functions returns .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set the argument .Ar err . .Sh ERRORS These functions may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_LOC_EXPR_BAD" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Va dbg , .Va bytes_in , .Va llbuf or .Va listlen was NULL. .It Bq Er DW_DLE_ARGUMENT Argument .Ar bytes_len was 0. .It Bq Er DW_DLE_ARGUMENT The value of argument .Ar addr_size was invalid. .It Bq Er DW_DLE_LOC_EXPR_BAD An unknown or invalid operation was found in the location expression bytes provided in argument .Ar bytes_in . .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of this function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , -.Xr dwarf_loclist_n 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg3 3 , -.Xr dwarf_get_loclist_entry 3 +.Xr dwarf_get_loclist_entry 3 , +.Xr dwarf_loclist_n 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_new_die.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_new_die.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_new_die.3 (revision 367466) @@ -1,164 +1,164 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_new_die.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_new_die.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 4, 2011 -.Os .Dt DWARF_NEW_DIE 3 +.Os .Sh NAME .Nm dwarf_new_die .Nd allocate a new debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Die .Fo dwarf_new_die .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Tag tag" .Fa "Dwarf_P_Die parent" .Fa "Dwarf_P_Die child" .Fa "Dwarf_P_Die left" .Fa "Dwarf_P_Die right" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_new_die allocates a new DWARF debugging information entry and links it to another debugging information entry. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar tag should specify the tag of the newly created debugging information entry. Valid values for this argument are those for the .Dv DW_TAG_ Ns * symbols defined in .In libdwarf.h . .Pp Argument .Ar parent specifies the parent link of the debugging information entry. .Pp Argument .Ar child specifies the first child link of the debugging information entry. .Pp Argument .Ar left specifies the left sibling link of the debugging information entry. .Pp Argument .Ar right specifies the right sibling link of the debugging information entry. .Pp Only one of arguments .Ar parent , .Ar child , .Ar left and .Ar right is allowed to be non-NULL. Application code can subsequently call the function .Xr dwarf_die_link 3 to change the links for the created debugging information entry. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_new_die returns the newly created debugging information entry. In case of an error, function .Fn dwarf_new_die returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_new_die -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -Argument -.Ar dbg -was NULL. -.It Bq Er DW_DLE_ARGUMENT -More than one of the arguments -.Ar parent , -.Ar child , -.Ar left -and -.Ar right -were non-NULL. -.It Bq Er DW_DLE_MEMORY -An out of memory condition was encountered during the execution of the -function. -.El .Sh EXAMPLES To create debugging information entries and add them to the producer instance, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_P_Die die1, die2; Dwarf_Error de; /* ... assume dbg refers to a DWARF producer instance ... */ die1 = dwarf_new_die(dbg, DW_TAG_compilation_unit, NULL, NULL, NULL, NULL, &de); if (die1 == NULL) { warnx("dwarf_new_die failed: %s", dwarf_errmsg(-1)); return; } die2 = dwarf_new_die(dbg, DW_TAG_base_type, die1, NULL, NULL, NULL, &de); if (die1 == NULL) { warnx("dwarf_new_die failed: %s", dwarf_errmsg(-1)); return; } if (dwarf_add_die_to_debug(dbg, die1, &de) != DW_DLV_OK) { warnx("dwarf_add_die_to_debug failed: %s", dwarf_errmsg(-1)); return; } .Ed +.Sh ERRORS +Function +.Fn dwarf_new_die +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_ARGUMENT +More than one of the arguments +.Ar parent , +.Ar child , +.Ar left +and +.Ar right +were non-NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of the +function. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_die_to_debug 3 , .Xr dwarf_die_link 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_new_expr.3 (revision 367466) @@ -1,135 +1,135 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_new_expr.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_new_expr.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 8, 2011 -.Os .Dt DWARF_NEW_EXPR 3 +.Os .Sh NAME .Nm dwarf_new_expr .Nd create a location expression descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Expr" .Fo dwarf_new_expr .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_new_expr allocates a DWARF location expression descriptor used to build up a location expression stream. .Pp The application can use the functions .Xr dwarf_add_expr_gen 3 and .Xr dwarf_add_expr_addr_b 3 to add location expression operators to the created descriptor. When done, the application can call the function .Xr dwarf_expr_into_block 3 to retrieve the generated byte stream for the location expression, or call the function .Xr dwarf_add_AT_location_expr 3 to create an attribute with the location expression stream as its value. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_new_expr returns the created location expression descriptor. In case of an error, function .Fn dwarf_new_expr returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_new_expr -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -Argument -.Ar dbg -was NULL. -.It Bq Er DW_DLE_MEMORY -An out of memory condition was encountered during the execution of -the function. -.El .Sh EXAMPLES To create a location expression descriptor, add location expression operators to it and to retrieve the generated byte stream, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_Error de; Dwarf_P_Expr pe; Dwarf_Addr buf; Dwarf_Unsigned len; /* ...Assume that `dbg' refers to a DWARF producer instance... */ if ((pe = dwarf_new_expr(dbg, &de)) == DW_DLV_BADADDR) { warnx("dwarf_new_expr failed: %s", dwarf_errmsg(-1)); return; } if (dwarf_add_expr_gen(pe, DW_OP_regx, 55, 0, &de) == DW_DLV_NOCOUNT) { warnx("dwarf_add_expr_gen failed: %s", dwarf_errmsg(-1)); return; } if ((buf = dwarf_expr_into_block(pe, &len, &de)) == DW_DLV_BADADDR) { warnx("dwarf_expr_into_block failed: %s", dwarf_errmsg(-1)); return; } .Ed +.Sh ERRORS +Function +.Fn dwarf_new_expr +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Ar dbg +was NULL. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +the function. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_AT_location_expr 3 , -.Xr dwarf_add_expr_gen 3 , .Xr dwarf_add_expr_addr 3 , .Xr dwarf_add_expr_addr_b 3 , +.Xr dwarf_add_expr_gen 3 , .Xr dwarf_expr_current_offset 3 , .Xr dwarf_expr_into_block 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_new_fde.3 (revision 367466) @@ -1,87 +1,87 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_new_fde.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_new_fde.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 24, 2011 -.Os .Dt DWARF_NEW_FDE 3 +.Os .Sh NAME .Nm dwarf_new_fde .Nd allocate a DWARF frame descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "Dwarf_P_Fde" .Fo dwarf_new_fde .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_new_fde allocates a new DWARF frame descriptor. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_new_fde returns the newly created frame descriptor. In case of an error, function .Fn dwarf_new_fde returns .Dv DW_DLV_BADADDR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_new_fde can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_fde_inst 3 , +.Xr dwarf_add_frame_cie 3 , .Xr dwarf_add_frame_fde 3 , .Xr dwarf_add_frame_fde_b 3 , -.Xr dwarf_add_frame_cie 3 , .Xr dwarf_fde_cfa_offset 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_next_cu_header.3 (revision 367466) @@ -1,288 +1,287 @@ .\" Copyright (c) 2010,2014 Kai Wang .\" 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: dwarf_next_cu_header.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_next_cu_header.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd December 21, 2014 -.Os .Dt DWARF_NEXT_CU_HEADER 3 +.Os .Sh NAME .Nm dwarf_next_cu_header , .Nm dwarf_next_cu_header_b , .Nm dwarf_next_cu_header_c .Nd step through compilation units in a DWARF debug context .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_next_cu_header .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Unsigned *cu_length" .Fa "Dwarf_Half *cu_version" .Fa "Dwarf_Off *cu_abbrev_offset" .Fa "Dwarf_Half *cu_pointer_size" .Fa "Dwarf_Unsigned *cu_next_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_next_cu_header_b .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Unsigned *cu_length" .Fa "Dwarf_Half *cu_version" .Fa "Dwarf_Off *cu_abbrev_offset" .Fa "Dwarf_Half *cu_pointer_size" .Fa "Dwarf_Half *cu_offset_size" .Fa "Dwarf_Half *cu_extension_size" .Fa "Dwarf_Unsigned *cu_next_offset" .Fa "Dwarf_Error *err" .Fc .Ft int .Fo dwarf_next_cu_header_c .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Bool is_info" .Fa "Dwarf_Unsigned *cu_length" .Fa "Dwarf_Half *cu_version" .Fa "Dwarf_Off *cu_abbrev_offset" .Fa "Dwarf_Half *cu_pointer_size" .Fa "Dwarf_Half *cu_offset_size" .Fa "Dwarf_Half *cu_extension_size" .Fa "Dwarf_Sig8 *type_signature" .Fa "Dwarf_Unsigned *type_offset" .Fa "Dwarf_Unsigned *cu_next_offset" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION These functions are used to step through compilation or type units associated with a DWARF debug context, optionally returning information about the unit. .Pp Function .Fn dwarf_next_cu_header_c is the API recommended for new application code. Function .Fn dwarf_next_cu_header and .Fn dwarf_next_cu_header_b can only operate on compilation units associated with the .Dq \&.debug_info section. They are less general than function .Fn dwarf_next_cu_header_c , and are deprecated for use by new application code. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . If argument .Ar is_info is set to 1, the function returns information for compilation units found in the .Dq \&.debug_info section. If argument .Ar is_info is set to 0, the function returns information for type units found in the .Dq \&.debug_types sections. Argument .Ar cu_length should point to a location that will be set to the length of the compilation or type unit. Argument .Ar cu_version should point to a location that will be set to the version number for the compilation or type unit. Argument .Ar cu_abbrev_offset should point to a location that will be set to the starting offset (in the .Dq .debug_abbrev section) of the set of debugging information entry abbreviations associated with this compilation or type unit. Argument .Ar cu_pointer_size should point to a location that will be set to the size in bytes of an address for the machine architecture of the underlying object being debugged. Argument .Ar cu_offset_size should point to a location that will be set to the size in bytes for a DWARF offset in the compilation or type unit. Argument .Ar cu_extension_size is only needed for processing MIPS/IRIX objects that use a non-standard DWARF format. It should point to a location that will be set to 4 for normal objects and to 0 for non-standard ones. Argument .Ar type_signature and .Ar type_offset is only needed for processing type units. Argument .Ar type_signature should point to a location that will be set to the 64-bit unique signature of the type described in the type unit. Argument .Ar type_offset should point to a location that will be set to the offset of the debugging information entry that describes the type. Argument .Ar cu_next_offset should point to a location that will be set to the offset of the next compilation unit header in the .Dq \&.debug_info section, or the offset of the next type unit header in the .Dq \&.debug_types section. Argument .Ar err should point to a location that will hold an error descriptor in case of an error. .Pp Function .Fn dwarf_next_cu_header_b is identical to function .Fn dwarf_next_cu_header_c except that it does not provide arguments .Ar is_info , .Ar type_signature and .Ar type_offset . .Pp Function .Fn dwarf_next_cu_header is identical to function .Fn dwarf_next_cu_header_b except that it does not provide arguments .Ar cu_offset_size and .Ar cu_extension_size . .Pp A value of NULL may be used for any of the arguments .Ar cu_length , .Ar cu_version , .Ar cu_abbrev_offset , .Ar cu_pointer_size , .Ar cu_offset_size , .Ar cu_extension_size , .Ar type_signature , .Ar type_offset , .Ar cu_next_offset and .Ar err if the caller is not interested in the respective value. .Ss Iterating Through Compilation Units in a Debug Context -.Pp The first call to function .Fn dwarf_next_cu_header_c for a given debug context with argument .Ar is_info set to 1 will return information about the first compilation unit in the .Dq \&.debug_info section. Subsequent calls to the function will iterate through the remaining compilation units in the section. On stepping past the last compilation unit in the section, function .Fn dwarf_next_cu_header_c returns .Dv DW_DLV_NO_ENTRY and resets its internal state. The next call to the function will restart from the first compilation unit in the section. .Ss Iterating Through Type Units in a Debug Context When a DWARF debug context is allocated using .Xr dwarf_init 3 , an internal pointer associated with the context will point to the first .Dq \&.debug_types section found in the debug object. The first call to function .Fn dwarf_next_cu_header_c for the debug context with argument .Ar is_info set to 0 will return information about the first type unit in that .Dq \&.debug_types section. Subsequent calls to the function will iterate through the remaining type units in the section. On stepping past the last type unit in the debug context, function .Fn dwarf_next_cu_header_c returns .Dv DW_DLV_NO_ENTRY and resets its internal state. The next call to the function will restart from the first type unit in the .Dq \&.debug_types section. .Pp If the debug object contains multiple .Dq \&.debug_types sections, the function .Fn dwarf_next_types_section can be called to move the internal pointer to the next .Dq \&.debug_types section. As a result, subsequent calls of the function .Fn dwarf_next_cu_header_c will operate on the new .Dq \&.debug_types section. Function .Fn dwarf_next_types_section returns .Dv DW_DLV_NO_ENTRY when there are no more .Dq \&.debug_types sections left in the debug object. .Sh RETURN VALUES On success, these functions return .Dv DW_DLV_OK . In case of an error, they return .Dv DW_DLV_ERROR and set argument .Ar err . When there are no more compilation units left to traverse, they return .Dv DW_DLV_NO_ENTRY . .Sh ERRORS These functions can fail with the following error: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Va dbg was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_cu_die_offset_given_cu_header_offset 3 , .Xr dwarf_init 3 , .Xr dwarf_next_types_section 3 , .Xr dwarf_siblingof 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_next_types_section.3 (revision 367466) @@ -1,134 +1,134 @@ .\" Copyright (c) 2014 Kai Wang .\" 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: dwarf_next_types_section.3 3116 2014-12-20 18:26:55Z jkoshy $ +.\" $Id: dwarf_next_types_section.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd December 20, 2014 -.Os .Dt DWARF_NEXT_TYPES_SECTION 3 +.Os .Sh NAME .Nm dwarf_next_types_section .Nd step through .debug_types sections in a debug context .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_next_types_section .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_next_types_section steps through the .Dq \&.debug_types sections found in a debug context. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . Argument .Ar err should point to a location that will hold an error descriptor in case of an error. .Pp When a DWARF debug context is allocated using .Xr dwarf_init 3 , an internal pointer associated with the context will point to the first .Dq \&.debug_types section present in the debug object. When the application calls function .Fn dwarf_next_types_section , this internal pointer will move to the next .Dq \&.debug_types section present. On stepping past the last .Dq \&.debug_types section left in the debug context, function .Fn dwarf_next_types_section returns .Dv DW_DLV_NO_ENTRY . The next call to the function will restart from the first .Dq \&.debug_types section in the debug context. .Pp Application code should call function .Xr dwarf_next_cu_header_c 3 to iterate though the type units associated with the current .Dq \&.debug_types section. .Sh RETURN VALUES On success, function .Fn dwarf_next_types_section returns .Dv DW_DLV_OK . .Pp In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . When there are no more .Dq \&.debug_types sections left to traverse, it returns .Dv DW_DLV_NO_ENTRY . -.Sh COMPATIBILITY -This function is an extension to the -.Xr DWARF 3 -API. -.Sh ERRORS -The -.Fn dwarf_next_types_section -function may fail with the following errors: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -Argument -.Va dbg -was NULL. -.El .Sh EXAMPLES To iterate though every type unit in all the .Dq \&.debug_types sections found in a debug context: .Bd -literal -offset indent Dwarf_Debug dbg; Dwarf_Sig8 sig8; Dwarf_Unsigned typeoff; Dwarf_Error de; \&... allocate dbg using dwarf_init() etc ... do { while ((ret = dwarf_next_cu_header_c(dbg, 0, NULL, NULL, NULL, NULL, NULL, NULL, &sig8, &typeoff, NULL, &de)) == DW_DLV_OK) { /* Access DIEs etc ... */ } } while (dwarf_next_types_section(dbg, &de) == DW_DLV_OK); .Ed +.Sh COMPATIBILITY +This function is an extension to the +.Xr DWARF 3 +API. +.Sh ERRORS +The +.Fn dwarf_next_types_section +function may fail with the following errors: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +Argument +.Va dbg +was NULL. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_init 3 , .Xr dwarf_next_cu_header_c 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_object_init.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_object_init.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_object_init.3 (revision 367466) @@ -1,227 +1,226 @@ .\" Copyright (c) 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: dwarf_object_init.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_object_init.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 29, 2011 -.Os .Dt DWARF_OBJECT_INIT 3 +.Os .Sh NAME .Nm dwarf_object_init .Nd allocate a DWARF debug descriptor with application-specific file \ access methods .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_object_init .Fa "Dwarf_Obj_Access_Interface *iface" .Fa "Dwarf_Handler errhand" .Fa "Dwarf_Ptr errarg" .Fa "Dwarf_Debug *dbg" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION -.Pp The .Fn dwarf_object_init function allocates and returns a .Vt Dwarf_Debug instance that uses application-supplied access methods to read file content. .Pp The argument .Ar iface should point to a populated .Vt Dwarf_Obj_Access_Interface structure. The contents of the .Vt Dwarf_Obj_Access_Interface structure are described in the section .Sx "Object Access Functions" below. .Pp The argument .Ar errhand should point to a function to be called in case of an error. If this argument is .Dv NULL then a default error handling scheme is used. See .Xr dwarf 3 for a description of the error handling schemes available. .Pp The argument .Ar errarg will be passed to the error handler function pointed to by argument .Ar errhand . .Pp The argument .Ar dbg should point to a memory location that will be set to a reference to the returned .Vt Dwarf_Debug descriptor. .Pp The argument .Ar err will be used to return a .Vt Dwarf_Error descriptor in case of an error. .Ss Object Access Functions The data structures used to specify object access methods are defined in .In libdwarf.h . .Bl -tag -width indent .It Vt "Dwarf_Obj_Access_Interface" This structure bundles together a set of file access methods along with a pointer to application-private state. .Bd -literal -offset indent typedef struct { void *object; const Dwarf_Obj_Access_Methods *methods; } Dwarf_Obj_Access_Interface; .Ed .Pp .Bl -tag -width ".Ar methods" -compact .It Ar object This field points to application-specific state that will be passed as the first parameter to the actual access object methods. .It Ar methods This structure contains pointers to the functions implementing the access methods, as described below. .El .It Vt Dwarf_Obj_Access_Methods This structure specifies the functions implementing low-level access. .Bd -literal -offset indent typedef struct { int (*get_section_info)(void *obj, Dwarf_Half index, Dwarf_Obj_Access_Section *ret, int *error); Dwarf_Endianness (*get_byte_order)(void *obj); Dwarf_Small (*get_length_size)(void *obj); Dwarf_Small (*get_pointer_size)(void *obj); Dwarf_Unsigned (*get_section_count)(void *obj); int (*load_section)(void *obj, Dwarf_Half ndx, Dwarf_Small **ret_data, int *error); } Dwarf_Obj_Access_Methods; .Ed .Pp .Bl -tag -width ".Ar get_section_count" -compact .It Ar get_byte_order This function should return the endianness of the DWARF object by returning one of the constants .Dv DW_OBJECT_MSB or .Dv DW_OBJECT_LSB . .It Ar get_length_size This function should return the number of bytes needed to represent a DWARF offset in the object being debugged. .It Ar get_pointer_size This function should return the size in bytes, in the object being debugged, of a memory address. .It Ar get_section_count This function should return the number of sections in the object being debugged. .It Ar get_section_info This function should return information about the section at the index .Ar ndx by filling in the structure of type .Vt Dwarf_Obj_Access_Section pointed to by argument .Ar ret . The .Vt Dwarf_Obj_Access_Section structure is described below. .It Ar load_section This function should load the section specified by argument .Ar ndx into memory and place a pointer to the section's data into the location pointed to by argument .Ar ret_data . .El .Pp The argument .Ar obj passed to these functions will be set to the pointer value in the .Ar object field of the associated .Vt Dwarf_Obj_Access_Interface structure. .Pp The argument .Ar error is used to return an error code in case of an error. .It Vt Dwarf_Obj_Access_Section This structure describes the layout of a section in the DWARF object. .Bd -literal -offset indent typedef struct { Dwarf_Addr addr; Dwarf_Unsigned size; const char *name; } Dwarf_Obj_Access_Section; .Ed .Pp .Bl -tag -width ".Ar name" -compact .It Ar addr A pointer to the start of the section's data. .It Ar size The size of the section in bytes. .It Ar name A pointer to a NUL-terminated string containing the name of the section. .El .El .Sh RETURN VALUES On success, the .Fn dwarf_object_init function returns .Dv DW_DLV_OK . In case of an error, the function returns .Dv DW_DLV_ERROR and sets the argument -.Ar err. +.Ar err . .Sh ERRORS The .Fn dwarf_object_init function may fail with the following errors: .Bl -tag -width ".Bq Er DW_DLE_DEBUG_INFO_NULL" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar iface or .Ar dbg was NULL. .It Bq Er DW_DLE_DEBUG_INFO_NULL The underlying object did not contain debugging information. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_init 3 , .Xr dwarf_init_elf 3 , .Xr dwarf_object_finish 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_pro_attr.c (revision 367466) @@ -1,384 +1,386 @@ /*- * Copyright (c) 2009 Kai Wang * 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 "_libdwarf.h" ELFTC_VCSID("$Id: dwarf_pro_attr.c 2074 2011-10-27 03:34:33Z jkoshy $"); Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_P_Expr loc_expr, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL || loc_expr == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; at->at_expr = loc_expr; - if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) + if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) { + free(at); return (DW_DLV_BADADDR); + } at->u[0].u64 = loc_expr->pe_length; at->u[1].u8p = loc_expr->pe_block; if (loc_expr->pe_length <= UCHAR_MAX) at->at_form = DW_FORM_block1; else if (loc_expr->pe_length <= USHRT_MAX) at->at_form = DW_FORM_block2; else if (loc_expr->pe_length <= UINT_MAX) at->at_form = DW_FORM_block4; else at->at_form = DW_FORM_block; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error) { Dwarf_Attribute at; if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); return (at); } Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error) { Dwarf_Attribute at; if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); return (at); } Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error) { Dwarf_Attribute at; if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); return (at); } Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value, Dwarf_Error *error) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = DW_AT_const_value; at->at_form = DW_FORM_sdata; at->u[0].s64 = value; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value, Dwarf_Error *error) { Dwarf_Attribute at; Dwarf_Debug dbg; dbg = die != NULL ? die->die_dbg : NULL; if (die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = DW_AT_const_value; at->at_form = DW_FORM_udata; at->u[0].u64 = value; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string, Dwarf_Error *error) { Dwarf_Attribute at; if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); return (at); } Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) { return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index, error)); } Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; at->at_form = DW_FORM_addr; at->at_relsym = sym_index; at->u[0].u64 = pc_value; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) { Dwarf_Attribute at; int ret; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index, NULL, &at, error); if (ret != DW_DLE_NONE) return (DW_DLV_BADADDR); return (at); } Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; at->at_form = DW_FORM_ref_addr; at->at_relsym = sym_index; at->u[0].u64 = pc_value; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Unsigned value, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; at->u[0].u64 = value; if (value <= UCHAR_MAX) at->at_form = DW_FORM_data1; else if (value <= USHRT_MAX) at->at_form = DW_FORM_data2; else if (value <= UINT_MAX) at->at_form = DW_FORM_data4; else at->at_form = DW_FORM_data8; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Signed value, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; at->u[0].u64 = value; if (value >= SCHAR_MIN && value <= SCHAR_MAX) at->at_form = DW_FORM_data1; else if (value >= SHRT_MIN && value <= SHRT_MAX) at->at_form = DW_FORM_data2; else if (value >= INT_MIN && value <= INT_MAX) at->at_form = DW_FORM_data4; else at->at_form = DW_FORM_data8; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_P_Die ref_die, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; if (dbg->dbg_offset_size == 4) at->at_form = DW_FORM_ref4; else at->at_form = DW_FORM_ref8; at->at_refdie = ref_die; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Small flag, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); at->at_die = die; at->at_attrib = attr; at->at_form = DW_FORM_flag; at->u[0].u64 = flag ? 1 : 0; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (at); } Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, char *string, Dwarf_Error *error) { Dwarf_Attribute at; if (dbg == NULL || die == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } /* XXX Add DW_FORM_string style string instead? */ if (_dwarf_add_string_attr(die, &at, attr, string, error) != DW_DLE_NONE) return (DW_DLV_BADADDR); return (at); } Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_pro_expr.c (revision 367466) @@ -1,223 +1,223 @@ /*- * Copyright (c) 2010 Kai Wang * 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 "_libdwarf.h" ELFTC_VCSID("$Id: dwarf_pro_expr.c 2074 2011-10-27 03:34:33Z jkoshy $"); static struct _Dwarf_P_Expr_Entry * _dwarf_add_expr(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error) { struct _Dwarf_P_Expr_Entry *ee; Dwarf_Debug dbg; int len; - dbg = expr != NULL ? expr->pe_dbg : NULL; + dbg = expr->pe_dbg; - if (_dwarf_loc_expr_add_atom(expr->pe_dbg, NULL, NULL, opcode, val1, - val2, &len, error) != DW_DLE_NONE) + if (_dwarf_loc_expr_add_atom(dbg, NULL, NULL, opcode, val1, val2, &len, + error) != DW_DLE_NONE) return (NULL); assert(len > 0); if ((ee = calloc(1, sizeof(*ee))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (NULL); } STAILQ_INSERT_TAIL(&expr->pe_eelist, ee, ee_next); ee->ee_loc.lr_atom = opcode; ee->ee_loc.lr_number = val1; ee->ee_loc.lr_number2 = val2; ee->ee_loc.lr_offset = expr->pe_length; expr->pe_length += len; expr->pe_invalid = 1; return (ee); } int _dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Error *error) { struct _Dwarf_P_Expr_Entry *ee; Dwarf_Debug dbg; int len, pos, ret; - dbg = expr != NULL ? expr->pe_dbg : NULL; + dbg = expr->pe_dbg; if (expr->pe_block != NULL) { free(expr->pe_block); expr->pe_block = NULL; } if (expr->pe_length <= 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_EXPR_LENGTH_BAD); return (DW_DLE_EXPR_LENGTH_BAD); } if ((expr->pe_block = calloc((size_t) expr->pe_length, 1)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } pos = 0; STAILQ_FOREACH(ee, &expr->pe_eelist, ee_next) { assert((Dwarf_Unsigned) pos < expr->pe_length); - ret = _dwarf_loc_expr_add_atom(expr->pe_dbg, + ret = _dwarf_loc_expr_add_atom(dbg, &expr->pe_block[pos], &expr->pe_block[expr->pe_length], ee->ee_loc.lr_atom, ee->ee_loc.lr_number, ee->ee_loc.lr_number2, &len, error); assert(ret == DW_DLE_NONE); assert(len > 0); pos += len; } expr->pe_invalid = 0; return (DW_DLE_NONE); } void _dwarf_expr_cleanup(Dwarf_P_Debug dbg) { Dwarf_P_Expr pe, tpe; struct _Dwarf_P_Expr_Entry *ee, *tee; assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); STAILQ_FOREACH_SAFE(pe, &dbg->dbgp_pelist, pe_next, tpe) { STAILQ_REMOVE(&dbg->dbgp_pelist, pe, _Dwarf_P_Expr, pe_next); STAILQ_FOREACH_SAFE(ee, &pe->pe_eelist, ee_next, tee) { STAILQ_REMOVE(&pe->pe_eelist, ee, _Dwarf_P_Expr_Entry, ee_next); free(ee); } if (pe->pe_block) free(pe->pe_block); free(pe); } } Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_P_Expr pe; if (dbg == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLV_BADADDR); } if ((pe = calloc(1, sizeof(struct _Dwarf_P_Expr))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLV_BADADDR); } STAILQ_INIT(&pe->pe_eelist); STAILQ_INSERT_TAIL(&dbg->dbgp_pelist, pe, pe_next); pe->pe_dbg = dbg; return (pe); } Dwarf_Unsigned dwarf_add_expr_gen(Dwarf_P_Expr expr, Dwarf_Small opcode, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error) { if (expr == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } if (_dwarf_add_expr(expr, opcode, val1, val2, error) == NULL) return (DW_DLV_NOCOUNT); return (expr->pe_length); } Dwarf_Unsigned dwarf_add_expr_addr(Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Signed sym_index, Dwarf_Error *error) { return (dwarf_add_expr_addr_b(expr, address, sym_index, error)); } Dwarf_Unsigned dwarf_add_expr_addr_b(Dwarf_P_Expr expr, Dwarf_Unsigned address, Dwarf_Unsigned sym_index, Dwarf_Error *error) { struct _Dwarf_P_Expr_Entry *ee; if (expr == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } if ((ee = _dwarf_add_expr(expr, DW_OP_addr, address, 0, error)) == NULL) return (DW_DLV_NOCOUNT); ee->ee_sym = sym_index; return (expr->pe_length); } Dwarf_Unsigned dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error *error) { if (expr == NULL) { DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); return (DW_DLV_NOCOUNT); } return (expr->pe_length); } Dwarf_Addr dwarf_expr_into_block(Dwarf_P_Expr expr, Dwarf_Unsigned *length, Dwarf_Error *error) { Dwarf_Debug dbg; dbg = expr != NULL ? expr->pe_dbg : NULL; if (expr == NULL || length == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return ((Dwarf_Addr) (uintptr_t) DW_DLV_BADADDR); } if (expr->pe_block == NULL || expr->pe_invalid) if (_dwarf_expr_into_block(expr, error) != DW_DLE_NONE) return ((Dwarf_Addr) (uintptr_t) DW_DLV_BADADDR); *length = expr->pe_length; return ((Dwarf_Addr) (uintptr_t) expr->pe_block); } Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_producer_init.3 (revision 367466) @@ -1,297 +1,296 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_producer_init.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: dwarf_producer_init.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd August 20, 2011 -.Os .Dt DWARF_PRODUCER_INIT 3 +.Os .Sh NAME -.Nm dwarf_producer_init +.Nm dwarf_producer_init , .Nm dwarf_producer_init_b .Nd allocate a DWARF producer descriptor .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_P_Debug .Fo dwarf_producer_init .Fa "Dwarf_Unsigned flags" .Fa "Dwarf_Callback_Func func" .Fa "Dwarf_Handler errhand" .Fa "Dwarf_Ptr errarg" .Fa "Dwarf_Error *err" .Fc .Ft Dwarf_P_Debug .Fo dwarf_producer_init_b .Fa "Dwarf_Unsigned flags" .Fa "Dwarf_Callback_Func_b func" .Fa "Dwarf_Handler errhand" .Fa "Dwarf_Ptr errarg" .Fa "Dwarf_Error *error" .Fc .Sh DESCRIPTION These functions allocate and return a .Vt Dwarf_P_Debug descriptor representing a DWARF producer instance. .Pp The argument .Ar errhand should contain the address of a function to be called in case of an error. If this argument is .Dv NULL , the default error handling scheme is used, see .Xr dwarf 3 . .Pp The argument .Ar errarg will be passed to the error handler function when it is invoked. .Pp The argument .Ar err references a memory location that would hold a .Vt Dwarf_Error descriptor in case of an error. .Pp The argument .Ar flags specifies additional characteristics of the DWARF producer instance. The following flags are recognized: -.Pp .Bl -tag -width "Dv DW_DLC_ISA_MIPS" .It Dv DW_DLC_ISA_IA64 .Pq Deprecated The target instruction set architecture is IA64. This flag is deprecated. Application code should use the .Xr dwarf_producer_set_isa 3 function to specify target instruction set architecture. .It Dv DW_DLC_ISA_MIPS .Pq Deprecated The target instruction set architecture is MIPS. This flag is deprecated. Application code should use the .Xr dwarf_producer_set_isa 3 function to specify target instruction set architecture. .It Dv DW_DLC_SIZE_32 .Pq Default The target address size is 32-bit. .It Dv DW_DLC_SIZE_64 The target address size is 64-bit. .It Dv DW_DLC_STREAM_RELOCATIONS .Pq Default Generate stream relocations. .It Dv DW_DLC_SYMBOLIC_RELOCATIONS Generate symbolic relocations. .It Dv DW_DLC_TARGET_BIGENDIAN The target is big endian. .It Dv DW_DLC_TARGET_LITTLEENDIAN The target is little endian. .It Dv DW_DLC_WRITE .Pq Required Permit writing of DWARF information. .El .Pp The following flags are mutually exclusive. .Bl -bullet -compact .It Flags .Dv DW_DLC_ISA_IA64 and .Dv DW_DLC_ISA_MIPS . .It Flags .Dv DW_DLC_SIZE_32 and .Dv DW_DLC_SIZE_64 . .It Flags .Dv DW_DLC_STREAM_RELOCATIONS and .Dv DW_DLC_SYMBOLIC_RELOCATIONS . .It Flags .Dv DW_DLC_TARGET_BIGENDIAN and .Dv DW_DLC_TARGET_LITTLEENDIAN . .El If neither of the flags .Dv DW_DLC_TARGET_BIGENDIAN and .Dv DW_DLC_TARGET_LITTLEENDIAN is set, the target's endianness is assumed to be the same as the host's endianness. .Pp Argument .Ar func should point to an application-provided callback function of type .Vt Dwarf_Callback_Func_b . The type .Vt Dwarf_Callback_Func_b is defined in the header file .In libdwarf.h as: .Bd -literal -offset indent typedef int (*Dwarf_Callback_Func_b)(char *name, int size, Dwarf_Unsigned type, Dwarf_Unsigned flags, Dwarf_Unsigned link, Dwarf_Unsigned info, Dwarf_Unsigned *index, int *error); .Ed .Pp This function is called by the .Lb libdwarf once for each section in the object file that the library needs to create. The arguments to this callback function specify the values in the ELF section header for the section being created: .Pp .Bl -tag -width indent -compact -offset indent .It Ar name The name of the section being created. .It Ar size The .Va sh_size value in the section header. .It Ar type The .Va sh_type value in the section header. .It Ar flags The .Va sh_flags value in the section header. .It Ar link The .Va sh_link value in the section header. .It Ar info The .Va sh_info value in the section header. .El .Pp On success, the callback function should return the section index value of the created section, and set the location pointed to by argument .Ar index to the symbol table index of the symbol that associated with the newly created section. This symbol table index will be used in relocation entries referring to the created section. .Pp In case of failure, the callback function should return -1 and set the location pointed to by argument .Ar error to an application-defined error code. This application returned error code is currently ignored by the library. .Pp Function .Fn dwarf_producer_init is deprecated. Function .Fn dwarf_producer_init is identical to function .Fn dwarf_producer_init_b except that the callback function it expects can not properly handle arbitrary section symbol index values. .Ss Memory Management The .Vt Dwarf_P_Debug instance returned by these functions should be freed using the function .Fn dwarf_producer_finish . .Sh RETURN VALUES On success, these functions return the created DWARF producer descriptor. In case of an error, they return .Dv DW_DLV_BADADDR and set the argument .Ar err . +.Sh EXAMPLES +To initialize a +.Vt Dwarf_P_Debug +instance for a MIPS32 big endian object, use: +.Bd -literal -offset indent +Dwarf_P_Debug dbg; +Dwarf_Unsigned flags; +Dwarf_Error de; + +/* ... assume cb_func points to the callback function ... */ + +flags = DW_DLC_WRITE | DW_DLC_SIZE_32 | DW_DLC_ISA_MIPS | + DW_DLC_STREAM_RELOCATIONS | DW_DLC_TARGET_BIGENDIAN; +if ((dbg = dwarf_producer_init(flags, cb_func, NULL, NULL, &de)) == + DW_DLV_BADADDR) + warnx("dwarf_producer_init failed: %s", dwarf_errmsg(-1)); +.Ed .Sh ERRORS These functions can fail with: .Bl -tag -width ".Bq Er DW_DLE_NO_ENTRY" .It Bq Er DW_DLE_ARGUMENT Argument .Ar func was NULL. .It Bq Er DW_DLE_ARGUMENT The flag .Dv DW_DLC_WRITE was not set in argument .Ar flags . .It Bq Er DW_DLE_ARGUMENT The flags .Dv DW_DLC_SIZE_32 and .Dv DW_DLC_SIZE_64 were both set in argument .Ar flags . .It Bq Er DW_DLE_ARGUMENT The flags .Dv DW_DLC_ISA_IA64 and .Dv DW_DLC_ISA_MIPS were both set in argument .Ar flags . .It Bq Er DW_DLE_ARGUMENT The flags .Dv DW_DLC_TARGET_BIGENDIAN and .Dv DW_DLC_TARGET_LITTLEENDIAN were both set in argument .Ar flags . .It Bq Er DW_DLE_ARGUMENT The flags .Dv DW_DLC_STREAM_RELOCATIONS and .Dv DW_DLC_SYMBOLIC_RELOCATIONS were both set in argument .Ar flags . .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered. .El -.Sh EXAMPLES -To initialize a -.Vt Dwarf_P_Debug -instance for a MIPS32 big endian object, use: -.Bd -literal -offset indent -Dwarf_P_Debug dbg; -Dwarf_Unsigned flags; -Dwarf_Error de; - -/* ... assume cb_func points to the callback function ... */ - -flags = DW_DLC_WRITE | DW_DLC_SIZE_32 | DW_DLC_ISA_MIPS | - DW_DLC_STREAM_RELOCATIONS | DW_DLC_TARGET_BIGENDIAN; -if ((dbg = dwarf_producer_init(flags, cb_func, NULL, NULL, &de)) == - DW_DLV_BADADDR) - warnx("dwarf_producer_init failed: %s", dwarf_errmsg(-1)); -.Ed .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_errmsg 3 , .Xr dwarf_producer_finish 3 , .Xr dwarf_producer_set_isa 3 , .Xr dwarf_transform_to_disk_form 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_producer_set_isa.3 (revision 367466) @@ -1,98 +1,98 @@ .\" Copyright (c) 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: dwarf_producer_set_isa.3 2074 2011-10-27 03:34:33Z jkoshy $ +.\" $Id: dwarf_producer_set_isa.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 29, 2011 -.Os .Dt DWARF_PRODUCER_SET_ISA 3 +.Os .Sh NAME .Nm dwarf_producer_set_isa .Nd specify the instruction set architecture for a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_producer_set_isa .Fa "Dwarf_P_Debug dbg" .Fa "enum Dwarf_ISA isa" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION The function .Fn dwarf_producer_set_isa sets the instruction set architecture for a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using one of the functions .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar isa specifies the desired instruction set architecture. Legal values for this argument are those defined by the .Vt "enum Dwarf_ISA" enumeration defined in the header file .In libdwarf.h . .Pp If the argument .Ar err is not NULL, it will be used to store error information in case of an error. -.Sh COMPATIBILITY -The -.Fn dwarf_producer_set_isa -function is a local extension. .Sh RETURN VALUES On success, the function .Fn dwarf_producer_set_isa returns .Dv DW_DLV_OK . In case of an error, this function returns .Dv DW_DLV_ERROR and sets the argument .Ar err . +.Sh COMPATIBILITY +The +.Fn dwarf_producer_set_isa +function is a local extension. .Sh ERRORS The .Fn dwarf_producer_set_isa function can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT The argument .Ar dbg was NULL. .It Bq Er DW_DLE_ARGUMENT The argument .Ar isa was invalid. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_reset_section_bytes.3 (revision 367466) @@ -1,69 +1,69 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_reset_section_bytes.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_reset_section_bytes.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 3, 2011 -.Os .Dt DWARF_RESET_SECTION_BYTES 3 +.Os .Sh NAME .Nm dwarf_reset_section_bytes .Nd reset the internal state of a producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft void .Fo dwarf_reset_section_bytes .Fa "Dwarf_P_Debug dbg" .Fc .Sh DESCRIPTION Function .Fn dwarf_reset_section_bytes resets the internal state of a DWARF producer instance, so that the next call to the function .Xr dwarf_get_section_bytes 3 will return the byte stream for the first generated section, and the next call to the function .Xr dwarf_get_relocation_info 3 will return the first relocation array for the DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Sh RETURN VALUES Function .Fn dwarf_reset_section_bytes has no return value. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_relocation_info 3 , .Xr dwarf_get_section_bytes 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_transform_to_disk_form 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_set_frame_cfa_value.3 (revision 367466) @@ -1,140 +1,140 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_set_frame_cfa_value.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_set_frame_cfa_value.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd June 18, 2011 -.Os .Dt DWARF_SET_FRAME_CFA_VALUE 3 +.Os .Sh NAME .Nm dwarf_set_frame_cfa_value , .Nm dwarf_set_frame_rule_initial_value , .Nm dwarf_set_frame_rule_table_size , .Nm dwarf_set_frame_same_value , .Nm dwarf_set_frame_undefined_value .Nd set internal register rule table parameters .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_Half .Fo dwarf_set_frame_cfa_value .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Half value" .Fc .Ft Dwarf_Half .Fo dwarf_set_frame_rule_initial_value .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Half value" .Fc .Ft Dwarf_Half .Fo dwarf_set_frame_rule_table_size .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Half value" .Fc .Ft Dwarf_Half .Fo dwarf_set_frame_same_value .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Half value" .Fc .Ft Dwarf_Half .Fo dwarf_set_frame_undefined_value .Fa "Dwarf_Debug dbg" .Fa "Dwarf_Half value" .Fc .Sh DESCRIPTION These functions set the parameters of the internal register rule table. .Pp Argument .Ar dbg should reference a DWARF debug context allocated using .Xr dwarf_init 3 . .Pp Argument .Ar value should hold the parameter value to set. .Pp Function .Fn dwarf_set_frame_cfa_value sets the column number for the CFA register rule in the internal register rule table. The constant .Dv DW_FRAME_CFA_COL is the default CFA register column number for DWARF2-only interfaces, and the constant .Dv DW_FRAME_CFA_COL3 is the default CFA column number for DWARF3-compatible interfaces. .Pp Function .Fn dwarf_set_frame_rule_initial_value sets the initial value of the register rules in the internal register rule table. The default initial value is the constant .Dv DW_FRAME_REG_INITIAL_VALUE , defined in the header file .In libdwarf.h . .Pp Function .Fn dwarf_set_frame_rule_table_size sets the maxmium number of columns of the internal register rule table. Argument .Ar value should be at least as large as the number of real registers in the ABI. .Pp Function .Fn dwarf_set_frame_same_value sets the register number representing the .Dq "same value" register rule. The default register number for the .Dq "same value" rule is the constant .Dv DW_FRAME_SAME_VAL , defined in the header file .In libdwarf.h . .Pp Function .Fn dwarf_set_frame_undefined_value sets the register number representing the .Dq undefined register rule. The default register number for the .Dq undefined rule is the constant .Dv DW_FRAME_UNDEFINED_VAL , defined in the header file .In libdwarf.h . .Sh RETURN VALUES These functions return the previous value of the parameter being set. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_fde_at_pc 3 , .Xr dwarf_get_fde_info_for_all_regs 3 , .Xr dwarf_get_fde_info_for_all_regs3 3 , .Xr dwarf_get_fde_info_for_cfa_reg3 3 , .Xr dwarf_get_fde_info_for_reg 3 , .Xr dwarf_get_fde_info_for_reg3 3 , .Xr dwarf_get_fde_n 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_set_reloc_application.3 (revision 367466) @@ -1,82 +1,82 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_set_reloc_application.3 3161 2015-02-15 21:43:36Z emaste $ +.\" $Id: dwarf_set_reloc_application.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd February 11, 2015 -.Os .Dt DWARF_SET_RELOC_APPLICATION 3 +.Os .Sh NAME .Nm dwarf_set_reloc_application .Nd set a library-wide relocation flag .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_set_reloc_application .Fa "int apply" .Fc .Sh DESCRIPTION Function .Fn dwarf_set_reloc_application allows applications to specify how relocation information is to be handled by the DWARF(3) library. .Pp If the argument .Ar apply holds a non-zero value, the library will process all the relevant .Dq ".rel" and .Dq ".rela" relocation sections and will apply the relocation records found to their corresponding DWARF sections. .Pp If the argument .Ar apply is zero, the library will not attempt to apply any relocations. .Pp The default behaviour of the library is to process relocation records. .Sh NOTES Function .Fn dwarf_set_reloc_application should be called before initialising a dwarf debugging context, i.e, it should be called by the application before calling either of the functions .Xr dwarf_init 3 or .Xr dwarf_elf_init 3 . .Sh RETURN VALUES Function .Fn dwarf_set_reloc_application returns the previous value of the library-wide relocation application flag. .Sh ERRORS Function .Fn dwarf_set_reloc_application does not return an error. .Sh SEE ALSO .Xr dwarf 3 , -.Xr dwarf_init 3 , -.Xr dwarf_elf_init 3 +.Xr dwarf_elf_init 3 , +.Xr dwarf_init 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_seterrarg.3 (revision 367466) @@ -1,102 +1,101 @@ .\" 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 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: dwarf_seterrarg.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_seterrarg.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd May 01, 2010 -.Os .Dt DWARF_SETERRARG 3 +.Os .Sh NAME .Nm dwarf_seterrarg , .Nm dwarf_seterrhand .Nd configure error handling .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_Ptr .Fn dwarf_seterrarg "Dwarf_Debug dbg" "Dwarf_Ptr arg" .Ft Dwarf_Handler .Fn dwarf_seterrhand "Dwarf_Debug dbg" "Dwarf_Handler handler" .Sh DESCRIPTION These functions may be used by applications to configure error handling callbacks. The error handling scheme used by the library is described in .Xr dwarf 3 . .Pp Function .Fn dwarf_seterrarg may be used to set the callback argument passed to a configured error handler at the time it is invoked. Argument .Ar arg is the callback argument being set. Argument .Ar dbg can be a debug context allocated by a prior call to .Xr dwarf_init 3 , or can be NULL to indicate that the library-wide callback argument is to be set. .Pp Function .Fn dwarf_seterrhand may be used to associate an error handler denoted by argument .Ar handler with the DWARF debug context descriptor denoted by argument .Ar dbg . Argument .Ar dbg should be a debug context allocated by a prior call to .Xr dwarf_init 3 , or may be NULL to indicate that the library-wide error handler is to be set. .Sh RETURN VALUES Function .Fn dwarf_seterrhand returns the previous error handler associated with argument .Ar dbg . If argument .Ar dbg is NULL, function .Fn dwarf_seterrhand returns the previous library-wide error handler. .Pp Function .Fn dwarf_seterrarg returns the previous callback argument associated with argument .Ar dbg . If argument .Ar dbg is NULL, function .Fn dwarf_seterrarg returns the previous library-wide callback argument. -.Pp .Sh COMPATIBILITY The behavior of these functions when argument .Ar dbg is NULL is a local extension. .Sh ERRORS These functions do not set an error code. .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_init 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_srcfiles.3 (revision 367466) @@ -1,105 +1,105 @@ .\" 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 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: dwarf_srcfiles.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_srcfiles.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 28, 2010 -.Os .Dt DWARF_SRCFILES 3 +.Os .Sh NAME .Nm dwarf_srcfiles .Nd retrieve source file information .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_srcfiles .Fa "Dwarf_Die die" .Fa "char ***filenames" .Fa "Dwarf_Signed *filenamecount" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_srcfiles returns the source file names associated with a compilation unit. Source file names are returned as an array of NUL-terminated strings. .Pp Argument .Ar die should reference a DWARF debugging information entry descriptor with source file information, see .Xr dwarf 3 . Argument .Ar filenames should point to a location that will hold a pointer to the returned array of file names. Argument .Ar filenamecount should point to a location that will hold the number of file names returned. If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Ss Memory Management The memory areas used for the file names and for array of pointers being returned are managed by the DWARF(3) library. The application should not attempt to directly free these memory areas. Portable code should indicate that the memory areas are to be freed by using .Xr dwarf_dealloc 3 . .Sh RETURN VALUES Function .Fn dwarf_srcfiles returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_srcfiles can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT One of the arguments .Ar die , .Ar filenames or .Ar filenamecount was NULL. .It Bq Er DW_DLE_NO_ENTRY The compilation unit referenced by argument .Ar die does not have associated source file information. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of this function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_dealloc 3 , .Xr dwarf_srclines 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_srclines.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_srclines.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_srclines.3 (revision 367466) @@ -1,163 +1,163 @@ .\" 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 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: dwarf_srclines.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_srclines.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_SRCLINES 3 +.Os .Sh NAME .Nm dwarf_srclines .Nd retrieve line number information for a debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_srclines .Fa "Dwarf_Die die" .Fa "Dwarf_Line **lines" .Fa "Dwarf_Signed *nlines" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_srclines returns line number information associated with a compilation unit. Line number information is returned as an array of .Vt Dwarf_Line descriptors. .Pp Argument .Ar die should reference a DWARF debugging information entry descriptor with line number information, see .Xr dwarf 3 . Argument .Ar lines should point to a location that will hold a pointer to the returned array of .Vt Dwarf_Line descriptors. Argument .Ar nlines should point to a location that will hold the number of descriptors returned. If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp The returned .Vt Dwarf_Line descriptors may be passed to the other line number functions in the API set to retrieve specific information about each source line. .Ss Memory Management The memory area used for the array of .Vt Dwarf_Line descriptors returned in argument .Ar lines is owned by the .Lb libdwarf . The application should not attempt to free this pointer. Portable code should instead use .Fn dwarf_srclines_dealloc to indicate that the memory may be freed. .Sh RETURN VALUES Function .Fn dwarf_srclines returns .Dv DW_DLV_OK when it succeeds. In case of an error, it returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh ERRORS -Function -.Fn dwarf_srclines -can fail with: -.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" -.It Bq Er DW_DLE_ARGUMENT -One of the arguments -.Ar die , -.Ar lines -or -.Ar nlines -was NULL. -.It Bq Er DW_DLE_NO_ENTRY -The compilation unit referenced by argument -.Ar die -does not have associated line number information. -.It Bq Er DW_DLE_MEMORY -An out of memory condition was encountered during the execution of -this function. -.El -.Sh EXAMPLE +.Sh EXAMPLES To obtain an array of .Vt Dwarf_Line descriptors and to retrieve the source file, line number, and virtual address associated with each descriptor: .Bd -literal -offset indent int n; Dwarf_Die die; Dwarf_Error de; char *filename; Dwarf_Line *lines; Dwarf_Signed nlines; Dwarf_Addr lineaddr; Dwarf_Unsigned lineno; /* variable "die" should reference a DIE for a compilation unit */ if (dwarf_srclines(die, &lines, &nlines, &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_srclines: %s", dwarf_errmsg(de)); for (n = 0; n < nlines; n++) { /* Retrieve the file name for this descriptor. */ if (dwarf_linesrc(lines[n], &filename, &de)) errx(EXIT_FAILURE, "dwarf_linesrc: %s", dwarf_errmsg(de)); /* Retrieve the line number in the source file. */ if (dwarf_lineno(lines[n], &lineno, &de)) errx(EXIT_FAILURE, "dwarf_lineno: %s", dwarf_errmsg(de)); /* Retrieve the virtual address for this line. */ if (dwarf_lineaddr(lines[n], &lineaddr, &de)) errx(EXIT_FAILURE, "dwarf_lineaddr: %s", dwarf_errmsg(de)); } .Ed +.Sh ERRORS +Function +.Fn dwarf_srclines +can fail with: +.Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" +.It Bq Er DW_DLE_ARGUMENT +One of the arguments +.Ar die , +.Ar lines +or +.Ar nlines +was NULL. +.It Bq Er DW_DLE_NO_ENTRY +The compilation unit referenced by argument +.Ar die +does not have associated line number information. +.It Bq Er DW_DLE_MEMORY +An out of memory condition was encountered during the execution of +this function. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_line_srcfileno 3 , .Xr dwarf_lineaddr 3 , .Xr dwarf_linebeginstatement 3 , .Xr dwarf_lineblock 3 , .Xr dwarf_lineendsequence 3 , .Xr dwarf_lineno 3 , .Xr dwarf_lineoff 3 , .Xr dwarf_linesrc 3 , .Xr dwarf_srcfiles 3 , .Xr dwarf_srclines_dealloc 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_start_macro_file.3 (revision 367466) @@ -1,106 +1,105 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_start_macro_file.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_start_macro_file.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd September 25, 2011 -.Os .Dt DWARF_START_MACRO_FILE 3 +.Os .Sh NAME .Nm dwarf_start_macro_file .Nd mark the start of a source file inclusion .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "int" .Fo dwarf_start_macro_file .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Unsigned lineno" .Fa "Dwarf_Unsigned fileindex" .Fa "Dwarf_Error *err" -.Fa .Fc .Sh DESCRIPTION Function .Fn dwarf_start_macro_file marks the start of a new source file inclusion. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar lineno specifies the line number of the source line where the source file inclusion occurs. A value of zero is used to indicate the file for the compilation unit source itself. .Pp Argument .Ar fileindex specifies the index of the source file that is being included. Valid source file indices are those returned by .Xr dwarf_add_file_decl 3 . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_start_macro_file returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_start_macro_file returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_start_macro_file can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_add_file_decl 3 , .Xr dwarf_def_macro 3 , .Xr dwarf_end_macro_file 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_undef_macro 3 , .Xr dwarf_vendor_ext 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_tag.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_tag.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_tag.3 (revision 367466) @@ -1,77 +1,77 @@ .\" Copyright (c) 2010 Kai Wang .\" 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: dwarf_tag.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_tag.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd April 14, 2010 -.Os .Dt DWARF_TAG 3 +.Os .Sh NAME .Nm dwarf_tag .Nd retrieve the tag associated with a DWARF debugging information entry .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fn dwarf_tag "Dwarf_Die die" "Dwarf_Half *tag" "Dwarf_Error *err" .Sh DESCRIPTION Function .Fn dwarf_tag retrieves the tag associated with the debugging information entry referenced by argument .Ar die , and stores it into the location pointed to by argument .Ar tag . .Pp If argument .Ar err if non-NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_tag returns .Dv DW_DLV_OK . In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_tag can fail with the following error: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Va die or .Va tag was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_die_abbrev_code 3 , .Xr dwarf_diename 3 , .Xr dwarf_dieoffset 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_transform_to_disk_form.3 (revision 367466) @@ -1,99 +1,99 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_transform_to_disk_form.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_transform_to_disk_form.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd August 25, 2011 -.Os .Dt DWARF_TRANSFORM_TO_DISK_FORM 3 +.Os .Sh NAME .Nm dwarf_transform_to_disk_form .Nd transform DWARF information into byte streams .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft Dwarf_Signed .Fo dwarf_transform_to_disk_form .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_transform_to_disk_form transforms the DWARF information gathered by the producer into byte streams for the application to write out as ELF sections. If the flag .Dv DW_DLC_SYMBOLIC_RELOCATIONS is set on the producer, the function will also generate the associated relocation arrays. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp After a call to this function, the application can call the function .Xr dwarf_get_section_bytes 3 to retrieve the byte streams for each ELF section. If the flag .Dv DW_DLC_SYMBOLIC_RELOCATIONS was set on the descriptor, the application can also call the function .Xr dwarf_get_relocation_info 3 to retrieve the generated relocation arrays. .Sh RETURN VALUES On success, function .Fn dwarf_transform_to_disk_form returns the total number of ELF sections generated. In case of an error, function .Fn dwarf_transform_to_disk_form returns .Dv DW_DLV_NOCOUNT and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_transform_to_disk_form can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Argument .Ar dbg was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during execution. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_get_relocation_info 3 , .Xr dwarf_get_section_bytes 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_undef_macro.3 (revision 367466) @@ -1,119 +1,119 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_undef_macro.3 2122 2011-11-09 15:35:14Z jkoshy $ +.\" $Id: dwarf_undef_macro.3 3644 2018-10-15 19:55:01Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt DWARF_UNDEF_MACRO 3 +.Os .Sh NAME .Nm dwarf_undef_macro .Nd record the removal of a macro definition .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "int" .Fo dwarf_undef_macro .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Unsigned lineno" .Fa "char *name" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_undef_macro records the removal of a macro definition in a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar lineno specifies the line number of the source line where the macro definition was removed. A value of zero indicates that the macro definition was removed before any source files were read. .Pp Argument .Ar name should point to a NUL-terminated string containing the name of the macro. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_undef_macro returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_undef_macro returns .Dv DW_DLV_ERROR and sets the argument .Ar err . -.Sh EXAMPLE +.Sh EXAMPLES To record the fact that the macro named .Dv _STDIO_H_ was removed at line 220 of the current macro file, use: .Bd -literal -offset indent Dwarf_P_Debug dbg; Dwarf_Error de; /* ... Assume 'dbg' refers to a DWARF producer instance... */ if (dwarf_undef_macro(dbg, 220, "_STDIO_H_", &de) != DW_DLV_OK) errx(EXIT_FAILURE, "dwarf_def_macro failed: %s", dwarf_errmsg(-1)); .Ed .Sh ERRORS Function .Fn dwarf_undef_macro can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either arguments .Ar dbg or .Ar name was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_def_macro 3 , .Xr dwarf_end_macro_file 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_start_macro_file 3 , .Xr dwarf_vendor_ext 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_vendor_ext.3 (revision 367466) @@ -1,110 +1,110 @@ .\" Copyright (c) 2011 Kai Wang .\" 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: dwarf_vendor_ext.3 2075 2011-10-27 03:47:28Z jkoshy $ +.\" $Id: dwarf_vendor_ext.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd September 25, 2011 -.Os .Dt DWARF_VENDOR_EXT 3 +.Os .Sh NAME .Nm dwarf_vendor_ext .Nd add vendor-specific macro information to a DWARF producer instance .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft "int" .Fo dwarf_vendor_ext .Fa "Dwarf_P_Debug dbg" .Fa "Dwarf_Unsigned constant" .Fa "char *string" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_vendor_ext adds a vendor-specific macro information entry to a DWARF producer instance. .Pp Argument .Ar dbg should reference a DWARF producer instance allocated using .Xr dwarf_producer_init 3 or .Xr dwarf_producer_init_b 3 . .Pp Argument .Ar constant specifies a constant value for the macro information entry. .Pp Argument .Ar string point to a NUL-terminated string containing the string value for the macro information entry. .Pp If argument .Ar err is not NULL, it will be used to store error information in case of an error. .Pp The meaning of the arguments .Ar constant and .Ar string are not defined by the DWARF specification, but are instead governed by application and vendor conventions. .Sh RETURN VALUES On success, function .Fn dwarf_vendor_ext returns .Dv DW_DLV_OK . In case of an error, function .Fn dwarf_vendor_ext returns .Dv DW_DLV_ERROR and sets the argument .Ar err . .Sh ERRORS Function .Fn dwarf_vendor_ext can fail with: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either arguments .Ar dbg or .Ar string was NULL. .It Bq Er DW_DLE_MEMORY An out of memory condition was encountered during the execution of the function. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_def_macro 3 , .Xr dwarf_end_macro_file 3 , .Xr dwarf_producer_init 3 , .Xr dwarf_producer_init_b 3 , .Xr dwarf_start_macro_file 3 , .Xr dwarf_undef_macro 3 Index: stable/11/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 (revision 367466) @@ -1,79 +1,79 @@ .\" 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: dwarf_whatattr.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: dwarf_whatattr.3 3640 2018-10-14 14:09:13Z jkoshy $ .\" .Dd May 22, 2010 -.Os .Dt DWARF_WHATATTR 3 +.Os .Sh NAME .Nm dwarf_whatattr .Nd retrieve the attribute code for a DWARF attribute .Sh LIBRARY .Lb libdwarf .Sh SYNOPSIS .In libdwarf.h .Ft int .Fo dwarf_whatattr .Fa "Dwarf_Attribute attr" .Fa "Dwarf_Half *retcode" .Fa "Dwarf_Error *err" .Fc .Sh DESCRIPTION Function .Fn dwarf_whatattr retrieves the attribute code for the DWARF attribute referenced by argument .Ar attr , and writes it to the location pointed to by argument .Ar retcode . If argument .Ar err is not NULL, it will be used to return an error descriptor in case of an error. .Sh RETURN VALUES On success, function .Fn dwarf_whatattr returns .Dv DW_DLV_OK . In case of an error, it returns .Dv DW_DLV_ERROR and sets argument .Ar err . .Sh ERRORS Function .Fn dwarf_whatattr can fail with the following error: .Bl -tag -width ".Bq Er DW_DLE_ARGUMENT" .It Bq Er DW_DLE_ARGUMENT Either of argument .Va attr or .Va retcode was NULL. .El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , .Xr dwarf_hasattr 3 Index: stable/11/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c (revision 367466) @@ -1,266 +1,264 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) * Copyright (c) 2009-2011 Kai Wang * 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 "_libdwarf.h" ELFTC_VCSID("$Id: libdwarf_abbrev.c 3420 2016-02-27 02:14:05Z emaste $"); int _dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children, uint64_t aboff, Dwarf_Abbrev *abp, Dwarf_Error *error) { Dwarf_Abbrev ab; Dwarf_Debug dbg; dbg = cu != NULL ? cu->cu_dbg : NULL; if ((ab = malloc(sizeof(struct _Dwarf_Abbrev))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } /* Initialise the abbrev structure. */ ab->ab_entry = entry; ab->ab_tag = tag; ab->ab_children = children; ab->ab_offset = aboff; ab->ab_length = 0; /* fill in later. */ ab->ab_atnum = 0; /* fill in later. */ /* Initialise the list of attribute definitions. */ STAILQ_INIT(&ab->ab_attrdef); /* Add the abbrev to the hash table of the compilation unit. */ if (cu != NULL) HASH_ADD(ab_hh, cu->cu_abbrev_hash, ab_entry, sizeof(ab->ab_entry), ab); - if (abp != NULL) - *abp = ab; - + *abp = ab; return (DW_DLE_NONE); } int _dwarf_attrdef_add(Dwarf_Debug dbg, Dwarf_Abbrev ab, uint64_t attr, uint64_t form, uint64_t adoff, Dwarf_AttrDef *adp, Dwarf_Error *error) { Dwarf_AttrDef ad; if (ab == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLE_ARGUMENT); } if ((ad = malloc(sizeof(struct _Dwarf_AttrDef))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } /* Initialise the attribute definition structure. */ ad->ad_attrib = attr; ad->ad_form = form; ad->ad_offset = adoff; /* Add the attribute definition to the list in the abbrev. */ STAILQ_INSERT_TAIL(&ab->ab_attrdef, ad, ad_next); /* Increase number of attribute counter. */ ab->ab_atnum++; if (adp != NULL) *adp = ad; return (DW_DLE_NONE); } int _dwarf_abbrev_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Unsigned *offset, Dwarf_Abbrev *abp, Dwarf_Error *error) { Dwarf_Section *ds; uint64_t attr; uint64_t entry; uint64_t form; uint64_t aboff; uint64_t adoff; uint64_t tag; uint8_t children; int ret; assert(abp != NULL); ds = _dwarf_find_section(dbg, ".debug_abbrev"); if (ds == NULL || *offset >= ds->ds_size) return (DW_DLE_NO_ENTRY); aboff = *offset; entry = _dwarf_read_uleb128(ds->ds_data, offset); if (entry == 0) { /* Last entry. */ ret = _dwarf_abbrev_add(cu, entry, 0, 0, aboff, abp, error); if (ret == DW_DLE_NONE) { (*abp)->ab_length = 1; return (ret); } else return (ret); } tag = _dwarf_read_uleb128(ds->ds_data, offset); children = dbg->read(ds->ds_data, offset, 1); if ((ret = _dwarf_abbrev_add(cu, entry, tag, children, aboff, abp, error)) != DW_DLE_NONE) return (ret); /* Parse attribute definitions. */ do { adoff = *offset; attr = _dwarf_read_uleb128(ds->ds_data, offset); form = _dwarf_read_uleb128(ds->ds_data, offset); if (attr != 0) if ((ret = _dwarf_attrdef_add(dbg, *abp, attr, form, adoff, NULL, error)) != DW_DLE_NONE) return (ret); } while (attr != 0); (*abp)->ab_length = *offset - aboff; return (ret); } int _dwarf_abbrev_find(Dwarf_CU cu, uint64_t entry, Dwarf_Abbrev *abp, Dwarf_Error *error) { Dwarf_Abbrev ab; Dwarf_Section *ds; Dwarf_Unsigned offset; int ret; if (entry == 0) return (DW_DLE_NO_ENTRY); /* Check if the desired abbrev entry is already in the hash table. */ HASH_FIND(ab_hh, cu->cu_abbrev_hash, &entry, sizeof(entry), ab); if (ab != NULL) { *abp = ab; return (DW_DLE_NONE); } if (cu->cu_abbrev_loaded) { return (DW_DLE_NO_ENTRY); } /* Load and search the abbrev table. */ ds = _dwarf_find_section(cu->cu_dbg, ".debug_abbrev"); if (ds == NULL) return (DW_DLE_NO_ENTRY); offset = cu->cu_abbrev_offset_cur; while (offset < ds->ds_size) { ret = _dwarf_abbrev_parse(cu->cu_dbg, cu, &offset, &ab, error); if (ret != DW_DLE_NONE) return (ret); if (ab->ab_entry == entry) { cu->cu_abbrev_offset_cur = offset; *abp = ab; return (DW_DLE_NONE); } if (ab->ab_entry == 0) { cu->cu_abbrev_offset_cur = offset; cu->cu_abbrev_loaded = 1; break; } } return (DW_DLE_NO_ENTRY); } void _dwarf_abbrev_cleanup(Dwarf_CU cu) { Dwarf_Abbrev ab, tab; Dwarf_AttrDef ad, tad; assert(cu != NULL); HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, ad_next); free(ad); } free(ab); } } int _dwarf_abbrev_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_CU cu; Dwarf_Abbrev ab; Dwarf_AttrDef ad; Dwarf_P_Section ds; int ret; cu = STAILQ_FIRST(&dbg->dbg_cu); if (cu == NULL) return (DW_DLE_NONE); /* Create .debug_abbrev section. */ if ((ret = _dwarf_section_init(dbg, &ds, ".debug_abbrev", 0, error)) != DW_DLE_NONE) return (ret); for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { RCHECK(WRITE_ULEB128(ab->ab_entry)); RCHECK(WRITE_ULEB128(ab->ab_tag)); RCHECK(WRITE_VALUE(ab->ab_children, 1)); STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { RCHECK(WRITE_ULEB128(ad->ad_attrib)); RCHECK(WRITE_ULEB128(ad->ad_form)); } /* Signal end of attribute spec list. */ RCHECK(WRITE_ULEB128(0)); RCHECK(WRITE_ULEB128(0)); } /* End of abbreviation for this CU. */ RCHECK(WRITE_ULEB128(0)); /* Notify the creation of .debug_abbrev ELF section. */ RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); return (DW_DLE_NONE); gen_fail: _dwarf_section_free(dbg, &ds); return (ret); } Index: stable/11/contrib/elftoolchain/libdwarf/libdwarf_attr.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/libdwarf_attr.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/libdwarf_attr.c (revision 367466) @@ -1,459 +1,456 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) * Copyright (c) 2009-2011 Kai Wang * 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 "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_attr.c 3748 2019-06-28 01:11:13Z emaste $"); int _dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) { Dwarf_Attribute at; assert(die != NULL); assert(atp != NULL); if ((at = calloc(1, sizeof(struct _Dwarf_Attribute))) == NULL) { DWARF_SET_ERROR(die->die_dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } *atp = at; return (DW_DLE_NONE); } static int _dwarf_attr_add(Dwarf_Die die, Dwarf_Attribute atref, Dwarf_Attribute *atp, Dwarf_Error *error) { Dwarf_Attribute at; int ret; if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) return (ret); memcpy(at, atref, sizeof(struct _Dwarf_Attribute)); STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); /* Save a pointer to the attribute name if this is one. */ if (at->at_attrib == DW_AT_name) { switch (at->at_form) { case DW_FORM_strp: die->die_name = at->u[1].s; break; case DW_FORM_string: die->die_name = at->u[0].s; break; default: break; } } if (atp != NULL) *atp = at; return (DW_DLE_NONE); } Dwarf_Attribute _dwarf_attr_find(Dwarf_Die die, Dwarf_Half attr) { Dwarf_Attribute at; STAILQ_FOREACH(at, &die->die_attr, at_next) { if (at->at_attrib == attr) break; } return (at); } int _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, int dwarf_size, Dwarf_CU cu, Dwarf_Die die, Dwarf_AttrDef ad, uint64_t form, int indirect, Dwarf_Error *error) { struct _Dwarf_Attribute atref; - Dwarf_Section *str; int ret; ret = DW_DLE_NONE; memset(&atref, 0, sizeof(atref)); atref.at_die = die; atref.at_offset = *offsetp; atref.at_attrib = ad->ad_attrib; atref.at_form = indirect ? form : ad->ad_form; atref.at_indirect = indirect; atref.at_ld = NULL; switch (form) { case DW_FORM_addr: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, cu->cu_pointer_size); break; case DW_FORM_block: case DW_FORM_exprloc: atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, atref.u[0].u64); break; case DW_FORM_block1: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, atref.u[0].u64); break; case DW_FORM_block2: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, atref.u[0].u64); break; case DW_FORM_block4: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, atref.u[0].u64); break; case DW_FORM_data1: case DW_FORM_flag: case DW_FORM_ref1: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); break; case DW_FORM_data2: case DW_FORM_ref2: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); break; case DW_FORM_data4: case DW_FORM_ref4: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); break; case DW_FORM_data8: case DW_FORM_ref8: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 8); break; case DW_FORM_indirect: form = _dwarf_read_uleb128(ds->ds_data, offsetp); return (_dwarf_attr_init(dbg, ds, offsetp, dwarf_size, cu, die, ad, form, 1, error)); case DW_FORM_ref_addr: if (cu->cu_version == 2) atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, cu->cu_pointer_size); else atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); break; case DW_FORM_ref_udata: case DW_FORM_udata: atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); break; case DW_FORM_sdata: atref.u[0].s64 = _dwarf_read_sleb128(ds->ds_data, offsetp); break; case DW_FORM_sec_offset: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); break; case DW_FORM_string: atref.u[0].s = _dwarf_read_string(ds->ds_data, ds->ds_size, offsetp); break; case DW_FORM_strp: atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); - str = _dwarf_find_section(dbg, ".debug_str"); - assert(str != NULL); - atref.u[1].s = (char *) str->ds_data + atref.u[0].u64; + atref.u[1].s = _dwarf_strtab_get_table(dbg) + atref.u[0].u64; break; case DW_FORM_ref_sig8: atref.u[0].u64 = 8; atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, atref.u[0].u64); break; case DW_FORM_flag_present: /* This form has no value encoded in the DIE. */ atref.u[0].u64 = 1; break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); ret = DW_DLE_ATTR_FORM_BAD; break; } if (ret == DW_DLE_NONE) { if (form == DW_FORM_block || form == DW_FORM_block1 || form == DW_FORM_block2 || form == DW_FORM_block4) { atref.at_block.bl_len = atref.u[0].u64; atref.at_block.bl_data = atref.u[1].u8p; } ret = _dwarf_attr_add(die, &atref, NULL, error); } return (ret); } static int _dwarf_attr_write(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, Dwarf_CU cu, Dwarf_Attribute at, int pass2, Dwarf_Error *error) { struct _Dwarf_P_Expr_Entry *ee; uint64_t value, offset, bs; int ret; assert(dbg != NULL && ds != NULL && cu != NULL && at != NULL); /* Fill in reference to other DIE in the second pass. */ if (pass2) { if (at->at_form != DW_FORM_ref4 && at->at_form != DW_FORM_ref8) return (DW_DLE_NONE); if (at->at_refdie == NULL || at->at_offset == 0) return (DW_DLE_NONE); offset = at->at_offset; dbg->write(ds->ds_data, &offset, at->at_refdie->die_offset, at->at_form == DW_FORM_ref4 ? 4 : 8); return (DW_DLE_NONE); } switch (at->at_form) { case DW_FORM_addr: if (at->at_relsym) ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, cu->cu_pointer_size, ds->ds_size, at->at_relsym, at->u[0].u64, NULL, error); else ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); break; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: /* Write block size. */ if (at->at_form == DW_FORM_block) { ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, at->u[0].u64, error); if (ret != DW_DLE_NONE) break; } else { if (at->at_form == DW_FORM_block1) bs = 1; else if (at->at_form == DW_FORM_block2) bs = 2; else bs = 4; ret = WRITE_VALUE(at->u[0].u64, bs); if (ret != DW_DLE_NONE) break; } /* Keep block data offset for later use. */ offset = ds->ds_size; /* Write block data. */ ret = WRITE_BLOCK(at->u[1].u8p, at->u[0].u64); if (ret != DW_DLE_NONE) break; if (at->at_expr == NULL) break; /* Generate relocation entry for DW_OP_addr expressions. */ STAILQ_FOREACH(ee, &at->at_expr->pe_eelist, ee_next) { if (ee->ee_loc.lr_atom != DW_OP_addr || ee->ee_sym == 0) continue; ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, dbg->dbg_pointer_size, offset + ee->ee_loc.lr_offset + 1, ee->ee_sym, ee->ee_loc.lr_number, NULL, error); if (ret != DW_DLE_NONE) break; } break; case DW_FORM_data1: case DW_FORM_flag: case DW_FORM_ref1: ret = WRITE_VALUE(at->u[0].u64, 1); break; case DW_FORM_data2: case DW_FORM_ref2: ret = WRITE_VALUE(at->u[0].u64, 2); break; case DW_FORM_data4: if (at->at_relsym || at->at_relsec != NULL) ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, ds->ds_size, at->at_relsym, at->u[0].u64, at->at_relsec, error); else ret = WRITE_VALUE(at->u[0].u64, 4); break; case DW_FORM_data8: if (at->at_relsym || at->at_relsec != NULL) ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 8, ds->ds_size, at->at_relsym, at->u[0].u64, at->at_relsec, error); else ret = WRITE_VALUE(at->u[0].u64, 8); break; case DW_FORM_ref4: case DW_FORM_ref8: /* * The value of ref4 and ref8 could be a reference to another * DIE within the CU. And if we don't know the ref DIE's * offset at the moement, then we remember at_offset and fill * it in the second pass. */ if (at->at_refdie) { value = at->at_refdie->die_offset; if (value == 0) { cu->cu_pass2 = 1; at->at_offset = ds->ds_size; } } else value = at->u[0].u64; ret = WRITE_VALUE(value, at->at_form == DW_FORM_ref4 ? 4 : 8); break; case DW_FORM_indirect: /* TODO. */ DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); ret = DW_DLE_ATTR_FORM_BAD; break; case DW_FORM_ref_addr: /* DWARF2 format. */ if (at->at_relsym) ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, cu->cu_pointer_size, ds->ds_size, at->at_relsym, at->u[0].u64, NULL, error); else ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); break; case DW_FORM_ref_udata: case DW_FORM_udata: ret = WRITE_ULEB128(at->u[0].u64); break; case DW_FORM_sdata: ret = WRITE_SLEB128(at->u[0].s64); break; case DW_FORM_string: assert(at->u[0].s != NULL); ret = WRITE_STRING(at->u[0].s); break; case DW_FORM_strp: ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, ds->ds_size, 0, at->u[0].u64, ".debug_str", error); break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); ret = DW_DLE_ATTR_FORM_BAD; break; } return (ret); } int _dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, const char *secname, Dwarf_P_Attribute *atp, Dwarf_Error *error) { Dwarf_Attribute at; int ret; assert(dbg != NULL && die != NULL); if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) return (ret); at->at_die = die; at->at_attrib = attr; if (dbg->dbg_pointer_size == 4) at->at_form = DW_FORM_data4; else at->at_form = DW_FORM_data8; at->at_relsym = sym_index; at->at_relsec = secname; at->u[0].u64 = pc_value; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); if (atp) *atp = at; return (DW_DLE_NONE); } int _dwarf_add_string_attr(Dwarf_P_Die die, Dwarf_P_Attribute *atp, Dwarf_Half attr, char *string, Dwarf_Error *error) { Dwarf_Attribute at; Dwarf_Debug dbg; int ret; dbg = die != NULL ? die->die_dbg : NULL; assert(atp != NULL); if (die == NULL || string == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); return (DW_DLE_ARGUMENT); } if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) return (ret); at->at_die = die; at->at_attrib = attr; at->at_form = DW_FORM_strp; if ((ret = _dwarf_strtab_add(dbg, string, &at->u[0].u64, error)) != DW_DLE_NONE) { free(at); return (ret); } at->u[1].s = _dwarf_strtab_get_table(dbg) + at->u[0].u64; *atp = at; STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); return (DW_DLE_NONE); } int _dwarf_attr_gen(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, Dwarf_CU cu, Dwarf_Die die, int pass2, Dwarf_Error *error) { Dwarf_Attribute at; int ret; assert(dbg != NULL && ds != NULL && cu != NULL && die != NULL); STAILQ_FOREACH(at, &die->die_attr, at_next) { ret = _dwarf_attr_write(dbg, ds, drs, cu, at, pass2, error); if (ret != DW_DLE_NONE) return (ret); } return (DW_DLE_NONE); } Index: stable/11/contrib/elftoolchain/libdwarf/libdwarf_die.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/libdwarf_die.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/libdwarf_die.c (revision 367466) @@ -1,457 +1,456 @@ /*- * Copyright (c) 2007 John Birrell (jb@freebsd.org) * Copyright (c) 2009-2011 Kai Wang * 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 "_libdwarf.h" ELFTC_VCSID("$Id: libdwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $"); int _dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error) { Dwarf_Die die; assert(ret_die != NULL); if ((die = calloc(1, sizeof(struct _Dwarf_Die))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INIT(&die->die_attr); *ret_die = die; return (DW_DLE_NONE); } static int _dwarf_die_add(Dwarf_CU cu, uint64_t offset, uint64_t abnum, Dwarf_Abbrev ab, Dwarf_Die *diep, Dwarf_Error *error) { Dwarf_Debug dbg; Dwarf_Die die; int ret; assert(cu != NULL); assert(ab != NULL); dbg = cu->cu_dbg; if ((ret = _dwarf_die_alloc(dbg, &die, error)) != DW_DLE_NONE) return (ret); die->die_offset = offset; die->die_abnum = abnum; die->die_ab = ab; die->die_cu = cu; die->die_dbg = cu->cu_dbg; - if (diep != NULL) - *diep = die; + *diep = die; return (DW_DLE_NONE); } /* Find die at offset 'off' within the same CU. */ Dwarf_Die _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) { Dwarf_Debug dbg; Dwarf_Section *ds; Dwarf_CU cu; Dwarf_Die die1; Dwarf_Error de; int ret; cu = die->die_cu; dbg = die->die_dbg; ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec; ret = _dwarf_die_parse(dbg, ds, cu, cu->cu_dwarf_size, off, cu->cu_next_offset, &die1, 0, &de); if (ret == DW_DLE_NONE) return (die1); else return (NULL); } int _dwarf_die_parse(Dwarf_Debug dbg, Dwarf_Section *ds, Dwarf_CU cu, int dwarf_size, uint64_t offset, uint64_t next_offset, Dwarf_Die *ret_die, int search_sibling, Dwarf_Error *error) { Dwarf_Abbrev ab; Dwarf_AttrDef ad; Dwarf_Die die; uint64_t abnum; uint64_t die_offset; int ret, level; assert(cu != NULL); level = 1; die = NULL; while (offset < next_offset && offset < ds->ds_size) { die_offset = offset; abnum = _dwarf_read_uleb128(ds->ds_data, &offset); if (abnum == 0) { if (level == 0 || !search_sibling) return (DW_DLE_NO_ENTRY); /* * Return to previous DIE level. */ level--; continue; } if ((ret = _dwarf_abbrev_find(cu, abnum, &ab, error)) != DW_DLE_NONE) return (ret); if ((ret = _dwarf_die_add(cu, die_offset, abnum, ab, &die, error)) != DW_DLE_NONE) return (ret); STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { if ((ret = _dwarf_attr_init(dbg, ds, &offset, dwarf_size, cu, die, ad, ad->ad_form, 0, error)) != DW_DLE_NONE) return (ret); } die->die_next_off = offset; if (search_sibling && level > 0) { dwarf_dealloc(dbg, die, DW_DLA_DIE); if (ab->ab_children == DW_CHILDREN_yes) { /* Advance to next DIE level. */ level++; } } else { *ret_die = die; return (DW_DLE_NONE); } } return (DW_DLE_NO_ENTRY); } void _dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) { Dwarf_P_Die last_child; assert(die != NULL); if (parent) { /* Disconnect from old parent. */ if (die->die_parent) { if (die->die_parent != parent) { if (die->die_parent->die_child == die) die->die_parent->die_child = NULL; die->die_parent = NULL; } } /* Find the last child of this parent. */ last_child = parent->die_child; if (last_child) { while (last_child->die_right != NULL) last_child = last_child->die_right; } /* Connect to new parent. */ die->die_parent = parent; /* * Attach this DIE to the end of sibling list. If new * parent doesn't have any child, set this DIE as the * first child. */ if (last_child) { assert(last_child->die_right == NULL); last_child->die_right = die; die->die_left = last_child; } else parent->die_child = die; } if (child) { /* Disconnect from old child. */ if (die->die_child) { if (die->die_child != child) { die->die_child->die_parent = NULL; die->die_child = NULL; } } /* Connect to new child. */ die->die_child = child; child->die_parent = die; } if (left_sibling) { /* Disconnect from old left sibling. */ if (die->die_left) { if (die->die_left != left_sibling) { die->die_left->die_right = NULL; die->die_left = NULL; } } /* Connect to new right sibling. */ die->die_left = left_sibling; left_sibling->die_right = die; } if (right_sibling) { /* Disconnect from old right sibling. */ if (die->die_right) { if (die->die_right != right_sibling) { die->die_right->die_left = NULL; die->die_right = NULL; } } /* Connect to new right sibling. */ die->die_right = right_sibling; right_sibling->die_left = die; } } int _dwarf_die_count_links(Dwarf_P_Die parent, Dwarf_P_Die child, Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) { int count; count = 0; if (parent) count++; if (child) count++; if (left_sibling) count++; if (right_sibling) count++; return (count); } static int _dwarf_die_gen_recursive(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, Dwarf_P_Die die, int pass2, Dwarf_Error *error) { Dwarf_P_Section ds; Dwarf_Abbrev ab; Dwarf_Attribute at; Dwarf_AttrDef ad; int match, ret; ds = dbg->dbgp_info; assert(ds != NULL); if (pass2) goto attr_gen; /* * Add DW_AT_sibling attribute for DIEs with children, so consumers * can quickly scan chains of siblings, while ignoring the children * of individual siblings. */ if (die->die_child && die->die_right) { if (_dwarf_attr_find(die, DW_AT_sibling) == NULL) (void) dwarf_add_AT_reference(dbg, die, DW_AT_sibling, die->die_right, error); } /* * Search abbrev list to find a matching entry. */ die->die_ab = NULL; for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { if (die->die_tag != ab->ab_tag) continue; if (ab->ab_children == DW_CHILDREN_no && die->die_child != NULL) continue; if (ab->ab_children == DW_CHILDREN_yes && die->die_child == NULL) continue; at = STAILQ_FIRST(&die->die_attr); ad = STAILQ_FIRST(&ab->ab_attrdef); match = 1; while (at != NULL && ad != NULL) { if (at->at_attrib != ad->ad_attrib || at->at_form != ad->ad_form) { match = 0; break; } at = STAILQ_NEXT(at, at_next); ad = STAILQ_NEXT(ad, ad_next); } if ((at == NULL && ad != NULL) || (at != NULL && ad == NULL)) match = 0; if (match) { die->die_ab = ab; break; } } /* * Create a new abbrev entry if we can not reuse any existing one. */ if (die->die_ab == NULL) { ret = _dwarf_abbrev_add(cu, ++cu->cu_abbrev_cnt, die->die_tag, die->die_child != NULL ? DW_CHILDREN_yes : DW_CHILDREN_no, 0, &ab, error); if (ret != DW_DLE_NONE) return (ret); STAILQ_FOREACH(at, &die->die_attr, at_next) { ret = _dwarf_attrdef_add(dbg, ab, at->at_attrib, at->at_form, 0, NULL, error); if (ret != DW_DLE_NONE) return (ret); } die->die_ab = ab; } die->die_offset = ds->ds_size; /* * Transform the DIE to bytes stream. */ ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, die->die_ab->ab_entry, error); if (ret != DW_DLE_NONE) return (ret); attr_gen: /* Transform the attributes of this DIE. */ ret = _dwarf_attr_gen(dbg, ds, drs, cu, die, pass2, error); if (ret != DW_DLE_NONE) return (ret); /* Proceed to child DIE. */ if (die->die_child != NULL) { ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_child, pass2, error); if (ret != DW_DLE_NONE) return (ret); } /* Proceed to sibling DIE. */ if (die->die_right != NULL) { ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_right, pass2, error); if (ret != DW_DLE_NONE) return (ret); } /* Write a null DIE indicating the end of current level. */ if (die->die_right == NULL) { ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, 0, error); if (ret != DW_DLE_NONE) return (ret); } return (DW_DLE_NONE); } int _dwarf_die_gen(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, Dwarf_Error *error) { Dwarf_Abbrev ab, tab; Dwarf_AttrDef ad, tad; Dwarf_Die die; int ret; assert(dbg != NULL && cu != NULL); assert(dbg->dbgp_root_die != NULL); die = dbg->dbgp_root_die; /* * Insert a DW_AT_stmt_list attribute into root DIE, if there are * line number information. */ if (!STAILQ_EMPTY(&dbg->dbgp_lineinfo->li_lnlist)) RCHECK(_dwarf_add_AT_dataref(dbg, die, DW_AT_stmt_list, 0, 0, ".debug_line", NULL, error)); RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 0, error)); if (cu->cu_pass2) RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 1, error)); return (DW_DLE_NONE); gen_fail: HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, ad_next); free(ad); } free(ab); } return (ret); } void _dwarf_die_pro_cleanup(Dwarf_P_Debug dbg) { Dwarf_P_Die die, tdie; Dwarf_P_Attribute at, tat; assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); STAILQ_FOREACH_SAFE(die, &dbg->dbgp_dielist, die_pro_next, tdie) { STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) { STAILQ_REMOVE(&die->die_attr, at, _Dwarf_Attribute, at_next); free(at); } free(die); } } Index: stable/11/contrib/elftoolchain/libdwarf/libdwarf_frame.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/libdwarf_frame.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/libdwarf_frame.c (revision 367466) @@ -1,1608 +1,1608 @@ /*- * Copyright (c) 2009-2011,2014 Kai Wang * 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 "_libdwarf.h" ELFTC_VCSID("$Id: libdwarf_frame.c 3589 2018-03-13 20:34:33Z kaiwang27 $"); static int _dwarf_frame_find_cie(Dwarf_FrameSec fs, Dwarf_Unsigned offset, Dwarf_Cie *ret_cie) { Dwarf_Cie cie; STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) { if (cie->cie_offset == offset) break; } if (cie == NULL) return (DW_DLE_NO_ENTRY); if (ret_cie != NULL) *ret_cie = cie; return (DW_DLE_NONE); } static int _dwarf_frame_read_lsb_encoded(Dwarf_Debug dbg, Dwarf_Cie cie, uint64_t *val, uint8_t *data, uint64_t *offsetp, uint8_t encode, Dwarf_Addr pc, Dwarf_Error *error) { uint8_t application; if (encode == DW_EH_PE_omit) return (DW_DLE_NONE); application = encode & 0xf0; encode &= 0x0f; switch (encode) { case DW_EH_PE_absptr: *val = dbg->read(data, offsetp, cie->cie_addrsize); break; case DW_EH_PE_uleb128: *val = _dwarf_read_uleb128(data, offsetp); break; case DW_EH_PE_udata2: *val = dbg->read(data, offsetp, 2); break; case DW_EH_PE_udata4: *val = dbg->read(data, offsetp, 4); break; case DW_EH_PE_udata8: *val = dbg->read(data, offsetp, 8); break; case DW_EH_PE_sleb128: *val = _dwarf_read_sleb128(data, offsetp); break; case DW_EH_PE_sdata2: *val = (int16_t) dbg->read(data, offsetp, 2); break; case DW_EH_PE_sdata4: *val = (int32_t) dbg->read(data, offsetp, 4); break; case DW_EH_PE_sdata8: *val = dbg->read(data, offsetp, 8); break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN); } if (application == DW_EH_PE_pcrel) { /* * Value is relative to .eh_frame section virtual addr. */ switch (encode) { case DW_EH_PE_uleb128: case DW_EH_PE_udata2: case DW_EH_PE_udata4: case DW_EH_PE_udata8: *val += pc; break; case DW_EH_PE_sleb128: case DW_EH_PE_sdata2: case DW_EH_PE_sdata4: case DW_EH_PE_sdata8: *val = pc + (int64_t) *val; break; default: /* DW_EH_PE_absptr is absolute value. */ break; } } /* XXX Applications other than DW_EH_PE_pcrel are not handled. */ return (DW_DLE_NONE); } static int _dwarf_frame_parse_lsb_cie_augment(Dwarf_Debug dbg, Dwarf_Cie cie, Dwarf_Error *error) { uint8_t *aug_p, *augdata_p; uint64_t val, offset; uint8_t encode; int ret; assert(cie->cie_augment != NULL && *cie->cie_augment == 'z'); /* * Here we're only interested in the presence of augment 'R' * and associated CIE augment data, which describes the * encoding scheme of FDE PC begin and range. */ aug_p = &cie->cie_augment[1]; augdata_p = cie->cie_augdata; while (*aug_p != '\0') { switch (*aug_p) { case 'S': break; case 'L': /* Skip one augment in augment data. */ augdata_p++; break; case 'P': /* Skip two augments in augment data. */ encode = *augdata_p++; offset = 0; ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, augdata_p, &offset, encode, 0, error); if (ret != DW_DLE_NONE) return (ret); augdata_p += offset; break; case 'R': cie->cie_fde_encode = *augdata_p++; break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN); return (DW_DLE_FRAME_AUGMENTATION_UNKNOWN); } aug_p++; } return (DW_DLE_NONE); } static int _dwarf_frame_add_cie(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, Dwarf_Unsigned *off, Dwarf_Cie *ret_cie, Dwarf_Error *error) { Dwarf_Cie cie; uint64_t length; int dwarf_size, ret; char *p; /* Check if we already added this CIE. */ if (_dwarf_frame_find_cie(fs, *off, &cie) != DW_DLE_NO_ENTRY) { *off += cie->cie_length + 4; return (DW_DLE_NONE); } if ((cie = calloc(1, sizeof(struct _Dwarf_Cie))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INSERT_TAIL(&fs->fs_cielist, cie, cie_next); cie->cie_dbg = dbg; cie->cie_index = fs->fs_cielen; cie->cie_offset = *off; length = dbg->read(ds->ds_data, off, 4); if (length == 0xffffffff) { dwarf_size = 8; length = dbg->read(ds->ds_data, off, 8); } else dwarf_size = 4; if (length > ds->ds_size - *off) { DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); } (void) dbg->read(ds->ds_data, off, dwarf_size); /* Skip CIE id. */ cie->cie_length = length; cie->cie_version = dbg->read(ds->ds_data, off, 1); if (cie->cie_version != 1 && cie->cie_version != 3 && cie->cie_version != 4) { DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_VERSION_BAD); return (DW_DLE_FRAME_VERSION_BAD); } cie->cie_augment = ds->ds_data + *off; p = (char *) ds->ds_data; while (p[(*off)++] != '\0') ; /* We only recognize normal .dwarf_frame and GNU .eh_frame sections. */ if (*cie->cie_augment != 0 && *cie->cie_augment != 'z') { *off = cie->cie_offset + ((dwarf_size == 4) ? 4 : 12) + cie->cie_length; return (DW_DLE_NONE); } /* Optional EH Data field for .eh_frame section. */ if (strstr((char *)cie->cie_augment, "eh") != NULL) cie->cie_ehdata = dbg->read(ds->ds_data, off, dbg->dbg_pointer_size); /* DWARF4 added "address_size" and "segment_size". */ if (cie->cie_version == 4) { cie->cie_addrsize = dbg->read(ds->ds_data, off, 1); cie->cie_segmentsize = dbg->read(ds->ds_data, off, 1); } else { /* * Otherwise (DWARF[23]) we just set CIE addrsize to the * debug context pointer size. */ cie->cie_addrsize = dbg->dbg_pointer_size; } cie->cie_caf = _dwarf_read_uleb128(ds->ds_data, off); cie->cie_daf = _dwarf_read_sleb128(ds->ds_data, off); /* Return address register. */ if (cie->cie_version == 1) cie->cie_ra = dbg->read(ds->ds_data, off, 1); else cie->cie_ra = _dwarf_read_uleb128(ds->ds_data, off); /* Optional CIE augmentation data for .eh_frame section. */ if (*cie->cie_augment == 'z') { cie->cie_auglen = _dwarf_read_uleb128(ds->ds_data, off); cie->cie_augdata = ds->ds_data + *off; *off += cie->cie_auglen; /* * XXX Use DW_EH_PE_absptr for default FDE PC start/range, * in case _dwarf_frame_parse_lsb_cie_augment fails to * find out the real encode. */ cie->cie_fde_encode = DW_EH_PE_absptr; ret = _dwarf_frame_parse_lsb_cie_augment(dbg, cie, error); if (ret != DW_DLE_NONE) return (ret); } /* CIE Initial instructions. */ cie->cie_initinst = ds->ds_data + *off; if (dwarf_size == 4) cie->cie_instlen = cie->cie_offset + 4 + length - *off; else cie->cie_instlen = cie->cie_offset + 12 + length - *off; *off += cie->cie_instlen; #ifdef FRAME_DEBUG printf("cie:\n"); printf("\tcie_version=%u cie_offset=%ju cie_length=%ju cie_augment=%s" " cie_instlen=%ju cie->cie_caf=%ju cie->cie_daf=%jd off=%ju\n", cie->cie_version, cie->cie_offset, cie->cie_length, (char *)cie->cie_augment, cie->cie_instlen, cie->cie_caf, cie->cie_daf, *off); #endif if (ret_cie != NULL) *ret_cie = cie; fs->fs_cielen++; return (DW_DLE_NONE); } static int _dwarf_frame_add_fde(Dwarf_Debug dbg, Dwarf_FrameSec fs, Dwarf_Section *ds, Dwarf_Unsigned *off, int eh_frame, Dwarf_Error *error) { Dwarf_Cie cie; Dwarf_Fde fde; Dwarf_Unsigned cieoff; uint64_t length, val; int dwarf_size, ret; if ((fde = calloc(1, sizeof(struct _Dwarf_Fde))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INSERT_TAIL(&fs->fs_fdelist, fde, fde_next); fde->fde_dbg = dbg; fde->fde_fs = fs; fde->fde_addr = ds->ds_data + *off; fde->fde_offset = *off; length = dbg->read(ds->ds_data, off, 4); if (length == 0xffffffff) { dwarf_size = 8; length = dbg->read(ds->ds_data, off, 8); } else dwarf_size = 4; if (length > ds->ds_size - *off) { DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD); return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); } fde->fde_length = length; if (eh_frame) { fde->fde_cieoff = dbg->read(ds->ds_data, off, 4); cieoff = *off - (4 + fde->fde_cieoff); /* This delta should never be 0. */ if (cieoff == fde->fde_offset) { DWARF_SET_ERROR(dbg, error, DW_DLE_NO_CIE_FOR_FDE); return (DW_DLE_NO_CIE_FOR_FDE); } } else { fde->fde_cieoff = dbg->read(ds->ds_data, off, dwarf_size); cieoff = fde->fde_cieoff; } if (_dwarf_frame_find_cie(fs, cieoff, &cie) == DW_DLE_NO_ENTRY) { ret = _dwarf_frame_add_cie(dbg, fs, ds, &cieoff, &cie, error); if (ret != DW_DLE_NONE) return (ret); } fde->fde_cie = cie; if (eh_frame) { /* * The FDE PC start/range for .eh_frame is encoded according * to the LSB spec's extension to DWARF2. */ ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, ds->ds_data, off, cie->cie_fde_encode, ds->ds_addr + *off, error); if (ret != DW_DLE_NONE) return (ret); fde->fde_initloc = val; /* * FDE PC range should not be relative value to anything. * So pass 0 for pc value. */ ret = _dwarf_frame_read_lsb_encoded(dbg, cie, &val, ds->ds_data, off, cie->cie_fde_encode, 0, error); if (ret != DW_DLE_NONE) return (ret); fde->fde_adrange = val; } else { fde->fde_initloc = dbg->read(ds->ds_data, off, cie->cie_addrsize); fde->fde_adrange = dbg->read(ds->ds_data, off, cie->cie_addrsize); } /* Optional FDE augmentation data for .eh_frame section. (ignored) */ if (eh_frame && *cie->cie_augment == 'z') { fde->fde_auglen = _dwarf_read_uleb128(ds->ds_data, off); fde->fde_augdata = ds->ds_data + *off; *off += fde->fde_auglen; } fde->fde_inst = ds->ds_data + *off; if (dwarf_size == 4) fde->fde_instlen = fde->fde_offset + 4 + length - *off; else fde->fde_instlen = fde->fde_offset + 12 + length - *off; *off += fde->fde_instlen; #ifdef FRAME_DEBUG printf("fde:"); if (eh_frame) printf("(eh_frame)"); putchar('\n'); printf("\tfde_offset=%ju fde_length=%ju fde_cieoff=%ju" " fde_instlen=%ju off=%ju\n", fde->fde_offset, fde->fde_length, fde->fde_cieoff, fde->fde_instlen, *off); #endif fs->fs_fdelen++; return (DW_DLE_NONE); } static void _dwarf_frame_section_cleanup(Dwarf_FrameSec fs) { Dwarf_Cie cie, tcie; Dwarf_Fde fde, tfde; STAILQ_FOREACH_SAFE(cie, &fs->fs_cielist, cie_next, tcie) { STAILQ_REMOVE(&fs->fs_cielist, cie, _Dwarf_Cie, cie_next); free(cie); } STAILQ_FOREACH_SAFE(fde, &fs->fs_fdelist, fde_next, tfde) { STAILQ_REMOVE(&fs->fs_fdelist, fde, _Dwarf_Fde, fde_next); free(fde); } if (fs->fs_ciearray != NULL) free(fs->fs_ciearray); if (fs->fs_fdearray != NULL) free(fs->fs_fdearray); free(fs); } static int _dwarf_frame_section_init(Dwarf_Debug dbg, Dwarf_FrameSec *frame_sec, Dwarf_Section *ds, int eh_frame, Dwarf_Error *error) { Dwarf_FrameSec fs; Dwarf_Cie cie; Dwarf_Fde fde; uint64_t length, offset, cie_id, entry_off; int dwarf_size, i, ret; assert(frame_sec != NULL); assert(*frame_sec == NULL); if ((fs = calloc(1, sizeof(struct _Dwarf_FrameSec))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INIT(&fs->fs_cielist); STAILQ_INIT(&fs->fs_fdelist); offset = 0; while (offset < ds->ds_size) { entry_off = offset; length = dbg->read(ds->ds_data, &offset, 4); if (length == 0xffffffff) { dwarf_size = 8; length = dbg->read(ds->ds_data, &offset, 8); } else dwarf_size = 4; if (length > ds->ds_size - offset || (length == 0 && !eh_frame)) { - DWARF_SET_ERROR(dbg, error, - DW_DLE_DEBUG_FRAME_LENGTH_BAD); - return (DW_DLE_DEBUG_FRAME_LENGTH_BAD); + ret = DW_DLE_DEBUG_FRAME_LENGTH_BAD; + DWARF_SET_ERROR(dbg, error, ret); + goto fail_cleanup; } /* Check terminator for .eh_frame */ if (eh_frame && length == 0) break; cie_id = dbg->read(ds->ds_data, &offset, dwarf_size); if (eh_frame) { /* GNU .eh_frame use CIE id 0. */ if (cie_id == 0) ret = _dwarf_frame_add_cie(dbg, fs, ds, &entry_off, NULL, error); else ret = _dwarf_frame_add_fde(dbg, fs, ds, &entry_off, 1, error); } else { /* .dwarf_frame use CIE id ~0 */ if ((dwarf_size == 4 && cie_id == ~0U) || (dwarf_size == 8 && cie_id == ~0ULL)) ret = _dwarf_frame_add_cie(dbg, fs, ds, &entry_off, NULL, error); else ret = _dwarf_frame_add_fde(dbg, fs, ds, &entry_off, 0, error); } if (ret != DW_DLE_NONE) goto fail_cleanup; offset = entry_off; } /* Create CIE array. */ if (fs->fs_cielen > 0) { if ((fs->fs_ciearray = malloc(sizeof(Dwarf_Cie) * fs->fs_cielen)) == NULL) { ret = DW_DLE_MEMORY; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } i = 0; STAILQ_FOREACH(cie, &fs->fs_cielist, cie_next) { fs->fs_ciearray[i++] = cie; } assert((Dwarf_Unsigned)i == fs->fs_cielen); } /* Create FDE array. */ if (fs->fs_fdelen > 0) { if ((fs->fs_fdearray = malloc(sizeof(Dwarf_Fde) * fs->fs_fdelen)) == NULL) { ret = DW_DLE_MEMORY; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } i = 0; STAILQ_FOREACH(fde, &fs->fs_fdelist, fde_next) { fs->fs_fdearray[i++] = fde; } assert((Dwarf_Unsigned)i == fs->fs_fdelen); } *frame_sec = fs; return (DW_DLE_NONE); fail_cleanup: _dwarf_frame_section_cleanup(fs); return (ret); } static int _dwarf_frame_run_inst(Dwarf_Debug dbg, Dwarf_Regtable3 *rt, uint8_t addr_size, uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, Dwarf_Addr pc_req, Dwarf_Addr *row_pc, Dwarf_Error *error) { Dwarf_Regtable3 *init_rt, *saved_rt; uint8_t *p, *pe; uint8_t high2, low6; uint64_t reg, reg2, uoff, soff; int ret; #define CFA rt->rt3_cfa_rule #define INITCFA init_rt->rt3_cfa_rule #define RL rt->rt3_rules #define INITRL init_rt->rt3_rules #define CHECK_TABLE_SIZE(x) \ do { \ if ((x) >= rt->rt3_reg_table_size) { \ DWARF_SET_ERROR(dbg, error, \ DW_DLE_DF_REG_NUM_TOO_HIGH); \ ret = DW_DLE_DF_REG_NUM_TOO_HIGH; \ goto program_done; \ } \ } while(0) #ifdef FRAME_DEBUG printf("frame_run_inst: (caf=%ju, daf=%jd)\n", caf, daf); #endif ret = DW_DLE_NONE; init_rt = saved_rt = NULL; *row_pc = pc; /* Save a copy of the table as initial state. */ _dwarf_frame_regtable_copy(dbg, &init_rt, rt, error); p = insts; pe = p + len; while (p < pe) { #ifdef FRAME_DEBUG printf("p=%p pe=%p pc=%#jx pc_req=%#jx\n", p, pe, pc, pc_req); #endif if (*p == DW_CFA_nop) { #ifdef FRAME_DEBUG printf("DW_CFA_nop\n"); #endif p++; continue; } high2 = *p & 0xc0; low6 = *p & 0x3f; p++; if (high2 > 0) { switch (high2) { case DW_CFA_advance_loc: pc += low6 * caf; #ifdef FRAME_DEBUG printf("DW_CFA_advance_loc(%#jx(%u))\n", pc, low6); #endif if (pc_req < pc) goto program_done; break; case DW_CFA_offset: *row_pc = pc; CHECK_TABLE_SIZE(low6); RL[low6].dw_offset_relevant = 1; RL[low6].dw_value_type = DW_EXPR_OFFSET; RL[low6].dw_regnum = dbg->dbg_frame_cfa_value; RL[low6].dw_offset_or_block_len = _dwarf_decode_uleb128(&p) * daf; #ifdef FRAME_DEBUG printf("DW_CFA_offset(%jd)\n", RL[low6].dw_offset_or_block_len); #endif break; case DW_CFA_restore: *row_pc = pc; CHECK_TABLE_SIZE(low6); memcpy(&RL[low6], &INITRL[low6], sizeof(Dwarf_Regtable_Entry3)); #ifdef FRAME_DEBUG printf("DW_CFA_restore(%u)\n", low6); #endif break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); ret = DW_DLE_FRAME_INSTR_EXEC_ERROR; goto program_done; } continue; } switch (low6) { case DW_CFA_set_loc: pc = dbg->decode(&p, addr_size); #ifdef FRAME_DEBUG printf("DW_CFA_set_loc(pc=%#jx)\n", pc); #endif if (pc_req < pc) goto program_done; break; case DW_CFA_advance_loc1: pc += dbg->decode(&p, 1) * caf; #ifdef FRAME_DEBUG printf("DW_CFA_set_loc1(pc=%#jx)\n", pc); #endif if (pc_req < pc) goto program_done; break; case DW_CFA_advance_loc2: pc += dbg->decode(&p, 2) * caf; #ifdef FRAME_DEBUG printf("DW_CFA_set_loc2(pc=%#jx)\n", pc); #endif if (pc_req < pc) goto program_done; break; case DW_CFA_advance_loc4: pc += dbg->decode(&p, 4) * caf; #ifdef FRAME_DEBUG printf("DW_CFA_set_loc4(pc=%#jx)\n", pc); #endif if (pc_req < pc) goto program_done; break; case DW_CFA_offset_extended: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); uoff = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 1; RL[reg].dw_value_type = DW_EXPR_OFFSET; RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; RL[reg].dw_offset_or_block_len = uoff * daf; #ifdef FRAME_DEBUG printf("DW_CFA_offset_extended(reg=%ju,uoff=%ju)\n", reg, uoff); #endif break; case DW_CFA_restore_extended: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); memcpy(&RL[reg], &INITRL[reg], sizeof(Dwarf_Regtable_Entry3)); #ifdef FRAME_DEBUG printf("DW_CFA_restore_extended(%ju)\n", reg); #endif break; case DW_CFA_undefined: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 0; RL[reg].dw_regnum = dbg->dbg_frame_undefined_value; #ifdef FRAME_DEBUG printf("DW_CFA_undefined(%ju)\n", reg); #endif break; case DW_CFA_same_value: reg = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 0; RL[reg].dw_regnum = dbg->dbg_frame_same_value; #ifdef FRAME_DEBUG printf("DW_CFA_same_value(%ju)\n", reg); #endif break; case DW_CFA_register: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); reg2 = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 0; RL[reg].dw_regnum = reg2; #ifdef FRAME_DEBUG printf("DW_CFA_register(reg=%ju,reg2=%ju)\n", reg, reg2); #endif break; case DW_CFA_remember_state: _dwarf_frame_regtable_copy(dbg, &saved_rt, rt, error); #ifdef FRAME_DEBUG printf("DW_CFA_remember_state\n"); #endif break; case DW_CFA_restore_state: *row_pc = pc; _dwarf_frame_regtable_copy(dbg, &rt, saved_rt, error); #ifdef FRAME_DEBUG printf("DW_CFA_restore_state\n"); #endif break; case DW_CFA_def_cfa: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); uoff = _dwarf_decode_uleb128(&p); CFA.dw_offset_relevant = 1; CFA.dw_value_type = DW_EXPR_OFFSET; CFA.dw_regnum = reg; CFA.dw_offset_or_block_len = uoff; #ifdef FRAME_DEBUG printf("DW_CFA_def_cfa(reg=%ju,uoff=%ju)\n", reg, uoff); #endif break; case DW_CFA_def_cfa_register: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); CFA.dw_regnum = reg; /* * Note that DW_CFA_def_cfa_register change the CFA * rule register while keep the old offset. So we * should not touch the CFA.dw_offset_relevant flag * here. */ #ifdef FRAME_DEBUG printf("DW_CFA_def_cfa_register(%ju)\n", reg); #endif break; case DW_CFA_def_cfa_offset: *row_pc = pc; uoff = _dwarf_decode_uleb128(&p); CFA.dw_offset_relevant = 1; CFA.dw_value_type = DW_EXPR_OFFSET; CFA.dw_offset_or_block_len = uoff; #ifdef FRAME_DEBUG printf("DW_CFA_def_cfa_offset(%ju)\n", uoff); #endif break; case DW_CFA_def_cfa_expression: *row_pc = pc; CFA.dw_offset_relevant = 0; CFA.dw_value_type = DW_EXPR_EXPRESSION; CFA.dw_offset_or_block_len = _dwarf_decode_uleb128(&p); CFA.dw_block_ptr = p; p += CFA.dw_offset_or_block_len; #ifdef FRAME_DEBUG printf("DW_CFA_def_cfa_expression\n"); #endif break; case DW_CFA_expression: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 0; RL[reg].dw_value_type = DW_EXPR_EXPRESSION; RL[reg].dw_offset_or_block_len = _dwarf_decode_uleb128(&p); RL[reg].dw_block_ptr = p; p += RL[reg].dw_offset_or_block_len; #ifdef FRAME_DEBUG printf("DW_CFA_expression\n"); #endif break; case DW_CFA_offset_extended_sf: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); soff = _dwarf_decode_sleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 1; RL[reg].dw_value_type = DW_EXPR_OFFSET; RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; RL[reg].dw_offset_or_block_len = soff * daf; #ifdef FRAME_DEBUG printf("DW_CFA_offset_extended_sf(reg=%ju,soff=%jd)\n", reg, soff); #endif break; case DW_CFA_def_cfa_sf: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); soff = _dwarf_decode_sleb128(&p); CFA.dw_offset_relevant = 1; CFA.dw_value_type = DW_EXPR_OFFSET; CFA.dw_regnum = reg; CFA.dw_offset_or_block_len = soff * daf; #ifdef FRAME_DEBUG printf("DW_CFA_def_cfa_sf(reg=%ju,soff=%jd)\n", reg, soff); #endif break; case DW_CFA_def_cfa_offset_sf: *row_pc = pc; soff = _dwarf_decode_sleb128(&p); CFA.dw_offset_relevant = 1; CFA.dw_value_type = DW_EXPR_OFFSET; CFA.dw_offset_or_block_len = soff * daf; #ifdef FRAME_DEBUG printf("DW_CFA_def_cfa_offset_sf(soff=%jd)\n", soff); #endif break; case DW_CFA_val_offset: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); uoff = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 1; RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET; RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; RL[reg].dw_offset_or_block_len = uoff * daf; #ifdef FRAME_DEBUG printf("DW_CFA_val_offset(reg=%ju,uoff=%ju)\n", reg, uoff); #endif break; case DW_CFA_val_offset_sf: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); soff = _dwarf_decode_sleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 1; RL[reg].dw_value_type = DW_EXPR_VAL_OFFSET; RL[reg].dw_regnum = dbg->dbg_frame_cfa_value; RL[reg].dw_offset_or_block_len = soff * daf; #ifdef FRAME_DEBUG printf("DW_CFA_val_offset_sf(reg=%ju,soff=%jd)\n", reg, soff); #endif break; case DW_CFA_val_expression: *row_pc = pc; reg = _dwarf_decode_uleb128(&p); CHECK_TABLE_SIZE(reg); RL[reg].dw_offset_relevant = 0; RL[reg].dw_value_type = DW_EXPR_VAL_EXPRESSION; RL[reg].dw_offset_or_block_len = _dwarf_decode_uleb128(&p); RL[reg].dw_block_ptr = p; p += RL[reg].dw_offset_or_block_len; #ifdef FRAME_DEBUG printf("DW_CFA_val_expression\n"); #endif break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); ret = DW_DLE_FRAME_INSTR_EXEC_ERROR; goto program_done; } } program_done: free(init_rt->rt3_rules); free(init_rt); if (saved_rt) { free(saved_rt->rt3_rules); free(saved_rt); } return (ret); #undef CFA #undef INITCFA #undef RL #undef INITRL #undef CHECK_TABLE_SIZE } static int _dwarf_frame_convert_inst(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned *count, Dwarf_Frame_Op *fop, Dwarf_Frame_Op3 *fop3, Dwarf_Error *error) { uint8_t *p, *pe; uint8_t high2, low6; uint64_t reg, reg2, uoff, soff, blen; #define SET_BASE_OP(x) \ do { \ if (fop != NULL) \ fop[*count].fp_base_op = (x) >> 6; \ if (fop3 != NULL) \ fop3[*count].fp_base_op = (x) >> 6; \ } while(0) #define SET_EXTENDED_OP(x) \ do { \ if (fop != NULL) \ fop[*count].fp_extended_op = (x); \ if (fop3 != NULL) \ fop3[*count].fp_extended_op = (x); \ } while(0) #define SET_REGISTER(x) \ do { \ if (fop != NULL) \ fop[*count].fp_register = (x); \ if (fop3 != NULL) \ fop3[*count].fp_register = (x); \ } while(0) #define SET_OFFSET(x) \ do { \ if (fop != NULL) \ fop[*count].fp_offset = (x); \ if (fop3 != NULL) \ fop3[*count].fp_offset_or_block_len = \ (x); \ } while(0) #define SET_INSTR_OFFSET(x) \ do { \ if (fop != NULL) \ fop[*count].fp_instr_offset = (x); \ if (fop3 != NULL) \ fop3[*count].fp_instr_offset = (x); \ } while(0) #define SET_BLOCK_LEN(x) \ do { \ if (fop3 != NULL) \ fop3[*count].fp_offset_or_block_len = \ (x); \ } while(0) #define SET_EXPR_BLOCK(addr, len) \ do { \ if (fop3 != NULL) { \ fop3[*count].fp_expr_block = \ malloc((size_t) (len)); \ if (fop3[*count].fp_expr_block == NULL) { \ DWARF_SET_ERROR(dbg, error, \ DW_DLE_MEMORY); \ return (DW_DLE_MEMORY); \ } \ memcpy(&fop3[*count].fp_expr_block, \ (addr), (len)); \ } \ } while(0) *count = 0; p = insts; pe = p + len; while (p < pe) { SET_INSTR_OFFSET(p - insts); if (*p == DW_CFA_nop) { p++; (*count)++; continue; } high2 = *p & 0xc0; low6 = *p & 0x3f; p++; if (high2 > 0) { switch (high2) { case DW_CFA_advance_loc: SET_BASE_OP(high2); SET_OFFSET(low6); break; case DW_CFA_offset: SET_BASE_OP(high2); SET_REGISTER(low6); uoff = _dwarf_decode_uleb128(&p); SET_OFFSET(uoff); break; case DW_CFA_restore: SET_BASE_OP(high2); SET_REGISTER(low6); break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); return (DW_DLE_FRAME_INSTR_EXEC_ERROR); } (*count)++; continue; } SET_EXTENDED_OP(low6); switch (low6) { case DW_CFA_set_loc: uoff = dbg->decode(&p, addr_size); SET_OFFSET(uoff); break; case DW_CFA_advance_loc1: uoff = dbg->decode(&p, 1); SET_OFFSET(uoff); break; case DW_CFA_advance_loc2: uoff = dbg->decode(&p, 2); SET_OFFSET(uoff); break; case DW_CFA_advance_loc4: uoff = dbg->decode(&p, 4); SET_OFFSET(uoff); break; case DW_CFA_offset_extended: case DW_CFA_def_cfa: case DW_CFA_val_offset: reg = _dwarf_decode_uleb128(&p); uoff = _dwarf_decode_uleb128(&p); SET_REGISTER(reg); SET_OFFSET(uoff); break; case DW_CFA_restore_extended: case DW_CFA_undefined: case DW_CFA_same_value: case DW_CFA_def_cfa_register: reg = _dwarf_decode_uleb128(&p); SET_REGISTER(reg); break; case DW_CFA_register: reg = _dwarf_decode_uleb128(&p); reg2 = _dwarf_decode_uleb128(&p); SET_REGISTER(reg); SET_OFFSET(reg2); break; case DW_CFA_remember_state: case DW_CFA_restore_state: break; case DW_CFA_def_cfa_offset: uoff = _dwarf_decode_uleb128(&p); SET_OFFSET(uoff); break; case DW_CFA_def_cfa_expression: blen = _dwarf_decode_uleb128(&p); SET_BLOCK_LEN(blen); SET_EXPR_BLOCK(p, blen); p += blen; break; case DW_CFA_expression: case DW_CFA_val_expression: reg = _dwarf_decode_uleb128(&p); blen = _dwarf_decode_uleb128(&p); SET_REGISTER(reg); SET_BLOCK_LEN(blen); SET_EXPR_BLOCK(p, blen); p += blen; break; case DW_CFA_offset_extended_sf: case DW_CFA_def_cfa_sf: case DW_CFA_val_offset_sf: reg = _dwarf_decode_uleb128(&p); soff = _dwarf_decode_sleb128(&p); SET_REGISTER(reg); SET_OFFSET(soff); break; case DW_CFA_def_cfa_offset_sf: soff = _dwarf_decode_sleb128(&p); SET_OFFSET(soff); break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); return (DW_DLE_FRAME_INSTR_EXEC_ERROR); } (*count)++; } return (DW_DLE_NONE); } int _dwarf_frame_get_fop(Dwarf_Debug dbg, uint8_t addr_size, uint8_t *insts, Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, Dwarf_Error *error) { Dwarf_Frame_Op *oplist; Dwarf_Unsigned count; int ret; ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, NULL, NULL, error); if (ret != DW_DLE_NONE) return (ret); if ((oplist = calloc(count, sizeof(Dwarf_Frame_Op))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } ret = _dwarf_frame_convert_inst(dbg, addr_size, insts, len, &count, oplist, NULL, error); if (ret != DW_DLE_NONE) { free(oplist); return (ret); } *ret_oplist = oplist; *ret_opcnt = count; return (DW_DLE_NONE); } int _dwarf_frame_regtable_copy(Dwarf_Debug dbg, Dwarf_Regtable3 **dest, Dwarf_Regtable3 *src, Dwarf_Error *error) { int i; assert(dest != NULL); assert(src != NULL); if (*dest == NULL) { if ((*dest = malloc(sizeof(Dwarf_Regtable3))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } (*dest)->rt3_reg_table_size = src->rt3_reg_table_size; (*dest)->rt3_rules = malloc(src->rt3_reg_table_size * sizeof(Dwarf_Regtable_Entry3)); if ((*dest)->rt3_rules == NULL) { free(*dest); DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } } memcpy(&(*dest)->rt3_cfa_rule, &src->rt3_cfa_rule, sizeof(Dwarf_Regtable_Entry3)); for (i = 0; i < (*dest)->rt3_reg_table_size && i < src->rt3_reg_table_size; i++) memcpy(&(*dest)->rt3_rules[i], &src->rt3_rules[i], sizeof(Dwarf_Regtable_Entry3)); for (; i < (*dest)->rt3_reg_table_size; i++) (*dest)->rt3_rules[i].dw_regnum = dbg->dbg_frame_undefined_value; return (DW_DLE_NONE); } int _dwarf_frame_get_internal_table(Dwarf_Fde fde, Dwarf_Addr pc_req, Dwarf_Regtable3 **ret_rt, Dwarf_Addr *ret_row_pc, Dwarf_Error *error) { Dwarf_Debug dbg; Dwarf_Cie cie; Dwarf_Regtable3 *rt; Dwarf_Addr row_pc; int i, ret; assert(ret_rt != NULL); dbg = fde->fde_dbg; assert(dbg != NULL); rt = dbg->dbg_internal_reg_table; /* Clear the content of regtable from previous run. */ memset(&rt->rt3_cfa_rule, 0, sizeof(Dwarf_Regtable_Entry3)); memset(rt->rt3_rules, 0, rt->rt3_reg_table_size * sizeof(Dwarf_Regtable_Entry3)); /* Set rules to initial values. */ for (i = 0; i < rt->rt3_reg_table_size; i++) rt->rt3_rules[i].dw_regnum = dbg->dbg_frame_rule_initial_value; /* Run initial instructions in CIE. */ cie = fde->fde_cie; assert(cie != NULL); ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, cie->cie_initinst, cie->cie_instlen, cie->cie_caf, cie->cie_daf, 0, ~0ULL, &row_pc, error); if (ret != DW_DLE_NONE) return (ret); /* Run instructions in FDE. */ if (pc_req >= fde->fde_initloc) { ret = _dwarf_frame_run_inst(dbg, rt, cie->cie_addrsize, fde->fde_inst, fde->fde_instlen, cie->cie_caf, cie->cie_daf, fde->fde_initloc, pc_req, &row_pc, error); if (ret != DW_DLE_NONE) return (ret); } *ret_rt = rt; *ret_row_pc = row_pc; return (DW_DLE_NONE); } void _dwarf_frame_cleanup(Dwarf_Debug dbg) { Dwarf_Regtable3 *rt; assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); if (dbg->dbg_internal_reg_table) { rt = dbg->dbg_internal_reg_table; free(rt->rt3_rules); free(rt); dbg->dbg_internal_reg_table = NULL; } if (dbg->dbg_frame) { _dwarf_frame_section_cleanup(dbg->dbg_frame); dbg->dbg_frame = NULL; } if (dbg->dbg_eh_frame) { _dwarf_frame_section_cleanup(dbg->dbg_eh_frame); dbg->dbg_eh_frame = NULL; } } int _dwarf_frame_section_load(Dwarf_Debug dbg, Dwarf_Error *error) { Dwarf_Section *ds; if ((ds = _dwarf_find_section(dbg, ".debug_frame")) != NULL) { return (_dwarf_frame_section_init(dbg, &dbg->dbg_frame, ds, 0, error)); } return (DW_DLE_NONE); } int _dwarf_frame_section_load_eh(Dwarf_Debug dbg, Dwarf_Error *error) { Dwarf_Section *ds; if ((ds = _dwarf_find_section(dbg, ".eh_frame")) != NULL) { return (_dwarf_frame_section_init(dbg, &dbg->dbg_eh_frame, ds, 1, error)); } return (DW_DLE_NONE); } void _dwarf_frame_params_init(Dwarf_Debug dbg) { /* Initialise call frame related parameters. */ dbg->dbg_frame_rule_table_size = DW_FRAME_LAST_REG_NUM; dbg->dbg_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; dbg->dbg_frame_cfa_value = DW_FRAME_CFA_COL3; dbg->dbg_frame_same_value = DW_FRAME_SAME_VAL; dbg->dbg_frame_undefined_value = DW_FRAME_UNDEFINED_VAL; } int _dwarf_frame_interal_table_init(Dwarf_Debug dbg, Dwarf_Error *error) { Dwarf_Regtable3 *rt; if (dbg->dbg_internal_reg_table != NULL) return (DW_DLE_NONE); /* Initialise internal register table. */ if ((rt = calloc(1, sizeof(Dwarf_Regtable3))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } rt->rt3_reg_table_size = dbg->dbg_frame_rule_table_size; if ((rt->rt3_rules = calloc(rt->rt3_reg_table_size, sizeof(Dwarf_Regtable_Entry3))) == NULL) { free(rt); DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } dbg->dbg_internal_reg_table = rt; return (DW_DLE_NONE); } #define _FDE_INST_INIT_SIZE 128 int _dwarf_frame_fde_add_inst(Dwarf_P_Fde fde, Dwarf_Small op, Dwarf_Unsigned val1, Dwarf_Unsigned val2, Dwarf_Error *error) { Dwarf_P_Debug dbg; uint8_t high2, low6; int ret; #define ds fde #define ds_data fde_inst #define ds_cap fde_instcap #define ds_size fde_instlen assert(fde != NULL && fde->fde_dbg != NULL); dbg = fde->fde_dbg; if (fde->fde_inst == NULL) { fde->fde_instcap = _FDE_INST_INIT_SIZE; fde->fde_instlen = 0; if ((fde->fde_inst = malloc((size_t) fde->fde_instcap)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } } assert(fde->fde_instcap != 0); RCHECK(WRITE_VALUE(op, 1)); if (op == DW_CFA_nop) return (DW_DLE_NONE); high2 = op & 0xc0; low6 = op & 0x3f; if (high2 > 0) { switch (high2) { case DW_CFA_advance_loc: case DW_CFA_restore: break; case DW_CFA_offset: RCHECK(WRITE_ULEB128(val1)); break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); return (DW_DLE_FRAME_INSTR_EXEC_ERROR); } return (DW_DLE_NONE); } switch (low6) { case DW_CFA_set_loc: RCHECK(WRITE_VALUE(val1, dbg->dbg_pointer_size)); break; case DW_CFA_advance_loc1: RCHECK(WRITE_VALUE(val1, 1)); break; case DW_CFA_advance_loc2: RCHECK(WRITE_VALUE(val1, 2)); break; case DW_CFA_advance_loc4: RCHECK(WRITE_VALUE(val1, 4)); break; case DW_CFA_offset_extended: case DW_CFA_def_cfa: case DW_CFA_register: RCHECK(WRITE_ULEB128(val1)); RCHECK(WRITE_ULEB128(val2)); break; case DW_CFA_restore_extended: case DW_CFA_undefined: case DW_CFA_same_value: case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_offset: RCHECK(WRITE_ULEB128(val1)); break; case DW_CFA_remember_state: case DW_CFA_restore_state: break; default: DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_INSTR_EXEC_ERROR); return (DW_DLE_FRAME_INSTR_EXEC_ERROR); } return (DW_DLE_NONE); gen_fail: return (ret); #undef ds #undef ds_data #undef ds_cap #undef ds_size } static int _dwarf_frame_gen_cie(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_P_Cie cie, Dwarf_Error *error) { Dwarf_Unsigned len; uint64_t offset; int ret; assert(dbg != NULL && ds != NULL && cie != NULL); cie->cie_offset = offset = ds->ds_size; cie->cie_length = 0; cie->cie_version = 1; /* Length placeholder. */ RCHECK(WRITE_VALUE(cie->cie_length, 4)); /* .debug_frame use CIE id ~0. */ RCHECK(WRITE_VALUE(~0U, 4)); /* .debug_frame version is 1. (DWARF2) */ RCHECK(WRITE_VALUE(cie->cie_version, 1)); /* Write augmentation, if present. */ if (cie->cie_augment != NULL) RCHECK(WRITE_BLOCK(cie->cie_augment, strlen((char *) cie->cie_augment) + 1)); else RCHECK(WRITE_VALUE(0, 1)); /* Write caf, daf and ra. */ RCHECK(WRITE_ULEB128(cie->cie_caf)); RCHECK(WRITE_SLEB128(cie->cie_daf)); RCHECK(WRITE_VALUE(cie->cie_ra, 1)); /* Write initial instructions, if present. */ if (cie->cie_initinst != NULL) RCHECK(WRITE_BLOCK(cie->cie_initinst, cie->cie_instlen)); /* Add padding. */ len = ds->ds_size - cie->cie_offset - 4; cie->cie_length = roundup(len, dbg->dbg_pointer_size); while (len++ < cie->cie_length) RCHECK(WRITE_VALUE(DW_CFA_nop, 1)); /* Fill in the length field. */ dbg->write(ds->ds_data, &offset, cie->cie_length, 4); return (DW_DLE_NONE); gen_fail: return (ret); } static int _dwarf_frame_gen_fde(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, Dwarf_P_Fde fde, Dwarf_Error *error) { Dwarf_Unsigned len; uint64_t offset; int ret; assert(dbg != NULL && ds != NULL && drs != NULL); assert(fde != NULL && fde->fde_cie != NULL); fde->fde_offset = offset = ds->ds_size; fde->fde_length = 0; fde->fde_cieoff = fde->fde_cie->cie_offset; /* Length placeholder. */ RCHECK(WRITE_VALUE(fde->fde_length, 4)); /* Write CIE pointer. */ RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, ds->ds_size, 0, fde->fde_cieoff, ".debug_frame", error)); /* Write FDE initial location. */ RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx, fde->fde_initloc, NULL, error)); /* * Write FDE address range. Use a pair of relocation entries if * application provided end symbol index. Otherwise write the * length without assoicating any relocation info. */ if (fde->fde_esymndx > 0) RCHECK(_dwarf_reloc_entry_add_pair(dbg, drs, ds, dbg->dbg_pointer_size, ds->ds_size, fde->fde_symndx, fde->fde_esymndx, fde->fde_initloc, fde->fde_eoff, error)); else RCHECK(WRITE_VALUE(fde->fde_adrange, dbg->dbg_pointer_size)); /* Write FDE frame instructions. */ RCHECK(WRITE_BLOCK(fde->fde_inst, fde->fde_instlen)); /* Add padding. */ len = ds->ds_size - fde->fde_offset - 4; fde->fde_length = roundup(len, dbg->dbg_pointer_size); while (len++ < fde->fde_length) RCHECK(WRITE_VALUE(DW_CFA_nop, 1)); /* Fill in the length field. */ dbg->write(ds->ds_data, &offset, fde->fde_length, 4); return (DW_DLE_NONE); gen_fail: return (ret); } int _dwarf_frame_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_P_Section ds; Dwarf_Rel_Section drs; Dwarf_P_Cie cie; Dwarf_P_Fde fde; int ret; if (STAILQ_EMPTY(&dbg->dbgp_cielist)) return (DW_DLE_NONE); /* Create .debug_frame section. */ if ((ret = _dwarf_section_init(dbg, &ds, ".debug_frame", 0, error)) != DW_DLE_NONE) goto gen_fail0; /* Create relocation section for .debug_frame */ RCHECK(_dwarf_reloc_section_init(dbg, &drs, ds, error)); /* Generate list of CIE. */ STAILQ_FOREACH(cie, &dbg->dbgp_cielist, cie_next) RCHECK(_dwarf_frame_gen_cie(dbg, ds, cie, error)); /* Generate list of FDE. */ STAILQ_FOREACH(fde, &dbg->dbgp_fdelist, fde_next) RCHECK(_dwarf_frame_gen_fde(dbg, ds, drs, fde, error)); /* Inform application the creation of .debug_frame ELF section. */ RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); /* Finalize relocation section for .debug_frame */ RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); return (DW_DLE_NONE); gen_fail: _dwarf_reloc_section_free(dbg, &drs); gen_fail0: _dwarf_section_free(dbg, &ds); return (ret); } void _dwarf_frame_pro_cleanup(Dwarf_P_Debug dbg) { Dwarf_P_Cie cie, tcie; Dwarf_P_Fde fde, tfde; assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); STAILQ_FOREACH_SAFE(cie, &dbg->dbgp_cielist, cie_next, tcie) { STAILQ_REMOVE(&dbg->dbgp_cielist, cie, _Dwarf_Cie, cie_next); if (cie->cie_augment) free(cie->cie_augment); if (cie->cie_initinst) free(cie->cie_initinst); free(cie); } dbg->dbgp_cielen = 0; STAILQ_FOREACH_SAFE(fde, &dbg->dbgp_fdelist, fde_next, tfde) { STAILQ_REMOVE(&dbg->dbgp_fdelist, fde, _Dwarf_Fde, fde_next); if (fde->fde_inst != NULL) free(fde->fde_inst); free(fde); } dbg->dbgp_fdelen = 0; } Index: stable/11/contrib/elftoolchain/libdwarf/libdwarf_lineno.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/libdwarf_lineno.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/libdwarf_lineno.c (revision 367466) @@ -1,777 +1,791 @@ /*- * Copyright (c) 2009,2010 Kai Wang * 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 "_libdwarf.h" ELFTC_VCSID("$Id: libdwarf_lineno.c 3164 2015-02-19 01:20:12Z kaiwang27 $"); static int _dwarf_lineno_add_file(Dwarf_LineInfo li, uint8_t **p, const char *compdir, Dwarf_Error *error, Dwarf_Debug dbg) { Dwarf_LineFile lf; - const char *dirname; + FILE *filepath; + const char *incdir; uint8_t *src; - int slen; + size_t slen; src = *p; if ((lf = malloc(sizeof(struct _Dwarf_LineFile))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } lf->lf_fullpath = NULL; lf->lf_fname = (char *) src; src += strlen(lf->lf_fname) + 1; lf->lf_dirndx = _dwarf_decode_uleb128(&src); if (lf->lf_dirndx > li->li_inclen) { free(lf); DWARF_SET_ERROR(dbg, error, DW_DLE_DIR_INDEX_BAD); return (DW_DLE_DIR_INDEX_BAD); } - /* Make full pathname if need. */ + /* Make a full pathname if needed. */ if (*lf->lf_fname != '/') { - dirname = compdir; + filepath = open_memstream(&lf->lf_fullpath, &slen); + if (filepath == NULL) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); + } + if (lf->lf_dirndx > 0) - dirname = li->li_incdirs[lf->lf_dirndx - 1]; - if (dirname != NULL) { - slen = strlen(dirname) + strlen(lf->lf_fname) + 2; - if ((lf->lf_fullpath = malloc(slen)) == NULL) { - free(lf); - DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); - return (DW_DLE_MEMORY); - } - snprintf(lf->lf_fullpath, slen, "%s/%s", dirname, - lf->lf_fname); + incdir = li->li_incdirs[lf->lf_dirndx - 1]; + else + incdir = NULL; + + /* + * Prepend the compilation directory if the directory table + * entry is relative. + */ + if (incdir == NULL || *incdir != '/') + fprintf(filepath, "%s/", compdir); + if (incdir != NULL) + fprintf(filepath, "%s/", incdir); + fprintf(filepath, "%s", lf->lf_fname); + if (fclose(filepath) != 0) { + free(lf); + DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); + return (DW_DLE_MEMORY); } } lf->lf_mtime = _dwarf_decode_uleb128(&src); lf->lf_size = _dwarf_decode_uleb128(&src); STAILQ_INSERT_TAIL(&li->li_lflist, lf, lf_next); li->li_lflen++; *p = src; return (DW_DLE_NONE); } static int _dwarf_lineno_run_program(Dwarf_CU cu, Dwarf_LineInfo li, uint8_t *p, uint8_t *pe, const char *compdir, Dwarf_Error *error) { Dwarf_Debug dbg; Dwarf_Line ln, tln; uint64_t address, file, line, column, opsize; int is_stmt, basic_block, end_sequence; int ret; #define RESET_REGISTERS \ do { \ address = 0; \ file = 1; \ line = 1; \ column = 0; \ is_stmt = li->li_defstmt; \ basic_block = 0; \ end_sequence = 0; \ } while(0) #define APPEND_ROW \ do { \ ln = malloc(sizeof(struct _Dwarf_Line)); \ if (ln == NULL) { \ ret = DW_DLE_MEMORY; \ DWARF_SET_ERROR(dbg, error, ret); \ goto prog_fail; \ } \ ln->ln_li = li; \ ln->ln_addr = address; \ ln->ln_symndx = 0; \ ln->ln_fileno = file; \ ln->ln_lineno = line; \ ln->ln_column = column; \ ln->ln_bblock = basic_block; \ ln->ln_stmt = is_stmt; \ ln->ln_endseq = end_sequence; \ STAILQ_INSERT_TAIL(&li->li_lnlist, ln, ln_next);\ li->li_lnlen++; \ } while(0) #define LINE(x) (li->li_lbase + (((x) - li->li_opbase) % li->li_lrange)) #define ADDRESS(x) ((((x) - li->li_opbase) / li->li_lrange) * li->li_minlen) dbg = cu->cu_dbg; /* * Set registers to their default values. */ RESET_REGISTERS; /* * Start line number program. */ while (p < pe) { if (*p == 0) { /* * Extended Opcodes. */ p++; opsize = _dwarf_decode_uleb128(&p); switch (*p) { case DW_LNE_end_sequence: p++; end_sequence = 1; APPEND_ROW; RESET_REGISTERS; break; case DW_LNE_set_address: p++; address = dbg->decode(&p, cu->cu_pointer_size); break; case DW_LNE_define_file: p++; ret = _dwarf_lineno_add_file(li, &p, compdir, error, dbg); if (ret != DW_DLE_NONE) goto prog_fail; break; default: /* Unrecognized extened opcodes. */ p += opsize; } } else if (*p > 0 && *p < li->li_opbase) { /* * Standard Opcodes. */ switch (*p++) { case DW_LNS_copy: APPEND_ROW; basic_block = 0; break; case DW_LNS_advance_pc: address += _dwarf_decode_uleb128(&p) * li->li_minlen; break; case DW_LNS_advance_line: line += _dwarf_decode_sleb128(&p); break; case DW_LNS_set_file: file = _dwarf_decode_uleb128(&p); break; case DW_LNS_set_column: column = _dwarf_decode_uleb128(&p); break; case DW_LNS_negate_stmt: is_stmt = !is_stmt; break; case DW_LNS_set_basic_block: basic_block = 1; break; case DW_LNS_const_add_pc: address += ADDRESS(255); break; case DW_LNS_fixed_advance_pc: address += dbg->decode(&p, 2); break; case DW_LNS_set_prologue_end: break; case DW_LNS_set_epilogue_begin: break; case DW_LNS_set_isa: (void) _dwarf_decode_uleb128(&p); break; default: /* Unrecognized extened opcodes. What to do? */ break; } } else { /* * Special Opcodes. */ line += LINE(*p); address += ADDRESS(*p); APPEND_ROW; basic_block = 0; p++; } } return (DW_DLE_NONE); prog_fail: STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); free(ln); } return (ret); #undef RESET_REGISTERS #undef APPEND_ROW #undef LINE #undef ADDRESS } int _dwarf_lineno_init(Dwarf_Die die, uint64_t offset, Dwarf_Error *error) { Dwarf_Debug dbg; Dwarf_Section *ds; Dwarf_CU cu; Dwarf_Attribute at; Dwarf_LineInfo li; Dwarf_LineFile lf, tlf; const char *compdir; uint64_t length, hdroff, endoff; uint8_t *p; int dwarf_size, i, ret; cu = die->die_cu; assert(cu != NULL); dbg = cu->cu_dbg; assert(dbg != NULL); if ((ds = _dwarf_find_section(dbg, ".debug_line")) == NULL) return (DW_DLE_NONE); /* * Try to find out the dir where the CU was compiled. Later we * will use the dir to create full pathnames, if need. */ compdir = NULL; at = _dwarf_attr_find(die, DW_AT_comp_dir); if (at != NULL) { switch (at->at_form) { case DW_FORM_strp: compdir = at->u[1].s; break; case DW_FORM_string: compdir = at->u[0].s; break; default: break; } } length = dbg->read(ds->ds_data, &offset, 4); if (length == 0xffffffff) { dwarf_size = 8; length = dbg->read(ds->ds_data, &offset, 8); } else dwarf_size = 4; if (length > ds->ds_size - offset) { DWARF_SET_ERROR(dbg, error, DW_DLE_DEBUG_LINE_LENGTH_BAD); return (DW_DLE_DEBUG_LINE_LENGTH_BAD); } if ((li = calloc(1, sizeof(struct _Dwarf_LineInfo))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } /* * Read in line number program header. */ li->li_length = length; endoff = offset + length; li->li_version = dbg->read(ds->ds_data, &offset, 2); /* FIXME: verify version */ li->li_hdrlen = dbg->read(ds->ds_data, &offset, dwarf_size); hdroff = offset; li->li_minlen = dbg->read(ds->ds_data, &offset, 1); if (li->li_version == 4) li->li_maxop = dbg->read(ds->ds_data, &offset, 1); li->li_defstmt = dbg->read(ds->ds_data, &offset, 1); li->li_lbase = dbg->read(ds->ds_data, &offset, 1); li->li_lrange = dbg->read(ds->ds_data, &offset, 1); li->li_opbase = dbg->read(ds->ds_data, &offset, 1); STAILQ_INIT(&li->li_lflist); STAILQ_INIT(&li->li_lnlist); if ((int)li->li_hdrlen - 5 < li->li_opbase - 1) { ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } if ((li->li_oplen = malloc(li->li_opbase)) == NULL) { ret = DW_DLE_MEMORY; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } /* * Read in std opcode arg length list. Note that the first * element is not used. */ for (i = 1; i < li->li_opbase; i++) li->li_oplen[i] = dbg->read(ds->ds_data, &offset, 1); /* * Check how many strings in the include dir string array. */ length = 0; p = ds->ds_data + offset; while (*p != '\0') { while (*p++ != '\0') ; length++; } li->li_inclen = length; /* Sanity check. */ if (p - ds->ds_data > (int) ds->ds_size) { ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } if (length != 0) { if ((li->li_incdirs = malloc(length * sizeof(char *))) == NULL) { ret = DW_DLE_MEMORY; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } } /* Fill in include dir array. */ i = 0; p = ds->ds_data + offset; while (*p != '\0') { li->li_incdirs[i++] = (char *) p; while (*p++ != '\0') ; } p++; /* * Process file list. */ while (*p != '\0') { ret = _dwarf_lineno_add_file(li, &p, compdir, error, dbg); if (ret != DW_DLE_NONE) goto fail_cleanup; if (p - ds->ds_data > (int) ds->ds_size) { ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } } p++; /* Sanity check. */ if (p - ds->ds_data - hdroff != li->li_hdrlen) { ret = DW_DLE_DEBUG_LINE_LENGTH_BAD; DWARF_SET_ERROR(dbg, error, ret); goto fail_cleanup; } /* * Process line number program. */ ret = _dwarf_lineno_run_program(cu, li, p, ds->ds_data + endoff, compdir, error); if (ret != DW_DLE_NONE) goto fail_cleanup; cu->cu_lineinfo = li; return (DW_DLE_NONE); fail_cleanup: STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, lf_next); if (lf->lf_fullpath) free(lf->lf_fullpath); free(lf); } if (li->li_oplen) free(li->li_oplen); if (li->li_incdirs) free(li->li_incdirs); free(li); return (ret); } void _dwarf_lineno_cleanup(Dwarf_LineInfo li) { Dwarf_LineFile lf, tlf; Dwarf_Line ln, tln; if (li == NULL) return; STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, lf_next); if (lf->lf_fullpath) free(lf->lf_fullpath); free(lf); } STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); free(ln); } if (li->li_oplen) free(li->li_oplen); if (li->li_incdirs) free(li->li_incdirs); if (li->li_lnarray) free(li->li_lnarray); if (li->li_lfnarray) free(li->li_lfnarray); free(li); } static int _dwarf_lineno_gen_program(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, Dwarf_Error * error) { Dwarf_LineInfo li; Dwarf_Line ln; Dwarf_Unsigned address, file, line, spc; Dwarf_Unsigned addr0, maddr; Dwarf_Signed line0, column; int is_stmt, basic_block; int need_copy; int ret; #define RESET_REGISTERS \ do { \ address = 0; \ file = 1; \ line = 1; \ column = 0; \ is_stmt = li->li_defstmt; \ basic_block = 0; \ } while(0) li = dbg->dbgp_lineinfo; maddr = (255 - li->li_opbase) / li->li_lrange; RESET_REGISTERS; STAILQ_FOREACH(ln, &li->li_lnlist, ln_next) { if (ln->ln_symndx > 0) { /* * Generate DW_LNE_set_address extended op. */ RCHECK(WRITE_VALUE(0, 1)); RCHECK(WRITE_ULEB128(dbg->dbg_pointer_size + 1)); RCHECK(WRITE_VALUE(DW_LNE_set_address, 1)); RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, dbg->dbg_pointer_size, ds->ds_size, ln->ln_symndx, ln->ln_addr, NULL, error)); address = ln->ln_addr; continue; } else if (ln->ln_endseq) { addr0 = (ln->ln_addr - address) / li->li_minlen; if (addr0 != 0) { RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); RCHECK(WRITE_ULEB128(addr0)); } /* * Generate DW_LNE_end_sequence. */ RCHECK(WRITE_VALUE(0, 1)); RCHECK(WRITE_ULEB128(1)); RCHECK(WRITE_VALUE(DW_LNE_end_sequence, 1)); RESET_REGISTERS; continue; } /* * Generate standard opcodes for file, column, is_stmt or * basic_block changes. */ if (ln->ln_fileno != file) { RCHECK(WRITE_VALUE(DW_LNS_set_file, 1)); RCHECK(WRITE_ULEB128(ln->ln_fileno)); file = ln->ln_fileno; } if (ln->ln_column != column) { RCHECK(WRITE_VALUE(DW_LNS_set_column, 1)); RCHECK(WRITE_ULEB128(ln->ln_column)); column = ln->ln_column; } if (ln->ln_stmt != is_stmt) { RCHECK(WRITE_VALUE(DW_LNS_negate_stmt, 1)); is_stmt = ln->ln_stmt; } if (ln->ln_bblock && !basic_block) { RCHECK(WRITE_VALUE(DW_LNS_set_basic_block, 1)); basic_block = 1; } /* * Calculate address and line number change. */ addr0 = (ln->ln_addr - address) / li->li_minlen; line0 = ln->ln_lineno - line; if (addr0 == 0 && line0 == 0) continue; /* * Check if line delta is with the range and if the special * opcode can be used. */ assert(li->li_lbase <= 0); if (line0 >= li->li_lbase && line0 <= li->li_lbase + li->li_lrange - 1) { spc = (line0 - li->li_lbase) + (li->li_lrange * addr0) + li->li_opbase; if (spc <= 255) { RCHECK(WRITE_VALUE(spc, 1)); basic_block = 0; goto next_line; } } /* Generate DW_LNS_advance_line for line number change. */ if (line0 != 0) { RCHECK(WRITE_VALUE(DW_LNS_advance_line, 1)); RCHECK(WRITE_SLEB128(line0)); line0 = 0; need_copy = 1; } else need_copy = basic_block; if (addr0 != 0) { /* See if it can be handled by DW_LNS_const_add_pc. */ spc = (line0 - li->li_lbase) + (li->li_lrange * (addr0 - maddr)) + li->li_opbase; if (addr0 >= maddr && spc <= 255) { RCHECK(WRITE_VALUE(DW_LNS_const_add_pc, 1)); RCHECK(WRITE_VALUE(spc, 1)); } else { /* Otherwise we use DW_LNS_advance_pc. */ RCHECK(WRITE_VALUE(DW_LNS_advance_pc, 1)); RCHECK(WRITE_ULEB128(addr0)); } } if (need_copy) { RCHECK(WRITE_VALUE(DW_LNS_copy, 1)); basic_block = 0; } next_line: address = ln->ln_addr; line = ln->ln_lineno; } return (DW_DLE_NONE); gen_fail: return (ret); #undef RESET_REGISTERS } static uint8_t _dwarf_get_minlen(Dwarf_P_Debug dbg) { assert(dbg != NULL); switch (dbg->dbgp_isa) { case DW_ISA_ARM: return (2); case DW_ISA_X86: case DW_ISA_X86_64: return (1); default: return (4); } } static uint8_t oplen[] = {0, 1, 1, 1, 1, 0, 0, 0, 1}; int _dwarf_lineno_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_LineInfo li; Dwarf_LineFile lf; Dwarf_P_Section ds; Dwarf_Rel_Section drs; Dwarf_Unsigned offset; int i, ret; assert(dbg != NULL && dbg->dbgp_lineinfo != NULL); li = dbg->dbgp_lineinfo; if (STAILQ_EMPTY(&li->li_lnlist)) return (DW_DLE_NONE); li->li_length = 0; li->li_version = 2; li->li_hdrlen = 0; li->li_minlen = _dwarf_get_minlen(dbg); li->li_defstmt = 1; li->li_lbase = -5; li->li_lrange = 14; li->li_opbase = 10; /* Create .debug_line section. */ if ((ret = _dwarf_section_init(dbg, &ds, ".debug_line", 0, error)) != DW_DLE_NONE) return (ret); /* Create relocation section for .debug_line */ if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != DW_DLE_NONE) goto gen_fail1; /* Length placeholder. (We only use 32-bit DWARF format) */ RCHECK(WRITE_VALUE(0, 4)); /* Write line number dwarf version. (DWARF2) */ RCHECK(WRITE_VALUE(li->li_version, 2)); /* Header length placeholder. */ offset = ds->ds_size; RCHECK(WRITE_VALUE(li->li_hdrlen, 4)); /* Write minimum instruction length. */ RCHECK(WRITE_VALUE(li->li_minlen, 1)); /* * Write initial value for is_stmt. XXX Which default value we * should use? */ RCHECK(WRITE_VALUE(li->li_defstmt, 1)); /* * Write line_base and line_range. FIXME These value needs to be * fine tuned. */ RCHECK(WRITE_VALUE(li->li_lbase, 1)); RCHECK(WRITE_VALUE(li->li_lrange, 1)); /* Write opcode_base. (DWARF2) */ RCHECK(WRITE_VALUE(li->li_opbase, 1)); /* Write standard op length array. */ RCHECK(WRITE_BLOCK(oplen, sizeof(oplen) / sizeof(oplen[0]))); /* Write the list of include directories. */ for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) RCHECK(WRITE_STRING(li->li_incdirs[i])); RCHECK(WRITE_VALUE(0, 1)); /* Write the list of filenames. */ STAILQ_FOREACH(lf, &li->li_lflist, lf_next) { RCHECK(WRITE_STRING(lf->lf_fname)); RCHECK(WRITE_ULEB128(lf->lf_dirndx)); RCHECK(WRITE_ULEB128(lf->lf_mtime)); RCHECK(WRITE_ULEB128(lf->lf_size)); } RCHECK(WRITE_VALUE(0, 1)); /* Fill in the header length. */ li->li_hdrlen = ds->ds_size - offset - 4; dbg->write(ds->ds_data, &offset, li->li_hdrlen, 4); /* Generate the line number program. */ RCHECK(_dwarf_lineno_gen_program(dbg, ds, drs, error)); /* Fill in the length of this line info. */ li->li_length = ds->ds_size - 4; offset = 0; dbg->write(ds->ds_data, &offset, li->li_length, 4); /* Notify the creation of .debug_line ELF section. */ RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); /* Finalize relocation section for .debug_line. */ RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); return (DW_DLE_NONE); gen_fail: _dwarf_reloc_section_free(dbg, &drs); gen_fail1: _dwarf_section_free(dbg, &ds); return (ret); } void _dwarf_lineno_pro_cleanup(Dwarf_P_Debug dbg) { Dwarf_LineInfo li; Dwarf_LineFile lf, tlf; Dwarf_Line ln, tln; int i; assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); if (dbg->dbgp_lineinfo == NULL) return; li = dbg->dbgp_lineinfo; STAILQ_FOREACH_SAFE(lf, &li->li_lflist, lf_next, tlf) { STAILQ_REMOVE(&li->li_lflist, lf, _Dwarf_LineFile, lf_next); if (lf->lf_fname) free(lf->lf_fname); free(lf); } STAILQ_FOREACH_SAFE(ln, &li->li_lnlist, ln_next, tln) { STAILQ_REMOVE(&li->li_lnlist, ln, _Dwarf_Line, ln_next); free(ln); } if (li->li_incdirs) { for (i = 0; (Dwarf_Unsigned) i < li->li_inclen; i++) free(li->li_incdirs[i]); free(li->li_incdirs); } free(li); dbg->dbgp_lineinfo = NULL; } Index: stable/11/contrib/elftoolchain/libdwarf/libdwarf_reloc.c =================================================================== --- stable/11/contrib/elftoolchain/libdwarf/libdwarf_reloc.c (revision 367465) +++ stable/11/contrib/elftoolchain/libdwarf/libdwarf_reloc.c (revision 367466) @@ -1,493 +1,499 @@ /*- * Copyright (c) 2010 Kai Wang * 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 "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_reloc.c 3578 2017-09-14 02:21:28Z emaste $"); +ELFTC_VCSID("$Id: libdwarf_reloc.c 3741 2019-06-07 06:32:01Z jkoshy $"); Dwarf_Unsigned _dwarf_get_reloc_type(Dwarf_P_Debug dbg, int is64) { assert(dbg != NULL); switch (dbg->dbgp_isa) { case DW_ISA_AARCH64: return (is64 ? R_AARCH64_ABS64 : R_AARCH64_ABS32); case DW_ISA_X86: return (R_386_32); case DW_ISA_X86_64: return (is64 ? R_X86_64_64 : R_X86_64_32); case DW_ISA_SPARC: return (is64 ? R_SPARC_UA64 : R_SPARC_UA32); case DW_ISA_PPC: - return (R_PPC_ADDR32); + return (is64 ? R_PPC64_ADDR64 : R_PPC_ADDR32); case DW_ISA_ARM: return (R_ARM_ABS32); case DW_ISA_MIPS: return (is64 ? R_MIPS_64 : R_MIPS_32); case DW_ISA_RISCV: return (is64 ? R_RISCV_64 : R_RISCV_32); case DW_ISA_IA64: return (is64 ? R_IA_64_DIR64LSB : R_IA_64_DIR32LSB); default: break; } return (0); /* NOT REACHED */ } int _dwarf_get_reloc_size(Dwarf_Debug dbg, Dwarf_Unsigned rel_type) { switch (dbg->dbg_machine) { case EM_NONE: break; case EM_AARCH64: if (rel_type == R_AARCH64_ABS32) return (4); else if (rel_type == R_AARCH64_ABS64) return (8); break; case EM_ARM: if (rel_type == R_ARM_ABS32) return (4); break; case EM_386: case EM_IAMCU: if (rel_type == R_386_32) return (4); break; case EM_X86_64: if (rel_type == R_X86_64_32) return (4); else if (rel_type == R_X86_64_64) return (8); break; case EM_SPARC: if (rel_type == R_SPARC_UA32) return (4); else if (rel_type == R_SPARC_UA64) return (8); break; case EM_PPC: if (rel_type == R_PPC_ADDR32) return (4); + break; + case EM_PPC64: + if (rel_type == R_PPC_ADDR32) + return (4); + else if (rel_type == R_PPC64_ADDR64) + return (8); break; case EM_MIPS: if (rel_type == R_MIPS_32) return (4); else if (rel_type == R_MIPS_64) return (8); break; case EM_RISCV: if (rel_type == R_RISCV_32) return (4); else if (rel_type == R_RISCV_64) return (8); break; case EM_IA_64: if (rel_type == R_IA_64_SECREL32LSB) return (4); else if (rel_type == R_IA_64_DIR64LSB) return (8); break; default: break; } /* unknown relocation. */ return (0); } int _dwarf_reloc_section_init(Dwarf_P_Debug dbg, Dwarf_Rel_Section *drsp, Dwarf_P_Section ref, Dwarf_Error *error) { Dwarf_Rel_Section drs; char name[128]; int pseudo; assert(dbg != NULL && drsp != NULL && ref != NULL); if ((drs = calloc(1, sizeof(struct _Dwarf_Rel_Section))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } drs->drs_ref = ref; /* * FIXME The logic here is most likely wrong. It should * be the ISA that determines relocation type. */ if (dbg->dbgp_flags & DW_DLC_SIZE_64) drs->drs_addend = 1; else drs->drs_addend = 0; if (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) pseudo = 1; else pseudo = 0; snprintf(name, sizeof(name), "%s%s", drs->drs_addend ? ".rela" : ".rel", ref->ds_name); if (_dwarf_section_init(dbg, &drs->drs_ds, name, pseudo, error) != DW_DLE_NONE) { free(drs); DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INIT(&drs->drs_dre); STAILQ_INSERT_TAIL(&dbg->dbgp_drslist, drs, drs_next); dbg->dbgp_drscnt++; *drsp = drs; return (DW_DLE_NONE); } void _dwarf_reloc_section_free(Dwarf_P_Debug dbg, Dwarf_Rel_Section *drsp) { Dwarf_Rel_Section drs, tdrs; Dwarf_Rel_Entry dre, tdre; assert(dbg != NULL && drsp != NULL); if (*drsp == NULL) return; STAILQ_FOREACH_SAFE(drs, &dbg->dbgp_drslist, drs_next, tdrs) { if (drs != *drsp) continue; STAILQ_REMOVE(&dbg->dbgp_drslist, drs, _Dwarf_Rel_Section, drs_next); STAILQ_FOREACH_SAFE(dre, &drs->drs_dre, dre_next, tdre) { STAILQ_REMOVE(&drs->drs_dre, dre, _Dwarf_Rel_Entry, dre_next); free(dre); } if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) _dwarf_section_free(dbg, &drs->drs_ds); else { if (drs->drs_ds->ds_name) free(drs->drs_ds->ds_name); free(drs->drs_ds); } free(drs); *drsp = NULL; dbg->dbgp_drscnt--; break; } } int _dwarf_reloc_entry_add(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, Dwarf_P_Section ds, unsigned char type, unsigned char length, Dwarf_Unsigned offset, Dwarf_Unsigned symndx, Dwarf_Unsigned addend, const char *secname, Dwarf_Error *error) { Dwarf_Rel_Entry dre; Dwarf_Unsigned reloff; int ret; assert(drs != NULL); assert(offset <= ds->ds_size); reloff = offset; /* * If the DW_DLC_SYMBOLIC_RELOCATIONS flag is set or ElfXX_Rel * is used instead of ELfXX_Rela, we need to write the addend * in the storage unit to be relocated. Otherwise write 0 in the * storage unit and the addend will be written into relocation * section later. */ if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) || drs->drs_addend == 0) ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, addend, length, error); else ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, 0, length, error); if (ret != DW_DLE_NONE) return (ret); if (offset > ds->ds_size) ds->ds_size = offset; if ((dre = calloc(1, sizeof(struct _Dwarf_Rel_Entry))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INSERT_TAIL(&drs->drs_dre, dre, dre_next); dre->dre_type = type; dre->dre_length = length; dre->dre_offset = reloff; dre->dre_symndx = symndx; dre->dre_addend = addend; dre->dre_secname = secname; drs->drs_drecnt++; return (DW_DLE_NONE); } int _dwarf_reloc_entry_add_pair(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, Dwarf_P_Section ds, unsigned char length, Dwarf_Unsigned offset, Dwarf_Unsigned symndx, Dwarf_Unsigned esymndx, Dwarf_Unsigned symoff, Dwarf_Unsigned esymoff, Dwarf_Error *error) { Dwarf_Rel_Entry dre; Dwarf_Unsigned reloff; int ret; assert(drs != NULL); assert(offset <= ds->ds_size); assert(dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS); reloff = offset; /* Write net offset into section stream. */ ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &offset, esymoff - symoff, length, error); if (ret != DW_DLE_NONE) return (ret); if (offset > ds->ds_size) ds->ds_size = offset; if ((dre = calloc(2, sizeof(struct _Dwarf_Rel_Entry))) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } STAILQ_INSERT_TAIL(&drs->drs_dre, &dre[0], dre_next); STAILQ_INSERT_TAIL(&drs->drs_dre, &dre[1], dre_next); dre[0].dre_type = dwarf_drt_first_of_length_pair; dre[0].dre_length = length; dre[0].dre_offset = reloff; dre[0].dre_symndx = symndx; dre[0].dre_addend = 0; dre[0].dre_secname = NULL; dre[1].dre_type = dwarf_drt_second_of_length_pair; dre[1].dre_length = length; dre[1].dre_offset = reloff; dre[1].dre_symndx = esymndx; dre[1].dre_addend = 0; dre[1].dre_secname = NULL; drs->drs_drecnt += 2; return (DW_DLE_NONE); } int _dwarf_reloc_section_finalize(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, Dwarf_Error *error) { Dwarf_P_Section ds; Dwarf_Unsigned unit; int ret, size; assert(dbg != NULL && drs != NULL && drs->drs_ds != NULL && drs->drs_ref != NULL); ds = drs->drs_ds; /* * Calculate the size (in bytes) of the relocation section. */ if (dbg->dbgp_flags & DW_DLC_SIZE_64) unit = drs->drs_addend ? sizeof(Elf64_Rela) : sizeof(Elf64_Rel); else unit = drs->drs_addend ? sizeof(Elf32_Rela) : sizeof(Elf32_Rel); assert(ds->ds_size == 0); size = drs->drs_drecnt * unit; /* * Discard this relocation section if there is no entry in it. */ if (size == 0) { _dwarf_reloc_section_free(dbg, &drs); return (DW_DLE_NONE); } /* * If we are under stream mode, realloc the section data block to * this size. */ if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { ds->ds_cap = size; if ((ds->ds_data = realloc(ds->ds_data, (size_t) ds->ds_cap)) == NULL) { DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); return (DW_DLE_MEMORY); } } /* * Notify the application the creation of this relocation section. * Note that the section link here should point to the .symtab * section, we set it to 0 since we have no way to know .symtab * section index. */ ret = _dwarf_pro_callback(dbg, ds->ds_name, size, drs->drs_addend ? SHT_RELA : SHT_REL, 0, 0, drs->drs_ref->ds_ndx, &ds->ds_symndx, NULL); if (ret < 0) { DWARF_SET_ERROR(dbg, error, DW_DLE_ELF_SECT_ERR); return (DW_DLE_ELF_SECT_ERR); } ds->ds_ndx = ret; return (DW_DLE_NONE); } int _dwarf_reloc_section_gen(Dwarf_P_Debug dbg, Dwarf_Rel_Section drs, Dwarf_Error *error) { Dwarf_Rel_Entry dre; Dwarf_P_Section ds; Dwarf_Unsigned type; int ret; assert((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0); assert(drs->drs_ds != NULL && drs->drs_ds->ds_size == 0); assert(!STAILQ_EMPTY(&drs->drs_dre)); ds = drs->drs_ds; STAILQ_FOREACH(dre, &drs->drs_dre, dre_next) { assert(dre->dre_length == 4 || dre->dre_length == 8); type = _dwarf_get_reloc_type(dbg, dre->dre_length == 8); if (dbg->dbgp_flags & DW_DLC_SIZE_64) { /* Write r_offset (8 bytes) */ ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, dre->dre_offset, 8, error); if (ret != DW_DLE_NONE) return (ret); /* Write r_info (8 bytes) */ ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, ELF64_R_INFO(dre->dre_symndx, type), 8, error); if (ret != DW_DLE_NONE) return (ret); /* Write r_addend (8 bytes) */ if (drs->drs_addend) { ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, dre->dre_addend, 8, error); if (ret != DW_DLE_NONE) return (ret); } } else { /* Write r_offset (4 bytes) */ ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, dre->dre_offset, 4, error); if (ret != DW_DLE_NONE) return (ret); /* Write r_info (4 bytes) */ ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, ELF32_R_INFO(dre->dre_symndx, type), 4, error); if (ret != DW_DLE_NONE) return (ret); /* Write r_addend (4 bytes) */ if (drs->drs_addend) { ret = dbg->write_alloc(&ds->ds_data, &ds->ds_cap, &ds->ds_size, dre->dre_addend, 4, error); if (ret != DW_DLE_NONE) return (ret); } } } assert(ds->ds_size == ds->ds_cap); return (DW_DLE_NONE); } int _dwarf_reloc_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) { Dwarf_Rel_Section drs; Dwarf_Rel_Entry dre; Dwarf_P_Section ds; int ret; STAILQ_FOREACH(drs, &dbg->dbgp_drslist, drs_next) { /* * Update relocation entries: translate any section name * reference to section symbol index. */ STAILQ_FOREACH(dre, &drs->drs_dre, dre_next) { if (dre->dre_secname == NULL) continue; ds = _dwarf_pro_find_section(dbg, dre->dre_secname); assert(ds != NULL && ds->ds_symndx != 0); dre->dre_symndx = ds->ds_symndx; } /* * Generate ELF relocation section if we are under stream * mode. */ if ((dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) == 0) { ret = _dwarf_reloc_section_gen(dbg, drs, error); if (ret != DW_DLE_NONE) return (ret); } } return (DW_DLE_NONE); } void _dwarf_reloc_cleanup(Dwarf_P_Debug dbg) { Dwarf_Rel_Section drs, tdrs; Dwarf_Rel_Entry dre, tdre; assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); STAILQ_FOREACH_SAFE(drs, &dbg->dbgp_drslist, drs_next, tdrs) { STAILQ_REMOVE(&dbg->dbgp_drslist, drs, _Dwarf_Rel_Section, drs_next); free(drs->drs_drd); STAILQ_FOREACH_SAFE(dre, &drs->drs_dre, dre_next, tdre) { STAILQ_REMOVE(&drs->drs_dre, dre, _Dwarf_Rel_Entry, dre_next); free(dre); } if (dbg->dbgp_flags & DW_DLC_SYMBOLIC_RELOCATIONS) { if (drs->drs_ds) { if (drs->drs_ds->ds_name) free(drs->drs_ds->ds_name); free(drs->drs_ds); } } free(drs); } dbg->dbgp_drscnt = 0; dbg->dbgp_drspos = NULL; } Index: stable/11/contrib/elftoolchain/libelf/Makefile =================================================================== --- stable/11/contrib/elftoolchain/libelf/Makefile (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/Makefile (revision 367466) @@ -1,166 +1,167 @@ -# $Id: Makefile 3594 2018-04-11 18:26:50Z jkoshy $ +# $Id: Makefile 3632 2018-10-10 21:12:43Z jkoshy $ TOP= .. 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_open.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_mips64el.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_elfmachine.c \ libelf_extended.c \ libelf_memory.c \ libelf_open.c \ libelf_phdr.c \ libelf_shdr.c \ libelf_xlate.c \ ${GENSRCS} INCS= libelf.h gelf.h INCSDIR= /usr/include 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_open.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 \ elf_open.3 elf_openmemory.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" Index: stable/11/contrib/elftoolchain/libelf/Version.map =================================================================== --- stable/11/contrib/elftoolchain/libelf/Version.map (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/Version.map (revision 367466) @@ -1,96 +1,103 @@ /* $Id: Version.map 2574 2012-09-11 15:11:59Z jkoshy $ */ R1.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_getphdrnum; elf_getphnum; elf_getscn; elf_getshdrnum; elf_getshdrstrndx; elf_getshnum; elf_getshstrndx; elf_hash; elf_kind; elf_memory; elf_ndxscn; elf_newdata; elf_newscn; elf_next; elf_nextscn; elf_open; elf_openmemory; 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; +}; + +R1.1 { +global: + elf32_getchdr; + elf64_getchdr; + gelf_getchdr; local: *; -}; +} R1.0; Index: stable/11/contrib/elftoolchain/libelf/_libelf.h =================================================================== --- stable/11/contrib/elftoolchain/libelf/_libelf.h (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/_libelf.h (revision 367466) @@ -1,242 +1,250 @@ /*- * 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 3174 2015-03-27 17:13:41Z emaste $ + * $Id: _libelf.h 3738 2019-05-05 21:49:06Z jkoshy $ */ #ifndef __LIBELF_H_ #define __LIBELF_H_ #include +#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; unsigned 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_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) | \ ((O) << LIBELF_OS_ERROR_SHIFT)) #define LIBELF_SET_ERROR(E, O) do { \ LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O)); \ } 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 0x00FFFFU /* Flags defined by the API. */ #define LIBELF_F_AR_HEADER 0x010000U /* translated header available */ #define LIBELF_F_AR_VARIANT_SVR4 0x020000U /* BSD style ar(1) archive */ #define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */ #define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */ #define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */ #define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */ #define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */ +RB_HEAD(scntree, _Elf_Scn); +RB_PROTOTYPE(scntree, _Elf_Scn, e_scn, elfscn_cmp); + 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 */ unsigned char *e_rawfile; /* uninterpreted bytes */ - size_t e_rawsize; /* size of uninterpreted bytes */ + off_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 */ unsigned 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; unsigned char *e_rawstrtab; /* file name strings */ size_t e_rawstrtabsz; unsigned 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 */ + struct scntree e_scn; /* sections */ 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; }; /* * The internal descriptor wrapping the "Elf_Data" type. */ struct _Libelf_Data { Elf_Data d_data; /* The exported descriptor. */ Elf_Scn *d_scn; /* The containing section */ unsigned int d_flags; STAILQ_ENTRY(_Libelf_Data) d_next; }; struct _Elf_Scn { union { Elf32_Shdr s_shdr32; Elf64_Shdr s_shdr64; } s_shdr; STAILQ_HEAD(, _Libelf_Data) s_data; /* translated data */ STAILQ_HEAD(, _Libelf_Data) s_rawdata; /* raw data */ - STAILQ_ENTRY(_Elf_Scn) s_next; + RB_ENTRY(_Elf_Scn) s_tree; 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 }; /* * The LIBELF_COPY macros are used to copy fields from a GElf_* * structure to their 32-bit counterparts, while checking for out of * range values. * * - LIBELF_COPY_U32 :: copy an unsigned 32 bit field. * - LIBELF_COPY_S32 :: copy a signed 32 bit field. */ #define LIBELF_COPY_U32(DST, SRC, NAME) do { \ if ((SRC)->NAME > UINT32_MAX) { \ LIBELF_SET_ERROR(RANGE, 0); \ return (0); \ } \ (DST)->NAME = (SRC)->NAME & 0xFFFFFFFFU; \ } while (0) #define LIBELF_COPY_S32(DST, SRC, NAME) do { \ if ((SRC)->NAME > INT32_MAX || \ (SRC)->NAME < INT32_MIN) { \ LIBELF_SET_ERROR(RANGE, 0); \ return (0); \ } \ (DST)->NAME = (int32_t) (SRC)->NAME; \ } while (0) /* * Function Prototypes. */ +typedef int _libelf_translator_function(unsigned char *_dst, size_t dsz, + unsigned char *_src, size_t _cnt, int _byteswap); + #ifdef __cplusplus extern "C" { #endif struct _Libelf_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, int _reporterror); Elf *_libelf_ar_open_member(int _fd, Elf_Cmd _c, Elf *_ar); Elf_Arsym *_libelf_ar_process_bsd_symtab(Elf *_ar, size_t *_dst); Elf_Arsym *_libelf_ar_process_svr4_symtab(Elf *_ar, size_t *_dst); long _libelf_checksum(Elf *_e, int _elfclass); void *_libelf_ehdr(Elf *_e, int _elfclass, int _allocate); +int _libelf_elfmachine(Elf *_e); unsigned 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)) - (unsigned char *_dst, size_t dsz, unsigned char *_src, - size_t _cnt, int _byteswap); +_libelf_translator_function *_libelf_get_translator(Elf_Type _t, + int _direction, int _elfclass, int _elfmachine); +void *_libelf_getchdr(Elf_Scn *_e, int _elfclass); 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_is_mips64el(Elf *e); int _libelf_load_section_headers(Elf *e, void *ehdr); unsigned int _libelf_malign(Elf_Type _t, int _elfclass); Elf *_libelf_memory(unsigned char *_image, size_t _sz, int _reporterror); size_t _libelf_msize(Elf_Type _t, int _elfclass, unsigned int _version); void *_libelf_newphdr(Elf *_e, int _elfclass, size_t _count); Elf *_libelf_open_object(int _fd, Elf_Cmd _c, int _reporterror); Elf64_Xword _libelf_mips64el_r_info_tof(Elf64_Xword r_info); Elf64_Xword _libelf_mips64el_r_info_tom(Elf64_Xword r_info); struct _Libelf_Data *_libelf_release_data(struct _Libelf_Data *_d); -Elf *_libelf_release_elf(Elf *_e); +void _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); + unsigned int _encoding, int _elfclass, int _elfmachine, int _direction); int _libelf_xlate_shtype(uint32_t _sht); #ifdef __cplusplus } #endif #endif /* __LIBELF_H_ */ Index: stable/11/contrib/elftoolchain/libelf/_libelf_config.h =================================================================== --- stable/11/contrib/elftoolchain/libelf/_libelf_config.h (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/_libelf_config.h (revision 367466) @@ -1,189 +1,205 @@ /*- * 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 3566 2017-08-31 02:28:40Z emaste $ + * $Id: _libelf_config.h 3764 2019-06-28 21:44:46Z emaste $ */ #if defined(__APPLE__) || defined(__DragonFly__) #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 #endif #endif /* __DragonFly__ */ #ifdef __FreeBSD__ /* * 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(__aarch64__) #define LIBELF_ARCH EM_AARCH64 #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(__powerpc64__) + +#define LIBELF_ARCH EM_PPC64 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define LIBELF_BYTEORDER ELFDATA2LSB +#else +#define LIBELF_BYTEORDER ELFDATA2MSB +#endif +#define LIBELF_CLASS ELFCLASS64 + #elif defined(__powerpc__) #define LIBELF_ARCH EM_PPC #define LIBELF_BYTEORDER ELFDATA2MSB #define LIBELF_CLASS ELFCLASS32 + +#elif defined(__riscv64) + +#define LIBELF_ARCH EM_RISCV +#define LIBELF_BYTEORDER ELFDATA2LSB +#define LIBELF_CLASS ELFCLASS64 #elif defined(__riscv64) #define LIBELF_ARCH EM_RISCV #define LIBELF_BYTEORDER ELFDATA2LSB #define LIBELF_CLASS ELFCLASS64 #elif defined(__sparc__) #define LIBELF_ARCH EM_SPARCV9 #define LIBELF_BYTEORDER ELFDATA2MSB #define LIBELF_CLASS ELFCLASS64 #else #error Unknown FreeBSD architecture. #endif #endif /* __FreeBSD__ */ /* * Definitions for Minix3. */ #ifdef __minix #define LIBELF_ARCH EM_386 #define LIBELF_BYTEORDER ELFDATA2LSB #define LIBELF_CLASS ELFCLASS32 #endif /* __minix */ #ifdef __NetBSD__ #include #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__ */ #if defined(__OpenBSD__) #include #define LIBELF_ARCH ELF_TARG_MACH #define LIBELF_BYTEORDER ELF_TARG_DATA #define LIBELF_CLASS ELF_TARG_CLASS #endif /* * 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__) */ #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 #endif /* defined(__linux__) || defined(__GNU__) || defined(__GLIBC__) */ Index: stable/11/contrib/elftoolchain/libelf/elf.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf.3 (revision 367466) @@ -1,611 +1,626 @@ -.\" Copyright (c) 2006-2008,2011 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2006-2008,2011,2019 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 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: elf.3 3743 2019-06-12 19:36:30Z jkoshy $ .\" -.Dd July 28, 2014 -.Os +.Dd June 12, 2019 .Dt ELF 3 +.Os .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. +to and from these representations. +It also provides higher-level APIs +.Xr ( gelf_xlatetof 3 , +.Xr gelf_xlatetom 3 ) +that retrieve and store data from the ELF object in a class-agnostic +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 +.Vt 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 within the containing section where this descriptor's 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 +descriptors are usually used in conjunction 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. +descriptors represent sections in an ELF object. +These descriptors are opaque and contain no application modifiable +fields. .Pp -They are retrieved using the +The +.Vt Elf_Scn +descriptor for a specific section in an ELF object can be +retrieved using the .Fn elf_getscn function. -An application may iterate through the existing sections of an ELF -object using the +The sections contained in an ELF object can be traversed using the .Fn elf_nextscn function. -New sections may be allocated using the +New sections are allocated using the .Fn elf_newscn function. .Pp The -.Vt Elf_Scn -descriptor is opaque and contains no application modifiable fields. +.Vt Elf_Data +descriptors associated with a given section can be retrieved +using the +.Fn elf_getdata +function. +New data descriptors can be added to a section +descriptor using the +.Fn elf_newdata +function. +The untranslated +.Dq file +representation of data in a section can be retrieved using the +.Fn elf_rawdata +function. .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_GNU_HASH Ta Dv ELF_T_GNUHASH Ta GNU hash sections. .It Dv SHT_GNU_LIBLIST Ta Dv ELF_T_WORD Ta List of libraries to be pre-linked. .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_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_SUNW_dof Ta Dv ELF_T_BYTE Ta Xo Used by .Xr dtrace 1 . .Xc .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. .It Dv SHT_SUNW_verdef Ta Dv ELF_T_VDEF Ta Xo Same as .Dv SHT_GNU_verdef . .Xc .It Dv SHT_SUNW_verneed Ta Dv ELF_T_VNEED Ta Xo Same as .Dv SHT_GNU_verneed . .Xc .It Dv SHT_SUNW_versym Ta Dv ELF_T_HALF Ta Xo Same as .Dv SHT_GNU_versym . .Xc .El .Pp Section types in the range -.Ns [ Dv SHT_LOOS , +.Dv [ SHT_LOOS , .Dv SHT_HIUSER ] are otherwise considered to be of type .Dv ELF_T_BYTE . .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 +.Bl -tag -compact -width indent .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 +.Bl -tag -compact -width indent .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 section. .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 +.Bl -tag -compact -width indent .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 +.Bl -tag -compact -width indent .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 +.Bl -tag -compact -width indent .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 +.It Fn elf_getphdrnum +Retrieve the number of program headers in an ELF object. +.It Fn elf_getshdrnum Retrieve the number of sections in an ELF object. -.It Fn elf_getshstrndx +.It Fn elf_getshdrstrndx 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 ar 5 , .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 +The original +.Nm +API was developed for +.At V . +The current implementation of the API appeared in .Fx 7.0 . .Sh AUTHORS The ELF library was written by .An Joseph Koshy Aq Mt jkoshy@FreeBSD.org . Index: stable/11/contrib/elftoolchain/libelf/elf_begin.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_begin.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_begin.3 (revision 367466) @@ -1,315 +1,315 @@ .\" 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 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: elf_begin.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd December 11, 2011 -.Os .Dt ELF_BEGIN 3 +.Os .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 .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 . .It Bq Er ELF_E_VERSION The ELF object referenced by argument .Ar fd was of an unsupported ELF version. .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 Index: stable/11/contrib/elftoolchain/libelf/elf_cntl.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_cntl.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_cntl.3 (revision 367466) @@ -1,111 +1,111 @@ .\" 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 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: elf_cntl.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 9, 2006 -.Os .Dt ELF_CNTL 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_data.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_data.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_data.c (revision 367466) @@ -1,276 +1,280 @@ /*- * 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 "_libelf.h" -ELFTC_VCSID("$Id: elf_data.c 3466 2016-05-11 18:35:44Z emaste $"); +ELFTC_VCSID("$Id: elf_data.c 3732 2019-04-22 11:08:38Z jkoshy $"); Elf_Data * elf_getdata(Elf_Scn *s, Elf_Data *ed) { Elf *e; unsigned int sh_type; int elfclass, elftype; size_t count, fsz, msz; struct _Libelf_Data *d; - uint64_t sh_align, sh_offset, sh_size; - int (*xlate)(unsigned char *_d, size_t _dsz, unsigned char *_s, - size_t _c, int _swap); + uint64_t sh_align, sh_offset, sh_size, raw_size; + _libelf_translator_function *xlate; d = (struct _Libelf_Data *) ed; 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->d_data); if (d != NULL) - return (&STAILQ_NEXT(d, d_next)->d_data); + return (STAILQ_NEXT(d, d_next) ? + &STAILQ_NEXT(d, d_next)->d_data : NULL); 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); } + raw_size = (uint64_t) e->e_rawsize; if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && - (sh_offset > e->e_rawsize || sh_size > e->e_rawsize - sh_offset))) { + (sh_offset > raw_size || sh_size > raw_size - sh_offset))) { 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); } if (sh_size / fsz > SIZE_MAX) { LIBELF_SET_ERROR(RANGE, 0); return (NULL); } count = (size_t) (sh_size / fsz); - msz = _libelf_msize(elftype, elfclass, e->e_version); + if ((msz = _libelf_msize(elftype, elfclass, e->e_version)) == 0) + return (NULL); if (count > 0 && msz > SIZE_MAX / count) { LIBELF_SET_ERROR(RANGE, 0); return (NULL); } assert(msz > 0); assert(count <= SIZE_MAX); assert(msz * count <= SIZE_MAX); if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); d->d_data.d_buf = NULL; d->d_data.d_off = 0; d->d_data.d_align = sh_align; d->d_data.d_size = msz * count; d->d_data.d_type = elftype; d->d_data.d_version = e->e_version; if (sh_type == SHT_NOBITS || sh_size == 0) { STAILQ_INSERT_TAIL(&s->s_data, d, d_next); return (&d->d_data); } if ((d->d_data.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); + xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass, + _libelf_elfmachine(e)); if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.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->d_data); } Elf_Data * elf_newdata(Elf_Scn *s) { Elf *e; struct _Libelf_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_data.d_align = 1; d->d_data.d_buf = NULL; d->d_data.d_off = (uint64_t) ~0; d->d_data.d_size = 0; d->d_data.d_type = ELF_T_BYTE; d->d_data.d_version = LIBELF_PRIVATE(version); (void) elf_flagscn(s, ELF_C_SET, ELF_F_DIRTY); return (&d->d_data); } /* * Retrieve a data descriptor for raw (untranslated) data for section * `s'. */ Elf_Data * elf_rawdata(Elf_Scn *s, Elf_Data *ed) { Elf *e; int elf_class; uint32_t sh_type; struct _Libelf_Data *d; - uint64_t sh_align, sh_offset, sh_size; + uint64_t sh_align, sh_offset, sh_size, raw_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); d = (struct _Libelf_Data *) ed; if (d == NULL && (d = STAILQ_FIRST(&s->s_rawdata)) != NULL) return (&d->d_data); if (d != NULL) return (&STAILQ_NEXT(d, d_next)->d_data); 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) { LIBELF_SET_ERROR(SECTION, 0); return (NULL); } + raw_size = (uint64_t) e->e_rawsize; if (sh_type != SHT_NOBITS && - (sh_offset > e->e_rawsize || sh_size > e->e_rawsize - sh_offset)) { + (sh_offset > raw_size || sh_size > raw_size - sh_offset)) { LIBELF_SET_ERROR(SECTION, 0); return (NULL); } if ((d = _libelf_allocate_data(s)) == NULL) return (NULL); d->d_data.d_buf = (sh_type == SHT_NOBITS || sh_size == 0) ? NULL : e->e_rawfile + sh_offset; d->d_data.d_off = 0; d->d_data.d_align = sh_align; d->d_data.d_size = sh_size; d->d_data.d_type = ELF_T_BYTE; d->d_data.d_version = e->e_version; STAILQ_INSERT_TAIL(&s->s_rawdata, d, d_next); return (&d->d_data); } Index: stable/11/contrib/elftoolchain/libelf/elf_end.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_end.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_end.3 (revision 367466) @@ -1,76 +1,76 @@ .\" 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 $ +.\" $Id: elf_end.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 29, 2006 -.Os .Dt ELF_END 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_end.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_end.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_end.c (revision 367466) @@ -1,95 +1,94 @@ /*- * 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 "_libelf.h" #if ELFTC_HAVE_MMAP #include #endif -ELFTC_VCSID("$Id: elf_end.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: elf_end.c 3738 2019-05-05 21:49:06Z 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) + RB_FOREACH_SAFE(scn, scntree, &e->e_u.e_elf.e_scn, 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_MALLOC) free(e->e_rawfile); #if ELFTC_HAVE_MMAP else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) - (void) munmap(e->e_rawfile, e->e_rawsize); + (void) munmap(e->e_rawfile, (size_t) e->e_rawsize); #endif } sv = e; if ((e = e->e_parent) != NULL) e->e_u.e_ar.e_nchildren--; - sv = _libelf_release_elf(sv); + _libelf_release_elf(sv); } return (0); } Index: stable/11/contrib/elftoolchain/libelf/elf_errmsg.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_errmsg.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_errmsg.3 (revision 367466) @@ -1,107 +1,107 @@ .\" 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 $ +.\" $Id: elf_errmsg.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 11, 2006 -.Os .Dt ELF_ERRMSG 3 +.Os .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. Index: stable/11/contrib/elftoolchain/libelf/elf_fill.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_fill.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_fill.3 (revision 367466) @@ -1,52 +1,52 @@ .\" 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 $ +.\" $Id: elf_fill.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 11, 2006 -.Os .Dt ELF_FILL 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_flagdata.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_flagdata.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_flagdata.3 (revision 367466) @@ -1,223 +1,227 @@ .\" 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_flagdata.3 3479 2016-06-25 20:44:33Z jkoshy $ +.\" $Id: elf_flagdata.3 3743 2019-06-12 19:36:30Z jkoshy $ .\" -.Dd December 3, 2011 -.Os +.Dd June 12, 2019 .Dt ELF_FLAGDATA 3 +.Os .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 +.Nd manipulate flags associated with ELF 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 should have been returned by prior calls to -functions in the ELF(3) API set: +functions in the +.Xr elf 3 +API set: .Bl -bullet -compact .It Argument .Ar arhdr should have been returned by a prior call to .Xr elf_getarhdr 3 . .It Argument .Ar data should have been returned by a prior call to one of .Xr elf_newdata 3 , .Xr elf_getdata 3 or .Xr elf_rawdata 3 . .It Argument .Ar elf should have been allocated by a prior call to one of .Xr elf_begin 3 or .Xr elf_memory 3 . .It Argument .Ar scn should have been returned by a prior call to one of .Xr elf_getscn 3 , .Xr elf_newscn 3 or .Xr elf_nextscn 3 . .El 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 if successful, or 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. +flags are an extension to the +.Xr 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 elf64_newehdr 3 , .Xr elf64_newphdr 3 , .Xr elf_newdata 3 , .Xr elf_update 3 , .Xr gelf 3 , .Xr gelf_newehdr 3 , .Xr gelf_newphdr 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 Index: stable/11/contrib/elftoolchain/libelf/elf_getarhdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getarhdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getarhdr.3 (revision 367466) @@ -1,97 +1,97 @@ .\" 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 $ +.\" $Id: elf_getarhdr.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 15, 2006 -.Os .Dt ELF_GETARHDR 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getarsym.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getarsym.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getarsym.3 (revision 367466) @@ -1,130 +1,130 @@ .\" 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 $ +.\" $Id: elf_getarsym.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 15, 2006 -.Os .Dt ELF_GETARSYM 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getbase.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getbase.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getbase.3 (revision 367466) @@ -1,71 +1,71 @@ .\" 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 $ +.\" $Id: elf_getbase.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 6, 2010 -.Os .Dt ELF_GETBASE 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getdata.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getdata.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getdata.3 (revision 367466) @@ -1,229 +1,234 @@ .\" 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 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: elf_getdata.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd January 26, 2011 -.Os +.Dd April 22, 2019 .Dt ELF_GETDATA 3 +.Os .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, +.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. +is not supported. +.It Bq Er ELF_E_VERSION +Section +.Ar scn +was associated with an ELF object with an unsupported +version. .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getident.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getident.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getident.3 (revision 367466) @@ -1,83 +1,83 @@ .\" 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 $ +.\" $Id: elf_getident.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd July 3, 2006 -.Os .Dt ELF_GETIDENT 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getident.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getident.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getident.c (revision 367466) @@ -1,66 +1,66 @@ /*- * 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" -ELFTC_VCSID("$Id: elf_getident.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: elf_getident.c 3712 2019-03-16 22:23:34Z 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; + *sz = (size_t) e->e_rawsize; } return ((char *) e->e_rawfile); error: if (sz) *sz = 0; return (NULL); } Index: stable/11/contrib/elftoolchain/libelf/elf_getphdrnum.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getphdrnum.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getphdrnum.3 (revision 367466) @@ -1,86 +1,85 @@ .\" 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 $ +.\" $Id: elf_getphdrnum.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" -.Dd August 5, 2009 -.Os +.Dd July 25, 2018 .Dt ELF_GETPHDRNUM 3 +.Os .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 +.Fn elf_getphdrnum 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 Index: stable/11/contrib/elftoolchain/libelf/elf_getphnum.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getphnum.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getphnum.3 (revision 367466) @@ -1,93 +1,92 @@ .\" 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 $ +.\" $Id: elf_getphnum.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" .Dd August 5, 2009 -.Os .Dt ELF_GETPHNUM 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getscn.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getscn.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getscn.3 (revision 367466) @@ -1,151 +1,155 @@ -.\" Copyright (c) 2006-2008 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2006-2008,2018 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 $ +.\" $Id: elf_getscn.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" -.Dd October 22, 2007 -.Os +.Dd September 24, 2018 .Dt ELF_GETSCN 3 +.Os .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. +As a consequence, +.Fn elf_nextscn +will never return a pointer to the empty section at index zero +.Dv ( SHN_UNDEF ) . 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 Index: stable/11/contrib/elftoolchain/libelf/elf_getshdrnum.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getshdrnum.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getshdrnum.3 (revision 367466) @@ -1,78 +1,77 @@ .\" 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 $ +.\" $Id: elf_getshdrnum.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" .Dd August 4, 2009 -.Os .Dt ELF_GETSHDRNUM 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getshdrstrndx.3 (revision 367466) @@ -1,79 +1,78 @@ .\" 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 $ +.\" $Id: elf_getshdrstrndx.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" .Dd August 5, 2009 -.Os .Dt ELF_GETSHDRSTRNDX 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getshnum.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getshnum.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getshnum.3 (revision 367466) @@ -1,84 +1,83 @@ .\" 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 $ +.\" $Id: elf_getshnum.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" .Dd August 5, 2009 -.Os .Dt ELF_GETSHNUM 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_getshstrndx.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_getshstrndx.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_getshstrndx.3 (revision 367466) @@ -1,94 +1,94 @@ .\" 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 $ +.\" $Id: elf_getshstrndx.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" -.Dd August 5, 2009 -.Os +.Dd July 25, 2018 .Dt ELF_GETSHSTRNDX 3 +.Os .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 +is deprecated. +Please use +.Xr elf_getshdrstrndx 3 +instead. +.Pp +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 Index: stable/11/contrib/elftoolchain/libelf/elf_hash.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_hash.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_hash.3 (revision 367466) @@ -1,57 +1,57 @@ .\" 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 $ +.\" $Id: elf_hash.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 15, 2006 -.Os .Dt ELF_HASH 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_kind.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_kind.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_kind.3 (revision 367466) @@ -1,71 +1,71 @@ .\" 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 $ +.\" $Id: elf_kind.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 1, 2006 -.Os .Dt ELF_KIND 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_memory.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_memory.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_memory.3 (revision 367466) @@ -1,122 +1,122 @@ .\" 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 2314 2011-12-11 06:19:51Z jkoshy $ +.\" $Id: elf_memory.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 28, 2006 -.Os .Dt ELF_MEMORY 3 +.Os .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 ELF object referenced by argument .Ar image was of an unsupported ELF 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 Index: stable/11/contrib/elftoolchain/libelf/elf_next.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_next.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_next.3 (revision 367466) @@ -1,96 +1,99 @@ .\" 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 $ +.\" $Id: elf_next.3 3698 2019-02-28 06:34:42Z jkoshy $ .\" -.Dd June 17, 2006 -.Os +.Dd February 27, 2019 .Dt ELF_NEXT 3 +.Os .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. +.It Bq Er ELF_E_ARGUMENT +An error was encountered while parsing the archive containing argument +.Ar elf . .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_end 3 , .Xr elf_rand 3 Index: stable/11/contrib/elftoolchain/libelf/elf_next.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_next.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_next.c (revision 367466) @@ -1,64 +1,78 @@ /*- * 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" -ELFTC_VCSID("$Id: elf_next.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: elf_next.c 3710 2019-03-12 09:42:35Z 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 + (off_t) e->e_rawsize; next = (next + 1) & ~1; /* round up to an even boundary */ /* * Setup the 'e_next' field of the archive descriptor for the * next call to 'elf_begin()'. */ parent->e_u.e_ar.e_next = (next >= (off_t) parent->e_rawsize) ? (off_t) 0 : next; + + /* + * Return an error if the 'e_next' field falls outside the current + * file. + * + * This check is performed after updating the parent descriptor's + * 'e_next' field so that the next call to elf_begin(3) will terminate + * traversal of a too-small archive even if client code forgets to + * check the return value from elf_next(3). + */ + if (next > (off_t) parent->e_rawsize) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (ELF_C_NULL); + } return (ELF_C_READ); } Index: stable/11/contrib/elftoolchain/libelf/elf_open.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_open.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_open.3 (revision 367466) @@ -1,121 +1,125 @@ .\" Copyright (c) 2012 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_open.3 3181 2015-04-10 13:22:51Z emaste $ +.\" $Id: elf_open.3 3743 2019-06-12 19:36:30Z jkoshy $ .\" -.Dd May 31, 2012 -.Os +.Dd June 12, 2019 .Dt ELF_OPEN 3 +.Os .Sh NAME .Nm elf_open .Nd open ELF objects and ar(1) archives .Sh LIBRARY .Lb libelf .Sh SYNOPSIS .In libelf.h .Ft "Elf *" .Fn elf_open "int fd" .Ft "Elf *" .Fn elf_openmemory "char *image" "size_t sz" .Sh DESCRIPTION .Em Important : The functions .Fn elf_open and .Fn elf_openmemory -are extensions to the ELF(3) API, for the internal use of the +are extensions to the +.Xr elf 3 +API, for the internal use of the Elftoolchain project. Portable applications should not use these functions. .Pp The function .Fn elf_open returns an Elf descriptor opened with mode .Dv ELF_C_READ for the ELF object or .Xr ar 1 archive referenced by the file descriptor in argument .Ar fd . .Pp The function .Fn elf_openmemory returns an ELF descriptor opened with mode .Dv ELF_C_READ for the ELF object or .Xr ar 1 archive contained in the memory area pointed to by the argument .Ar image . The argument .Ar sz specifies the size of the memory area in bytes. +.Sh RETURN VALUES +The function returns a pointer to a ELF descriptor if successful, or +NULL if an error occurred. .Sh COMPATIBILITY -These functions are non-standard extensions to the ELF(3) API set. +These functions are non-standard extensions to the +.Xr elf 3 +API set. .Pp The behavior of these functions differs from their counterparts .Xr elf_begin 3 and .Xr elf_memory 3 in that these functions will successfully open malformed ELF objects and .Xr ar 1 archives, returning an Elf descriptor of type .Dv ELF_K_NONE . -.Sh RETURN VALUES -The function returns a pointer to a ELF descriptor if successful, or -NULL if an error occurred. .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 fd was of an unsupported file type. .It Bq Er ELF_E_ARGUMENT The argument .Ar sz was zero, or the argument .Ar image was NULL. .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. .It Bq Er ELF_E_RESOURCE An out of memory condition was encountered. .It Bq Er ELF_E_SEQUENCE Functions .Fn elf_open or .Fn elf_openmemory was called before a working version was established with .Xr elf_version 3 . .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_begin 3 , .Xr elf_errno 3 , .Xr elf_memory 3 , .Xr gelf 3 Index: stable/11/contrib/elftoolchain/libelf/elf_rand.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_rand.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_rand.3 (revision 367466) @@ -1,118 +1,118 @@ .\" 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 $ +.\" $Id: elf_rand.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd June 17, 2006 -.Os .Dt ELF_RAND 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_rand.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_rand.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_rand.c (revision 367466) @@ -1,57 +1,66 @@ /*- * 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" -ELFTC_VCSID("$Id: elf_rand.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: elf_rand.c 3716 2019-03-18 22:01:01Z jkoshy $"); off_t elf_rand(Elf *ar, off_t offset) { struct ar_hdr *arh; + off_t offset_of_member; if (ar == NULL || ar->e_kind != ELF_K_AR || (offset & 1) || offset < SARMAG || - (size_t) offset + sizeof(struct ar_hdr) >= ar->e_rawsize) { + offset >= ar->e_rawsize) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return 0; + } + + offset_of_member = offset + (off_t) sizeof(struct ar_hdr); + + if (offset_of_member <= 0 || /* Numeric overflow. */ + offset_of_member >= 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); } Index: stable/11/contrib/elftoolchain/libelf/elf_rawfile.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_rawfile.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_rawfile.3 (revision 367466) @@ -1,76 +1,76 @@ .\" 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 $ +.\" $Id: elf_rawfile.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd July 3, 2006 -.Os .Dt ELF_RAWFILE 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_rawfile.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_rawfile.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_rawfile.c (revision 367466) @@ -1,51 +1,49 @@ /*- * 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" -ELFTC_VCSID("$Id: elf_rawfile.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: elf_rawfile.c 3712 2019-03-16 22:23:34Z jkoshy $"); char * elf_rawfile(Elf *e, size_t *sz) { - size_t size; unsigned char *ptr; - 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; + *sz = e ? (size_t) e->e_rawsize : 0; return ((char *) ptr); } Index: stable/11/contrib/elftoolchain/libelf/elf_scn.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_scn.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_scn.c (revision 367466) @@ -1,235 +1,255 @@ /*- * 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" -ELFTC_VCSID("$Id: elf_scn.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: elf_scn.c 3712 2019-03-16 22:23:34Z jkoshy $"); +static int +elfscn_cmp(struct _Elf_Scn *s1, struct _Elf_Scn *s2) +{ + + if (s1->s_ndx < s2->s_ndx) + return (-1); + if (s1->s_ndx > s2->s_ndx) + return (1); + return (0); +} + +RB_GENERATE(scntree, _Elf_Scn, s_tree, elfscn_cmp); + /* * Load an ELF section table and create a list of Elf_Scn structures. */ int _libelf_load_section_headers(Elf *e, void *ehdr) { Elf_Scn *scn; uint64_t shoff; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; int ec, swapbytes; unsigned char *src; size_t fsz, i, shnum; - int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, - size_t _c, int _swap); + _libelf_translator_function *xlator; assert(e != NULL); assert(ehdr != NULL); assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); #define CHECK_EHDR(E,EH) do { \ - if (shoff > e->e_rawsize || \ + uintmax_t rawsize = (uintmax_t) e->e_rawsize; \ + if (shoff > (uintmax_t) e->e_rawsize || \ fsz != (EH)->e_shentsize || \ shnum > SIZE_MAX / fsz || \ - fsz * shnum > e->e_rawsize - shoff) { \ + fsz * shnum > rawsize - shoff) { \ 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); + xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); 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)); + if (!RB_EMPTY(&e->e_u.e_elf.e_scn)) { + assert(RB_MIN(scntree, &e->e_u.e_elf.e_scn) == + RB_MAX(scntree, &e->e_u.e_elf.e_scn)); i = 1; src += fsz; } for (; i < shnum; i++, src += fsz) { if ((scn = _libelf_allocate_scn(e, i)) == NULL) return (0); (*xlator)((unsigned 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) + for (s = RB_ROOT(&e->e_u.e_elf.e_scn); s != NULL;) { if (s->s_ndx == index) return (s); + if (s->s_ndx < index) + s = RB_RIGHT(s, s_tree); + else + s = RB_LEFT(s, s_tree); + } + 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)) { + if (RB_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)); + RB_NEXT(scntree, &e->e_u.e_elf.e_scn, s)); } Index: stable/11/contrib/elftoolchain/libelf/elf_strptr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_strptr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_strptr.3 (revision 367466) @@ -1,116 +1,116 @@ .\" 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 $ +.\" $Id: elf_strptr.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd December 16, 2006 -.Os .Dt ELF_STRPTR 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/elf_update.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_update.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_update.3 (revision 367466) @@ -1,378 +1,382 @@ .\" 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 $ +.\" $Id: elf_update.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 14, 2011 -.Os +.Dd April 22, 2019 .Dt ELF_UPDATE 3 +.Os .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_UNIMPL +Argument +.Ar elf +contained a section with an unsupported ELF type. .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 Index: stable/11/contrib/elftoolchain/libelf/elf_update.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_update.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_update.c (revision 367466) @@ -1,1217 +1,1247 @@ /*- * 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" #if ELFTC_HAVE_MMAP #include #endif -ELFTC_VCSID("$Id: elf_update.c 3190 2015-05-04 15:23:08Z jkoshy $"); +ELFTC_VCSID("$Id: elf_update.c 3763 2019-06-28 21:43:27Z emaste $"); /* * 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) { Elf_Data *d; size_t fsz, msz; int ec, elftype; uint32_t sh_type; uint64_t d_align; Elf32_Shdr *shdr32; Elf64_Shdr *shdr64; struct _Libelf_Data *ld; 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) { + if (elftype < ELF_T_FIRST || 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(ld, &s->s_data, d_next) { d = &ld->d_data; /* * 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 data buffer's ELF type, ELF class and ELF version + * should be supported. + */ + if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 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, (size_t) 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 || sh_offset % _libelf_falign(elftype, ec)) { 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((uint64_t) 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) { + RB_FOREACH(s, scntree, &e->e_u.e_elf.e_scn) { 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 = (off_t) (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; 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 = (off_t) eh32->e_phoff; shoff = (off_t) eh32->e_shoff; eh_version = eh32->e_version; } else { eh_byteorder = eh64->e_ident[EI_DATA]; eh_class = eh64->e_ident[EI_CLASS]; phoff = (off_t) eh64->e_phoff; shoff = (off_t) eh64->e_shoff; eh_version = eh64->e_version; } if (phoff < 0 || shoff < 0) { LIBELF_SET_ERROR(HEADER, 0); return ((off_t) -1); } 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 { \ unsigned int _version = (unsigned int) (V); \ (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] = (unsigned char) (EC); \ (E)->e_ident[EI_VERSION] = (_version & 0xFFU); \ (E)->e_ehsize = (uint16_t) _libelf_fsize(ELF_T_EHDR, \ (EC), _version, (size_t) 1); \ (E)->e_phentsize = (uint16_t) ((phnum == 0) ? 0 : \ _libelf_fsize(ELF_T_PHDR, (EC), _version, \ (size_t) 1)); \ (E)->e_shentsize = (uint16_t) _libelf_fsize(ELF_T_SHDR, \ (EC), _version, (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 += (off_t) _libelf_fsize(ELF_T_EHDR, ec, eh_version, (size_t) 1); if (!_libelf_insert_extent(extents, ELF_EXTENT_EHDR, 0, (uint64_t) 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 % (off_t) align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else phoff = roundup(rc, (off_t) align); rc = phoff + (off_t) fsz; phdr = _libelf_getphdr(e, ec); if (!_libelf_insert_extent(extents, ELF_EXTENT_PHDR, (uint64_t) 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 % (off_t) align) { LIBELF_SET_ERROR(LAYOUT, 0); return ((off_t) -1); } } else shoff = roundup(rc, (off_t) align); if (shoff + (off_t) fsz > rc) rc = shoff + (off_t) fsz; if (!_libelf_insert_extent(extents, ELF_EXTENT_SHDR, (uint64_t) 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 off_t _libelf_write_scn(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { - int ec; off_t rc; + int ec, em; Elf_Scn *s; int elftype; Elf_Data *d, dst; uint32_t sh_type; struct _Libelf_Data *ld; uint64_t sh_off, sh_size; size_t fsz, msz, nobjects; assert(ex->ex_type == ELF_EXTENT_SECTION); s = ex->ex_desc; rc = (off_t) 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); + em = _libelf_elfmachine(e); +#if 0 + assert(em >= EM_NONE && em < EM__LAST__); +#endif + /* * 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(ld, &s->s_rawdata, d_next) { d = &ld->d_data; if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, LIBELF_PRIVATE(fillchar), (size_t) (sh_off + d->d_off - (uint64_t) rc)); rc = (off_t) (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, (size_t) d->d_size); rc += (off_t) 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(ld, &s->s_data, d_next) { d = &ld->d_data; - msz = _libelf_msize(d->d_type, ec, e->e_version); + if ((msz = _libelf_msize(d->d_type, ec, e->e_version)) == 0) + return ((off_t) -1); if ((uint64_t) rc < sh_off + d->d_off) (void) memset(nf + rc, LIBELF_PRIVATE(fillchar), (size_t) (sh_off + d->d_off - (uint64_t) rc)); rc = (off_t) (sh_off + d->d_off); assert(d->d_buf != NULL); assert(d->d_version == e->e_version); - assert(msz != 0); assert(d->d_size % msz == 0); + assert(msz != 0); nobjects = (size_t) (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) + if (_libelf_xlate(&dst, d, e->e_byteorder, ec, em, ELF_TOFILE) + == NULL) return ((off_t) -1); rc += (off_t) fsz; } return (rc); } /* * Write out an ELF Executable Header. */ static off_t _libelf_write_ehdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { - int ec; + int ec, em; 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); + if ((msz = _libelf_msize(ELF_T_EHDR, ec, e->e_version)) == 0) + return ((off_t) -1); + em = _libelf_elfmachine(e); + (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) == + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, em, 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, unsigned char *nf, struct _Elf_Extent *ex) { - int ec; + int ec, em; void *ehdr; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; Elf_Data dst, src; - size_t fsz, phnum; + size_t fsz, msz, 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(ehdr != NULL); + 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; } + em = _libelf_elfmachine(e); + 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)); + if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0) + return ((off_t) -1); 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); + src.d_size = phnum * msz; dst.d_size = fsz; dst.d_buf = nf + ex->ex_start; - if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, ELF_TOFILE) == + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, em, ELF_TOFILE) == NULL) return ((off_t) -1); return ((off_t) (phoff + fsz)); } /* * Write out an ELF section header table. */ static off_t _libelf_write_shdr(Elf *e, unsigned char *nf, struct _Elf_Extent *ex) { - int ec; + int ec, em; void *ehdr; Elf_Scn *scn; uint64_t shoff; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; - size_t fsz, nscn; + size_t fsz, msz, nscn; Elf_Data dst, src; assert(ex->ex_type == ELF_EXTENT_SHDR); ec = e->e_class; + ehdr = _libelf_ehdr(e, ec, 0); + assert(ehdr != NULL); + 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; } + em = _libelf_elfmachine(e); + 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)); + if ((msz = _libelf_msize(ELF_T_SHDR, ec, e->e_version)) == 0) + return ((off_t) -1); + src.d_type = ELF_T_SHDR; - src.d_size = _libelf_msize(ELF_T_SHDR, ec, e->e_version); + src.d_size = msz; 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) { + RB_FOREACH(scn, scntree, &e->e_u.e_elf.e_scn) { 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) + if (_libelf_xlate(&dst, &src, e->e_byteorder, ec, em, + ELF_TOFILE) == NULL) return ((off_t) -1); } return ((off_t) (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; Elf_Scn *scn, *tscn; struct _Elf_Extent *ex; unsigned char *newfile; 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), (size_t) (ex->ex_start - (uint64_t) 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 ELFTC_HAVE_MMAP 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) { + if (munmap(e->e_rawfile, (size_t) e->e_rawsize) < 0) { LIBELF_SET_ERROR(IO, errno); goto error; } } #endif } /* * 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); assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) || (e->e_flags & LIBELF_F_RAWFILE_MMAP)); if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) { + assert((e->e_flags & LIBELF_F_RAWFILE_MMAP) == 0); free(e->e_rawfile); e->e_rawfile = newfile; newfile = NULL; } #if ELFTC_HAVE_MMAP else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) { + assert((e->e_flags & LIBELF_F_RAWFILE_MALLOC) == 0); 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; } } #endif /* ELFTC_HAVE_MMAP */ /* Record the new size of the file. */ - e->e_rawsize = (size_t) newsize; + 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) + RB_FOREACH_SAFE(scn, scntree, &e->e_u.e_elf.e_scn, 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; } rc = _libelf_write_elf(e, rc, &extents); done: _libelf_release_extents(&extents); e->e_flags &= ~LIBELF_F_SHDRS_LOADED; return (rc); } Index: stable/11/contrib/elftoolchain/libelf/elf_version.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/elf_version.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/elf_version.3 (revision 367466) @@ -1,95 +1,95 @@ .\" 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 $ +.\" $Id: elf_version.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd November 9, 2011 -.Os .Dt ELF_VERSION 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf.3 (revision 367466) @@ -1,200 +1,207 @@ .\" 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 3195 2015-05-12 17:22:19Z emaste $ +.\" $Id: gelf.3 3743 2019-06-12 19:36:30Z jkoshy $ .\" -.Dd September 1, 2006 -.Os +.Dd October 23, 2020 .Dt GELF 3 +.Os .Sh NAME -.Nm GElf +.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_Chdr +A class-independent representation of an ELF Compression Header. .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 +.Bl -tag -width indent .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 +.Bl -tag -width indent .It "Allocating ELF Data Structures" -.Bl -tag -compact +.Bl -tag -compact -width indent .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 +.Bl -tag -compact -width indent .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 +.Bl -tag -compact -width indent +.It Fn gelf_getchdr +Retrieve an ELF Compression Header from the underlying ELF descriptor. .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 +.Bl -tag -compact -width indent .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. +The +.Nm +API first appeared in +.At V.4 . This implementation of the API first appeared in .Fx 7.0 . .Sh AUTHORS The GElf API was implemented by .An Joseph Koshy Aq Mt jkoshy@FreeBSD.org . Index: stable/11/contrib/elftoolchain/libelf/gelf.h =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf.h (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf.h (revision 367466) @@ -1,110 +1,112 @@ /*- * 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 3174 2015-03-27 17:13:41Z emaste $ */ #ifndef _GELF_H_ #define _GELF_H_ #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_Chdr GElf_Chdr; /* Compressed section header */ 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 #ifdef __cplusplus extern "C" { #endif long gelf_checksum(Elf *_elf); size_t gelf_fsize(Elf *_elf, Elf_Type _type, size_t _count, unsigned int _version); +GElf_Chdr *gelf_getchdr(Elf_Scn *_scn, GElf_Chdr *_dst); 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); #ifdef __cplusplus } #endif #endif /* _GELF_H_ */ Index: stable/11/contrib/elftoolchain/libelf/gelf_cap.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_cap.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_cap.c (revision 367466) @@ -1,150 +1,149 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_cap.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_cap.c 3732 2019-04-22 11:08:38Z jkoshy $"); GElf_Cap * gelf_getcap(Elf_Data *ed, int ndx, GElf_Cap *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; Elf32_Cap *cap32; Elf64_Cap *cap64; uint32_t sh_type; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); - if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { cap32 = (Elf32_Cap *) d->d_data.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_data.d_buf + ndx; *dst = *cap64; } return (dst); } int gelf_update_cap(Elf_Data *ed, int ndx, GElf_Cap *gc) { int ec; Elf *e; size_t msz; Elf_Scn *scn; Elf32_Cap *cap32; Elf64_Cap *cap64; uint32_t sh_type; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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 = _libelf_msize(ELF_T_CAP, ec, e->e_version)) == 0) + return (0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { cap32 = (Elf32_Cap *) d->d_data.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_data.d_buf + ndx; *cap64 = *gc; } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_chdr.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_chdr.c (nonexistent) +++ stable/11/contrib/elftoolchain/libelf/gelf_chdr.c (revision 367466) @@ -0,0 +1,82 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 The FreeBSD Foundation + * + * This software was developed by Tiger Gao under sponsorship from + * the FreeBSD Foundation. + * + * 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" + +Elf32_Chdr * +elf32_getchdr(Elf_Scn *s) +{ + return (_libelf_getchdr(s, ELFCLASS32)); +} + +Elf64_Chdr * +elf64_getchdr(Elf_Scn *s) +{ + return (_libelf_getchdr(s, ELFCLASS64)); +} + +GElf_Chdr * +gelf_getchdr(Elf_Scn *s, GElf_Chdr *d) +{ + int ec; + void *ch; + Elf32_Chdr *ch32; + Elf64_Chdr *ch64; + + if (d == NULL) { + LIBELF_SET_ERROR(ARGUMENT, 0); + return (NULL); + } + + if ((ch = _libelf_getchdr(s, ELFCLASSNONE)) == NULL) + return (NULL); + + ec = s->s_elf->e_class; + assert(ec == ELFCLASS32 || ec == ELFCLASS64); + + if (ec == ELFCLASS32) { + ch32 = (Elf32_Chdr *)ch; + + d->ch_type = (Elf64_Word)ch32->ch_type; + d->ch_size = (Elf64_Xword)ch32->ch_size; + d->ch_addralign = (Elf64_Xword)ch32->ch_addralign; + } else { + ch64 = (Elf64_Chdr *)ch; + *d = *ch64; + } + + return (d); +} Property changes on: stable/11/contrib/elftoolchain/libelf/gelf_chdr.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/contrib/elftoolchain/libelf/gelf_checksum.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_checksum.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_checksum.3 (revision 367466) @@ -1,115 +1,115 @@ .\" 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 $ +.\" $Id: gelf_checksum.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 29, 2006 -.Os .Dt GELF_CHECKSUM 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_dyn.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_dyn.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_dyn.c (revision 367466) @@ -1,152 +1,152 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_dyn.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_dyn.c 3732 2019-04-22 11:08:38Z jkoshy $"); GElf_Dyn * gelf_getdyn(Elf_Data *ed, int ndx, GElf_Dyn *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; Elf32_Dyn *dyn32; Elf64_Dyn *dyn64; uint32_t sh_type; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { dyn32 = (Elf32_Dyn *) d->d_data.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_data.d_buf + ndx; *dst = *dyn64; } return (dst); } int gelf_update_dyn(Elf_Data *ed, int ndx, GElf_Dyn *ds) { int ec; Elf *e; size_t msz; Elf_Scn *scn; Elf32_Dyn *dyn32; Elf64_Dyn *dyn64; uint32_t sh_type; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_DYN, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { dyn32 = (Elf32_Dyn *) d->d_data.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_data.d_buf + ndx; *dyn64 = *ds; } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_fsize.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_fsize.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_fsize.3 (revision 367466) @@ -1,96 +1,96 @@ .\" 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 $ +.\" $Id: gelf_fsize.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd February 5, 2008 -.Os .Dt GELF_FSIZE 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getcap.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getcap.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getcap.3 (revision 367466) @@ -1,121 +1,127 @@ .\" 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 $ +.\" $Id: gelf_getcap.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETCAP 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 Index: stable/11/contrib/elftoolchain/libelf/gelf_getchdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getchdr.3 (nonexistent) +++ stable/11/contrib/elftoolchain/libelf/gelf_getchdr.3 (revision 367466) @@ -0,0 +1,117 @@ +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.\" Copyright (c) 2020 The FreeBSD Foundation +.\" +.\" This document was written by Tiger Gao under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" 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_getchdr.3 3639 2020-10-20 16:07:02Z tig $ +.\" +.Dd October 23, 2020 +.Dt GELF_GETCHDR 3 +.Os +.Sh NAME +.Nm elf32_getchdr , +.Nm elf64_getchdr , +.Nm gelf_getchdr +.Nd retrieve the compression header of a section +.Sh LIBRARY +.Lb libelf +.Sh SYNOPSIS +.In libelf.h +.Ft "Elf32_Chdr *" +.Fn elf32_getchdr "Elf_Scn *s" +.Ft "Elf64_Chdr *" +.Fn elf64_getchdr "Elf_Scn *s" +.In gelf.h +.Ft "GElf_Chdr *" +.Fn gelf_getchdr "Elf_Scn *scn" "GElf_Chdr *chdr" +.Sh DESCRIPTION +These functions return a pointer to the ELF Compression Header data +structure associated with section descriptor +.Ar scn . +.Pp +Function +.Fn elf32_getchdr +retrieves a pointer to an +.Vt Elf32_Chdr +structure. +Section descriptor +.Ar scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS32 . +.Pp +Function +.Fn elf64_getchdr +retrieves a pointer to an +.Vt Elf64_Chdr +structure. +Section descriptor +.Ar scn +must be associated with an ELF descriptor of class +.Dv ELFCLASS64 . +.Pp +Function +.Fn gelf_getchdr +copies the values in the compression header associated with argument +.Ar scn +to the structure pointed to be argument +.Ar dst . +The +.Vt GElf_Chdr +data structure is described in +.Xr gelf 3 . +.Sh RETURN VALUES +Functions +.Fn elf32_getchdr +and +.Fn elf64_getchdr +return a valid pointer to the appropriate compression header on success +or NULL if an error was encountered. +.Pp +Function +.Fn gelf_getchdr +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_INVALID_SECTION_FLAGS +Arguments +.Ar scn +has invalid flags. +.It Bq Er ELF_E_INVALID_SECTION_TYPE +Argument +.Ar scn +has invalid type. +.It Bq Er ELF_E_NOT_COMPRESSED +Argument +.Ar scn +is not compressed. +.El +.Sh SEE ALSO +.Xr elf 3 , +.Xr elf_getscn 3 , +.Xr gelf 3 , Property changes on: stable/11/contrib/elftoolchain/libelf/gelf_getchdr.3 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/contrib/elftoolchain/libelf/gelf_getclass.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getclass.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getclass.3 (revision 367466) @@ -1,61 +1,61 @@ .\" 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 $ +.\" $Id: gelf_getclass.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd July 3, 2006 -.Os .Dt GELF_GETCLASS 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getdyn.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getdyn.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getdyn.3 (revision 367466) @@ -1,123 +1,130 @@ .\" 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 $ +.\" $Id: gelf_getdyn.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETDYN 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. +.El .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 Index: stable/11/contrib/elftoolchain/libelf/gelf_getehdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getehdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getehdr.3 (revision 367466) @@ -1,123 +1,123 @@ .\" 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 $ +.\" $Id: gelf_getehdr.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd December 16, 2006 -.Os .Dt GELF_GETEHDR 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getmove.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getmove.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getmove.3 (revision 367466) @@ -1,120 +1,126 @@ .\" 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 $ +.\" $Id: gelf_getmove.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETMOVE 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 Index: stable/11/contrib/elftoolchain/libelf/gelf_getphdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getphdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getphdr.3 (revision 367466) @@ -1,141 +1,141 @@ .\" 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 $ +.\" $Id: gelf_getphdr.3 3643 2018-10-14 21:09:24Z jkoshy $ .\" .Dd October 21, 2007 -.Os .Dt GELF_GETPHDR 3 +.Os .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. +.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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getrel.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getrel.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getrel.3 (revision 367466) @@ -1,121 +1,127 @@ .\" 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 $ +.\" $Id: gelf_getrel.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETREL 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 Index: stable/11/contrib/elftoolchain/libelf/gelf_getrela.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getrela.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getrela.3 (revision 367466) @@ -1,121 +1,127 @@ .\" 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 $ +.\" $Id: gelf_getrela.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETRELA 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_getdata 3 , .Xr elf_getscn 3 , .Xr gelf 3 Index: stable/11/contrib/elftoolchain/libelf/gelf_getshdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getshdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getshdr.3 (revision 367466) @@ -1,115 +1,115 @@ .\" 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 $ +.\" $Id: gelf_getshdr.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 27, 2006 -.Os .Dt GELF_GETSHDR 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getsym.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getsym.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getsym.3 (revision 367466) @@ -1,125 +1,131 @@ .\" 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 $ +.\" $Id: gelf_getsym.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETSYM 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getsyminfo.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getsyminfo.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getsyminfo.3 (revision 367466) @@ -1,115 +1,121 @@ .\" 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 $ +.\" $Id: gelf_getsyminfo.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd August 29, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETSYMINFO 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptor denoted by argument +.Ar data +is associated with an ELF object with an unsupported version. .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_getsymshndx.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_getsymshndx.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_getsymshndx.3 (revision 367466) @@ -1,162 +1,170 @@ .\" 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 $ +.\" $Id: gelf_getsymshndx.3 3734 2019-04-22 14:10:49Z jkoshy $ .\" -.Dd November 5, 2006 -.Os +.Dd April 22, 2019 .Dt GELF_GETSYMSHNDX 3 +.Os .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. +.It Bq Er ELF_E_VERSION +The +.Vt Elf_Data +descriptors denoted by arguments +.Ar symdata +and +.Ar xndxdata +are associated with an ELF object with an unsupported version. .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_move.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_move.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_move.c (revision 367466) @@ -1,159 +1,159 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_move.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_move.c 3732 2019-04-22 11:08:38Z jkoshy $"); GElf_Move * gelf_getmove(Elf_Data *ed, int ndx, GElf_Move *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Move *move32; Elf64_Move *move64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { move32 = (Elf32_Move *) d->d_data.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_data.d_buf + ndx; *dst = *move64; } return (dst); } int gelf_update_move(Elf_Data *ed, int ndx, GElf_Move *gm) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Move *move32; Elf64_Move *move64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_MOVE, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { move32 = (Elf32_Move *) d->d_data.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_data.d_buf + ndx; *move64 = *gm; } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_newehdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_newehdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_newehdr.3 (revision 367466) @@ -1,194 +1,197 @@ .\" 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 3500 2016-12-04 11:08:44Z jkoshy $ +.\" $Id: gelf_newehdr.3 3743 2019-06-12 19:36:30Z jkoshy $ .\" -.Dd October 22, 2007 -.Os +.Dd June 12, 2019 .Dt GELF_NEWEHDR 3 +.Os .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. +.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 COMPATIBILITY The .Fn gelf_newehdr function uses a type of .Ft "void *" for its returned value. -This differs from some other implementations of the ELF(3) API, which use an +This differs from some other implementations of the +.Xr elf 3 +API, which use an .Ft "unsigned long" return type. .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_newphdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_newphdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_newphdr.3 (revision 367466) @@ -1,142 +1,144 @@ .\" 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 3500 2016-12-04 11:08:44Z jkoshy $ +.\" $Id: gelf_newphdr.3 3743 2019-06-12 19:36:30Z jkoshy $ .\" -.Dd October 22, 2007 -.Os +.Dd June 12, 2019 .Dt GELF_NEWPHDR 3 +.Os .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 COMPATIBILITY The .Fn gelf_newphdr function uses a type of .Ft "void *" for its returned value. -This differs from some other implementations of the ELF(3) API, which use an +This differs from some other implementations of the +.Xr elf 3 +API, which use an .Ft "unsigned long" return type. .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_rel.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_rel.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_rel.c (revision 367466) @@ -1,168 +1,168 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_rel.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_rel.c 3739 2019-05-06 05:18:15Z jkoshy $"); GElf_Rel * gelf_getrel(Elf_Data *ed, int ndx, GElf_Rel *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Rel *rel32; Elf64_Rel *rel64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { rel32 = (Elf32_Rel *) d->d_data.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_data.d_buf + ndx; *dst = *rel64; if (_libelf_is_mips64el(e)) dst->r_info = _libelf_mips64el_r_info_tom(rel64->r_info); } return (dst); } int gelf_update_rel(Elf_Data *ed, int ndx, GElf_Rel *dr) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Rel *rel32; Elf64_Rel *rel64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_REL, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { rel32 = (Elf32_Rel *) d->d_data.d_buf + ndx; LIBELF_COPY_U32(rel32, dr, r_offset); - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) || ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { LIBELF_SET_ERROR(RANGE, 0); return (0); } rel32->r_info = ELF32_R_INFO( (Elf32_Word) ELF64_R_SYM(dr->r_info), (Elf32_Word) ELF64_R_TYPE(dr->r_info)); } else { rel64 = (Elf64_Rel *) d->d_data.d_buf + ndx; *rel64 = *dr; if (_libelf_is_mips64el(e)) rel64->r_info = _libelf_mips64el_r_info_tof(dr->r_info); } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_rela.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_rela.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_rela.c (revision 367466) @@ -1,172 +1,172 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_rela.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_rela.c 3739 2019-05-06 05:18:15Z jkoshy $"); GElf_Rela * gelf_getrela(Elf_Data *ed, int ndx, GElf_Rela *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Rela *rela32; Elf64_Rela *rela64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { rela32 = (Elf32_Rela *) d->d_data.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_data.d_buf + ndx; *dst = *rela64; if (_libelf_is_mips64el(e)) dst->r_info = _libelf_mips64el_r_info_tom(rela64->r_info); } return (dst); } int gelf_update_rela(Elf_Data *ed, int ndx, GElf_Rela *dr) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Rela *rela32; Elf64_Rela *rela64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_RELA, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { rela32 = (Elf32_Rela *) d->d_data.d_buf + ndx; LIBELF_COPY_U32(rela32, dr, r_offset); - if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0UL) || + if (ELF64_R_SYM(dr->r_info) > ELF32_R_SYM(~0U) || ELF64_R_TYPE(dr->r_info) > ELF32_R_TYPE(~0U)) { LIBELF_SET_ERROR(RANGE, 0); return (0); } rela32->r_info = ELF32_R_INFO( (Elf32_Word) ELF64_R_SYM(dr->r_info), (Elf32_Word) ELF64_R_TYPE(dr->r_info)); LIBELF_COPY_S32(rela32, dr, r_addend); } else { rela64 = (Elf64_Rela *) d->d_data.d_buf + ndx; *rela64 = *dr; if (_libelf_is_mips64el(e)) rela64->r_info = _libelf_mips64el_r_info_tof(dr->r_info); } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_sym.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_sym.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_sym.c (revision 367466) @@ -1,159 +1,159 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_sym.c 3177 2015-03-30 18:19:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_sym.c 3732 2019-04-22 11:08:38Z jkoshy $"); GElf_Sym * gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Sym *sym32; Elf64_Sym *sym64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { sym32 = (Elf32_Sym *) d->d_data.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 = sym32->st_info; dst->st_other = sym32->st_other; dst->st_shndx = sym32->st_shndx; } else { sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; *dst = *sym64; } return (dst); } int gelf_update_sym(Elf_Data *ed, int ndx, GElf_Sym *gs) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; Elf32_Sym *sym32; Elf64_Sym *sym64; struct _Libelf_Data *d; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_SYM, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { sym32 = (Elf32_Sym *) d->d_data.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_data.d_buf + ndx; *sym64 = *gs; } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_syminfo.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_syminfo.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_syminfo.c (revision 367466) @@ -1,152 +1,152 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_syminfo.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_syminfo.c 3732 2019-04-22 11:08:38Z jkoshy $"); GElf_Syminfo * gelf_getsyminfo(Elf_Data *ed, int ndx, GElf_Syminfo *dst) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; struct _Libelf_Data *d; Elf32_Syminfo *syminfo32; Elf64_Syminfo *syminfo64; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } if (ec == ELFCLASS32) { syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; dst->si_boundto = syminfo32->si_boundto; dst->si_flags = syminfo32->si_flags; } else { syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; *dst = *syminfo64; } return (dst); } int gelf_update_syminfo(Elf_Data *ed, int ndx, GElf_Syminfo *gs) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; struct _Libelf_Data *d; Elf32_Syminfo *syminfo32; Elf64_Syminfo *syminfo64; d = (struct _Libelf_Data *) ed; 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); + if ((msz = _libelf_msize(ELF_T_SYMINFO, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= d->d_data.d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } if (ec == ELFCLASS32) { syminfo32 = (Elf32_Syminfo *) d->d_data.d_buf + ndx; syminfo32->si_boundto = gs->si_boundto; syminfo32->si_flags = gs->si_flags; } else { syminfo64 = (Elf64_Syminfo *) d->d_data.d_buf + ndx; *syminfo64 = *gs; } return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_symshndx.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_symshndx.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_symshndx.c (revision 367466) @@ -1,137 +1,137 @@ /*- * 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" -ELFTC_VCSID("$Id: gelf_symshndx.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_symshndx.c 3732 2019-04-22 11:08:38Z jkoshy $"); GElf_Sym * gelf_getsymshndx(Elf_Data *d, Elf_Data *id, int ndx, GElf_Sym *dst, Elf32_Word *shindex) { int ec; Elf *e; size_t msz; Elf_Scn *scn; uint32_t sh_type; struct _Libelf_Data *ld, *lid; ld = (struct _Libelf_Data *) d; lid = (struct _Libelf_Data *) id; if (gelf_getsym(d, ndx, dst) == 0) return (NULL); if (lid == NULL || (scn = lid->d_scn) == NULL || (e = scn->s_elf) == NULL || (e != ld->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); + if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0) + return (NULL); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) 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; size_t msz; Elf_Scn *scn; uint32_t sh_type; struct _Libelf_Data *ld, *lid; ld = (struct _Libelf_Data *) d; lid = (struct _Libelf_Data *) id; if (gelf_update_sym(d, ndx, gs) == 0) return (0); if (lid == NULL || (scn = lid->d_scn) == NULL || (e = scn->s_elf) == NULL || (e != ld->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); + if ((msz = _libelf_msize(ELF_T_WORD, ec, e->e_version)) == 0) + return (0); - assert(msz > 0); assert(ndx >= 0); if (msz * (size_t) ndx >= id->d_size) { LIBELF_SET_ERROR(ARGUMENT, 0); return (0); } *(((Elf32_Word *) id->d_buf) + ndx) = xindex; return (1); } Index: stable/11/contrib/elftoolchain/libelf/gelf_update_ehdr.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_update_ehdr.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_update_ehdr.3 (revision 367466) @@ -1,123 +1,123 @@ .\" 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 $ +.\" $Id: gelf_update_ehdr.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" .Dd August 27, 2006 -.Os .Dt GELF_UPDATE_EHDR 3 +.Os .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 Index: stable/11/contrib/elftoolchain/libelf/gelf_xlate.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_xlate.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_xlate.c (revision 367466) @@ -1,79 +1,83 @@ /*- - * Copyright (c) 2006,2008 Joseph Koshy + * Copyright (c) 2006,2008,2018 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" -ELFTC_VCSID("$Id: gelf_xlate.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: gelf_xlate.c 3632 2018-10-10 21:12:43Z jkoshy $"); Elf_Data * elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned int encoding) { - return _libelf_xlate(dst, src, encoding, ELFCLASS32, ELF_TOFILE); + return _libelf_xlate(dst, src, encoding, ELFCLASS32, EM_NONE, + 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); + return _libelf_xlate(dst, src, encoding, ELFCLASS64, EM_NONE, + 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); + return _libelf_xlate(dst, src, encoding, ELFCLASS32, EM_NONE, + 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); + return _libelf_xlate(dst, src, encoding, ELFCLASS64, EM_NONE, + 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_elfmachine(e), 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_elfmachine(e), ELF_TOFILE)); LIBELF_SET_ERROR(ARGUMENT, 0); return (NULL); } Index: stable/11/contrib/elftoolchain/libelf/gelf_xlatetof.3 =================================================================== --- stable/11/contrib/elftoolchain/libelf/gelf_xlatetof.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/gelf_xlatetof.3 (revision 367466) @@ -1,247 +1,277 @@ -.\" Copyright (c) 2006,2008 Joseph Koshy. All rights reserved. +.\" Copyright (c) 2006,2008,2018 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 $ +.\" $Id: gelf_xlatetof.3 3639 2018-10-14 14:07:02Z jkoshy $ .\" -.Dd July 24, 2006 -.Os +.Dd October 11, 2018 .Dt GELF_XLATETOF 3 +.Os .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" +.Fn elf32_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" .Ft "Elf_Data *" -.Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.Fn elf32_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" .Ft "Elf_Data *" -.Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.Fn elf64_xlatetof "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" .Ft "Elf_Data *" -.Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int encode" +.Fn elf64_xlatetom "Elf_Data *dst" "Elf_Data *src" "unsigned int file_encoding" .In gelf.h .Ft "Elf_Data *" .Fo gelf_xlatetof .Fa "Elf *elf" .Fa "Elf_Data *dst" .Fa "Elf_Data *src" -.Fa "unsigned int encode" +.Fa "unsigned int file_encoding" .Fc .Ft "Elf_Data *" .Fo gelf_xlatetom .Fa "Elf *elf" .Fa "Elf_Data *dst" .Fa "Elf_Data *src" -.Fa "unsigned int encode" +.Fa "unsigned int file_encoding" .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 in-memory representation of an ELF data structure would conform 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. +As described in +.Xr elf 3 , +the file representation of this data structure could use a different byte +ordering from that of the host, or could use a different layout within +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 +.Ar file_encoding 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 +select the appropriate translation scheme based on the properties 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 +To translate a +.Vt GElf_Rel +structure to its LSB file representation use: +.Bd -literal -offset indent +Elf_Data dst, src; +GElf_Rel rel; +Elf *e; + +e = ...; /* See elf_begin(3). */ + +/* Set up the 'src' descriptor. */ +memset(&src, 0, sizeof src); +src.d_buf = &rel; +src.d_size = sizeof(rel); +src.d_type = ELF_T_REL; +src.d_version = EV_CURRENT; + +/* Set up the 'dst' descriptor. */ +memset(&dst, 0, sizeof dst); +dst.d_buf = filebuf; +dst.d_size = gelf_fsize(e, ELF_T_REL, 1, EV_CURRENT); +dst.d_version = EV_CURRENT; + +if (gelf_xlatetof(e, &dst, &src, ELFDATA2LSB) == NULL) { + printf("error: %s", elf_errmsg(0)); +} +.Ed .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 Index: stable/11/contrib/elftoolchain/libelf/libelf.h =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf.h (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf.h (revision 367466) @@ -1,256 +1,261 @@ /*- * 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 3174 2015-03-27 17:13:41Z emaste $ */ #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; } 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. */ unsigned 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_INVALID_SECTION_FLAGS, /* Invalid ELF section header flags */ + ELF_E_INVALID_SECTION_TYPE, /* Invalid ELF section header type */ + ELF_E_NOT_COMPRESSED, /* Section is not compressed */ 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 */ #ifdef __cplusplus extern "C" { #endif 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); Elf *elf_open(int _fd); Elf *elf_openmemory(char *_image, size_t _size); 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_Chdr *elf32_getchdr(Elf_Scn *_scn); 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_Chdr *elf64_getchdr(Elf_Scn *_scn); 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); #ifdef __cplusplus } #endif #endif /* _LIBELF_H_ */ Index: stable/11/contrib/elftoolchain/libelf/libelf_allocate.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_allocate.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_allocate.c (revision 367466) @@ -1,210 +1,195 @@ /*- * 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 "_libelf.h" -ELFTC_VCSID("$Id: libelf_allocate.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelf_allocate.c 3738 2019-05-05 21:49:06Z jkoshy $"); Elf * _libelf_allocate_elf(void) { Elf *e; - if ((e = malloc(sizeof(*e))) == NULL) { + if ((e = calloc((size_t) 1, 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); + RB_INIT(&e->e_u.e_elf.e_scn); break; default: break; } } -#define FREE(P) do { \ - if (P) \ - free(P); \ - } while (0) - - -Elf * +void _libelf_release_elf(Elf *e) { Elf_Arhdr *arh; switch (e->e_kind) { case ELF_K_AR: - FREE(e->e_u.e_ar.e_symtab); + 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); + 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); + 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)); + assert(RB_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->ar_name); + free(arh->ar_rawname); free(arh); } break; default: break; } free(e); - - return (NULL); } struct _Libelf_Data * _libelf_allocate_data(Elf_Scn *s) { struct _Libelf_Data *d; if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { LIBELF_SET_ERROR(RESOURCE, 0); return (NULL); } d->d_scn = s; return (d); } struct _Libelf_Data * _libelf_release_data(struct _Libelf_Data *d) { if (d->d_flags & LIBELF_F_DATA_MALLOCED) free(d->d_data.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); + RB_INSERT(scntree, &e->e_u.e_elf.e_scn, s); return (s); } Elf_Scn * _libelf_release_scn(Elf_Scn *s) { Elf *e; struct _Libelf_Data *d, *td; assert(s != NULL); STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { STAILQ_REMOVE(&s->s_data, d, _Libelf_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, _Libelf_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); + RB_REMOVE(scntree, &e->e_u.e_elf.e_scn, s); free(s); return (NULL); } Index: stable/11/contrib/elftoolchain/libelf/libelf_ar.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_ar.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_ar.c (revision 367466) @@ -1,466 +1,497 @@ /*- * 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 "_libelf.h" #include "_libelf_ar.h" -ELFTC_VCSID("$Id: libelf_ar.c 3446 2016-05-03 01:31:17Z emaste $"); +ELFTC_VCSID("$Id: libelf_ar.c 3712 2019-03-16 22:23:34Z 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 up to 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; Elf_Arhdr *eh; char *namelen; 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)); + /* + * There needs to be enough space remaining in the file for the + * archive header. + */ + if ((uintptr_t) arh > (uintptr_t) parent->e_rawfile + + (uintptr_t) parent->e_rawsize - sizeof(struct ar_hdr)) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + 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 = (unsigned char *) arh; return (NULL); } Elf * _libelf_ar_open_member(int fd, Elf_Cmd c, Elf *elf) { Elf *e; - off_t next; size_t nsz, sz; + off_t next, end; struct ar_hdr *arh; char *member, *namelen; 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); + /* + * There needs to be enough space in the file to contain an + * ar(1) header. + */ + end = next + (off_t) sizeof(struct ar_hdr); + if ((uintmax_t) end < (uintmax_t) next || /* Overflow. */ + end > (off_t) elf->e_rawsize) { + LIBELF_SET_ERROR(ARCHIVE, 0); + return (NULL); + } + 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); } /* + * Check if the archive member that follows will fit in the + * containing archive. + */ + end += (off_t) sz; + if (end < next || /* Overflow. */ + end > (off_t) elf->e_rawsize) { + 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(member, sz)) == NULL) return (NULL); e->e_fd = fd; e->e_cmd = c; e->e_hdr.e_rawhdr = (unsigned 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 int n, nentries; + unsigned int n; + size_t nentries; unsigned char *end, *p, *p0, *s, *s0; const size_t entrysize = 2 * sizeof(long); long arraysize, fileoffset, 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 (arraysize < 0 || p0 + arraysize >= end || ((size_t) 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 (strtabsize < 0 || s0 + strtabsize > end) goto symtaberror; nentries = (size_t) 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); if (stroffset < 0 || fileoffset < 0 || - (size_t) fileoffset >= e->e_rawsize) + (off_t) fileoffset >= e->e_rawsize) goto symtaberror; s = s0 + stroffset; if (s >= end) goto symtaberror; sym->as_off = (off_t) 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) { uint32_t off; size_t n, nentries; 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; GET_WORD(p, off); if (off >= e->e_rawsize) goto symtaberror; sym->as_off = (off_t) 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); } Index: stable/11/contrib/elftoolchain/libelf/libelf_chdr.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_chdr.c (nonexistent) +++ stable/11/contrib/elftoolchain/libelf/libelf_chdr.c (revision 367466) @@ -0,0 +1,104 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 The FreeBSD Foundation + * + * This software was developed by Tiger Gao under sponsorship from + * the FreeBSD Foundation. + * + * 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" + +void * +_libelf_getchdr(Elf_Scn *s, int ec) +{ + Elf *e; + void *sh; + Elf32_Shdr *sh32; + Elf64_Shdr *sh64; + + sh32 = NULL; + sh64 = NULL; + + 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; + } else if (ec != e->e_class) { + LIBELF_SET_ERROR(CLASS, 0); + return (NULL); + } + + if ((sh = _libelf_getshdr(s, ec)) == NULL) { + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + + if (ec == ELFCLASS32) { + sh32 = (Elf32_Shdr *)sh; + if ((sh32->sh_flags & SHF_ALLOC) != 0) { + LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0); + return (NULL); + } + + if (sh32->sh_type == SHT_NULL || sh32->sh_type == SHT_NOBITS) { + LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0); + return (NULL); + } + + if ((sh32->sh_flags & SHF_COMPRESSED) == 0) { + LIBELF_SET_ERROR(NOT_COMPRESSED, 0); + return (NULL); + } + } else { + sh64 = (Elf64_Shdr *)sh; + if ((sh64->sh_flags & SHF_ALLOC) != 0) { + LIBELF_SET_ERROR(INVALID_SECTION_FLAGS, 0); + return (NULL); + } + + if (sh64->sh_type == SHT_NULL || sh64->sh_type == SHT_NOBITS) { + LIBELF_SET_ERROR(INVALID_SECTION_TYPE, 0); + return (NULL); + } + + if ((sh64->sh_flags & SHF_COMPRESSED) == 0) { + LIBELF_SET_ERROR(NOT_COMPRESSED, 0); + return (NULL); + } + } + + Elf_Data *d = elf_getdata(s, NULL); + + if (!d) + return (NULL); + + return ((void *)d->d_buf); +} Property changes on: stable/11/contrib/elftoolchain/libelf/libelf_chdr.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/contrib/elftoolchain/libelf/libelf_convert.m4 =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_convert.m4 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_convert.m4 (revision 367466) @@ -1,1088 +1,1090 @@ /*- * 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 "_libelf.h" -ELFTC_VCSID("$Id: libelf_convert.m4 3429 2016-03-12 04:12:39Z emaste $"); +ELFTC_VCSID("$Id: libelf_convert.m4 3712 2019-03-16 22:23:34Z 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(unsigned char *dst, size_t dsz, unsigned 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(unsigned char *dst, size_t dsz, unsigned 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(unsigned char *dst, size_t dsz, unsigned 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(unsigned char *dst, size_t dsz, unsigned char *src, size_t count, int byteswap) { Elf$3_$2 t, *d; unsigned 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 = 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(unsigned char *dst, size_t dsz, unsigned 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); unsigned char * const dstend = dst + dsz; unsigned char * const srcend = src + count; unsigned char *dtmp, *dstaux, *srcaux; Elf$5_Word aux, anext, cnt, vnext; for (dtmp = dst, vnext = ~0U; 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 = ~0U, 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(unsigned char *dst, size_t dsz, unsigned 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); unsigned char * const dstend = dst + dsz; unsigned char * const srcend = src + count; unsigned char *dstaux, *s, *srcaux, *stmp; Elf$5_Word aux, anext, cnt, vnext; for (stmp = src, vnext = ~0U; 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 = ~0U, 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); \ uint32_t _t = _x & 0xFFU; \ _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ (X) = (uint16_t) _t; \ } while (0) #define _SWAP_WORD(X, T) 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) _t; \ } while (0) #define SWAP_ADDR32(X) _SWAP_WORD(X, Elf32_Addr) #define SWAP_OFF32(X) _SWAP_WORD(X, Elf32_Off) #define SWAP_SWORD(X) _SWAP_WORD(X, Elf32_Sword) #define SWAP_WORD(X) _SWAP_WORD(X, Elf32_Word) #define _SWAP_WORD64(X, T) 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) _t; \ } while (0) #define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) #define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) #define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) #define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) #define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) /* * 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 { \ unsigned char *const _p = (unsigned char *) (P); \ _p[0] = (unsigned char) (X); \ (P) = _p + 1; \ } while (0) #define WRITE_HALF(P,X) do { \ uint16_t _t = (X); \ unsigned char *const _p = (unsigned char *) (P); \ const unsigned char *const _q = (unsigned char *) &_t; \ _p[0] = _q[0]; \ _p[1] = _q[1]; \ (P) = _p + 2; \ } while (0) #define WRITE_WORD(P,X) do { \ uint32_t _t = (uint32_t) (X); \ unsigned char *const _p = (unsigned char *) (P); \ const unsigned char *const _q = (unsigned 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 = (uint64_t) (X); \ unsigned char *const _p = (unsigned char *) (P); \ const unsigned char *const _q = (unsigned 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 unsigned char *const _p = \ (const unsigned char *) (P); \ (X) = _p[0]; \ (P) = (P) + 1; \ } while (0) #define READ_HALF(P,X) do { \ uint16_t _t; \ unsigned char *const _q = (unsigned char *) &_t; \ const unsigned char *const _p = \ (const unsigned char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ (P) = (P) + 2; \ (X) = _t; \ } while (0) #define _READ_WORD(P,X,T) do { \ uint32_t _t; \ unsigned char *const _q = (unsigned char *) &_t; \ const unsigned char *const _p = \ (const unsigned char *) (P); \ _q[0] = _p[0]; \ _q[1] = _p[1]; \ _q[2] = _p[2]; \ _q[3] = _p[3]; \ (P) = (P) + 4; \ (X) = (T) _t; \ } while (0) #define READ_ADDR32(P,X) _READ_WORD(P, X, Elf32_Addr) #define READ_OFF32(P,X) _READ_WORD(P, X, Elf32_Off) #define READ_SWORD(P,X) _READ_WORD(P, X, Elf32_Sword) #define READ_WORD(P,X) _READ_WORD(P, X, Elf32_Word) #define _READ_WORD64(P,X,T) do { \ uint64_t _t; \ unsigned char *const _q = (unsigned char *) &_t; \ const unsigned char *const _p = \ (const unsigned 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) _t; \ } while (0) #define READ_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) #define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) #define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) #define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) #define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) #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(unsigned char *dst, size_t dsz, unsigned 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(unsigned char *dst, size_t dsz, unsigned 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(unsigned char *dst, size_t dsz, unsigned 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(unsigned char *dst, size_t dsz, unsigned 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); + nchains = (uint32_t) (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(unsigned char *dst, size_t dsz, unsigned 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); + nchains = (uint32_t) (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(unsigned char *dst, size_t dsz, unsigned 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, 4U); ROUNDUP2(descsz, 4U); 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(unsigned char *dst, size_t dsz, unsigned 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; sz = namesz; ROUNDUP2(sz, 4U); sz += descsz; ROUNDUP2(sz, 4U); 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); count -= sizeof(Elf_Note); if (count < sz) - sz = count; + return (0); (void) memcpy(dst, src, sz); src += sz; dst += sz; count -= sz; } return (1); } struct converters { int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, size_t cnt, int byteswap); int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, size_t cnt, int byteswap); int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, size_t cnt, int byteswap); int (*tom64)(unsigned char *dst, size_t dsz, unsigned 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)) - (unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt, - int _byteswap) +/* + * Return a translator function for the specified ELF section type, conversion + * direction, ELF class and ELF machine. + */ +_libelf_translator_function * +_libelf_get_translator(Elf_Type t, int direction, int elfclass, int elfmachine) { assert(elfclass == ELFCLASS32 || elfclass == ELFCLASS64); assert(direction == ELF_TOFILE || direction == ELF_TOMEMORY); + assert(t >= ELF_T_FIRST && t <= ELF_T_LAST); - if (t >= ELF_T_NUM || - (elfclass != ELFCLASS32 && elfclass != ELFCLASS64) || - (direction != ELF_TOFILE && direction != ELF_TOMEMORY)) - return (NULL); + /* TODO: Handle MIPS64 REL{,A} sections (ticket #559). */ + (void) elfmachine; return ((elfclass == ELFCLASS32) ? (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); } Index: stable/11/contrib/elftoolchain/libelf/libelf_data.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_data.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_data.c (revision 367466) @@ -1,101 +1,107 @@ /*- * 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" -ELFTC_VCSID("$Id: libelf_data.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelf_data.c 3737 2019-05-05 14:49:50Z jkoshy $"); int _libelf_xlate_shtype(uint32_t sht) { /* * Look for known section types. */ 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: /* * Values in the range [SHT_LOOS..SHT_HIUSER] (i.e., * OS, processor and user-defined section types) are * legal, but since we do not know anything more about * their semantics, we return a type of ELF_T_BYTE. + * + * The ELF specification uses 32 bit unsigned values for + * denoting section types, and defines SHT_HIUSER to be + * 0xFFFFFFFFUL (i.e., UINT32_MAX). Consequently, we only + * need to check that 'sht' is greater than or equal to + * SHT_LOOS. */ - if (sht >= SHT_LOOS && sht <= SHT_HIUSER) + if (sht >= SHT_LOOS) return (ELF_T_BYTE); /* * Other values are unsupported. */ return (-1); } } Index: stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_ehdr.c (revision 367466) @@ -1,207 +1,212 @@ /*- * 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" -ELFTC_VCSID("$Id: libelf_ehdr.c 3575 2017-09-14 02:13:36Z emaste $"); +ELFTC_VCSID("$Id: libelf_ehdr.c 3732 2019-04-22 11:08:38Z 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)(unsigned char *_d, size_t _dsz, unsigned char *_s, - size_t _c, int _swap); + Elf_Scn *scn; uint32_t shtype; + _libelf_translator_function *xlator; - assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); + assert(RB_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 */ + if (shoff + fsz < shoff) { /* Numeric overflow. */ LIBELF_SET_ERROR(HEADER, 0); return (0); } + if ((uint64_t) e->e_rawsize < shoff + fsz) { + 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 = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), (unsigned char *) 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 = (size_t) 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) & 0xFFU; \ 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)(unsigned char *_d, size_t _dsz, unsigned 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) { + if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < (off_t) fsz) { LIBELF_SET_ERROR(HEADER, 0); return (NULL); } - msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); + if ((msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT)) == 0) + return (NULL); - 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 = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1, e->e_byteorder != LIBELF_PRIVATE(byteorder)); 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 extended numbering is being used, read the correct * number of sections and program header entries. */ if ((shnum == 0 && shoff != 0) || phnum == PN_XNUM || strndx == SHN_XINDEX) { if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) return (NULL); } else { /* 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; } return (ehdr); } Index: stable/11/contrib/elftoolchain/libelf/libelf_elfmachine.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_elfmachine.c (nonexistent) +++ stable/11/contrib/elftoolchain/libelf/libelf_elfmachine.c (revision 367466) @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2018 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" + +ELFTC_VCSID("$Id$"); + +/* + * A convenience helper that returns the ELF machine architecture for + * a ELF descriptor. + */ +int +_libelf_elfmachine(Elf *e) +{ + Elf32_Ehdr *eh32; + Elf64_Ehdr *eh64; + + if (!e) + return EM_NONE; + + assert(e->e_kind == ELF_K_ELF); + assert(e->e_class != ELFCLASSNONE); + + eh32 = NULL; + eh64 = NULL; + + switch (e->e_class) { + case ELFCLASS32: + eh32 = e->e_u.e_elf.e_ehdr.e_ehdr32; + return eh32 ? eh32->e_machine : EM_NONE; + case ELFCLASS64: + eh64 = e->e_u.e_elf.e_ehdr.e_ehdr64; + return eh64 ? eh64->e_machine : EM_NONE; + } + + return (EM_NONE); +} Property changes on: stable/11/contrib/elftoolchain/libelf/libelf_elfmachine.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/contrib/elftoolchain/libelf/libelf_extended.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_extended.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_extended.c (revision 367466) @@ -1,134 +1,134 @@ /*- * 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" -ELFTC_VCSID("$Id: libelf_extended.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelf_extended.c 3712 2019-03-16 22:23:34Z 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) + if ((s = RB_MIN(scntree, &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; + scn->s_shdr.s_shdr32.sh_size = (Elf32_Word) 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 & 0xFFFFU; else ((Elf64_Ehdr *) eh)->e_shnum = shnum & 0xFFFFU; 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; + scn->s_shdr.s_shdr32.sh_link = (Elf32_Word) shstrndx; else - scn->s_shdr.s_shdr64.sh_link = shstrndx; + scn->s_shdr.s_shdr64.sh_link = (Elf64_Word) shstrndx; (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); shstrndx = SHN_XINDEX; } if (ec == ELFCLASS32) ((Elf32_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; else ((Elf64_Ehdr *) eh)->e_shstrndx = shstrndx & 0xFFFFU; 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; + scn->s_shdr.s_shdr32.sh_info = (Elf32_Word) phnum; else - scn->s_shdr.s_shdr64.sh_info = phnum; + scn->s_shdr.s_shdr64.sh_info = (Elf64_Word) phnum; (void) elf_flagshdr(scn, ELF_C_SET, ELF_F_DIRTY); phnum = PN_XNUM; } if (ec == ELFCLASS32) ((Elf32_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; else ((Elf64_Ehdr *) eh)->e_phnum = phnum & 0xFFFFU; return (1); } Index: stable/11/contrib/elftoolchain/libelf/libelf_memory.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_memory.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_memory.c (revision 367466) @@ -1,96 +1,96 @@ /*- * Copyright (c) 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" -ELFTC_VCSID("$Id: libelf_memory.c 3013 2014-03-23 06:16:59Z jkoshy $"); +ELFTC_VCSID("$Id: libelf_memory.c 3738 2019-05-05 21:49:06Z jkoshy $"); /* * Create an ELF descriptor for a memory image, optionally reporting * parse errors. */ Elf * _libelf_memory(unsigned char *image, size_t sz, int reporterror) { Elf *e; int e_class; enum Elf_Error error; unsigned int e_byteorder, e_version; assert(image != NULL); assert(sz > 0); if ((e = _libelf_allocate_elf()) == NULL) return (NULL); e->e_cmd = ELF_C_READ; e->e_rawfile = image; - e->e_rawsize = sz; + e->e_rawsize = (off_t) 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)) { e_byteorder = image[EI_DATA]; e_class = image[EI_CLASS]; e_version = image[EI_VERSION]; error = ELF_E_NONE; if (e_version > EV_CURRENT) error = ELF_E_VERSION; else if ((e_byteorder != ELFDATA2LSB && e_byteorder != ELFDATA2MSB) || (e_class != ELFCLASS32 && e_class != ELFCLASS64)) error = ELF_E_HEADER; if (error != ELF_E_NONE) { if (reporterror) { LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0); - (void) _libelf_release_elf(e); + _libelf_release_elf(e); return (NULL); } } else { _libelf_init_elf(e, ELF_K_ELF); e->e_byteorder = e_byteorder; e->e_class = e_class; e->e_version = e_version; } } else if (sz >= SARMAG && strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0) return (_libelf_ar_open(e, reporterror)); return (e); } Index: stable/11/contrib/elftoolchain/libelf/libelf_msize.m4 =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_msize.m4 (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_msize.m4 (revision 367466) @@ -1,106 +1,119 @@ /*- * 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 "_libelf.h" -ELFTC_VCSID("$Id: libelf_msize.m4 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelf_msize.m4 3732 2019-04-22 11:08:38Z 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) }; +/* + * Returns the memory size of the specified ELF type 't' of ELF + * class 'ec' and ELF version 'version'. + * + * If the specified combination of ELF type, class, and version is + * unsupported then a value of 0 will be returned and the appropriate + * library error code set. + */ 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; + + if (sz == 0) { + LIBELF_SET_ERROR(UNIMPL, 0); + return (0); + } return (sz); } Index: stable/11/contrib/elftoolchain/libelf/libelf_phdr.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_phdr.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_phdr.c (revision 367466) @@ -1,153 +1,156 @@ /*- * 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" -ELFTC_VCSID("$Id: libelf_phdr.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelf_phdr.c 3732 2019-04-22 11:08:38Z jkoshy $"); void * _libelf_getphdr(Elf *e, int ec) { size_t phnum; size_t fsz, msz; uint64_t phoff; Elf32_Ehdr *eh32; Elf64_Ehdr *eh64; void *ehdr, *phdr; - int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, - size_t _c, int _swap); + _libelf_translator_function *xlator; 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; phoff = (uint64_t) eh32->e_phoff; } else { eh64 = (Elf64_Ehdr *) ehdr; phoff = (uint64_t) eh64->e_phoff; } fsz = gelf_fsize(e, ELF_T_PHDR, phnum, e->e_version); assert(fsz > 0); + if (phoff + fsz < phoff) { /* Numeric overflow. */ + LIBELF_SET_ERROR(HEADER, 0); + return (NULL); + } + if ((uint64_t) e->e_rawsize < (phoff + fsz)) { LIBELF_SET_ERROR(HEADER, 0); return (NULL); } - msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT); + if ((msz = _libelf_msize(ELF_T_PHDR, ec, EV_CURRENT)) == 0) + return (NULL); - 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 = _libelf_get_translator(ELF_T_PHDR, ELF_TOMEMORY, ec, + _libelf_elfmachine(e)); (*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); + if ((msz = _libelf_msize(ELF_T_PHDR, ec, e->e_version)) == 0) + return (NULL); 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); } Index: stable/11/contrib/elftoolchain/libelf/libelf_xlate.c =================================================================== --- stable/11/contrib/elftoolchain/libelf/libelf_xlate.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelf/libelf_xlate.c (revision 367466) @@ -1,148 +1,149 @@ /*- * 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" -ELFTC_VCSID("$Id: libelf_xlate.c 3174 2015-03-27 17:13:41Z emaste $"); +ELFTC_VCSID("$Id: libelf_xlate.c 3732 2019-04-22 11:08:38Z 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 elfclass, int elfmachine, int direction) { int byteswap; size_t cnt, dsz, fsz, msz; uintptr_t sb, se, db, de; + _libelf_translator_function *xlator; 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); + if ((msz = _libelf_msize(src->d_type, elfclass, src->d_version)) == 0) + return (NULL); - 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 = (size_t) src->d_size / fsz; dsz = cnt * msz; } else { cnt = (size_t) 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 + (size_t) src->d_size; db = (uintptr_t) dst->d_buf; de = db + (size_t) 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)) { + xlator = _libelf_get_translator(src->d_type, direction, elfclass, + elfmachine); + if (!xlator(dst->d_buf, dsz, src->d_buf, cnt, byteswap)) { LIBELF_SET_ERROR(DATA, 0); return (NULL); } return (dst); } Index: stable/11/contrib/elftoolchain/libelf/os.Linux.mk =================================================================== --- stable/11/contrib/elftoolchain/libelf/os.Linux.mk (nonexistent) +++ stable/11/contrib/elftoolchain/libelf/os.Linux.mk (revision 367466) @@ -0,0 +1,31 @@ +# Enable additional warnings. +CFLAGS+= -Wa,--fatal-warnings +CFLAGS+= -Wall +CFLAGS+= -Wcast-align +CFLAGS+= -Wcast-qual +CFLAGS+= -Wchar-subscripts +CFLAGS+= -Wconversion +CFLAGS+= -Werror +CFLAGS+= -Wextra +CFLAGS+= -Wformat=2 +CFLAGS+= -Winline +CFLAGS+= -Wmissing-prototypes +CFLAGS+= -Wnested-externs +CFLAGS+= -Wempty-body +CFLAGS+= -Wformat-y2k +CFLAGS+= -Wformat-zero-length +CFLAGS+= -Wpointer-sign +CFLAGS+= -Wpointer-to-int-cast +CFLAGS+= -Wsign-compare +CFLAGS+= -Wunused-const-variable +CFLAGS+= -Wunused-parameter +CFLAGS+= -Wold-style-definition +CFLAGS+= -Wpointer-arith +CFLAGS+= -Wredundant-decls +CFLAGS+= -Wreturn-type +CFLAGS+= -Wshadow +CFLAGS+= -Wstrict-prototypes +CFLAGS+= -Wstrict-overflow +CFLAGS+= -Wswitch +CFLAGS+= -Wunused-parameter +CFLAGS+= -Wwrite-strings Property changes on: stable/11/contrib/elftoolchain/libelf/os.Linux.mk ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/contrib/elftoolchain/libelftc/_libelftc.h =================================================================== --- stable/11/contrib/elftoolchain/libelftc/_libelftc.h (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/_libelftc.h (revision 367466) @@ -1,95 +1,96 @@ /*- * Copyright (c) 2009 Kai Wang * Copyright (c) 2007,2008 Hyogeol Lee * 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 * in this position and unchanged. * 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 AUTHORS ``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 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: _libelftc.h 3531 2017-06-05 05:08:43Z kaiwang27 $ */ #ifndef __LIBELFTC_H_ #define __LIBELFTC_H_ #include #include "_elftc.h" struct _Elftc_Bfd_Target { const char *bt_name; /* target name. */ unsigned int bt_type; /* target type. */ unsigned int bt_byteorder; /* elf target byteorder. */ unsigned int bt_elfclass; /* elf target class (32/64bit). */ unsigned int bt_machine; /* elf target arch. */ unsigned int bt_osabi; /* elf target abi. */ }; extern struct _Elftc_Bfd_Target _libelftc_targets[]; /** @brief Dynamic vector data for string. */ struct vector_str { /** Current size */ size_t size; /** Total capacity */ size_t capacity; /** String array */ char **container; }; #define BUFFER_GROWFACTOR 1.618 +#define BUFFER_GROW(x) (((x)+0.5)*BUFFER_GROWFACTOR) #define ELFTC_FAILURE 0 #define ELFTC_ISDIGIT(C) (isdigit((C) & 0xFF)) #define ELFTC_SUCCESS 1 #define VECTOR_DEF_CAPACITY 8 #ifdef __cplusplus extern "C" { #endif char *cpp_demangle_ARM(const char *_org); char *cpp_demangle_gnu2(const char *_org); char *cpp_demangle_gnu3(const char *_org); bool is_cpp_mangled_ARM(const char *_org); bool is_cpp_mangled_gnu2(const char *_org); bool is_cpp_mangled_gnu3(const char *_org); unsigned int libelftc_hash_string(const char *); void vector_str_dest(struct vector_str *_vec); int vector_str_find(const struct vector_str *_vs, const char *_str, size_t _len); char *vector_str_get_flat(const struct vector_str *_vs, size_t *_len); bool vector_str_init(struct vector_str *_vs); bool vector_str_pop(struct vector_str *_vs); bool vector_str_push(struct vector_str *_vs, const char *_str, size_t _len); bool vector_str_push_vector(struct vector_str *_dst, struct vector_str *_org); bool vector_str_push_vector_head(struct vector_str *_dst, struct vector_str *_org); char *vector_str_substr(const struct vector_str *_vs, size_t _begin, size_t _end, size_t *_rlen); #ifdef __cplusplus } #endif #endif /* __LIBELFTC_H */ Index: stable/11/contrib/elftoolchain/libelftc/elftc.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc.3 (revision 367466) @@ -1,83 +1,85 @@ .\" Copyright (c) 2012 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: elftc.3 2818 2012-12-24 12:32:48Z jkoshy $ +.\" $Id: elftc.3 3645 2018-10-15 20:17:14Z jkoshy $ .\" -.Dd December 24, 2012 -.Os +.Dd February 12, 2020 .Dt ELFTC 3 +.Os .Sh NAME .Nm elftc .Nd support routines used in the Elftoolchain project .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Sh DESCRIPTION The .Lb libelftc provides support routines used for developing the utilities in the Elftoolchain source tree. .Pp This manual page serves as an overview of the functionality in this library. Additional reference information may be found in the individual manual pages for the functions listed below. .Ss Functional Grouping .Bl -tag -width indent .It "Binary Object Handling" -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn elftc_bfd_find_target Locate a binary object descriptor. .It Fn elftc_bfd_target_class Query the ELF class for a binary object descriptor. .It Fn elftc_bfd_target_byteorder Query the byte order for a binary object descriptor. .It Fn elftc_bfd_target_flavor Query the object format for a binary object descriptor. .It Fn elftc_bfd_target_machine Query the target machine for a binary object descriptor. +.It Fn elftc_bfd_target_osabi +Query the target osabi for a binary object descriptor. .El .It "C++ support" -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn elftc_demangle Decodes a symbol name encoded according to the encoding rules for the C++ language. .El .It "Programming conveniences" -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn elftc_copyfile Copies the contents of a file to another. .It Fn elftc_set_timestamp Portably set the time stamps on a file. .El .It "Project Configuration" -.Bl -tag -compact +.Bl -tag -compact -width indent .It Fn elftc_version Returns a project-wide identifier string that encodes the source revision of the source tree. .El .El .Sh SEE ALSO .Xr dwarf 3 , .Xr elf 3 Index: stable/11/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_bfd_find_target.3 (revision 367466) @@ -1,200 +1,205 @@ .\" Copyright (c) 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: elftc_bfd_find_target.3 3516 2017-02-10 02:33:08Z emaste $ +.\" $Id: elftc_bfd_find_target.3 3752 2019-06-28 01:12:53Z emaste $ .\" -.Dd November 30, 2011 +.Dd February 12, 2020 +.Dt ELFTC_BFD_FIND_TARGET 3 .Os -.Dt ELFTC_BFD_FIND_TARGET .Sh NAME .Nm elftc_bfd_find_target , .Nm elftc_bfd_target_byteorder , .Nm elftc_bfd_target_class , .Nm elftc_bfd_target_flavor , .Nm elftc_bfd_target_machine .Nd binary object descriptor handling .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Vt struct Elftc_Bfd_Target; .Ft "Elftc_Bfd_Target *" .Fn elftc_bfd_find_target "const char *target_name" .Ft "unsigned int" .Fn elftc_bfd_target_class "Elftc_Bfd_Target *target" .Ft "unsigned int" .Fn elftc_bfd_target_byteorder "Elftc_Bfd_Target *target" .Ft Elftc_Bfd_Target_Flavor .Fn elftc_bfd_target_flavor "Elftc_Bfd_Target *target" .Ft "unsigned int" .Fn elftc_bfd_target_machine "Elftc_Bfd_Target *target" +.Ft "unsigned int" +.Fn elftc_bfd_target_osabi "Elftc_Bfd_Target *target" .Sh DESCRIPTION Function .Fn elftc_bfd_find_target locates a binary object descriptor corresponding to the descriptor name in argument .Ar "target_name" . Binary object descriptors encapsulate properties of an object format such as its file representation, ELF class, and byte endianness. .Pp Known descriptor names and their properties include: .Bl -column -offset "XXXX" ".Li elf32-x86-64-freebsd" "Object format" "Byte Order" "Bit Width" .It Em Name Ta Em "Object Format" Ta Em "Byte Order" Ta Em "Bit Width" .It Li binary Ta Binary Ta - Ta - .It Li efi-app-ia32 Ta PE Ta LSB Ta 32 .It Li efi-app-x86_64 Ta PE Ta LSB Ta 64 .It Li elf32-avr Ta ELF Ta LSB Ta 32 .It Li elf32-big Ta ELF Ta MSB Ta 32 .It Li elf32-bigarm Ta ELF Ta MSB Ta 32 .It Li elf32-bigmips Ta ELF Ta MSB Ta 32 .It Li elf32-i386 Ta ELF Ta LSB Ta 32 .It Li elf32-i386-freebsd Ta ELF Ta LSB Ta 32 .It Li elf32-ia64-big Ta ELF Ta MSB Ta 32 .It Li elf32-little Ta ELF Ta LSB Ta 32 .It Li elf32-littlearm Ta ELF Ta LSB Ta 32 .It Li elf32-littlemips Ta ELF Ta LSB Ta 32 .It Li elf32-powerpc Ta ELF Ta MSB Ta 32 .It Li elf32-powerpc-freebsd Ta ELF Ta MSB Ta 32 .It Li elf32-powerpcle Ta ELF Ta LSB Ta 32 +.It Li elf32-riscv Ta ELF Ta LSB Ta 32 +.It Li elf64-riscv Ta ELF Ta LSB Ta 64 +.It Li elf64-riscv-freebsd Ta ELF Ta LSB Ta 64 .It Li elf32-sh Ta ELF Ta MSB Ta 32 .It Li elf32-shl Ta ELF Ta LSB Ta 32 .It Li elf32-sh-nbsd Ta ELF Ta MSB Ta 32 .It Li elf32-shl-nbsd Ta ELF Ta LSB Ta 32 .It Li elf32-shbig-linux Ta ELF Ta MSB Ta 32 .It Li elf32-shl-linux Ta ELF Ta LSB Ta 32 .It Li elf32-sparc Ta ELF Ta MSB Ta 32 .It Li elf32-tradbigmips Ta ELF Ta MSB Ta 32 .It Li elf32-tradlittlemips Ta ELF Ta LSB Ta 32 .It Li elf64-alpha Ta ELF Ta LSB Ta 64 .It Li elf64-alpha-freebsd Ta ELF Ta LSB Ta 64 .It Li elf64-big Ta ELF Ta MSB Ta 64 .It Li elf64-bigmips Ta ELF Ta MSB Ta 64 .It Li elf64-ia64-big Ta ELF Ta MSB Ta 64 .It Li elf64-ia64-little Ta ELF Ta LSB Ta 64 .It Li elf64-little Ta ELF Ta LSB Ta 64 .It Li elf64-littleaarch64 Ta ELF Ta LSB Ta 64 .It Li elf64-littlemips Ta ELF Ta LSB Ta 64 .It Li elf64-powerpc Ta ELF Ta MSB Ta 64 .It Li elf64-powerpc-freebsd Ta ELF Ta MSB Ta 64 .It Li elf64-powerpcle Ta ELF Ta LSB Ta 64 .It Li elf64-sh64 Ta ELF Ta MSB Ta 64 .It Li elf64-sh64l Ta ELF Ta LSB Ta 64 .It Li elf64-sh64-nbsd Ta ELF Ta MSB Ta 64 .It Li elf64-sh64l-nbsd Ta ELF Ta LSB Ta 64 .It Li elf64-sh64big-linux Ta ELF Ta MSB Ta 64 .It Li elf64-sh64-linux Ta ELF Ta LSB Ta 64 .It Li elf64-sparc Ta ELF Ta MSB Ta 64 .It Li elf64-sparc-freebsd Ta ELF Ta MSB Ta 64 .It Li elf64-tradbigmips Ta ELF Ta MSB Ta 64 .It Li elf64-tradlittlemips Ta ELF Ta LSB Ta 64 .It Li elf64-x86-64 Ta ELF Ta LSB Ta 64 .It Li elf64-x86-64-freebsd Ta ELF Ta LSB Ta 64 .It Li ihex Ta IHEX Ta - Ta - .It Li pei-i386 Ta PE Ta LSB Ta 32 .It Li pei-x86-64 Ta PE Ta LSB Ta 64 .It Li srec Ta SREC Ta - Ta - .It Li symbolsrec Ta SREC Ta - Ta - .El .Pp Function .Fn elftc_bfd_target_byteorder returns the ELF byte order associated with target descriptor .Ar target . .Pp Function .Fn elftc_bfd_target_class returns the ELF class associated with target descriptor .Ar target . .Pp Function .Fn elftc_bfd_target_flavor returns the object format associated with target descriptor .Ar target . The known object formats are: .Bl -tag -offset "XXXX" -width ".Dv ETF_BINARY" -compact .It Dv ETF_ELF An ELF object. .It Dv ETF_BINARY Raw binary. .It Dv ETF_IHEX An object encoded in .Tn Intel hex format. .It Dv ETF_NONE An unknown object format. .It Dv ETF_SREC An object encoded as S-records. .El .Sh RETURN VALUES Function .Fn elftc_bfd_find_target returns a valid pointer to an opaque binary target descriptor if successful, or NULL in case of an error. .Pp Function .Fn elftc_bfd_target_byteorder returns the ELF byte order associated with the target descriptor; one of .Dv ELFDATA2MSB or .Dv ELFDATA2LSB . .Pp Function .Fn elftc_bfd_target_class returns the ELF class associated with the target descriptor; one of .Dv ELFCLASS32 or .Dv ELFCLASS64 . .Pp Function .Fn elftc_bfd_target_machine returns the ELF architecture associated with the target descriptor. .Pp Function .Fn elftc_bfd_target_flavor returns one of .Dv ETF_BINARY , .Dv ETF_ELF , .Dv ETF_IHEX or .Dv ETF_SREC if successful or .Dv ETF_NONE in case of error. .Sh EXAMPLES To return descriptor information associated with target name .Dq elf64-big use: .Bd -literal -offset indent struct Elftc_Bfd_Target *t; if ((t = elftc_bfd_find_target("elf64-big")) == NULL) errx(EXIT_FAILURE, "Cannot find target descriptor"); printf("Class: %s\\n", elftc_bfd_target_class(t) == ELFCLASS32 ? "ELFCLASS32" : "ELFCLASS64"); printf("Byteorder: %s\\n", elftc_bfd_target_byteorder(t) == ELFDATA2LSB ? "LSB" : "MSB"); printf("Flavor: %d\\n", elftc_bfd_target_flavor(t)); .Ed .Sh SEE ALSO .Xr elf 3 Index: stable/11/contrib/elftoolchain/libelftc/elftc_bfdtarget.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_bfdtarget.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_bfdtarget.c (revision 367466) @@ -1,73 +1,80 @@ /*- * Copyright (c) 2008,2009 Kai Wang * 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 * in this position and unchanged. * 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(S) ``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(S) 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 "_libelftc.h" ELFTC_VCSID("$Id: elftc_bfdtarget.c 3174 2015-03-27 17:13:41Z emaste $"); Elftc_Bfd_Target * elftc_bfd_find_target(const char *tgt_name) { Elftc_Bfd_Target *tgt; for (tgt = _libelftc_targets; tgt->bt_name; tgt++) if (!strcmp(tgt_name, tgt->bt_name)) return (tgt); return (NULL); /* not found */ } Elftc_Bfd_Target_Flavor elftc_bfd_target_flavor(Elftc_Bfd_Target *tgt) { return (tgt->bt_type); } unsigned int elftc_bfd_target_byteorder(Elftc_Bfd_Target *tgt) { return (tgt->bt_byteorder); } unsigned int elftc_bfd_target_class(Elftc_Bfd_Target *tgt) { return (tgt->bt_elfclass); } unsigned int elftc_bfd_target_machine(Elftc_Bfd_Target *tgt) { return (tgt->bt_machine); } + +unsigned int +elftc_bfd_target_osabi(Elftc_Bfd_Target *tgt) +{ + + return (tgt->bt_osabi); +} Index: stable/11/contrib/elftoolchain/libelftc/elftc_copyfile.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_copyfile.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_copyfile.3 (revision 367466) @@ -1,73 +1,73 @@ .\" Copyright (c) 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: elftc_copyfile.3 2315 2011-12-11 09:28:55Z jkoshy $ +.\" $Id: elftc_copyfile.3 3645 2018-10-15 20:17:14Z jkoshy $ .\" .Dd December 11, 2011 -.Os .Dt ELFTC_COPYFILE 3 +.Os .Sh NAME .Nm elftc_copyfile .Nd convenience function to copy data .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Ft in .Fn elftc_copyfile "int ifd" "int ofd" .Sh DESCRIPTION The function .Fn elftc_copyfile copies the contents of the file referenced by argument .Ar ifd to the file referenced by argument .Ar ofd . .Pp The argument .Ar ifd should contain a file descriptor opened for reading, with its file offset at the beginning of the file. .Pp The argument .Ar ofd should contain a file descriptor opened for writing. -.Sh RETURN VALUE +.Sh RETURN VALUES .Rv -std .Sh ERRORS The function .Fn elftc_copyfile may fail with any of the errors returned by .Xr fstat 2 , -.Xr malloc 3 , .Xr mmap 2 , .Xr munmap 2 , -.Xr read 2 +.Xr read 2 , +.Xr write 2 , or -.Xr write 2 . +.Xr malloc 3 . .Sh SEE ALSO .Xr fstat 2 , -.Xr malloc 3 , .Xr mmap 2 , .Xr munmap 2 , .Xr read 2 , -.Xr write 2 +.Xr write 2 , +.Xr malloc 3 Index: stable/11/contrib/elftoolchain/libelftc/elftc_demangle.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_demangle.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_demangle.3 (revision 367466) @@ -1,116 +1,116 @@ .\" Copyright (c) 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 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: elftc_demangle.3 3182 2015-04-10 16:08:10Z emaste $ +.\" $Id: elftc_demangle.3 3645 2018-10-15 20:17:14Z jkoshy $ .\" .Dd August 24, 2011 -.Os .Dt ELFTC_DEMANGLE 3 +.Os .Sh NAME .Nm elftc_demangle .Nd demangle a C++ name .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Ft int .Fo elftc_demangle .Fa "const char *encodedname" .Fa "char *buffer" .Fa "size_t bufsize" .Fa "unsigned int flags" .Fc .Sh DESCRIPTION Function .Fn elftc_demangle decodes a symbol name encoded according to the type encoding rules for the C++ language and returns a string denoting an equivalent C++ prototype. .Pp Argument .Ar encodedname specifies the encoded symbol name. Argument .Ar buffer denotes a programmer-specified area to place the prototype string in. Argument .Ar bufsize specifies the size of the programmer-specified area. Argument .Ar flags specifies the encoding style in use for argument .Ar encodedname . Supported encoding styles are: .Bl -tag -width ".Dv ELFTC_DEM_GNU3" .It Dv ELFTC_DEM_ARM The encoding style used by compilers adhering to the conventions of the C++ Annotated Reference Manual. .It Dv ELFTC_DEM_GNU2 The encoding style by GNU C++ version 2. .It Dv ELFTC_DEM_GNU3 The encoding style by GNU C++ version 3 and later. .El .Pp Argument .Ar flags may be zero, in which case the function will attempt to guess the encoding scheme from the contents of .Ar encodedname . -.Sh RETURN VALUE +.Sh RETURN VALUES Function .Fn elftc_demangle returns 0 on success. In case of an error it returns -1 and sets the .Va errno variable. .Sh EXAMPLES To decode a name that uses an unknown encoding style use: .Bd -literal -offset indent char buffer[1024]; const char *funcname; funcname = ...; /* points to string to be demangled */ if (elftc_demangle(funcname, buffer, sizeof(buffer), 0) == 0) printf("Demangled name: %\\n", buffer); else perror("Cannot demangle %s", funcname); .Ed .Sh ERRORS Function .Fn elftc_demangle may fail with the following errors: .Bl -tag -width ".Bq Er ENAMETOOLONG" .It Bq Er EINVAL Argument .Ar encodedname was not a valid encoded name. .It Bq Er ENAMETOOLONG The output buffer specified by arguments .Ar buffer and .Ar bufsize was too small to hold the decoded function prototype. .El .Sh SEE ALSO .Xr elf 3 , .Xr elf_strptr 3 Index: stable/11/contrib/elftoolchain/libelftc/elftc_reloc_type_str.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_reloc_type_str.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_reloc_type_str.3 (revision 367466) @@ -1,72 +1,72 @@ .\" Copyright (c) 2016 The FreeBSD Foundation. All rights reserved. .\" .\" This documentation was written by Ed Maste under sponsorship of .\" the FreeBSD Foundation. .\" .\" 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$ .\" .Dd February 19, 2016 -.Os .Dt ELFTC_RELOC_TYPE_STR 3 +.Os .Sh NAME .Nm elftc_reloc_type_str .Nd return the type name for an ELF relocation .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Ft const char * .Fo elftc_reloc_type_str .Fa "unsigned int mach" .Fa "unsigned int type" .Fc .Sh DESCRIPTION Function .Fn elftc_reloc_type_str returns the name for specified relocation type. .Pp Argument .Ar mach specifies the machine (architecture) type. Argument .Ar type specifies the relocation value. -.Sh RETURN VALUE +.Sh RETURN VALUES Function .Fn elftc_program_version returns a pointer to a string constant, or to an internal character buffer if the relocation type is unknown. .Sh EXAMPLES To print ARM relocation type 7, use: .Bd -literal -offset indent #include #include #include (void) printf("%s\en", elftc_reloc_type_str(EM_ARM, 7)); .Ed .Sh ERRORS Function .Fn elftc_reloc_type_str always succeeds. Index: stable/11/contrib/elftoolchain/libelftc/elftc_set_timestamps.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_set_timestamps.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_set_timestamps.3 (revision 367466) @@ -1,84 +1,84 @@ .\" Copyright (c) 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$ .\" .Dd December 15, 2011 -.Os .Dt ELFTC_SET_TIMESTAMPS 3 +.Os .Sh NAME .Nm elftc_set_timestamps .Nd set file timestamps .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Ft int .Fn elftc_set_timestamps "const char *filename" "struct stat *sb" .Sh DESCRIPTION The .Fn elftc_set_timestamps function is used to set the access and modified time stamps on a file based on the contents of a .Vt "struct stat" descriptor. .Pp Argument .Ar filename names an existing file in the file system. .Pp Argument .Ar sb points to structure of type .Vt "struct stat" populated by a prior call to .Xr fstat 2 or .Xr stat 2 . .Sh IMPLEMENTATION NOTES This function will invoke the high-resolution .Xr utimes 2 system call if the underlying operating system supports it. On operating systems lacking support for .Xr utimes 2 , the function will use lower resolution .Xr utime 2 system call. .Sh EXAMPLES To set the access and modified times for a new file to those of an existing file, use: .Bd -literal -offset indent struct stat sb; const char *existing_filename, *new_filename; if (stat(existing_filename, &sb) < 0) err(EXIT_FAILURE, "stat failed"); if (elftc_set_timestamps(new_filename, &sb) < 0) err(EXIT_FAILURE, "timestamps could not be set"); .Ed .Sh SEE ALSO .Xr fstat 2 , .Xr stat 2 , .Xr utime 2 , -.Xr utimes 2 . +.Xr utimes 2 Index: stable/11/contrib/elftoolchain/libelftc/elftc_set_timestamps.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_set_timestamps.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_set_timestamps.c (revision 367466) @@ -1,85 +1,85 @@ /*- * Copyright (c) 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 "libelftc.h" #include "_libelftc.h" ELFTC_VCSID("$Id$"); /* * Determine the field name for the timestamp fields inside a 'struct * stat'. */ -#if defined(__FreeBSD__) || defined(__NetBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) #define ATIME st_atimespec #define MTIME st_mtimespec #define LIBELFTC_HAVE_UTIMES 1 #endif #if defined(__DragonFly__) || defined(__linux__) || defined(__OpenBSD__) #define ATIME st_atim #define MTIME st_mtim #define LIBELFTC_HAVE_UTIMES 1 #endif #if LIBELFTC_HAVE_UTIMES #include #else #include #endif int elftc_set_timestamps(const char *fn, struct stat *sb) { #if LIBELFTC_HAVE_UTIMES /* * The BSD utimes() system call offers timestamps * 1-microsecond granularity. */ struct timeval tv[2]; tv[0].tv_sec = sb->ATIME.tv_sec; tv[0].tv_usec = sb->ATIME.tv_nsec / 1000; tv[1].tv_sec = sb->MTIME.tv_sec; tv[1].tv_usec = sb->MTIME.tv_nsec / 1000; return (utimes(fn, tv)); #else /* * On OSes without utimes(), fall back to the POSIX utime() * call, which offers 1-second granularity. */ struct utimbuf utb; utb.actime = sb->st_atime; utb.modtime = sb->st_mtime; return (utime(fn, &utb)); #endif } Index: stable/11/contrib/elftoolchain/libelftc/elftc_string_table.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_string_table.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_string_table.c (revision 367466) @@ -1,392 +1,393 @@ /*- * Copyright (c) 2013, 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 * in this position and unchanged. * 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(S) ``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(S) 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 "libelftc.h" #include "_libelftc.h" -ELFTC_VCSID("$Id: elftc_string_table.c 2869 2013-01-06 13:29:18Z jkoshy $"); +ELFTC_VCSID("$Id: elftc_string_table.c 3750 2019-06-28 01:12:10Z emaste $"); #define ELFTC_STRING_TABLE_DEFAULT_SIZE (4*1024) #define ELFTC_STRING_TABLE_EXPECTED_STRING_SIZE 16 #define ELFTC_STRING_TABLE_EXPECTED_CHAIN_LENGTH 8 #define ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT (4*1024) struct _Elftc_String_Table_Entry { - int ste_idx; + ssize_t ste_idx; SLIST_ENTRY(_Elftc_String_Table_Entry) ste_next; }; #define ELFTC_STRING_TABLE_COMPACTION_FLAG 0x1 #define ELFTC_STRING_TABLE_LENGTH(st) ((st)->st_len >> 1) #define ELFTC_STRING_TABLE_CLEAR_COMPACTION_FLAG(st) do { \ (st)->st_len &= ~ELFTC_STRING_TABLE_COMPACTION_FLAG; \ } while (0) #define ELFTC_STRING_TABLE_SET_COMPACTION_FLAG(st) do { \ (st)->st_len |= ELFTC_STRING_TABLE_COMPACTION_FLAG; \ } while (0) #define ELFTC_STRING_TABLE_UPDATE_LENGTH(st, len) do { \ (st)->st_len = \ ((st)->st_len & \ ELFTC_STRING_TABLE_COMPACTION_FLAG) | \ ((len) << 1); \ } while (0) struct _Elftc_String_Table { - unsigned int st_len; /* length and flags */ + size_t st_len; /* length and flags */ int st_nbuckets; - int st_string_pool_size; + size_t st_string_pool_size; char *st_string_pool; SLIST_HEAD(_Elftc_String_Table_Bucket, _Elftc_String_Table_Entry) st_buckets[]; }; static struct _Elftc_String_Table_Entry * elftc_string_table_find_hash_entry(Elftc_String_Table *st, const char *string, int *rhashindex) { struct _Elftc_String_Table_Entry *ste; int hashindex; char *s; hashindex = libelftc_hash_string(string) % st->st_nbuckets; if (rhashindex) *rhashindex = hashindex; SLIST_FOREACH(ste, &st->st_buckets[hashindex], ste_next) { - s = st->st_string_pool + abs(ste->ste_idx); + s = st->st_string_pool + labs(ste->ste_idx); assert(s > st->st_string_pool && s < st->st_string_pool + st->st_string_pool_size); if (strcmp(s, string) == 0) return (ste); } return (NULL); } static int elftc_string_table_add_to_pool(Elftc_String_Table *st, const char *string) { char *newpool; - int len, newsize, stlen; + size_t len, newsize, stlen; len = strlen(string) + 1; /* length, including the trailing NUL */ stlen = ELFTC_STRING_TABLE_LENGTH(st); /* Resize the pool, if needed. */ if (stlen + len >= st->st_string_pool_size) { newsize = roundup(st->st_string_pool_size + ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT, ELFTC_STRING_TABLE_POOL_SIZE_INCREMENT); if ((newpool = realloc(st->st_string_pool, newsize)) == NULL) return (0); st->st_string_pool = newpool; st->st_string_pool_size = newsize; } - strcpy(st->st_string_pool + stlen, string); + memcpy(st->st_string_pool + stlen, string, len); ELFTC_STRING_TABLE_UPDATE_LENGTH(st, stlen + len); return (stlen); } Elftc_String_Table * -elftc_string_table_create(int sizehint) +elftc_string_table_create(size_t sizehint) { - int n, nbuckets, tablesize; struct _Elftc_String_Table *st; + int n, nbuckets, tablesize; if (sizehint < ELFTC_STRING_TABLE_DEFAULT_SIZE) sizehint = ELFTC_STRING_TABLE_DEFAULT_SIZE; nbuckets = sizehint / (ELFTC_STRING_TABLE_EXPECTED_CHAIN_LENGTH * ELFTC_STRING_TABLE_EXPECTED_STRING_SIZE); tablesize = sizeof(struct _Elftc_String_Table) + nbuckets * sizeof(struct _Elftc_String_Table_Bucket); if ((st = malloc(tablesize)) == NULL) return (NULL); if ((st->st_string_pool = malloc(sizehint)) == NULL) { free(st); return (NULL); } for (n = 0; n < nbuckets; n++) SLIST_INIT(&st->st_buckets[n]); st->st_len = 0; st->st_nbuckets = nbuckets; st->st_string_pool_size = sizehint; *st->st_string_pool = '\0'; ELFTC_STRING_TABLE_UPDATE_LENGTH(st, 1); return (st); } void elftc_string_table_destroy(Elftc_String_Table *st) { int n; struct _Elftc_String_Table_Entry *s, *t; for (n = 0; n < st->st_nbuckets; n++) SLIST_FOREACH_SAFE(s, &st->st_buckets[n], ste_next, t) - free(s); + free(s); free(st->st_string_pool); free(st); - - return; } Elftc_String_Table * -elftc_string_table_from_section(Elf_Scn *scn, int sizehint) +elftc_string_table_from_section(Elf_Scn *scn, size_t sizehint) { - int len; Elf_Data *d; GElf_Shdr sh; const char *s, *end; Elftc_String_Table *st; + size_t len; /* Verify the type of the section passed in. */ if (gelf_getshdr(scn, &sh) == NULL || sh.sh_type != SHT_STRTAB) { errno = EINVAL; return (NULL); } if ((d = elf_getdata(scn, NULL)) == NULL || d->d_size == 0) { errno = EINVAL; return (NULL); } if ((st = elftc_string_table_create(sizehint)) == NULL) return (NULL); s = d->d_buf; /* * Verify that the first byte of the data buffer is '\0'. */ if (*s != '\0') { errno = EINVAL; goto fail; } end = s + d->d_size; /* * Skip the first '\0' and insert the strings in the buffer, * in order. */ for (s += 1; s < end; s += len) { if (elftc_string_table_insert(st, s) == 0) goto fail; len = strlen(s) + 1; /* Include space for the trailing NUL. */ } return (st); fail: if (st) (void) elftc_string_table_destroy(st); return (NULL); } const char * elftc_string_table_image(Elftc_String_Table *st, size_t *size) { char *r, *s, *end; struct _Elftc_String_Table_Entry *ste; struct _Elftc_String_Table_Bucket *head; - int copied, hashindex, offset, length, newsize; + size_t copied, offset, length, newsize; + int hashindex; /* * For the common case of a string table has not seen * a string deletion, we can just export the current * pool. */ if ((st->st_len & ELFTC_STRING_TABLE_COMPACTION_FLAG) == 0) { if (size) *size = ELFTC_STRING_TABLE_LENGTH(st); return (st->st_string_pool); } /* * Otherwise, compact the string table in-place. */ assert(*st->st_string_pool == '\0'); newsize = 1; end = st->st_string_pool + ELFTC_STRING_TABLE_LENGTH(st); for (r = s = st->st_string_pool + 1; s < end; s += length, r += copied) { copied = 0; length = strlen(s) + 1; ste = elftc_string_table_find_hash_entry(st, s, &hashindex); head = &st->st_buckets[hashindex]; assert(ste != NULL); /* Ignore deleted strings. */ if (ste->ste_idx < 0) { SLIST_REMOVE(head, ste, _Elftc_String_Table_Entry, ste_next); free(ste); continue; } /* Move 'live' strings up. */ offset = newsize; newsize += length; copied = length; if (r == s) /* Nothing removed yet. */ continue; memmove(r, s, copied); /* Update the index for this entry. */ ste->ste_idx = offset; } ELFTC_STRING_TABLE_CLEAR_COMPACTION_FLAG(st); ELFTC_STRING_TABLE_UPDATE_LENGTH(st, newsize); if (size) *size = newsize; return (st->st_string_pool); } size_t elftc_string_table_insert(Elftc_String_Table *st, const char *string) { - int hashindex, idx; struct _Elftc_String_Table_Entry *ste; + ssize_t idx; + int hashindex; hashindex = 0; ste = elftc_string_table_find_hash_entry(st, string, &hashindex); assert(hashindex >= 0 && hashindex < st->st_nbuckets); if (ste == NULL) { if ((ste = malloc(sizeof(*ste))) == NULL) return (0); if ((ste->ste_idx = elftc_string_table_add_to_pool(st, - string)) == 0) { + string)) == 0) { free(ste); return (0); } SLIST_INSERT_HEAD(&st->st_buckets[hashindex], ste, ste_next); } idx = ste->ste_idx; if (idx < 0) /* Undelete. */ - ste->ste_idx = idx = (- idx); + ste->ste_idx = idx = -idx; return (idx); } size_t elftc_string_table_lookup(Elftc_String_Table *st, const char *string) { - int hashindex, idx; struct _Elftc_String_Table_Entry *ste; + ssize_t idx; + int hashindex; ste = elftc_string_table_find_hash_entry(st, string, &hashindex); assert(hashindex >= 0 && hashindex < st->st_nbuckets); if (ste == NULL || (idx = ste->ste_idx) < 0) return (0); return (idx); } int elftc_string_table_remove(Elftc_String_Table *st, const char *string) { - int idx; struct _Elftc_String_Table_Entry *ste; + ssize_t idx; ste = elftc_string_table_find_hash_entry(st, string, NULL); if (ste == NULL || (idx = ste->ste_idx) < 0) return (ELFTC_FAILURE); - assert(idx > 0 && idx < (int) ELFTC_STRING_TABLE_LENGTH(st)); + assert(idx > 0 && (size_t)idx < ELFTC_STRING_TABLE_LENGTH(st)); - ste->ste_idx = (- idx); + ste->ste_idx = -idx; ELFTC_STRING_TABLE_SET_COMPACTION_FLAG(st); return (ELFTC_SUCCESS); } const char * elftc_string_table_to_string(Elftc_String_Table *st, size_t offset) { const char *s; s = st->st_string_pool + offset; /* * Check for: * - An offset value within pool bounds. * - A non-NUL byte at the specified offset. * - The end of the prior string at offset - 1. */ if (offset == 0 || offset >= ELFTC_STRING_TABLE_LENGTH(st) || *s == '\0' || *(s - 1) != '\0') { errno = EINVAL; return (NULL); } return (s); } Index: stable/11/contrib/elftoolchain/libelftc/elftc_string_table_create.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_string_table_create.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_string_table_create.3 (revision 367466) @@ -1,227 +1,226 @@ .\" Copyright (c) 2012-2013 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: elftc_string_table_create.3 2866 2013-01-06 03:20:14Z jkoshy $ +.\" $Id: elftc_string_table_create.3 3750 2019-06-28 01:12:10Z emaste $ .\" -.Dd January 5, 2013 -.Os +.Dd June 27, 2019 .Dt ELFTC_STRING_TABLE_CREATE 3 +.Os .Sh NAME .Nm elftc_string_table_create , .Nm elftc_string_table_destroy , .Nm elftc_string_table_from_section , .Nm elftc_string_table_image , .Nm elftc_string_table_insert , .Nm elftc_string_table_lookup , .Nm elftc_string_table_remove , .Nm elftc_string_table_to_string .Nd convenience routines for handling ELF string tables .Sh SYNOPSIS .In libelftc.h .Ft "Elftc_String_Table *" -.Fn elftc_string_table_create "int sizehint" -.Ft int +.Fn elftc_string_table_create "size_t sizehint" +.Ft void .Fn elftc_string_table_destroy "Elftc_String_Table *table" .Ft "Elftc_String_Table *" -.Fn elftc_string_table_from_section "Elf_Scn *scn" "int sizehint" +.Fn elftc_string_table_from_section "Elf_Scn *scn" "size_t sizehint" .Ft "const char *" .Fo elftc_string_table_image .Fa "Elftc_String_Table *table" .Fa "size_t *size" .Fc .Ft size_t .Fo elftc_string_table_insert .Fa "Elftc_String_Table *table" .Fa "const char *string" .Fc .Ft size_t .Fo elftc_string_table_lookup .Fa "Elftc_String_Table *table" .Fa "const char *string" .Fc .Ft int .Fo elftc_string_table_remove .Fa "Elftc_String_Table *table" .Fa "const char *string" .Fc .Ft "const char *" .Fo elftc_string_table_to_string .Fa "Elftc_String_Table *table" .Fa "size_t offset" .Fc .Sh DESCRIPTION This manual page documents convenience routines for handling ELF string tables. .Pp Function .Fn elftc_string_table_create creates a new, empty string table. The argument .Ar sizehint provides a hint about the expected number of bytes of string data in the table. If the argument .Ar sizehint is zero, an implementation-defined default will be used instead. .Pp Function .Fn elftc_string_table_destroy destroys the previously allocated string table specified by argument .Ar table , and frees the internal resources allocated for it. .Pp Function .Fn elftc_string_table_from_section creates a new string table and initializes it based on the contents of the section specified by argument .Ar scn . This section must be of type .Dv SHT_STRTAB . The argument .Ar sizehint provides a hint about expected number of bytes of string data in the table. If the value of .Ar sizehint is zero, an implementation-default will be used instead. .Pp Function .Fn elftc_string_table_image returns a pointer to the ELF representation of the contents of the string table specified by argument .Ar table . If argument .Ar size is not NULL, the size of the ELF representation of the string table is stored in the location pointed to by argument .Ar size . The function .Fn elftc_string_table_image will compact the string table if the table contains deleted strings. The string offsets returned by prior calls to .Fn elftc_string_table_insert and .Fn elftc_string_table_lookup should be treated as invalid after a call to this function. .Pp Function .Fn elftc_string_table_insert inserts the NUL-terminated string pointed to by argument .Ar string into the string table specified by argument .Ar table , and returns an offset value usable in ELF data structures. Multiple insertions of the same content will return the same offset. The offset returned will remain valid until the next call to .Fn elftc_string_table_image . .Pp Function .Fn elftc_string_table_lookup looks up the string referenced by argument .Ar string in the string table specified by argument .Ar table , and if found, returns the offset associated with the string. -The returned offset will be valid till the next call to function +The returned offset will be valid until the next call to .Fn elftc_string_table_image . .Pp Function .Fn elftc_string_table_remove removes the string pointed by argument .Ar string from the string table referenced by argument .Ar table , if it is present in the string table. .Pp Function .Fn elftc_string_table_to_string returns a pointer to the NUL-terminated string residing at argument .Ar offset in the string table specified by argument .Ar table . The value of argument .Ar offset should be one returned by a prior call to .Fn elftc_string_table_insert or .Fn elftc_string_table_lookup . The returned pointer will remain valid until the next call to .Fn elftc_string_table_insert or .Fn elftc_string_table_image . .Ss Memory Management The .Lb libelftc library manages its own memory allocations. The application should not free the pointers returned by the string table functions. -.El .Sh IMPLEMENTATION NOTES The current implementation is optimized for the case where strings are added to a string table, but rarely removed from it. .Pp The functions .Fn elftc_string_table_insert , .Fn elftc_string_table_lookup , .Fn elftc_string_table_remove and .Fn elftc_string_table_to_string have O(1) asymptotic behavior. The function .Fn elftc_string_table_image can have O(size) asymptotic behavior, where .Ar size denotes the size of the string table. .Sh RETURN VALUES Functions .Fn elftc_string_table_create and .Fn elftc_string_table_from_section return a valid pointer to an opaque structure of type .Vt Elftc_String_Table on success, or NULL in case of an error. .Pp The function .Fn elftc_string_table_image returns a pointer to an in-memory representation of an ELF string table on success, or NULL in case of an error. .Pp Functions .Fn elftc_string_table_insert and .Fn elftc_string_table_lookup return a non-zero offset on success, or zero in case of an error. .Pp Function .Fn elftc_string_table_remove returns a positive value on success, or zero in case of an error. .Pp Function .Fn elftc_string_table_to_string returns a valid pointer on success, or NULL in case of an error. .Sh SEE ALSO .Xr dwarf 3 , .Xr elf 3 , .Xr elftc 3 Index: stable/11/contrib/elftoolchain/libelftc/elftc_timestamp.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_timestamp.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_timestamp.3 (revision 367466) @@ -1,79 +1,79 @@ .\" Copyright (c) 2016 The FreeBSD Foundation. All rights reserved. .\" .\" This documentation was written by Ed Maste under sponsorship of .\" the FreeBSD Foundation. .\" .\" 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$ .\" .Dd August 24, 2016 -.Os .Dt ELFTC_TIMESTAMP 3 +.Os .Sh NAME .Nm elftc_timestamp .Nd return the current or environment-provided timestamp .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Ft int .Fo elftc_timestamp .Fa "time_t *timestamp" .Fc .Sh DESCRIPTION The .Fn elftc_timestamp function returns a timestamp supplied by the .Ev SOURCE_DATE_EPOCH environment variable, or the current time provided by .Xr time 3 if the environment variable is not set. .Pp The .Ar timestamp argument specifies a pointer to the location where the timestamp will be stored. -.Sh RETURN VALUE +.Sh RETURN VALUES Function .Fn elftc_timestamp returns 0 on success, and -1 in the event of an error. .Sh ERRORS The .Fn elftc_timestamp function may fail with the following errors: .Bl -tag -width ".Bq Er ERANGE" .It Bq Er EINVAL .Ev SOURCE_DATE_EPOCH contains invalid characters. .It Bq Er ERANGE .Ev SOURCE_DATE_EPOCH specifies a negative value or a value that cannot be stored in a time_t. .El The .Fn elftc_timestamp function may also fail for any of the reasons described in .Xr strtoll 3 . .Sh SEE ALSO .Xr strtoll 3 , .Xr time 3 Index: stable/11/contrib/elftoolchain/libelftc/elftc_version.3 =================================================================== --- stable/11/contrib/elftoolchain/libelftc/elftc_version.3 (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/elftc_version.3 (revision 367466) @@ -1,79 +1,81 @@ .\" Copyright (c) 2011,2012 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: elftc_version.3 2828 2012-12-30 04:41:27Z jkoshy $ +.\" $Id: elftc_version.3 3645 2018-10-15 20:17:14Z jkoshy $ .\" .Dd December 30, 2012 -.Os .Dt ELFTC_VERSION 3 +.Os .Sh NAME .Nm elftc_version .Nd return a project-wide version identifier string .Sh LIBRARY .Lb libelftc .Sh SYNOPSIS .In libelftc.h .Ft const char * .Fn elftc_version void .Sh DESCRIPTION Function .Fn elftc_version returns a project-wide identifier string that encodes the source revision of the project source tree. .Pp The returned identifier has four space-separated fields: .Bl -tag -width ".Em Project Branch" .It Em "Project-Name" This is always .Dq elftoolchain . .It Em "Project-Branch" The branch name for the project source tree. .It Em "Build-OS" The operating system that the tool chain was compiled for. .It Em "Version-Number" A tree-wide version number extracted from the version control system in use. .El -.Sh RETURN VALUE +.Sh RETURN VALUES Function .Fn elftc_program_version returns a pointer to an internal character buffer. .Sh EXAMPLES To retrieve and print the current toolchain version identifier, use: .Bd -literal -offset indent #include #include (void) printf("%s\en", elftc_version()); .Ed .Pp On the HEAD branch of the project's sources, when checked out using -Subversion and compiled on a NetBSD host, this would print: +Subversion and compiled on a +.Nx +host, this would print: .D1 Dq elftoolchain HEAD NetBSD svn: Ns Em REVINFO where .Em REVINFO would be the current revision information for the project source tree. .Sh ERRORS Function .Fn elftc_program_version always succeeds. Index: stable/11/contrib/elftoolchain/libelftc/libelftc.h =================================================================== --- stable/11/contrib/elftoolchain/libelftc/libelftc.h (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/libelftc.h (revision 367466) @@ -1,100 +1,101 @@ /*- * Copyright (c) 2009 Kai Wang * 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 * in this position and unchanged. * 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(S) ``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(S) 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. * * $FreeBSD: users/kaiwang27/elftc/libelftc.h 392 2009-05-31 19:17:46Z kaiwang27 $ - * $Id: libelftc.h 3489 2016-08-31 00:12:15Z emaste $ + * $Id: libelftc.h 3744 2019-06-28 00:41:47Z emaste $ */ #ifndef _LIBELFTC_H_ #define _LIBELFTC_H_ #include #include /* * Types meant to be opaque to the consumers of these APIs. */ typedef struct _Elftc_Bfd_Target Elftc_Bfd_Target; typedef struct _Elftc_String_Table Elftc_String_Table; /* Target types. */ typedef enum { ETF_NONE, ETF_ELF, ETF_BINARY, ETF_SREC, ETF_IHEX, ETF_PE, ETF_EFI, } Elftc_Bfd_Target_Flavor; /* * Demangler flags. */ /* Name mangling style. */ #define ELFTC_DEM_UNKNOWN 0x00000000U /* Not specified. */ #define ELFTC_DEM_ARM 0x00000001U /* C++ Ann. Ref. Manual. */ #define ELFTC_DEM_GNU2 0x00000002U /* GNU version 2. */ #define ELFTC_DEM_GNU3 0x00000004U /* GNU version 3. */ /* Demangling behaviour control. */ #define ELFTC_DEM_NOPARAM 0x00010000U #ifdef __cplusplus extern "C" { #endif Elftc_Bfd_Target *elftc_bfd_find_target(const char *_tgt_name); Elftc_Bfd_Target_Flavor elftc_bfd_target_flavor(Elftc_Bfd_Target *_tgt); unsigned int elftc_bfd_target_byteorder(Elftc_Bfd_Target *_tgt); unsigned int elftc_bfd_target_class(Elftc_Bfd_Target *_tgt); unsigned int elftc_bfd_target_machine(Elftc_Bfd_Target *_tgt); +unsigned int elftc_bfd_target_osabi(Elftc_Bfd_Target *_tgt); int elftc_copyfile(int _srcfd, int _dstfd); int elftc_demangle(const char *_mangledname, char *_buffer, size_t _bufsize, unsigned int _flags); const char *elftc_reloc_type_str(unsigned int mach, unsigned int type); int elftc_set_timestamps(const char *_filename, struct stat *_sb); -Elftc_String_Table *elftc_string_table_create(int _hint); +Elftc_String_Table *elftc_string_table_create(size_t _sizehint); void elftc_string_table_destroy(Elftc_String_Table *_table); Elftc_String_Table *elftc_string_table_from_section(Elf_Scn *_scn, - int _hint); + size_t _sizehint); const char *elftc_string_table_image(Elftc_String_Table *_table, size_t *_sz); size_t elftc_string_table_insert(Elftc_String_Table *_table, const char *_string); size_t elftc_string_table_lookup(Elftc_String_Table *_table, const char *_string); int elftc_string_table_remove(Elftc_String_Table *_table, const char *_string); const char *elftc_string_table_to_string(Elftc_String_Table *_table, size_t offset); int elftc_timestamp(time_t *_timestamp); const char *elftc_version(void); #ifdef __cplusplus } #endif #endif /* _LIBELFTC_H_ */ Index: stable/11/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/libelftc_bfdtarget.c (revision 367466) @@ -1,463 +1,488 @@ /*- * Copyright (c) 2008,2009 Kai Wang * 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 * in this position and unchanged. * 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(S) ``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(S) 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 "_libelftc.h" -ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3516 2017-02-10 02:33:08Z emaste $"); +ELFTC_VCSID("$Id: libelftc_bfdtarget.c 3752 2019-06-28 01:12:53Z emaste $"); struct _Elftc_Bfd_Target _libelftc_targets[] = { { .bt_name = "binary", .bt_type = ETF_BINARY, }, { .bt_name = "elf32-avr", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_AVR, }, { .bt_name = "elf32-big", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, }, { .bt_name = "elf32-bigarm", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_ARM, }, { .bt_name = "elf32-bigmips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_MIPS, }, { .bt_name = "elf32-i386", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_386, }, { .bt_name = "elf32-i386-freebsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_386, .bt_osabi = ELFOSABI_FREEBSD, }, { .bt_name = "elf32-ia64-big", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_IA_64, }, { .bt_name = "elf32-little", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, }, { .bt_name = "elf32-littlearm", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_ARM, }, { .bt_name = "elf32-littlemips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_MIPS, }, { .bt_name = "elf32-powerpc", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_PPC, }, { .bt_name = "elf32-powerpc-freebsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_PPC, .bt_osabi = ELFOSABI_FREEBSD, }, { .bt_name = "elf32-powerpcle", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_PPC, }, { .bt_name = "elf32-sh", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SH, }, { .bt_name = "elf32-shl", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SH, }, { .bt_name = "elf32-sh-nbsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_NETBSD, }, { .bt_name = "elf32-shl-nbsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_NETBSD, }, { .bt_name = "elf32-shbig-linux", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_LINUX, }, { .bt_name = "elf32-sh-linux", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_LINUX, }, { .bt_name = "elf32-sparc", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_SPARC, }, { .bt_name = "elf32-tradbigmips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_MIPS, }, { .bt_name = "elf32-tradlittlemips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS32, .bt_machine = EM_MIPS, }, { .bt_name = "elf64-alpha", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_ALPHA, }, { .bt_name = "elf64-alpha-freebsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_ALPHA, .bt_osabi = ELFOSABI_FREEBSD }, { .bt_name = "elf64-big", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, }, { .bt_name = "elf64-bigmips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_MIPS, }, { .bt_name = "elf64-ia64-big", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_IA_64, }, { .bt_name = "elf64-ia64-little", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_IA_64, }, { .bt_name = "elf64-little", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, }, { .bt_name = "elf64-littleaarch64", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_AARCH64, }, { .bt_name = "elf64-littlemips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_MIPS, }, { .bt_name = "elf64-powerpc", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_PPC64, }, { .bt_name = "elf64-powerpc-freebsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_PPC64, .bt_osabi = ELFOSABI_FREEBSD, }, { .bt_name = "elf64-powerpcle", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_PPC64, + }, + + { + .bt_name = "elf32-riscv", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS32, + .bt_machine = EM_RISCV, + }, + + { + .bt_name = "elf64-riscv", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2LSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_RISCV, + }, + + { + .bt_name = "elf64-riscv-freebsd", + .bt_type = ETF_ELF, + .bt_byteorder = ELFDATA2MSB, + .bt_elfclass = ELFCLASS64, + .bt_machine = EM_RISCV, + .bt_osabi = ELFOSABI_FREEBSD, }, { .bt_name = "elf64-sh64", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SH, }, { .bt_name = "elf64-sh64l", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SH, }, { .bt_name = "elf64-sh64-nbsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_NETBSD, }, { .bt_name = "elf64-sh64l-nbsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_NETBSD, }, { .bt_name = "elf64-sh64big-linux", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_LINUX, }, { .bt_name = "elf64-sh64-linux", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SH, .bt_osabi = ELFOSABI_LINUX, }, { .bt_name = "elf64-sparc", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SPARCV9, }, { .bt_name = "elf64-sparc-freebsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_SPARCV9, .bt_osabi = ELFOSABI_FREEBSD }, { .bt_name = "elf64-tradbigmips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2MSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_MIPS, }, { .bt_name = "elf64-tradlittlemips", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_MIPS, }, { .bt_name = "elf64-x86-64", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_X86_64, }, { .bt_name = "elf64-x86-64-freebsd", .bt_type = ETF_ELF, .bt_byteorder = ELFDATA2LSB, .bt_elfclass = ELFCLASS64, .bt_machine = EM_X86_64, .bt_osabi = ELFOSABI_FREEBSD }, { .bt_name = "ihex", .bt_type = ETF_IHEX, }, { .bt_name = "srec", .bt_type = ETF_SREC, }, { .bt_name = "symbolsrec", .bt_type = ETF_SREC, }, { .bt_name = "efi-app-ia32", .bt_type = ETF_EFI, .bt_machine = EM_386, }, { .bt_name = "efi-app-x86_64", .bt_type = ETF_EFI, .bt_machine = EM_X86_64, }, { .bt_name = "pei-i386", .bt_type = ETF_PE, .bt_machine = EM_386, }, { .bt_name = "pei-x86-64", .bt_type = ETF_PE, .bt_machine = EM_X86_64, }, { .bt_name = NULL, .bt_type = ETF_NONE, }, }; Index: stable/11/contrib/elftoolchain/libelftc/libelftc_dem_arm.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/libelftc_dem_arm.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/libelftc_dem_arm.c (revision 367466) @@ -1,1216 +1,1217 @@ /*- * Copyright (c) 2008 Hyogeol Lee * 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 * in this position and unchanged. * 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 AUTHORS ``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 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 "_libelftc.h" ELFTC_VCSID("$Id: libelftc_dem_arm.c 3513 2016-12-29 07:04:22Z kaiwang27 $"); /** * @file cpp_demangle_arm.c * @brief Decode function name encoding in ARM. * * Function name encoding in "The Annotated C++ Reference Manual". * * Ref : "The Annotated C++ Reference Manual", Margaet A.Ellis, * Bjarne Stroustrup, AT&T Bell Laboratories 1990, pp 122-126. */ enum encode_type { ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER }; struct cstring { char *buf; size_t size; }; struct demangle_data { bool ptr, ref, cnst, array; struct cstring array_str; const char *p; enum encode_type type; struct vector_str vec; struct vector_str arg; }; #define SIMPLE_HASH(x,y) (64 * x + y) #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) #define CPP_DEMANGLE_ARM_TRY 128 static void dest_cstring(struct cstring *); static void dest_demangle_data(struct demangle_data *); static bool init_cstring(struct cstring *, size_t); static bool init_demangle_data(struct demangle_data *); static bool push_CTDT(const char *, size_t, struct vector_str *); static bool read_array(struct demangle_data *); static bool read_class(struct demangle_data *); static bool read_func(struct demangle_data *); static bool read_func_name(struct demangle_data *); static bool read_func_ptr(struct demangle_data *); static bool read_memptr(struct demangle_data *); static bool read_op(struct demangle_data *); static bool read_op_user(struct demangle_data *); static bool read_qual_name(struct demangle_data *); static int read_subst(struct demangle_data *); static int read_subst_iter(struct demangle_data *); static bool read_type(struct demangle_data *); /** * @brief Decode the input string by the ARM style. * * @return New allocated demangled string or NULL if failed. */ char * cpp_demangle_ARM(const char *org) { struct demangle_data d; size_t arg_begin, arg_len; unsigned int try; char *rtn, *arg; if (org == NULL) return (NULL); if (init_demangle_data(&d) == false) return (NULL); try = 0; rtn = NULL; d.p = org; if (read_func_name(&d) == false) goto clean; if (d.type == ENCODE_OP_CT) { if (push_CTDT("::", 2, &d.vec) == false) goto clean; goto flat; } if (d.type == ENCODE_OP_DT) { if (push_CTDT("::~", 3, &d.vec) == false) goto clean; goto flat; } if (d.type == ENCODE_OP_USER) goto flat; /* function type */ if (*d.p != 'F') goto clean; ++d.p; /* start argument types */ if (VEC_PUSH_STR(&d.vec, "(") == false) goto clean; for (;;) { if (*d.p == 'T') { const int rtn_subst = read_subst(&d); if (rtn_subst == -1) goto clean; else if (rtn_subst == 1) break; continue; } if (*d.p == 'N') { const int rtn_subst_iter = read_subst_iter(&d); if (rtn_subst_iter == -1) goto clean; else if(rtn_subst_iter == 1) break; continue; } arg_begin = d.vec.size; if (read_type(&d) == false) goto clean; if (d.ptr == true) { if (VEC_PUSH_STR(&d.vec, "*") == false) goto clean; d.ptr = false; } if (d.ref == true) { if (VEC_PUSH_STR(&d.vec, "&") == false) goto clean; d.ref = false; } if (d.cnst == true) { if (VEC_PUSH_STR(&d.vec, " const") == false) goto clean; d.cnst = false; } if (d.array == true) { if (vector_str_push(&d.vec, d.array_str.buf, d.array_str.size) == false) goto clean; dest_cstring(&d.array_str); d.array = false; } if (*d.p == '\0') break; if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1, - &arg_len)) == NULL) + &arg_len)) == NULL) goto clean; - if (vector_str_push(&d.arg, arg, arg_len) == false) + if (vector_str_push(&d.arg, arg, arg_len) == false) { + free(arg); goto clean; + } free(arg); if (VEC_PUSH_STR(&d.vec, ", ") == false) goto clean; if (++try > CPP_DEMANGLE_ARM_TRY) goto clean; } /* end argument types */ if (VEC_PUSH_STR(&d.vec, ")") == false) goto clean; flat: rtn = vector_str_get_flat(&d.vec, NULL); clean: dest_demangle_data(&d); return (rtn); } /** * @brief Test input string is encoded by the ARM style. * * @return True if input string is encoded by the ARM style. */ bool is_cpp_mangled_ARM(const char *org) { if (org == NULL) return (false); return (strstr(org, "__") != NULL); } static void dest_cstring(struct cstring *s) { if (s == NULL) return; free(s->buf); s->buf = NULL; s->size = 0; } static void dest_demangle_data(struct demangle_data *d) { if (d != NULL) { vector_str_dest(&d->arg); vector_str_dest(&d->vec); dest_cstring(&d->array_str); } } static bool init_cstring(struct cstring *s, size_t len) { if (s == NULL || len <= 1) return (false); if ((s->buf = malloc(sizeof(char) * len)) == NULL) return (false); s->size = len - 1; return (true); } static bool init_demangle_data(struct demangle_data *d) { if (d == NULL) return (false); d->ptr = false; d->ref = false; d->cnst = false; d->array = false; d->array_str.buf = NULL; d->array_str.size = 0; d->type = ENCODE_FUNC; - if (vector_str_init(&d->vec) == false) + if (!vector_str_init(&d->vec)) return (false); - if (vector_str_init(&d->arg) == false) { + if (!vector_str_init(&d->arg)) { vector_str_dest(&d->vec); - return (false); } return (true); } static bool push_CTDT(const char *s, size_t l, struct vector_str *v) { if (s == NULL || l == 0 || v == NULL) return (false); if (vector_str_push(v, s, l) == false) return (false); assert(v->size > 1); if (VEC_PUSH_STR(v, v->container[v->size - 2]) == false) return (false); if (VEC_PUSH_STR(v, "()") == false) return (false); return (true); } static bool read_array(struct demangle_data *d) { size_t len; const char *end; if (d == NULL || d->p == NULL) return (false); end = d->p; assert(end != NULL); for (;;) { if (*end == '\0') return (false); if (ELFTC_ISDIGIT(*end) == 0) break; ++end; } if (*end != '_') return (false); len = end - d->p; assert(len > 0); dest_cstring(&d->array_str); if (init_cstring(&d->array_str, len + 3) == false) return (false); strncpy(d->array_str.buf + 1, d->p, len); *d->array_str.buf = '['; *(d->array_str.buf + len + 1) = ']'; d->array = true; d->p = end + 1; return (true); } static bool read_class(struct demangle_data *d) { size_t len; char *str; if (d == NULL) return (false); len = strtol(d->p, &str, 10); if (len == 0 && (errno == EINVAL || errno == ERANGE)) return (false); assert(len > 0); assert(str != NULL); if (vector_str_push(&d->vec, str, len) == false) return (false); d->p = str + len; return (true); } static bool read_func(struct demangle_data *d) { size_t len; const char *name; char *delim; if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); if ((delim = strstr(d->p, "__")) == NULL) return (false); len = delim - d->p; assert(len != 0); name = d->p; d->p = delim + 2; if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; if (read_qual_name(d) == false) return (false); } else if (ELFTC_ISDIGIT(*d->p)) { if (read_class(d) == false) return (false); if (VEC_PUSH_STR(&d->vec, "::") == false) return (false); } if (vector_str_push(&d->vec, name, len) == false) return (false); return (true); } static bool read_func_name(struct demangle_data *d) { size_t len; bool rtn; char *op_name; if (d == NULL) return (false); rtn = false; op_name = NULL; assert(d->p != NULL && "d->p (org str) is NULL"); if (*d->p == '_' && *(d->p + 1) == '_') { d->p += 2; d->type = ENCODE_OP; if (read_op(d) == false) return (false); if (d->type == ENCODE_OP_CT || d->type == ENCODE_OP_DT || d->type == ENCODE_OP_USER) return (true); /* skip "__" */ d->p += 2; /* assume delimiter is removed */ if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; assert(d->vec.size > 0); len = strlen(d->vec.container[d->vec.size - 1]); if ((op_name = malloc(sizeof(char) * (len + 1))) == NULL) return (false); snprintf(op_name, len + 1, "%s", d->vec.container[d->vec.size - 1]); vector_str_pop(&d->vec); if (read_qual_name(d) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::") == false) goto clean; if (vector_str_push(&d->vec, op_name, len) == false) goto clean; rtn = true; } else if (ELFTC_ISDIGIT(*d->p)) { assert(d->vec.size > 0); len = strlen(d->vec.container[d->vec.size - 1]); if ((op_name = malloc(sizeof(char) * (len + 1))) == NULL) return (false); snprintf(op_name, len + 1, "%s", d->vec.container[d->vec.size - 1]); vector_str_pop(&d->vec); if (read_class(d) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::") == false) goto clean; if (vector_str_push(&d->vec, op_name, len) == false) goto clean; rtn = true; } } else return (read_func(d)); clean: free(op_name); return (rtn); } /* Read function ptr type */ static bool read_func_ptr(struct demangle_data *d) { struct demangle_data fptr; size_t arg_len, rtn_len; char *arg_type, *rtn_type; int lim; if (d == NULL) return (false); if (init_demangle_data(&fptr) == false) return (false); fptr.p = d->p + 1; lim = 0; arg_type = NULL; rtn_type = NULL; for (;;) { if (read_type(&fptr) == false) { dest_demangle_data(&fptr); return (false); } if (fptr.ptr == true) { if (VEC_PUSH_STR(&fptr.vec, "*") == false) { dest_demangle_data(&fptr); return (false); } fptr.ptr = false; } if (fptr.ref == true) { if (VEC_PUSH_STR(&fptr.vec, "&") == false) { dest_demangle_data(&fptr); return (false); } fptr.ref = false; } if (fptr.cnst == true) { if (VEC_PUSH_STR(&fptr.vec, " const") == false) { dest_demangle_data(&fptr); return (false); } fptr.cnst = false; } if (*fptr.p == '_') break; if (VEC_PUSH_STR(&fptr.vec, ", ") == false) { dest_demangle_data(&fptr); return (false); } if (++lim > CPP_DEMANGLE_ARM_TRY) { dest_demangle_data(&fptr); return (false); } } arg_type = vector_str_get_flat(&fptr.vec, &arg_len); /* skip '_' */ d->p = fptr.p + 1; dest_demangle_data(&fptr); if (init_demangle_data(&fptr) == false) { free(arg_type); return (false); } fptr.p = d->p; lim = 0; if (read_type(&fptr) == false) { free(arg_type); dest_demangle_data(&fptr); return (false); } rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len); d->p = fptr.p; dest_demangle_data(&fptr); if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) { free(rtn_type); free(arg_type); return (false); } free(rtn_type); if (VEC_PUSH_STR(&d->vec, " (*)(") == false) { free(arg_type); return (false); } if (vector_str_push(&d->vec, arg_type, arg_len) == false) { free(arg_type); return (false); } free(arg_type); return (VEC_PUSH_STR(&d->vec, ")")); } static bool read_memptr(struct demangle_data *d) { struct demangle_data mptr; size_t len; bool rtn; char *mptr_str; if (d == NULL || d->p == NULL) return (false); if (init_demangle_data(&mptr) == false) return (false); rtn = false; mptr_str = NULL; mptr.p = d->p; if (*mptr.p == 'Q') { ++mptr.p; if (read_qual_name(&mptr) == false) goto clean; } else { if (read_class(&mptr) == false) goto clean; } d->p = mptr.p; if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL) goto clean; if (vector_str_push(&d->vec, mptr_str, len) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::*") == false) goto clean; rtn = true; clean: free(mptr_str); dest_demangle_data(&mptr); return (rtn); } static bool read_op(struct demangle_data *d) { if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); switch (SIMPLE_HASH(*(d->p), *(d->p+1))) { case SIMPLE_HASH('m', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator*")); case SIMPLE_HASH('d', 'v') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator/")); case SIMPLE_HASH('m', 'd') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator%")); case SIMPLE_HASH('p', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator+")); case SIMPLE_HASH('m', 'i') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator-")); case SIMPLE_HASH('l', 's') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator<<")); case SIMPLE_HASH('r', 's') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator>>")); case SIMPLE_HASH('e', 'q') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator==")); case SIMPLE_HASH('n', 'e') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator!=")); case SIMPLE_HASH('l', 't') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator<")); case SIMPLE_HASH('g', 't') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator>")); case SIMPLE_HASH('l', 'e') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator<=")); case SIMPLE_HASH('g', 'e') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator>=")); case SIMPLE_HASH('a', 'd') : d->p += 2; if (*d->p == 'v') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator/=")); } else return (VEC_PUSH_STR(&d->vec, "operator&")); case SIMPLE_HASH('o', 'r') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator|")); case SIMPLE_HASH('e', 'r') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator^")); case SIMPLE_HASH('a', 'a') : d->p += 2; if (*d->p == 'd') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator&=")); } else return (VEC_PUSH_STR(&d->vec, "operator&&")); case SIMPLE_HASH('o', 'o') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator||")); case SIMPLE_HASH('n', 't') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator!")); case SIMPLE_HASH('c', 'o') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator~")); case SIMPLE_HASH('p', 'p') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator++")); case SIMPLE_HASH('m', 'm') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator--")); case SIMPLE_HASH('a', 's') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator=")); case SIMPLE_HASH('r', 'f') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator->")); case SIMPLE_HASH('a', 'p') : /* apl */ if (*(d->p + 2) != 'l') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator+=")); case SIMPLE_HASH('a', 'm') : d->p += 2; if (*d->p == 'i') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator-=")); } else if (*d->p == 'u') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator*=")); } else if (*d->p == 'd') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator%=")); } return (false); case SIMPLE_HASH('a', 'l') : /* als */ if (*(d->p + 2) != 's') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator<<=")); case SIMPLE_HASH('a', 'r') : /* ars */ if (*(d->p + 2) != 's') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator>>=")); case SIMPLE_HASH('a', 'o') : /* aor */ if (*(d->p + 2) != 'r') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator|=")); case SIMPLE_HASH('a', 'e') : /* aer */ if (*(d->p + 2) != 'r') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator^=")); case SIMPLE_HASH('c', 'm') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator,")); case SIMPLE_HASH('r', 'm') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator->*")); case SIMPLE_HASH('c', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "()")); case SIMPLE_HASH('v', 'c') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "[]")); case SIMPLE_HASH('c', 't') : d->p += 4; d->type = ENCODE_OP_CT; if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; return (read_qual_name(d)); } else if (ELFTC_ISDIGIT(*d->p)) return (read_class(d)); return (false); case SIMPLE_HASH('d', 't') : d->p += 4; d->type = ENCODE_OP_DT; if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; return (read_qual_name(d)); } else if (ELFTC_ISDIGIT(*d->p)) return (read_class(d)); return (false); case SIMPLE_HASH('n', 'w') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator new()")); case SIMPLE_HASH('d', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator delete()")); case SIMPLE_HASH('o', 'p') : /* __op__ */ d->p += 2; d->type = ENCODE_OP_USER; return (read_op_user(d)); default : return (false); }; } static bool read_op_user(struct demangle_data *d) { struct demangle_data from, to; size_t from_len, to_len; bool rtn; char *from_str, *to_str; if (d == NULL) return (false); if (init_demangle_data(&from) == false) return (false); rtn = false; from_str = NULL; to_str = NULL; if (init_demangle_data(&to) == false) goto clean; to.p = d->p; if (*to.p == 'Q') { ++to.p; if (read_qual_name(&to) == false) goto clean; /* pop last '::' */ if (vector_str_pop(&to.vec) == false) goto clean; } else { if (read_class(&to) == false) goto clean; /* skip '__' */ to.p += 2; } if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL) goto clean; from.p = to.p; if (*from.p == 'Q') { ++from.p; if (read_qual_name(&from) == false) goto clean; /* pop last '::' */ if (vector_str_pop(&from.vec) == false) goto clean; } else { if (read_class(&from) == false) goto clean; } if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL) goto clean; if (vector_str_push(&d->vec, from_str, from_len) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::operator ") == false) - return (false); + goto clean; if (vector_str_push(&d->vec, to_str, to_len) == false) goto clean; rtn = VEC_PUSH_STR(&d->vec, "()"); clean: free(to_str); free(from_str); dest_demangle_data(&to); dest_demangle_data(&from); return (rtn); } /* single digit + class names */ static bool read_qual_name(struct demangle_data *d) { int i; char num; if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); num = *d->p - 48; assert(num > 0); ++d->p; for (i = 0; i < num ; ++i) { if (read_class(d) == false) return (false); if (VEC_PUSH_STR(&d->vec, "::") == false) return (false); } if (*d->p != '\0') d->p = d->p + 2; return (true); } /* Return -1 at fail, 0 at success, and 1 at end */ static int read_subst(struct demangle_data *d) { size_t idx; char *str; if (d == NULL) return (-1); idx = strtol(d->p + 1, &str, 10); if (idx == 0 && (errno == EINVAL || errno == ERANGE)) return (-1); assert(idx > 0); assert(str != NULL); d->p = str; if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) return (-1); if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) return (-1); if (*d->p == '\0') return (1); return (0); } static int read_subst_iter(struct demangle_data *d) { int i; size_t idx; char repeat; char *str; if (d == NULL) return (-1); ++d->p; assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); repeat = *d->p - 48; assert(repeat > 1); ++d->p; idx = strtol(d->p, &str, 10); if (idx == 0 && (errno == EINVAL || errno == ERANGE)) return (-1); assert(idx > 0); assert(str != NULL); d->p = str; for (i = 0; i < repeat ; ++i) { if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) return (-1); if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) return (-1); if (i != repeat - 1 && VEC_PUSH_STR(&d->vec, ", ") == false) return (-1); } if (*d->p == '\0') return (1); return (0); } static bool read_type(struct demangle_data *d) { if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' || *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' || *d->p == 'M') { switch (*d->p) { case 'U' : ++d->p; if (VEC_PUSH_STR(&d->vec, "unsigned ") == false) return (false); break; case 'C' : ++d->p; if (*d->p == 'P') d->cnst = true; else { if (VEC_PUSH_STR(&d->vec, "const ") == false) return (false); } break; case 'V' : ++d->p; if (VEC_PUSH_STR(&d->vec, "volatile ") == false) return (false); break; case 'S' : ++d->p; if (VEC_PUSH_STR(&d->vec, "signed ") == false) return (false); break; case 'P' : ++d->p; if (*d->p == 'F') return (read_func_ptr(d)); else d->ptr = true; break; case 'R' : ++d->p; d->ref = true; break; case 'F' : break; case 'A' : ++d->p; if (read_array(d) == false) return (false); break; case 'M' : ++d->p; if (read_memptr(d) == false) return (false); break; default : break; } } if (ELFTC_ISDIGIT(*d->p)) return (read_class(d)); switch (*d->p) { case 'Q' : ++d->p; return (read_qual_name(d)); case 'v' : ++d->p; return (VEC_PUSH_STR(&d->vec, "void")); case 'c' : ++d->p; return (VEC_PUSH_STR(&d->vec, "char")); case 's' : ++d->p; return (VEC_PUSH_STR(&d->vec, "short")); case 'i' : ++d->p; return (VEC_PUSH_STR(&d->vec, "int")); case 'l' : ++d->p; return (VEC_PUSH_STR(&d->vec, "long")); case 'f' : ++d->p; return (VEC_PUSH_STR(&d->vec, "float")); case 'd': ++d->p; return (VEC_PUSH_STR(&d->vec, "double")); case 'r': ++d->p; return (VEC_PUSH_STR(&d->vec, "long double")); case 'e': ++d->p; return (VEC_PUSH_STR(&d->vec, "...")); default: return (false); }; /* NOTREACHED */ return (false); } Index: stable/11/contrib/elftoolchain/libelftc/libelftc_dem_gnu2.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/libelftc_dem_gnu2.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/libelftc_dem_gnu2.c (revision 367466) @@ -1,1365 +1,1366 @@ /*- * Copyright (c) 2008 Hyogeol Lee * 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 * in this position and unchanged. * 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 AUTHORS ``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 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 "_libelftc.h" ELFTC_VCSID("$Id: libelftc_dem_gnu2.c 3513 2016-12-29 07:04:22Z kaiwang27 $"); /** * @file cpp_demangle_gnu2.c * @brief Decode function name encoding in GNU 2. * * Function name encoding in GNU 2 based on ARM style. */ enum encode_type { ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER, ENCODE_OP_TF, ENCODE_OP_TI, ENCODE_OP_VT }; struct cstring { char *buf; size_t size; }; struct demangle_data { bool ptr, ref, cnst, array, cnst_fn, class_name; struct cstring array_str; const char *p; enum encode_type type; struct vector_str vec; struct vector_str arg; }; #define SIMPLE_HASH(x,y) (64 * x + y) #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) #define CPP_DEMANGLE_GNU2_TRY 128 static void dest_cstring(struct cstring *); static void dest_demangle_data(struct demangle_data *); static bool init_cstring(struct cstring *, size_t); static bool init_demangle_data(struct demangle_data *); static bool push_CTDT(const char *, size_t, struct vector_str *); static bool read_array(struct demangle_data *); static bool read_class(struct demangle_data *); static bool read_func(struct demangle_data *); static bool read_func_name(struct demangle_data *); static bool read_func_ptr(struct demangle_data *); static bool read_memptr(struct demangle_data *); static bool read_op(struct demangle_data *); static bool read_op_user(struct demangle_data *); static bool read_qual_name(struct demangle_data *); static int read_subst(struct demangle_data *); static int read_subst_iter(struct demangle_data *); static bool read_type(struct demangle_data *); /** * @brief Decode the input string by the GNU 2 style. * * @return New allocated demangled string or NULL if failed. */ char * cpp_demangle_gnu2(const char *org) { struct demangle_data d; size_t arg_begin, arg_len; unsigned int try; char *rtn, *arg; if (org == NULL) return (NULL); if (init_demangle_data(&d) == false) return (NULL); try = 0; rtn = NULL; d.p = org; if (read_func_name(&d) == false) goto clean; switch (d.type) { case ENCODE_FUNC : case ENCODE_OP : break; case ENCODE_OP_CT : if (push_CTDT("::", 2, &d.vec) == false) goto clean; break; case ENCODE_OP_DT : if (push_CTDT("::~", 3, &d.vec) == false) goto clean; if (VEC_PUSH_STR(&d.vec, "(void)") == false) goto clean; goto flat; case ENCODE_OP_USER : case ENCODE_OP_TF : case ENCODE_OP_TI : case ENCODE_OP_VT : goto flat; } if (*d.p == 'F') ++d.p; else if (*d.p == '\0') { if (d.class_name == true) { if (VEC_PUSH_STR(&d.vec, "(void)") == false) goto clean; goto flat; } else goto clean; } /* start argument types */ if (VEC_PUSH_STR(&d.vec, "(") == false) goto clean; for (;;) { if (*d.p == 'T') { const int rtn_subst = read_subst(&d); if (rtn_subst == -1) goto clean; else if (rtn_subst == 1) break; continue; } if (*d.p == 'N') { const int rtn_subst_iter = read_subst_iter(&d); if (rtn_subst_iter == -1) goto clean; else if(rtn_subst_iter == 1) break; continue; } arg_begin = d.vec.size; if (read_type(&d) == false) goto clean; if (d.ptr == true) { if (VEC_PUSH_STR(&d.vec, "*") == false) goto clean; d.ptr = false; } if (d.ref == true) { if (VEC_PUSH_STR(&d.vec, "&") == false) goto clean; d.ref = false; } if (d.cnst == true) { if (VEC_PUSH_STR(&d.vec, " const") == false) goto clean; d.cnst = false; } if (d.array == true) { if (vector_str_push(&d.vec, d.array_str.buf, d.array_str.size) == false) goto clean; dest_cstring(&d.array_str); d.array = false; } if (*d.p == '\0') break; if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1, - &arg_len)) == NULL) + &arg_len)) == NULL) goto clean; - if (vector_str_push(&d.arg, arg, arg_len) == false) + if (vector_str_push(&d.arg, arg, arg_len) == false) { + free(arg); goto clean; + } free(arg); if (VEC_PUSH_STR(&d.vec, ", ") == false) goto clean; if (++try > CPP_DEMANGLE_GNU2_TRY) goto clean; } /* end argument types */ if (VEC_PUSH_STR(&d.vec, ")") == false) goto clean; flat: if (d.cnst_fn == true && VEC_PUSH_STR(&d.vec, " const") == false) goto clean; rtn = vector_str_get_flat(&d.vec, NULL); clean: dest_demangle_data(&d); return (rtn); } /** * @brief Test input string is encoded by the GNU 2 style. * * @return True if input string is encoded by the GNU 2 style. */ bool is_cpp_mangled_gnu2(const char *org) { char *str; bool rtn = false; if (org == NULL) return (false); /* search valid text to end */ str = strstr(org, "__"); while (str != NULL) { if (*(str + 2) != '\0') { if (*(str + 2) == 'C' || *(str + 2) == 'F' || *(str + 2) == 'Q' || ELFTC_ISDIGIT(*(str + 2))) { rtn |= true; break; } if (*(str + 3) != '\0') { switch (SIMPLE_HASH(*(str + 2), *(str + 3))) { case SIMPLE_HASH('m', 'l') : case SIMPLE_HASH('d', 'v') : case SIMPLE_HASH('m', 'd') : case SIMPLE_HASH('p', 'l') : case SIMPLE_HASH('m', 'i') : case SIMPLE_HASH('l', 's') : case SIMPLE_HASH('r', 's') : case SIMPLE_HASH('e', 'q') : case SIMPLE_HASH('n', 'e') : case SIMPLE_HASH('l', 't') : case SIMPLE_HASH('g', 't') : case SIMPLE_HASH('l', 'e') : case SIMPLE_HASH('g', 'e') : case SIMPLE_HASH('a', 'd') : case SIMPLE_HASH('o', 'r') : case SIMPLE_HASH('e', 'r') : case SIMPLE_HASH('a', 'a') : case SIMPLE_HASH('o', 'o') : case SIMPLE_HASH('n', 't') : case SIMPLE_HASH('c', 'o') : case SIMPLE_HASH('p', 'p') : case SIMPLE_HASH('m', 'm') : case SIMPLE_HASH('a', 's') : case SIMPLE_HASH('r', 'f') : case SIMPLE_HASH('a', 'p') : case SIMPLE_HASH('a', 'm') : case SIMPLE_HASH('a', 'l') : case SIMPLE_HASH('a', 'r') : case SIMPLE_HASH('a', 'o') : case SIMPLE_HASH('a', 'e') : case SIMPLE_HASH('c', 'm') : case SIMPLE_HASH('r', 'm') : case SIMPLE_HASH('c', 'l') : case SIMPLE_HASH('v', 'c') : case SIMPLE_HASH('n', 'w') : case SIMPLE_HASH('d', 'l') : case SIMPLE_HASH('o', 'p') : case SIMPLE_HASH('t', 'f') : case SIMPLE_HASH('t', 'i') : rtn |= true; break; } } } str = strstr(str + 2, "__"); } rtn |= strstr(org, "_$_") != NULL; rtn |= strstr(org, "_vt$") != NULL; return (rtn); } static void dest_cstring(struct cstring *s) { if (s == NULL) return; free(s->buf); s->buf = NULL; s->size = 0; } static void dest_demangle_data(struct demangle_data *d) { if (d != NULL) { vector_str_dest(&d->arg); vector_str_dest(&d->vec); dest_cstring(&d->array_str); } } static bool init_cstring(struct cstring *s, size_t len) { if (s == NULL || len <= 1) return (false); if ((s->buf = malloc(sizeof(char) * len)) == NULL) return (false); s->size = len - 1; return (true); } static bool init_demangle_data(struct demangle_data *d) { if (d == NULL) return (false); d->ptr = false; d->ref = false; d->cnst = false; d->array = false; d->cnst_fn = false; d->class_name = false; d->array_str.buf = NULL; d->array_str.size = 0; d->type = ENCODE_FUNC; - if (vector_str_init(&d->vec) == false) + if (!vector_str_init(&d->vec)) return (false); - if (vector_str_init(&d->arg) == false) { + if (!vector_str_init(&d->arg)) { vector_str_dest(&d->vec); - return (false); } return (true); } static bool push_CTDT(const char *s, size_t l, struct vector_str *v) { if (s == NULL || l == 0 || v == NULL) return (false); if (vector_str_push(v, s, l) == false) return (false); assert(v->size > 1); return (VEC_PUSH_STR(v, v->container[v->size - 2])); } static bool read_array(struct demangle_data *d) { size_t len; const char *end; if (d == NULL || d->p == NULL) return (false); end = d->p; assert(end != NULL); for (;;) { if (*end == '\0') return (false); if (ELFTC_ISDIGIT(*end) == 0) break; ++end; } if (*end != '_') return (false); len = end - d->p; assert(len > 0); dest_cstring(&d->array_str); if (init_cstring(&d->array_str, len + 3) == false) return (false); strncpy(d->array_str.buf + 1, d->p, len); *d->array_str.buf = '['; *(d->array_str.buf + len + 1) = ']'; d->array = true; d->p = end + 1; return (true); } static bool read_class(struct demangle_data *d) { size_t len; char *str; if (d == NULL) return (false); len = strtol(d->p, &str, 10); if (len == 0 && (errno == EINVAL || errno == ERANGE)) return (false); assert(len > 0); assert(str != NULL); if (vector_str_push(&d->vec, str, len) == false) return (false); d->p = str + len; d->class_name = true; return (true); } static bool read_func(struct demangle_data *d) { size_t len; const char *name; char *delim; if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); if ((delim = strstr(d->p, "__")) == NULL) return (false); len = delim - d->p; assert(len != 0); name = d->p; d->p = delim + 2; if (*d->p == 'C') { ++d->p; d->cnst_fn = true; } if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; if (read_qual_name(d) == false) return (false); } else if (ELFTC_ISDIGIT(*d->p)) { if (read_class(d) == false) return (false); if (VEC_PUSH_STR(&d->vec, "::") == false) return (false); } return (vector_str_push(&d->vec, name, len)); } static bool read_func_name(struct demangle_data *d) { size_t len; bool rtn; char *op_name; if (d == NULL) return (false); rtn = false; op_name = NULL; assert(d->p != NULL && "d->p (org str) is NULL"); if (*d->p == '_' && *(d->p + 1) == '_') { d->p += 2; /* CTOR */ if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; d->type = ENCODE_OP_CT; if (read_qual_name(d) == false) return (false); return (vector_str_pop(&d->vec)); } else if (ELFTC_ISDIGIT(*d->p)) { d->type = ENCODE_OP_CT; return (read_class(d)); } d->type = ENCODE_OP; if (read_op(d) == false) { /* not good condition, start function name with '__' */ d->type = ENCODE_FUNC; if (VEC_PUSH_STR(&d->vec, "__") == false) return (false); return (read_func(d)); } if (d->type == ENCODE_OP_USER || d->type == ENCODE_OP_TF || d->type == ENCODE_OP_TI) return (true); /* skip "__" */ d->p += 2; if (*d->p == 'C') { ++d->p; d->cnst_fn = true; } /* assume delimiter is removed */ if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; assert(d->vec.size > 0); len = strlen(d->vec.container[d->vec.size - 1]); if ((op_name = malloc(sizeof(char) * (len + 1))) == NULL) return (false); snprintf(op_name, len + 1, "%s", d->vec.container[d->vec.size - 1]); vector_str_pop(&d->vec); if (read_qual_name(d) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::") == false) goto clean; if (vector_str_push(&d->vec, op_name, len) == false) goto clean; rtn = true; } else if (ELFTC_ISDIGIT(*d->p)) { assert(d->vec.size > 0); len = strlen(d->vec.container[d->vec.size - 1]); if ((op_name = malloc(sizeof(char) * (len + 1))) == NULL) return (false); snprintf(op_name, len + 1, "%s", d->vec.container[d->vec.size - 1]); vector_str_pop(&d->vec); if (read_class(d) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::") == false) goto clean; if (vector_str_push(&d->vec, op_name, len) == false) goto clean; rtn = true; } } else if (memcmp(d->p, "_$_", 3) == 0) { /* DTOR */ d->p += 3; d->type = ENCODE_OP_DT; if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; if (read_qual_name(d) == false) return (false); return (vector_str_pop(&d->vec)); } else if (ELFTC_ISDIGIT(*d->p)) return (read_class(d)); return (false); } else if (memcmp(d->p, "_vt$", 4) == 0) { /* vtable */ d->p += 4; d->type = ENCODE_OP_VT; if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { ++d->p; if (read_qual_name(d) == false) return (false); if (vector_str_pop(&d->vec) == false) return (false); } else if (ELFTC_ISDIGIT(*d->p)) { if (read_class(d) == false) return (false); } return (VEC_PUSH_STR(&d->vec, " virtual table")); } else return (read_func(d)); clean: free(op_name); return (rtn); } /* Read function ptr type */ static bool read_func_ptr(struct demangle_data *d) { struct demangle_data fptr; size_t arg_len, rtn_len; char *arg_type, *rtn_type; int lim; if (d == NULL) return (false); if (init_demangle_data(&fptr) == false) return (false); fptr.p = d->p + 1; lim = 0; arg_type = NULL; rtn_type = NULL; for (;;) { if (read_type(&fptr) == false) { dest_demangle_data(&fptr); return (false); } if (fptr.ptr == true) { if (VEC_PUSH_STR(&fptr.vec, "*") == false) { dest_demangle_data(&fptr); return (false); } fptr.ptr = false; } if (fptr.ref == true) { if (VEC_PUSH_STR(&fptr.vec, "&") == false) { dest_demangle_data(&fptr); return (false); } fptr.ref = false; } if (fptr.cnst == true) { if (VEC_PUSH_STR(&fptr.vec, " const") == false) { dest_demangle_data(&fptr); return (false); } fptr.cnst = false; } if (*fptr.p == '_') break; if (VEC_PUSH_STR(&fptr.vec, ", ") == false) { dest_demangle_data(&fptr); return (false); } if (++lim > CPP_DEMANGLE_GNU2_TRY) { dest_demangle_data(&fptr); return (false); } } arg_type = vector_str_get_flat(&fptr.vec, &arg_len); /* skip '_' */ d->p = fptr.p + 1; dest_demangle_data(&fptr); if (init_demangle_data(&fptr) == false) { free(arg_type); return (false); } fptr.p = d->p; lim = 0; if (read_type(&fptr) == false) { free(arg_type); dest_demangle_data(&fptr); return (false); } rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len); d->p = fptr.p; dest_demangle_data(&fptr); if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) { free(rtn_type); free(arg_type); return (false); } free(rtn_type); if (VEC_PUSH_STR(&d->vec, " (*)(") == false) { free(arg_type); return (false); } if (vector_str_push(&d->vec, arg_type, arg_len) == false) { free(arg_type); return (false); } free(arg_type); return (VEC_PUSH_STR(&d->vec, ")")); } static bool read_memptr(struct demangle_data *d) { struct demangle_data mptr; size_t len; bool rtn; char *mptr_str; if (d == NULL || d->p == NULL) return (false); if (init_demangle_data(&mptr) == false) return (false); rtn = false; mptr_str = NULL; mptr.p = d->p; if (*mptr.p == 'Q') { ++mptr.p; if (read_qual_name(&mptr) == false) goto clean; } else if (read_class(&mptr) == false) goto clean; d->p = mptr.p; if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL) goto clean; if (vector_str_push(&d->vec, mptr_str, len) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::*") == false) goto clean; rtn = true; clean: free(mptr_str); dest_demangle_data(&mptr); return (rtn); } static bool read_op(struct demangle_data *d) { if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); switch (SIMPLE_HASH(*(d->p), *(d->p+1))) { case SIMPLE_HASH('m', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator*")); case SIMPLE_HASH('d', 'v') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator/")); case SIMPLE_HASH('m', 'd') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator%")); case SIMPLE_HASH('p', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator+")); case SIMPLE_HASH('m', 'i') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator-")); case SIMPLE_HASH('l', 's') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator<<")); case SIMPLE_HASH('r', 's') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator>>")); case SIMPLE_HASH('e', 'q') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator==")); case SIMPLE_HASH('n', 'e') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator!=")); case SIMPLE_HASH('l', 't') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator<")); case SIMPLE_HASH('g', 't') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator>")); case SIMPLE_HASH('l', 'e') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator<=")); case SIMPLE_HASH('g', 'e') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator>=")); case SIMPLE_HASH('a', 'd') : d->p += 2; if (*d->p == 'v') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator/=")); } else return (VEC_PUSH_STR(&d->vec, "operator&")); case SIMPLE_HASH('o', 'r') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator|")); case SIMPLE_HASH('e', 'r') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator^")); case SIMPLE_HASH('a', 'a') : d->p += 2; if (*d->p == 'd') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator&=")); } else return (VEC_PUSH_STR(&d->vec, "operator&&")); case SIMPLE_HASH('o', 'o') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator||")); case SIMPLE_HASH('n', 't') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator!")); case SIMPLE_HASH('c', 'o') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator~")); case SIMPLE_HASH('p', 'p') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator++")); case SIMPLE_HASH('m', 'm') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator--")); case SIMPLE_HASH('a', 's') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator=")); case SIMPLE_HASH('r', 'f') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator->")); case SIMPLE_HASH('a', 'p') : /* apl */ if (*(d->p + 2) != 'l') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator+=")); case SIMPLE_HASH('a', 'm') : d->p += 2; if (*d->p == 'i') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator-=")); } else if (*d->p == 'u') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator*=")); } else if (*d->p == 'd') { ++d->p; return (VEC_PUSH_STR(&d->vec, "operator%=")); } return (false); case SIMPLE_HASH('a', 'l') : /* als */ if (*(d->p + 2) != 's') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator<<=")); case SIMPLE_HASH('a', 'r') : /* ars */ if (*(d->p + 2) != 's') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator>>=")); case SIMPLE_HASH('a', 'o') : /* aor */ if (*(d->p + 2) != 'r') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator|=")); case SIMPLE_HASH('a', 'e') : /* aer */ if (*(d->p + 2) != 'r') return (false); d->p += 3; return (VEC_PUSH_STR(&d->vec, "operator^=")); case SIMPLE_HASH('c', 'm') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator,")); case SIMPLE_HASH('r', 'm') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator->*")); case SIMPLE_HASH('c', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "()")); case SIMPLE_HASH('v', 'c') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "[]")); case SIMPLE_HASH('n', 'w') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator new()")); case SIMPLE_HASH('d', 'l') : d->p += 2; return (VEC_PUSH_STR(&d->vec, "operator delete()")); case SIMPLE_HASH('o', 'p') : /* __op__ */ d->p += 2; d->type = ENCODE_OP_USER; return (read_op_user(d)); case SIMPLE_HASH('t', 'f') : d->p += 2; d->type = ENCODE_OP_TF; if (read_type(d) == false) return (false); return (VEC_PUSH_STR(&d->vec, " type_info function")); case SIMPLE_HASH('t', 'i') : d->p += 2; d->type = ENCODE_OP_TI; if (read_type(d) == false) return (false); return (VEC_PUSH_STR(&d->vec, " type_info node")); default : return (false); }; } static bool read_op_user(struct demangle_data *d) { struct demangle_data from, to; size_t from_len, to_len; bool rtn; char *from_str, *to_str; if (d == NULL) return (false); if (init_demangle_data(&from) == false) return (false); rtn = false; from_str = NULL; to_str = NULL; if (init_demangle_data(&to) == false) goto clean; to.p = d->p; if (*to.p == 'Q') { ++to.p; if (read_qual_name(&to) == false) goto clean; /* pop last '::' */ if (vector_str_pop(&to.vec) == false) goto clean; } else { if (read_class(&to) == false) goto clean; /* skip '__' */ to.p += 2; } if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL) goto clean; from.p = to.p; if (*from.p == 'Q') { ++from.p; if (read_qual_name(&from) == false) goto clean; /* pop last '::' */ if (vector_str_pop(&from.vec) == false) goto clean; } else if (read_class(&from) == false) goto clean; if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL) goto clean; if (vector_str_push(&d->vec, from_str, from_len) == false) goto clean; if (VEC_PUSH_STR(&d->vec, "::operator ") == false) goto clean; if (vector_str_push(&d->vec, to_str, to_len) == false) goto clean; rtn = VEC_PUSH_STR(&d->vec, "()"); clean: free(to_str); free(from_str); dest_demangle_data(&to); dest_demangle_data(&from); return (rtn); } /* single digit + class names */ static bool read_qual_name(struct demangle_data *d) { int i; char num; if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); num = *d->p - 48; assert(num > 0); ++d->p; for (i = 0; i < num ; ++i) { if (read_class(d) == false) return (false); if (VEC_PUSH_STR(&d->vec, "::") == false) return (false); } if (*d->p != '\0') d->p = d->p + 2; return (true); } /* Return -1 at fail, 0 at success, and 1 at end */ static int read_subst(struct demangle_data *d) { size_t idx; char *str; if (d == NULL) return (-1); idx = strtol(d->p + 1, &str, 10); if (idx == 0 && (errno == EINVAL || errno == ERANGE)) return (-1); assert(idx > 0); assert(str != NULL); d->p = str; if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) return (-1); if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) return (-1); if (*d->p == '\0') return (1); return (0); } static int read_subst_iter(struct demangle_data *d) { int i; size_t idx; char repeat; char *str; if (d == NULL) return (-1); ++d->p; assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); repeat = *d->p - 48; assert(repeat > 1); ++d->p; idx = strtol(d->p, &str, 10); if (idx == 0 && (errno == EINVAL || errno == ERANGE)) return (-1); assert(idx > 0); assert(str != NULL); d->p = str; for (i = 0; i < repeat ; ++i) { if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) return (-1); if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) return (-1); if (i != repeat - 1 && VEC_PUSH_STR(&d->vec, ", ") == false) return (-1); } if (*d->p == '\0') return (1); return (0); } static bool read_type(struct demangle_data *d) { if (d == NULL) return (false); assert(d->p != NULL && "d->p (org str) is NULL"); while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' || *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' || *d->p == 'M') { switch (*d->p) { case 'U' : ++d->p; if (VEC_PUSH_STR(&d->vec, "unsigned ") == false) return (false); break; case 'C' : ++d->p; if (*d->p == 'P') d->cnst = true; else { if (VEC_PUSH_STR(&d->vec, "const ") == false) return (false); } break; case 'V' : ++d->p; if (VEC_PUSH_STR(&d->vec, "volatile ") == false) return (false); break; case 'S' : ++d->p; if (VEC_PUSH_STR(&d->vec, "signed ") == false) return (false); break; case 'P' : ++d->p; if (*d->p == 'F') return (read_func_ptr(d)); else d->ptr = true; break; case 'R' : ++d->p; d->ref = true; break; case 'F' : break; case 'A' : ++d->p; if (read_array(d) == false) return (false); break; case 'M' : ++d->p; if (read_memptr(d) == false) return (false); break; default : break; } } if (ELFTC_ISDIGIT(*d->p)) return (read_class(d)); switch (*d->p) { case 'Q' : ++d->p; return (read_qual_name(d)); case 'v' : ++d->p; return (VEC_PUSH_STR(&d->vec, "void")); case 'b': ++d->p; return(VEC_PUSH_STR(&d->vec, "bool")); case 'c' : ++d->p; return (VEC_PUSH_STR(&d->vec, "char")); case 's' : ++d->p; return (VEC_PUSH_STR(&d->vec, "short")); case 'i' : ++d->p; return (VEC_PUSH_STR(&d->vec, "int")); case 'l' : ++d->p; return (VEC_PUSH_STR(&d->vec, "long")); case 'f' : ++d->p; return (VEC_PUSH_STR(&d->vec, "float")); case 'd': ++d->p; return (VEC_PUSH_STR(&d->vec, "double")); case 'r': ++d->p; return (VEC_PUSH_STR(&d->vec, "long double")); case 'e': ++d->p; return (VEC_PUSH_STR(&d->vec, "...")); case 'w': ++d->p; return (VEC_PUSH_STR(&d->vec, "wchar_t")); case 'x': ++d->p; return (VEC_PUSH_STR(&d->vec, "long long")); default: return (false); }; /* NOTREACHED */ return (false); } Index: stable/11/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c (revision 367466) @@ -1,3991 +1,3992 @@ /*- * Copyright (c) 2007 Hyogeol Lee * Copyright (c) 2015-2017 Kai Wang * 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 * in this position and unchanged. * 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 AUTHORS ``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 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 "_libelftc.h" ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3583 2017-10-15 15:38:47Z emaste $"); /** * @file cpp_demangle.c * @brief Decode IA-64 C++ ABI style implementation. * * IA-64 standard ABI(Itanium C++ ABI) references. * * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n * http://www.codesourcery.com/cxx-abi/abi-mangling.html */ enum type_qualifier { TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, TYPE_CST, TYPE_VEC, TYPE_RREF }; struct vector_type_qualifier { size_t size, capacity; enum type_qualifier *q_container; struct vector_str ext_name; }; enum read_cmd { READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL, READ_TYPE, READ_FUNC, READ_PTRMEM }; struct read_cmd_item { enum read_cmd cmd; void *data; }; struct vector_read_cmd { size_t size, capacity; struct read_cmd_item *r_container; }; enum push_qualifier { PUSH_ALL_QUALIFIER, PUSH_CV_QUALIFIER, PUSH_NON_CV_QUALIFIER, }; struct cpp_demangle_data { struct vector_str output; /* output string vector */ struct vector_str subst; /* substitution string vector */ struct vector_str tmpl; struct vector_str class_type; struct vector_str *cur_output; /* ptr to current output vec */ struct vector_read_cmd cmd; bool mem_rst; /* restrict member function */ bool mem_vat; /* volatile member function */ bool mem_cst; /* const member function */ bool mem_ref; /* lvalue-ref member func */ bool mem_rref; /* rvalue-ref member func */ bool is_tmpl; /* template args */ bool is_functype; /* function type */ bool ref_qualifier; /* ref qualifier */ enum type_qualifier ref_qualifier_type; /* ref qualifier type */ enum push_qualifier push_qualifier; /* which qualifiers to push */ int func_type; const char *cur; /* current mangled name ptr */ const char *last_sname; /* last source name */ }; struct type_delimit { bool paren; bool firstp; }; #define CPP_DEMANGLE_TRY_LIMIT 128 #define FLOAT_SPRINTF_TRY_LIMIT 5 #define FLOAT_QUADRUPLE_BYTES 16 #define FLOAT_EXTENED_BYTES 10 #define SIMPLE_HASH(x,y) (64 * x + y) #define DEM_PUSH_STR(d,s) cpp_demangle_push_str((d), (s), strlen((s))) #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) static void cpp_demangle_data_dest(struct cpp_demangle_data *); static int cpp_demangle_data_init(struct cpp_demangle_data *, const char *); static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); static int cpp_demangle_push_fp(struct cpp_demangle_data *, char *(*)(const char *, size_t)); static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, size_t); static int cpp_demangle_pop_str(struct cpp_demangle_data *); static int cpp_demangle_push_subst(struct cpp_demangle_data *, const char *, size_t); static int cpp_demangle_push_subst_v(struct cpp_demangle_data *, struct vector_str *); static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, struct vector_type_qualifier *, const char *); static int cpp_demangle_read_array(struct cpp_demangle_data *); static int cpp_demangle_read_encoding(struct cpp_demangle_data *); static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); static int cpp_demangle_read_expression(struct cpp_demangle_data *); static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *, char **); static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, const char *, size_t); static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, const char *, size_t); static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, const char *, size_t, const char *, size_t); static int cpp_demangle_read_function(struct cpp_demangle_data *, int *, struct vector_type_qualifier *); static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); static int cpp_demangle_read_local_name(struct cpp_demangle_data *); static int cpp_demangle_read_name(struct cpp_demangle_data *); static int cpp_demangle_read_name_flat(struct cpp_demangle_data *, char**); static int cpp_demangle_read_nested_name(struct cpp_demangle_data *); static int cpp_demangle_read_number(struct cpp_demangle_data *, long *); static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *, char **); static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); static int cpp_demangle_read_offset(struct cpp_demangle_data *); static int cpp_demangle_read_offset_number(struct cpp_demangle_data *); static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *, struct vector_type_qualifier *); static int cpp_demangle_read_sname(struct cpp_demangle_data *); static int cpp_demangle_read_subst(struct cpp_demangle_data *); static int cpp_demangle_read_subst_std(struct cpp_demangle_data *); static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, const char *); static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); static int cpp_demangle_read_type(struct cpp_demangle_data *, struct type_delimit *); static int cpp_demangle_read_type_flat(struct cpp_demangle_data *, char **); static int cpp_demangle_read_uqname(struct cpp_demangle_data *); static int cpp_demangle_read_v_offset(struct cpp_demangle_data *); static char *decode_fp_to_double(const char *, size_t); static char *decode_fp_to_float(const char *, size_t); static char *decode_fp_to_float128(const char *, size_t); static char *decode_fp_to_float80(const char *, size_t); static char *decode_fp_to_long_double(const char *, size_t); static int hex_to_dec(char); static void vector_read_cmd_dest(struct vector_read_cmd *); static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *, enum read_cmd); static int vector_read_cmd_init(struct vector_read_cmd *); static int vector_read_cmd_pop(struct vector_read_cmd *); static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd, void *); static void vector_type_qualifier_dest(struct vector_type_qualifier *); static int vector_type_qualifier_init(struct vector_type_qualifier *); static int vector_type_qualifier_push(struct vector_type_qualifier *, enum type_qualifier); /** * @brief Decode the input string by IA-64 C++ ABI style. * * GNU GCC v3 use IA-64 standard ABI. * @return New allocated demangled string or NULL if failed. * @todo 1. Testing and more test case. 2. Code cleaning. */ char * cpp_demangle_gnu3(const char *org) { struct cpp_demangle_data ddata; struct vector_str ret_type; struct type_delimit td; ssize_t org_len; unsigned int limit; char *rtn; bool has_ret, more_type; if (org == NULL || (org_len = strlen(org)) < 2) return (NULL); if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { if ((rtn = malloc(org_len + 19)) == NULL) return (NULL); snprintf(rtn, org_len + 19, "global constructors keyed to %s", org + 11); return (rtn); } if (org[0] != '_' || org[1] != 'Z') return (NULL); if (!cpp_demangle_data_init(&ddata, org + 2)) return (NULL); rtn = NULL; has_ret = more_type = false; if (!cpp_demangle_read_encoding(&ddata)) goto clean; /* * Pop function name from substitution candidate list. */ if (*ddata.cur != 0 && ddata.subst.size >= 1) { if (!vector_str_pop(&ddata.subst)) goto clean; } td.paren = false; td.firstp = true; limit = 0; /* * The first type is a return type if we just demangled template * args. (the template args is right next to the function name, * which means it's a template function) */ if (ddata.is_tmpl) { ddata.is_tmpl = false; if (!vector_str_init(&ret_type)) goto clean; ddata.cur_output = &ret_type; has_ret = true; } while (*ddata.cur != '\0') { /* * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 */ if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') break; if (has_ret) { /* Read return type */ if (!cpp_demangle_read_type(&ddata, NULL)) goto clean; } else { /* Read function arg type */ if (!cpp_demangle_read_type(&ddata, &td)) goto clean; } if (has_ret) { /* Push return type to the beginning */ if (!VEC_PUSH_STR(&ret_type, " ")) goto clean; if (!vector_str_push_vector_head(&ddata.output, &ret_type)) goto clean; ddata.cur_output = &ddata.output; vector_str_dest(&ret_type); has_ret = false; more_type = true; } else if (more_type) more_type = false; if (limit++ > CPP_DEMANGLE_TRY_LIMIT) goto clean; } if (more_type) goto clean; if (ddata.output.size == 0) goto clean; if (td.paren && !VEC_PUSH_STR(&ddata.output, ")")) goto clean; if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile")) goto clean; if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const")) goto clean; if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict")) goto clean; if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &")) goto clean; if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&")) goto clean; rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); clean: if (has_ret) vector_str_dest(&ret_type); cpp_demangle_data_dest(&ddata); return (rtn); } static void cpp_demangle_data_dest(struct cpp_demangle_data *d) { if (d == NULL) return; vector_read_cmd_dest(&d->cmd); vector_str_dest(&d->class_type); vector_str_dest(&d->tmpl); vector_str_dest(&d->subst); vector_str_dest(&d->output); } static int cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) { if (d == NULL || cur == NULL) return (0); if (!vector_str_init(&d->output)) return (0); if (!vector_str_init(&d->subst)) goto clean1; if (!vector_str_init(&d->tmpl)) goto clean2; if (!vector_str_init(&d->class_type)) goto clean3; if (!vector_read_cmd_init(&d->cmd)) goto clean4; assert(d->output.container != NULL); assert(d->subst.container != NULL); assert(d->tmpl.container != NULL); assert(d->class_type.container != NULL); d->mem_rst = false; d->mem_vat = false; d->mem_cst = false; d->mem_ref = false; d->mem_rref = false; d->is_tmpl = false; d->is_functype = false; d->ref_qualifier = false; d->push_qualifier = PUSH_ALL_QUALIFIER; d->func_type = 0; d->cur = cur; d->cur_output = &d->output; d->last_sname = NULL; return (1); clean4: vector_str_dest(&d->class_type); clean3: vector_str_dest(&d->tmpl); clean2: vector_str_dest(&d->subst); clean1: vector_str_dest(&d->output); return (0); } static int cpp_demangle_push_fp(struct cpp_demangle_data *ddata, char *(*decoder)(const char *, size_t)) { size_t len; int rtn; const char *fp; char *f; if (ddata == NULL || decoder == NULL) return (0); fp = ddata->cur; while (*ddata->cur != 'E') ++ddata->cur; if ((f = decoder(fp, ddata->cur - fp)) == NULL) return (0); rtn = 0; if ((len = strlen(f)) > 0) rtn = cpp_demangle_push_str(ddata, f, len); free(f); ++ddata->cur; return (rtn); } static int cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, size_t len) { if (ddata == NULL || str == NULL || len == 0) return (0); /* * is_tmpl is used to check if the type (function arg) is right next * to template args, and should always be cleared whenever new string * pushed. */ ddata->is_tmpl = false; return (vector_str_push(ddata->cur_output, str, len)); } static int cpp_demangle_pop_str(struct cpp_demangle_data *ddata) { if (ddata == NULL) return (0); return (vector_str_pop(ddata->cur_output)); } static int cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, size_t len) { if (ddata == NULL || str == NULL || len == 0) return (0); if (!vector_str_find(&ddata->subst, str, len)) return (vector_str_push(&ddata->subst, str, len)); return (1); } static int cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) { size_t str_len; int rtn; char *str; if (ddata == NULL || v == NULL) return (0); if ((str = vector_str_get_flat(v, &str_len)) == NULL) return (0); rtn = cpp_demangle_push_subst(ddata, str, str_len); free(str); return (rtn); } static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, struct vector_type_qualifier *v, const char *type_str) { struct vector_str subst_v; enum type_qualifier t; size_t idx, e_idx, e_len; char *buf; int rtn; bool cv; if (ddata == NULL || v == NULL) return (0); if ((idx = v->size) == 0) return (1); rtn = 0; if (type_str != NULL) { if (!vector_str_init(&subst_v)) return (0); if (!VEC_PUSH_STR(&subst_v, type_str)) goto clean; } cv = true; e_idx = 0; while (idx > 0) { switch (v->q_container[idx - 1]) { case TYPE_PTR: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (!DEM_PUSH_STR(ddata, "*")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, "*")) goto clean; if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_REF: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (!DEM_PUSH_STR(ddata, "&")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, "&")) goto clean; if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_RREF: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (!DEM_PUSH_STR(ddata, "&&")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, "&&")) goto clean; if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_CMX: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (!DEM_PUSH_STR(ddata, " complex")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, " complex")) goto clean; if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_IMG: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (!DEM_PUSH_STR(ddata, " imaginary")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, " imaginary")) goto clean; if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_EXT: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (v->ext_name.size == 0 || e_idx > v->ext_name.size - 1) goto clean; if ((e_len = strlen(v->ext_name.container[e_idx])) == 0) goto clean; if ((buf = malloc(e_len + 2)) == NULL) goto clean; snprintf(buf, e_len + 2, " %s", v->ext_name.container[e_idx]); if (!DEM_PUSH_STR(ddata, buf)) { free(buf); goto clean; } if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, buf)) { free(buf); goto clean; } if (!cpp_demangle_push_subst_v(ddata, &subst_v)) { free(buf); goto clean; } } free(buf); ++e_idx; break; case TYPE_RST: if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && cv) break; if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) break; if (!DEM_PUSH_STR(ddata, " restrict")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, " restrict")) goto clean; if (idx - 1 > 0) { t = v->q_container[idx - 2]; if (t == TYPE_RST || t == TYPE_VAT || t == TYPE_CST) break; } if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_VAT: if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && cv) break; if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) break; if (!DEM_PUSH_STR(ddata, " volatile")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, " volatile")) goto clean; if (idx - 1 > 0) { t = v->q_container[idx - 2]; if (t == TYPE_RST || t == TYPE_VAT || t == TYPE_CST) break; } if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_CST: if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER && cv) break; if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv) break; if (!DEM_PUSH_STR(ddata, " const")) goto clean; if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, " const")) goto clean; if (idx - 1 > 0) { t = v->q_container[idx - 2]; if (t == TYPE_RST || t == TYPE_VAT || t == TYPE_CST) break; } if (!cpp_demangle_push_subst_v(ddata, &subst_v)) goto clean; } break; case TYPE_VEC: cv = false; if (ddata->push_qualifier == PUSH_CV_QUALIFIER) break; if (v->ext_name.size == 0 || e_idx > v->ext_name.size - 1) goto clean; if ((e_len = strlen(v->ext_name.container[e_idx])) == 0) goto clean; if ((buf = malloc(e_len + 12)) == NULL) goto clean; snprintf(buf, e_len + 12, " __vector(%s)", v->ext_name.container[e_idx]); if (!DEM_PUSH_STR(ddata, buf)) { free(buf); goto clean; } if (type_str != NULL) { if (!VEC_PUSH_STR(&subst_v, buf)) { free(buf); goto clean; } if (!cpp_demangle_push_subst_v(ddata, &subst_v)) { free(buf); goto clean; } } free(buf); ++e_idx; break; } --idx; } rtn = 1; clean: if (type_str != NULL) vector_str_dest(&subst_v); return (rtn); } static int cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) { size_t len; if (ddata == NULL || ddata->subst.size <= idx) return (0); if ((len = strlen(ddata->subst.container[idx])) == 0) return (0); if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) return (0); /* skip '_' */ ++ddata->cur; return (1); } static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) { size_t len; if (ddata == NULL || ddata->tmpl.size <= idx) return (0); if ((len = strlen(ddata->tmpl.container[idx])) == 0) return (0); if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) return (0); ++ddata->cur; return (1); } static int cpp_demangle_read_array(struct cpp_demangle_data *ddata) { size_t i, num_len, exp_len, p_idx, idx; const char *num; char *exp; if (ddata == NULL || *(++ddata->cur) == '\0') return (0); if (*ddata->cur == '_') { if (*(++ddata->cur) == '\0') return (0); if (!cpp_demangle_read_type(ddata, NULL)) return (0); if (!DEM_PUSH_STR(ddata, "[]")) return (0); } else { if (ELFTC_ISDIGIT(*ddata->cur) != 0) { num = ddata->cur; while (ELFTC_ISDIGIT(*ddata->cur) != 0) ++ddata->cur; if (*ddata->cur != '_') return (0); num_len = ddata->cur - num; assert(num_len > 0); if (*(++ddata->cur) == '\0') return (0); if (!cpp_demangle_read_type(ddata, NULL)) return (0); if (!DEM_PUSH_STR(ddata, "[")) return (0); if (!cpp_demangle_push_str(ddata, num, num_len)) return (0); if (!DEM_PUSH_STR(ddata, "]")) return (0); } else { p_idx = ddata->output.size; if (!cpp_demangle_read_expression(ddata)) return (0); if ((exp = vector_str_substr(&ddata->output, p_idx, ddata->output.size - 1, &exp_len)) == NULL) return (0); idx = ddata->output.size; for (i = p_idx; i < idx; ++i) if (!vector_str_pop(&ddata->output)) { free(exp); return (0); } if (*ddata->cur != '_') { free(exp); return (0); } ++ddata->cur; if (*ddata->cur == '\0') { free(exp); return (0); } if (!cpp_demangle_read_type(ddata, NULL)) { free(exp); return (0); } if (!DEM_PUSH_STR(ddata, "[")) { free(exp); return (0); } if (!cpp_demangle_push_str(ddata, exp, exp_len)) { free(exp); return (0); } if (!DEM_PUSH_STR(ddata, "]")) { free(exp); return (0); } free(exp); } } return (1); } static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) { const char *num; if (ddata == NULL || *(++ddata->cur) == '\0') return (0); if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { ddata->cur += 2; if (*ddata->cur == '\0') return (0); if (!cpp_demangle_read_encoding(ddata)) return (0); ++ddata->cur; return (1); } switch (*ddata->cur) { case 'b': if (*(ddata->cur + 2) != 'E') return (0); switch (*(++ddata->cur)) { case '0': ddata->cur += 2; return (DEM_PUSH_STR(ddata, "false")); case '1': ddata->cur += 2; return (DEM_PUSH_STR(ddata, "true")); default: return (0); } case 'd': ++ddata->cur; return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); case 'e': ++ddata->cur; if (sizeof(long double) == 10) return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); case 'f': ++ddata->cur; return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); case 'g': ++ddata->cur; if (sizeof(long double) == 16) return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); case 'i': case 'j': case 'l': case 'm': case 'n': case 's': case 't': case 'x': case 'y': if (*(++ddata->cur) == 'n') { if (!DEM_PUSH_STR(ddata, "-")) return (0); ++ddata->cur; } num = ddata->cur; while (*ddata->cur != 'E') { if (!ELFTC_ISDIGIT(*ddata->cur)) return (0); ++ddata->cur; } ++ddata->cur; return (cpp_demangle_push_str(ddata, num, ddata->cur - num - 1)); default: return (0); } } static int cpp_demangle_read_expression(struct cpp_demangle_data *ddata) { if (ddata == NULL || *ddata->cur == '\0') return (0); switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { case SIMPLE_HASH('s', 't'): ddata->cur += 2; return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('s', 'r'): ddata->cur += 2; if (!cpp_demangle_read_type(ddata, NULL)) return (0); if (!cpp_demangle_read_uqname(ddata)) return (0); if (*ddata->cur == 'I') return (cpp_demangle_read_tmpl_args(ddata)); return (1); case SIMPLE_HASH('a', 'a'): /* operator && */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); case SIMPLE_HASH('a', 'd'): /* operator & (unary) */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "&", 1)); case SIMPLE_HASH('a', 'n'): /* operator & */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "&", 1)); case SIMPLE_HASH('a', 'N'): /* operator &= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); case SIMPLE_HASH('a', 'S'): /* operator = */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "=", 1)); case SIMPLE_HASH('c', 'l'): /* operator () */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "()", 2)); case SIMPLE_HASH('c', 'm'): /* operator , */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, ",", 1)); case SIMPLE_HASH('c', 'o'): /* operator ~ */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "~", 1)); case SIMPLE_HASH('c', 'v'): /* operator (cast) */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); case SIMPLE_HASH('d', 'a'): /* operator delete [] */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); case SIMPLE_HASH('d', 'e'): /* operator * (unary) */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "*", 1)); case SIMPLE_HASH('d', 'l'): /* operator delete */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); case SIMPLE_HASH('d', 'v'): /* operator / */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "/", 1)); case SIMPLE_HASH('d', 'V'): /* operator /= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); case SIMPLE_HASH('e', 'o'): /* operator ^ */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "^", 1)); case SIMPLE_HASH('e', 'O'): /* operator ^= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); case SIMPLE_HASH('e', 'q'): /* operator == */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "==", 2)); case SIMPLE_HASH('g', 'e'): /* operator >= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); case SIMPLE_HASH('g', 't'): /* operator > */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, ">", 1)); case SIMPLE_HASH('i', 'x'): /* operator [] */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); case SIMPLE_HASH('l', 'e'): /* operator <= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); case SIMPLE_HASH('l', 's'): /* operator << */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); case SIMPLE_HASH('l', 'S'): /* operator <<= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); case SIMPLE_HASH('l', 't'): /* operator < */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "<", 1)); case SIMPLE_HASH('m', 'i'): /* operator - */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "-", 1)); case SIMPLE_HASH('m', 'I'): /* operator -= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); case SIMPLE_HASH('m', 'l'): /* operator * */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "*", 1)); case SIMPLE_HASH('m', 'L'): /* operator *= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); case SIMPLE_HASH('m', 'm'): /* operator -- */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "--", 2)); case SIMPLE_HASH('n', 'a'): /* operator new[] */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); case SIMPLE_HASH('n', 'e'): /* operator != */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); case SIMPLE_HASH('n', 'g'): /* operator - (unary) */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "-", 1)); case SIMPLE_HASH('n', 't'): /* operator ! */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "!", 1)); case SIMPLE_HASH('n', 'w'): /* operator new */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "new", 3)); case SIMPLE_HASH('o', 'o'): /* operator || */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "||", 2)); case SIMPLE_HASH('o', 'r'): /* operator | */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "|", 1)); case SIMPLE_HASH('o', 'R'): /* operator |= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); case SIMPLE_HASH('p', 'l'): /* operator + */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "+", 1)); case SIMPLE_HASH('p', 'L'): /* operator += */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); case SIMPLE_HASH('p', 'm'): /* operator ->* */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); case SIMPLE_HASH('p', 'p'): /* operator ++ */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "++", 2)); case SIMPLE_HASH('p', 's'): /* operator + (unary) */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "+", 1)); case SIMPLE_HASH('p', 't'): /* operator -> */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "->", 2)); case SIMPLE_HASH('q', 'u'): /* operator ? */ ddata->cur += 2; return (cpp_demangle_read_expression_trinary(ddata, "?", 1, ":", 1)); case SIMPLE_HASH('r', 'm'): /* operator % */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "%", 1)); case SIMPLE_HASH('r', 'M'): /* operator %= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); case SIMPLE_HASH('r', 's'): /* operator >> */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); case SIMPLE_HASH('r', 'S'): /* operator >>= */ ddata->cur += 2; return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); case SIMPLE_HASH('r', 'z'): /* operator sizeof */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); case SIMPLE_HASH('s', 'v'): /* operator sizeof */ ddata->cur += 2; return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); } switch (*ddata->cur) { case 'L': return (cpp_demangle_read_expr_primary(ddata)); case 'T': return (cpp_demangle_read_tmpl_param(ddata)); } return (0); } static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str) { struct vector_str *output; size_t i, p_idx, idx, exp_len; char *exp; output = &ddata->output; p_idx = output->size; if (!cpp_demangle_read_expression(ddata)) return (0); if ((exp = vector_str_substr(output, p_idx, output->size - 1, &exp_len)) == NULL) return (0); idx = output->size; for (i = p_idx; i < idx; ++i) { if (!vector_str_pop(output)) { free(exp); return (0); } } *str = exp; return (1); } static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, const char *name, size_t len) { if (ddata == NULL || name == NULL || len == 0) return (0); if (!cpp_demangle_read_expression(ddata)) return (0); if (!cpp_demangle_push_str(ddata, name, len)) return (0); return (cpp_demangle_read_expression(ddata)); } static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, const char *name, size_t len) { if (ddata == NULL || name == NULL || len == 0) return (0); if (!cpp_demangle_read_expression(ddata)) return (0); return (cpp_demangle_push_str(ddata, name, len)); } static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, const char *name1, size_t len1, const char *name2, size_t len2) { if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || len2 == 0) return (0); if (!cpp_demangle_read_expression(ddata)) return (0); if (!cpp_demangle_push_str(ddata, name1, len1)) return (0); if (!cpp_demangle_read_expression(ddata)) return (0); if (!cpp_demangle_push_str(ddata, name2, len2)) return (0); return (cpp_demangle_read_expression(ddata)); } static int cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, struct vector_type_qualifier *v) { struct type_delimit td; struct read_cmd_item *rc; size_t class_type_size, class_type_len, limit; const char *class_type; int i; bool paren, non_cv_qualifier; if (ddata == NULL || *ddata->cur != 'F' || v == NULL) return (0); ++ddata->cur; if (*ddata->cur == 'Y') { if (ext_c != NULL) *ext_c = 1; ++ddata->cur; } /* Return type */ if (!cpp_demangle_read_type(ddata, NULL)) return (0); if (*ddata->cur != 'E') { if (!DEM_PUSH_STR(ddata, " ")) return (0); non_cv_qualifier = false; if (v->size > 0) { for (i = 0; (size_t) i < v->size; i++) { if (v->q_container[i] != TYPE_RST && v->q_container[i] != TYPE_VAT && v->q_container[i] != TYPE_CST) { non_cv_qualifier = true; break; } } } paren = false; rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM); if (non_cv_qualifier || rc != NULL) { if (!DEM_PUSH_STR(ddata, "(")) return (0); paren = true; } /* Push non-cv qualifiers. */ ddata->push_qualifier = PUSH_NON_CV_QUALIFIER; if (!cpp_demangle_push_type_qualifier(ddata, v, NULL)) return (0); if (rc) { if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " ")) return (0); if ((class_type_size = ddata->class_type.size) == 0) return (0); class_type = ddata->class_type.container[class_type_size - 1]; if (class_type == NULL) return (0); if ((class_type_len = strlen(class_type)) == 0) return (0); if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) return (0); if (!DEM_PUSH_STR(ddata, "::*")) return (0); /* Push pointer-to-member qualifiers. */ ddata->push_qualifier = PUSH_ALL_QUALIFIER; if (!cpp_demangle_push_type_qualifier(ddata, rc->data, NULL)) return (0); ++ddata->func_type; } if (paren) { if (!DEM_PUSH_STR(ddata, ")")) return (0); paren = false; } td.paren = false; td.firstp = true; limit = 0; ddata->is_functype = true; for (;;) { if (!cpp_demangle_read_type(ddata, &td)) return (0); if (*ddata->cur == 'E') break; if (limit++ > CPP_DEMANGLE_TRY_LIMIT) return (0); } ddata->is_functype = false; if (td.paren) { if (!DEM_PUSH_STR(ddata, ")")) return (0); td.paren = false; } /* Push CV qualifiers. */ ddata->push_qualifier = PUSH_CV_QUALIFIER; if (!cpp_demangle_push_type_qualifier(ddata, v, NULL)) return (0); ddata->push_qualifier = PUSH_ALL_QUALIFIER; /* Release type qualifier vector. */ vector_type_qualifier_dest(v); if (!vector_type_qualifier_init(v)) return (0); /* Push ref-qualifiers. */ if (ddata->ref_qualifier) { switch (ddata->ref_qualifier_type) { case TYPE_REF: if (!DEM_PUSH_STR(ddata, " &")) return (0); break; case TYPE_RREF: if (!DEM_PUSH_STR(ddata, " &&")) return (0); break; default: return (0); } ddata->ref_qualifier = false; } } ++ddata->cur; return (1); } /* read encoding, encoding are function name, data name, special-name */ static int cpp_demangle_read_encoding(struct cpp_demangle_data *ddata) { char *name, *type, *num_str; long offset; int rtn; if (ddata == NULL || *ddata->cur == '\0') return (0); /* special name */ switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { case SIMPLE_HASH('G', 'A'): if (!DEM_PUSH_STR(ddata, "hidden alias for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_encoding(ddata)); case SIMPLE_HASH('G', 'R'): if (!DEM_PUSH_STR(ddata, "reference temporary #")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); if (!cpp_demangle_read_name_flat(ddata, &name)) return (0); rtn = 0; if (!cpp_demangle_read_number_as_string(ddata, &num_str)) goto clean1; if (!DEM_PUSH_STR(ddata, num_str)) goto clean2; if (!DEM_PUSH_STR(ddata, " for ")) goto clean2; if (!DEM_PUSH_STR(ddata, name)) goto clean2; rtn = 1; clean2: free(num_str); clean1: free(name); return (rtn); case SIMPLE_HASH('G', 'T'): ddata->cur += 2; if (*ddata->cur == '\0') return (0); switch (*ddata->cur) { case 'n': if (!DEM_PUSH_STR(ddata, "non-transaction clone for ")) return (0); break; case 't': default: if (!DEM_PUSH_STR(ddata, "transaction clone for ")) return (0); break; } ++ddata->cur; return (cpp_demangle_read_encoding(ddata)); case SIMPLE_HASH('G', 'V'): /* sentry object for 1 time init */ if (!DEM_PUSH_STR(ddata, "guard variable for ")) return (0); ddata->cur += 2; break; case SIMPLE_HASH('T', 'c'): /* virtual function covariant override thunk */ if (!DEM_PUSH_STR(ddata, "virtual function covariant override ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); if (!cpp_demangle_read_offset(ddata)) return (0); if (!cpp_demangle_read_offset(ddata)) return (0); return (cpp_demangle_read_encoding(ddata)); case SIMPLE_HASH('T', 'C'): /* construction vtable */ if (!DEM_PUSH_STR(ddata, "construction vtable for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); if (!cpp_demangle_read_type_flat(ddata, &type)) return (0); rtn = 0; if (!cpp_demangle_read_number(ddata, &offset)) goto clean3; if (*ddata->cur++ != '_') goto clean3; if (!cpp_demangle_read_type(ddata, NULL)) goto clean3; if (!DEM_PUSH_STR(ddata, "-in-")) goto clean3; if (!DEM_PUSH_STR(ddata, type)) goto clean3; rtn = 1; clean3: free(type); return (rtn); case SIMPLE_HASH('T', 'D'): /* typeinfo common proxy */ break; case SIMPLE_HASH('T', 'F'): /* typeinfo fn */ if (!DEM_PUSH_STR(ddata, "typeinfo fn for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('T', 'h'): /* virtual function non-virtual override thunk */ if (!DEM_PUSH_STR(ddata, "virtual function non-virtual override ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); if (!cpp_demangle_read_nv_offset(ddata)) return (0); return (cpp_demangle_read_encoding(ddata)); case SIMPLE_HASH('T', 'H'): /* TLS init function */ if (!DEM_PUSH_STR(ddata, "TLS init function for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); break; case SIMPLE_HASH('T', 'I'): /* typeinfo structure */ if (!DEM_PUSH_STR(ddata, "typeinfo for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('T', 'J'): /* java class */ if (!DEM_PUSH_STR(ddata, "java Class for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('T', 'S'): /* RTTI name (NTBS) */ if (!DEM_PUSH_STR(ddata, "typeinfo name for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('T', 'T'): /* VTT table */ if (!DEM_PUSH_STR(ddata, "VTT for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('T', 'v'): /* virtual function virtual override thunk */ if (!DEM_PUSH_STR(ddata, "virtual function virtual override ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); if (!cpp_demangle_read_v_offset(ddata)) return (0); return (cpp_demangle_read_encoding(ddata)); case SIMPLE_HASH('T', 'V'): /* virtual table */ if (!DEM_PUSH_STR(ddata, "vtable for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('T', 'W'): /* TLS wrapper function */ if (!DEM_PUSH_STR(ddata, "TLS wrapper function for ")) return (0); ddata->cur += 2; if (*ddata->cur == '\0') return (0); break; } return (cpp_demangle_read_name(ddata)); } static int cpp_demangle_read_local_name(struct cpp_demangle_data *ddata) { struct vector_str local_name; struct type_delimit td; size_t limit; bool more_type; if (ddata == NULL) return (0); if (*(++ddata->cur) == '\0') return (0); - vector_str_init(&local_name); + if (!vector_str_init(&local_name)) + return (0); ddata->cur_output = &local_name; if (!cpp_demangle_read_encoding(ddata)) { vector_str_dest(&local_name); return (0); } ddata->cur_output = &ddata->output; td.paren = false; td.firstp = true; more_type = false; limit = 0; /* * The first type is a return type if we just demangled template * args. (the template args is right next to the function name, * which means it's a template function) */ if (ddata->is_tmpl) { ddata->is_tmpl = false; /* Read return type */ if (!cpp_demangle_read_type(ddata, NULL)) { vector_str_dest(&local_name); return (0); } more_type = true; } /* Now we can push the name after possible return type is handled. */ if (!vector_str_push_vector(&ddata->output, &local_name)) { vector_str_dest(&local_name); return (0); } vector_str_dest(&local_name); while (*ddata->cur != '\0') { if (!cpp_demangle_read_type(ddata, &td)) return (0); if (more_type) more_type = false; if (*ddata->cur == 'E') break; if (limit++ > CPP_DEMANGLE_TRY_LIMIT) return (0); } if (more_type) return (0); if (*(++ddata->cur) == '\0') return (0); if (td.paren == true) { if (!DEM_PUSH_STR(ddata, ")")) return (0); td.paren = false; } if (*ddata->cur == 's') ++ddata->cur; else { if (!DEM_PUSH_STR(ddata, "::")) return (0); if (!cpp_demangle_read_name(ddata)) return (0); } if (*ddata->cur == '_') { ++ddata->cur; while (ELFTC_ISDIGIT(*ddata->cur) != 0) ++ddata->cur; } return (1); } static int cpp_demangle_read_name(struct cpp_demangle_data *ddata) { struct vector_str *output, v; size_t p_idx, subst_str_len; int rtn; char *subst_str; if (ddata == NULL || *ddata->cur == '\0') return (0); output = ddata->cur_output; subst_str = NULL; switch (*ddata->cur) { case 'S': return (cpp_demangle_read_subst(ddata)); case 'N': return (cpp_demangle_read_nested_name(ddata)); case 'Z': return (cpp_demangle_read_local_name(ddata)); } if (!vector_str_init(&v)) return (0); p_idx = output->size; rtn = 0; if (!cpp_demangle_read_uqname(ddata)) goto clean; if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, &subst_str_len)) == NULL) goto clean; if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { rtn = 1; goto clean; } if (!vector_str_push(&v, subst_str, subst_str_len)) goto clean; if (!cpp_demangle_push_subst_v(ddata, &v)) goto clean; if (*ddata->cur == 'I') { p_idx = output->size; if (!cpp_demangle_read_tmpl_args(ddata)) goto clean; free(subst_str); if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, &subst_str_len)) == NULL) goto clean; if (!vector_str_push(&v, subst_str, subst_str_len)) goto clean; if (!cpp_demangle_push_subst_v(ddata, &v)) goto clean; } rtn = 1; clean: free(subst_str); vector_str_dest(&v); return (rtn); } static int cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str) { struct vector_str *output; size_t i, p_idx, idx, name_len; char *name; output = ddata->cur_output; p_idx = output->size; if (!cpp_demangle_read_name(ddata)) return (0); if ((name = vector_str_substr(output, p_idx, output->size - 1, &name_len)) == NULL) return (0); idx = output->size; for (i = p_idx; i < idx; ++i) { if (!vector_str_pop(output)) { free(name); return (0); } } *str = name; return (1); } static int cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) { struct vector_str *output, v; size_t limit, p_idx, subst_str_len; int rtn; char *subst_str; if (ddata == NULL || *ddata->cur != 'N') return (0); if (*(++ddata->cur) == '\0') return (0); do { switch (*ddata->cur) { case 'r': ddata->mem_rst = true; break; case 'V': ddata->mem_vat = true; break; case 'K': ddata->mem_cst = true; break; case 'R': ddata->mem_ref = true; break; case 'O': ddata->mem_rref = true; break; default: goto next; } } while (*(++ddata->cur)); next: output = ddata->cur_output; if (!vector_str_init(&v)) return (0); rtn = 0; limit = 0; for (;;) { p_idx = output->size; switch (*ddata->cur) { case 'I': if (!cpp_demangle_read_tmpl_args(ddata)) goto clean; break; case 'S': if (!cpp_demangle_read_subst(ddata)) goto clean; break; case 'T': if (!cpp_demangle_read_tmpl_param(ddata)) goto clean; break; default: if (!cpp_demangle_read_uqname(ddata)) goto clean; } if (p_idx == output->size) goto next_comp; if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, &subst_str_len)) == NULL) goto clean; if (!vector_str_push(&v, subst_str, subst_str_len)) { free(subst_str); goto clean; } free(subst_str); if (!cpp_demangle_push_subst_v(ddata, &v)) goto clean; next_comp: if (*ddata->cur == 'E') break; else if (*ddata->cur != 'I' && *ddata->cur != 'C' && *ddata->cur != 'D' && p_idx != output->size) { if (!DEM_PUSH_STR(ddata, "::")) goto clean; if (!VEC_PUSH_STR(&v, "::")) goto clean; } if (limit++ > CPP_DEMANGLE_TRY_LIMIT) goto clean; } ++ddata->cur; rtn = 1; clean: vector_str_dest(&v); return (rtn); } /* * read number * number ::= [n] */ static int cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) { long len, negative_factor; if (ddata == NULL || rtn == NULL) return (0); negative_factor = 1; if (*ddata->cur == 'n') { negative_factor = -1; ++ddata->cur; } if (ELFTC_ISDIGIT(*ddata->cur) == 0) return (0); errno = 0; if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && errno != 0) return (0); while (ELFTC_ISDIGIT(*ddata->cur) != 0) ++ddata->cur; assert(len >= 0); assert(negative_factor == 1 || negative_factor == -1); *rtn = len * negative_factor; return (1); } static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str) { long n; if (!cpp_demangle_read_number(ddata, &n)) { *str = NULL; return (0); } if (asprintf(str, "%ld", n) < 0) { *str = NULL; return (0); } return (1); } static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) { if (ddata == NULL) return (0); if (!DEM_PUSH_STR(ddata, "offset : ")) return (0); return (cpp_demangle_read_offset_number(ddata)); } /* read offset, offset are nv-offset, v-offset */ static int cpp_demangle_read_offset(struct cpp_demangle_data *ddata) { if (ddata == NULL) return (0); if (*ddata->cur == 'h') { ++ddata->cur; return (cpp_demangle_read_nv_offset(ddata)); } else if (*ddata->cur == 'v') { ++ddata->cur; return (cpp_demangle_read_v_offset(ddata)); } return (0); } static int cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) { bool negative; const char *start; if (ddata == NULL || *ddata->cur == '\0') return (0); /* offset could be negative */ if (*ddata->cur == 'n') { negative = true; start = ddata->cur + 1; } else { negative = false; start = ddata->cur; } while (*ddata->cur != '_') ++ddata->cur; if (negative && !DEM_PUSH_STR(ddata, "-")) return (0); assert(start != NULL); if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) return (0); if (!DEM_PUSH_STR(ddata, " ")) return (0); ++ddata->cur; return (1); } static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata, struct vector_type_qualifier *v) { size_t class_type_len, i, idx, p_idx; int p_func_type, rtn; char *class_type; if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') return (0); p_idx = ddata->output.size; if (!cpp_demangle_read_type(ddata, NULL)) return (0); if ((class_type = vector_str_substr(&ddata->output, p_idx, ddata->output.size - 1, &class_type_len)) == NULL) return (0); rtn = 0; idx = ddata->output.size; for (i = p_idx; i < idx; ++i) if (!vector_str_pop(&ddata->output)) goto clean1; if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v)) goto clean1; if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) goto clean2; p_func_type = ddata->func_type; if (!cpp_demangle_read_type(ddata, NULL)) goto clean3; if (p_func_type == ddata->func_type) { if (!DEM_PUSH_STR(ddata, " ")) goto clean3; if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) goto clean3; if (!DEM_PUSH_STR(ddata, "::*")) goto clean3; } rtn = 1; clean3: if (!vector_str_pop(&ddata->class_type)) rtn = 0; clean2: if (!vector_read_cmd_pop(&ddata->cmd)) rtn = 0; clean1: free(class_type); vector_type_qualifier_dest(v); if (!vector_type_qualifier_init(v)) return (0); return (rtn); } /* read source-name, source-name is */ static int cpp_demangle_read_sname(struct cpp_demangle_data *ddata) { long len; int err; if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || len <= 0) return (0); if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) err = DEM_PUSH_STR(ddata, "(anonymous namespace)"); else err = cpp_demangle_push_str(ddata, ddata->cur, len); if (err == 0) return (0); - assert(ddata->output.size > 0); + assert(ddata->cur_output->size > 0); if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL) ddata->last_sname = - ddata->output.container[ddata->output.size - 1]; + ddata->cur_output->container[ddata->output.size - 1]; ddata->cur += len; return (1); } static int cpp_demangle_read_subst(struct cpp_demangle_data *ddata) { long nth; if (ddata == NULL || *ddata->cur == '\0') return (0); /* abbreviations of the form Sx */ switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { case SIMPLE_HASH('S', 'a'): /* std::allocator */ if (!DEM_PUSH_STR(ddata, "std::allocator")) return (0); ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::allocator")); return (1); case SIMPLE_HASH('S', 'b'): /* std::basic_string */ if (!DEM_PUSH_STR(ddata, "std::basic_string")) return (0); ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_string")); return (1); case SIMPLE_HASH('S', 'd'): /* std::basic_iostream > */ if (!DEM_PUSH_STR(ddata, "std::basic_iostream >")) return (0); ddata->last_sname = "basic_iostream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_iostream >")); return (1); case SIMPLE_HASH('S', 'i'): /* std::basic_istream > */ if (!DEM_PUSH_STR(ddata, "std::basic_istream >")) return (0); ddata->last_sname = "basic_istream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_istream >")); return (1); case SIMPLE_HASH('S', 'o'): /* std::basic_ostream > */ if (!DEM_PUSH_STR(ddata, "std::basic_ostream >")) return (0); ddata->last_sname = "basic_ostream"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_ostream >")); return (1); case SIMPLE_HASH('S', 's'): /* * std::basic_string, * std::allocator > * * a.k.a std::string */ if (!DEM_PUSH_STR(ddata, "std::basic_string, std::allocator >")) return (0); ddata->last_sname = "string"; ddata->cur += 2; if (*ddata->cur == 'I') return (cpp_demangle_read_subst_stdtmpl(ddata, "std::basic_string," " std::allocator >")); return (1); case SIMPLE_HASH('S', 't'): /* std:: */ return (cpp_demangle_read_subst_std(ddata)); } if (*(++ddata->cur) == '\0') return (0); /* Skip unknown substitution abbreviations. */ if (!(*ddata->cur >= '0' && *ddata->cur <= '9') && !(*ddata->cur >= 'A' && *ddata->cur <= 'Z') && *ddata->cur != '_') { ++ddata->cur; return (1); } /* substitution */ if (*ddata->cur == '_') return (cpp_demangle_get_subst(ddata, 0)); else { errno = 0; /* substitution number is base 36 */ if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && errno != 0) return (0); /* first was '_', so increase one */ ++nth; while (*ddata->cur != '_') ++ddata->cur; assert(nth > 0); return (cpp_demangle_get_subst(ddata, nth)); } /* NOTREACHED */ return (0); } static int cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) { struct vector_str *output, v; size_t p_idx, subst_str_len; int rtn; char *subst_str; if (ddata == NULL) return (0); if (!vector_str_init(&v)) return (0); subst_str = NULL; rtn = 0; if (!DEM_PUSH_STR(ddata, "std::")) goto clean; if (!VEC_PUSH_STR(&v, "std::")) goto clean; ddata->cur += 2; output = ddata->cur_output; p_idx = output->size; if (!cpp_demangle_read_uqname(ddata)) goto clean; if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, &subst_str_len)) == NULL) goto clean; if (!vector_str_push(&v, subst_str, subst_str_len)) goto clean; if (!cpp_demangle_push_subst_v(ddata, &v)) goto clean; if (*ddata->cur == 'I') { p_idx = output->size; if (!cpp_demangle_read_tmpl_args(ddata)) goto clean; free(subst_str); if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, &subst_str_len)) == NULL) goto clean; if (!vector_str_push(&v, subst_str, subst_str_len)) goto clean; if (!cpp_demangle_push_subst_v(ddata, &v)) goto clean; } rtn = 1; clean: free(subst_str); vector_str_dest(&v); return (rtn); } static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, const char *str) { struct vector_str *output; size_t p_idx, substr_len, len; int rtn; char *subst_str, *substr; if (ddata == NULL || str == NULL) return (0); if ((len = strlen(str)) == 0) return (0); output = ddata->cur_output; p_idx = output->size; substr = NULL; subst_str = NULL; if (!cpp_demangle_read_tmpl_args(ddata)) return (0); if ((substr = vector_str_substr(output, p_idx, output->size - 1, &substr_len)) == NULL) return (0); rtn = 0; if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == NULL) goto clean; memcpy(subst_str, str, len); memcpy(subst_str + len, substr, substr_len); subst_str[substr_len + len] = '\0'; if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) goto clean; rtn = 1; clean: free(subst_str); free(substr); return (rtn); } static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) { if (ddata == NULL || *ddata->cur == '\0') return (0); switch (*ddata->cur) { case 'L': return (cpp_demangle_read_expr_primary(ddata)); case 'X': ++ddata->cur; if (!cpp_demangle_read_expression(ddata)) return (0); return (*ddata->cur++ == 'E'); } return (cpp_demangle_read_type(ddata, NULL)); } static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) { struct vector_str *v; size_t arg_len, idx, limit, size; char *arg; if (ddata == NULL || *ddata->cur == '\0') return (0); ++ddata->cur; if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL)) return (0); if (!DEM_PUSH_STR(ddata, "<")) return (0); limit = 0; - v = &ddata->output; + v = ddata->cur_output; for (;;) { idx = v->size; if (!cpp_demangle_read_tmpl_arg(ddata)) return (0); if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == NULL) return (0); if (!vector_str_find(&ddata->tmpl, arg, arg_len) && !vector_str_push(&ddata->tmpl, arg, arg_len)) { free(arg); return (0); } free(arg); if (*ddata->cur == 'E') { ++ddata->cur; size = v->size; assert(size > 0); if (!strncmp(v->container[size - 1], ">", 1)) { if (!DEM_PUSH_STR(ddata, " >")) return (0); } else if (!DEM_PUSH_STR(ddata, ">")) return (0); ddata->is_tmpl = true; break; } else if (*ddata->cur != 'I' && !DEM_PUSH_STR(ddata, ", ")) return (0); if (limit++ > CPP_DEMANGLE_TRY_LIMIT) return (0); } return (vector_read_cmd_pop(&ddata->cmd)); } /* * Read template parameter that forms in 'T[number]_'. * This function much like to read_subst but only for types. */ static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) { long nth; if (ddata == NULL || *ddata->cur != 'T') return (0); ++ddata->cur; if (*ddata->cur == '_') return (cpp_demangle_get_tmpl_param(ddata, 0)); else { errno = 0; if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && errno != 0) return (0); /* T_ is first */ ++nth; while (*ddata->cur != '_') ++ddata->cur; assert(nth > 0); return (cpp_demangle_get_tmpl_param(ddata, nth)); } /* NOTREACHED */ return (0); } static int cpp_demangle_read_type(struct cpp_demangle_data *ddata, struct type_delimit *td) { struct vector_type_qualifier v; struct vector_str *output, sv; size_t p_idx, type_str_len, subst_str_len; int extern_c, is_builtin; long len; const char *p; char *type_str, *exp_str, *num_str, *subst_str; bool skip_ref_qualifier, omit_void; if (ddata == NULL) return (0); output = ddata->cur_output; if (td) { if (td->paren == false) { if (!DEM_PUSH_STR(ddata, "(")) return (0); if (ddata->output.size < 2) return (0); td->paren = true; } if (!td->firstp) { if (*ddata->cur != 'I') { if (!DEM_PUSH_STR(ddata, ", ")) return (0); } } } assert(output != NULL); /* * [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array * pointer-to-member, template-param, template-template-param, subst */ if (!vector_type_qualifier_init(&v)) return (0); extern_c = 0; is_builtin = 1; p_idx = output->size; type_str = exp_str = num_str = NULL; skip_ref_qualifier = false; again: /* Clear ref-qualifier flag */ if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E') ddata->ref_qualifier = false; /* builtin type */ switch (*ddata->cur) { case 'a': /* signed char */ if (!DEM_PUSH_STR(ddata, "signed char")) goto clean; ++ddata->cur; goto rtn; case 'A': /* array type */ if (!cpp_demangle_read_array(ddata)) goto clean; is_builtin = 0; goto rtn; case 'b': /* bool */ if (!DEM_PUSH_STR(ddata, "bool")) goto clean; ++ddata->cur; goto rtn; case 'C': /* complex pair */ if (!vector_type_qualifier_push(&v, TYPE_CMX)) goto clean; ++ddata->cur; if (td) td->firstp = false; goto again; case 'c': /* char */ if (!DEM_PUSH_STR(ddata, "char")) goto clean; ++ddata->cur; goto rtn; case 'd': /* double */ if (!DEM_PUSH_STR(ddata, "double")) goto clean; ++ddata->cur; goto rtn; case 'D': ++ddata->cur; switch (*ddata->cur) { case 'a': /* auto */ if (!DEM_PUSH_STR(ddata, "auto")) goto clean; ++ddata->cur; break; case 'c': /* decltype(auto) */ if (!DEM_PUSH_STR(ddata, "decltype(auto)")) goto clean; ++ddata->cur; break; case 'd': /* IEEE 754r decimal floating point (64 bits) */ if (!DEM_PUSH_STR(ddata, "decimal64")) goto clean; ++ddata->cur; break; case 'e': /* IEEE 754r decimal floating point (128 bits) */ if (!DEM_PUSH_STR(ddata, "decimal128")) goto clean; ++ddata->cur; break; case 'f': /* IEEE 754r decimal floating point (32 bits) */ if (!DEM_PUSH_STR(ddata, "decimal32")) goto clean; ++ddata->cur; break; case 'h': /* IEEE 754r half-precision floating point (16 bits) */ if (!DEM_PUSH_STR(ddata, "half")) goto clean; ++ddata->cur; break; case 'i': /* char32_t */ if (!DEM_PUSH_STR(ddata, "char32_t")) goto clean; ++ddata->cur; break; case 'n': /* std::nullptr_t (i.e., decltype(nullptr)) */ if (!DEM_PUSH_STR(ddata, "decltype(nullptr)")) goto clean; ++ddata->cur; break; case 's': /* char16_t */ if (!DEM_PUSH_STR(ddata, "char16_t")) goto clean; ++ddata->cur; break; case 'v': /* gcc vector_size extension. */ ++ddata->cur; if (*ddata->cur == '_') { ++ddata->cur; if (!cpp_demangle_read_expression_flat(ddata, &exp_str)) goto clean; if (!VEC_PUSH_STR(&v.ext_name, exp_str)) goto clean; } else { if (!cpp_demangle_read_number_as_string(ddata, &num_str)) goto clean; if (!VEC_PUSH_STR(&v.ext_name, num_str)) goto clean; } if (*ddata->cur != '_') goto clean; ++ddata->cur; if (!vector_type_qualifier_push(&v, TYPE_VEC)) goto clean; if (td) td->firstp = false; goto again; default: goto clean; } goto rtn; case 'e': /* long double */ if (!DEM_PUSH_STR(ddata, "long double")) goto clean; ++ddata->cur; goto rtn; case 'E': /* unexpected end except ref-qualifiers */ if (ddata->ref_qualifier && ddata->is_functype) { skip_ref_qualifier = true; /* Pop the delimiter. */ cpp_demangle_pop_str(ddata); goto rtn; } goto clean; case 'f': /* float */ if (!DEM_PUSH_STR(ddata, "float")) goto clean; ++ddata->cur; goto rtn; case 'F': /* function */ if (!cpp_demangle_read_function(ddata, &extern_c, &v)) goto clean; is_builtin = 0; goto rtn; case 'g': /* __float128 */ if (!DEM_PUSH_STR(ddata, "__float128")) goto clean; ++ddata->cur; goto rtn; case 'G': /* imaginary */ if (!vector_type_qualifier_push(&v, TYPE_IMG)) goto clean; ++ddata->cur; if (td) td->firstp = false; goto again; case 'h': /* unsigned char */ if (!DEM_PUSH_STR(ddata, "unsigned char")) goto clean; ++ddata->cur; goto rtn; case 'i': /* int */ if (!DEM_PUSH_STR(ddata, "int")) goto clean; ++ddata->cur; goto rtn; case 'I': /* template args. */ /* handles */ p_idx = output->size; if (!cpp_demangle_read_tmpl_args(ddata)) goto clean; if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, &subst_str_len)) == NULL) goto clean; if (!vector_str_init(&sv)) { free(subst_str); goto clean; } if (!vector_str_push(&sv, subst_str, subst_str_len)) { free(subst_str); vector_str_dest(&sv); goto clean; } free(subst_str); if (!cpp_demangle_push_subst_v(ddata, &sv)) { vector_str_dest(&sv); goto clean; } vector_str_dest(&sv); goto rtn; case 'j': /* unsigned int */ if (!DEM_PUSH_STR(ddata, "unsigned int")) goto clean; ++ddata->cur; goto rtn; case 'K': /* const */ if (!vector_type_qualifier_push(&v, TYPE_CST)) goto clean; ++ddata->cur; if (td) td->firstp = false; goto again; case 'l': /* long */ if (!DEM_PUSH_STR(ddata, "long")) goto clean; ++ddata->cur; goto rtn; case 'm': /* unsigned long */ if (!DEM_PUSH_STR(ddata, "unsigned long")) goto clean; ++ddata->cur; goto rtn; case 'M': /* pointer to member */ if (!cpp_demangle_read_pointer_to_member(ddata, &v)) goto clean; is_builtin = 0; goto rtn; case 'n': /* __int128 */ if (!DEM_PUSH_STR(ddata, "__int128")) goto clean; ++ddata->cur; goto rtn; case 'o': /* unsigned __int128 */ if (!DEM_PUSH_STR(ddata, "unsigned __int128")) goto clean; ++ddata->cur; goto rtn; case 'O': /* rvalue reference */ if (ddata->ref_qualifier) goto clean; if (!vector_type_qualifier_push(&v, TYPE_RREF)) goto clean; ddata->ref_qualifier = true; ddata->ref_qualifier_type = TYPE_RREF; ++ddata->cur; if (td) td->firstp = false; goto again; case 'P': /* pointer */ if (!vector_type_qualifier_push(&v, TYPE_PTR)) goto clean; ++ddata->cur; if (td) td->firstp = false; goto again; case 'r': /* restrict */ if (!vector_type_qualifier_push(&v, TYPE_RST)) goto clean; ++ddata->cur; if (td) td->firstp = false; goto again; case 'R': /* reference */ if (ddata->ref_qualifier) goto clean; if (!vector_type_qualifier_push(&v, TYPE_REF)) goto clean; ddata->ref_qualifier = true; ddata->ref_qualifier_type = TYPE_REF; ++ddata->cur; if (td) td->firstp = false; goto again; case 's': /* short, local string */ if (!DEM_PUSH_STR(ddata, "short")) goto clean; ++ddata->cur; goto rtn; case 'S': /* substitution */ if (!cpp_demangle_read_subst(ddata)) goto clean; is_builtin = 0; goto rtn; case 't': /* unsigned short */ if (!DEM_PUSH_STR(ddata, "unsigned short")) goto clean; ++ddata->cur; goto rtn; case 'T': /* template parameter */ if (!cpp_demangle_read_tmpl_param(ddata)) goto clean; is_builtin = 0; goto rtn; case 'u': /* vendor extended builtin */ ++ddata->cur; if (!cpp_demangle_read_sname(ddata)) goto clean; is_builtin = 0; goto rtn; case 'U': /* vendor extended type qualifier */ ++ddata->cur; if (!cpp_demangle_read_number(ddata, &len)) goto clean; if (len <= 0) goto clean; if (!vector_str_push(&v.ext_name, ddata->cur, len)) - return (0); + goto clean; ddata->cur += len; if (!vector_type_qualifier_push(&v, TYPE_EXT)) goto clean; if (td) td->firstp = false; goto again; case 'v': /* void */ omit_void = false; if (td && td->firstp) { /* * peek into next bytes and see if we should omit * the "void". */ omit_void = true; for (p = ddata->cur + 1; *p != '\0'; p++) { if (*p == 'E') break; if (*p != 'R' && *p != 'O') { omit_void = false; break; } } } if (!omit_void && !DEM_PUSH_STR(ddata, "void")) goto clean; ++ddata->cur; goto rtn; case 'V': /* volatile */ if (!vector_type_qualifier_push(&v, TYPE_VAT)) goto clean; ++ddata->cur; if (td) td->firstp = false; goto again; case 'w': /* wchar_t */ if (!DEM_PUSH_STR(ddata, "wchar_t")) goto clean; ++ddata->cur; goto rtn; case 'x': /* long long */ if (!DEM_PUSH_STR(ddata, "long long")) goto clean; ++ddata->cur; goto rtn; case 'y': /* unsigned long long */ if (!DEM_PUSH_STR(ddata, "unsigned long long")) goto clean; ++ddata->cur; goto rtn; case 'z': /* ellipsis */ if (!DEM_PUSH_STR(ddata, "...")) goto clean; ++ddata->cur; goto rtn; } if (!cpp_demangle_read_name(ddata)) goto clean; is_builtin = 0; rtn: type_str = vector_str_substr(output, p_idx, output->size - 1, &type_str_len); if (is_builtin == 0) { if (!vector_str_find(&ddata->subst, type_str, type_str_len) && !vector_str_push(&ddata->subst, type_str, type_str_len)) goto clean; } if (!skip_ref_qualifier && !cpp_demangle_push_type_qualifier(ddata, &v, type_str)) goto clean; if (td) td->firstp = false; free(type_str); free(exp_str); free(num_str); vector_type_qualifier_dest(&v); return (1); clean: free(type_str); free(exp_str); free(num_str); vector_type_qualifier_dest(&v); return (0); } static int cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str) { struct vector_str *output; size_t i, p_idx, idx, type_len; char *type; output = ddata->cur_output; p_idx = output->size; if (!cpp_demangle_read_type(ddata, NULL)) return (0); if ((type = vector_str_substr(output, p_idx, output->size - 1, &type_len)) == NULL) return (0); idx = output->size; for (i = p_idx; i < idx; ++i) { if (!vector_str_pop(output)) { free(type); return (0); } } *str = type; return (1); } /* * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, * source-name */ static int cpp_demangle_read_uqname(struct cpp_demangle_data *ddata) { size_t len; if (ddata == NULL || *ddata->cur == '\0') return (0); /* operator name */ switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { case SIMPLE_HASH('a', 'a'): /* operator && */ if (!DEM_PUSH_STR(ddata, "operator&&")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('a', 'd'): /* operator & (unary) */ if (!DEM_PUSH_STR(ddata, "operator&")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('a', 'n'): /* operator & */ if (!DEM_PUSH_STR(ddata, "operator&")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('a', 'N'): /* operator &= */ if (!DEM_PUSH_STR(ddata, "operator&=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('a', 'S'): /* operator = */ if (!DEM_PUSH_STR(ddata, "operator=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('c', 'l'): /* operator () */ if (!DEM_PUSH_STR(ddata, "operator()")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('c', 'm'): /* operator , */ if (!DEM_PUSH_STR(ddata, "operator,")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('c', 'o'): /* operator ~ */ if (!DEM_PUSH_STR(ddata, "operator~")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('c', 'v'): /* operator (cast) */ if (!DEM_PUSH_STR(ddata, "operator(cast)")) return (0); ddata->cur += 2; return (cpp_demangle_read_type(ddata, NULL)); case SIMPLE_HASH('d', 'a'): /* operator delete [] */ if (!DEM_PUSH_STR(ddata, "operator delete []")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('d', 'e'): /* operator * (unary) */ if (!DEM_PUSH_STR(ddata, "operator*")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('d', 'l'): /* operator delete */ if (!DEM_PUSH_STR(ddata, "operator delete")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('d', 'v'): /* operator / */ if (!DEM_PUSH_STR(ddata, "operator/")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('d', 'V'): /* operator /= */ if (!DEM_PUSH_STR(ddata, "operator/=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('e', 'o'): /* operator ^ */ if (!DEM_PUSH_STR(ddata, "operator^")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('e', 'O'): /* operator ^= */ if (!DEM_PUSH_STR(ddata, "operator^=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('e', 'q'): /* operator == */ if (!DEM_PUSH_STR(ddata, "operator==")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('g', 'e'): /* operator >= */ if (!DEM_PUSH_STR(ddata, "operator>=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('g', 't'): /* operator > */ if (!DEM_PUSH_STR(ddata, "operator>")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('i', 'x'): /* operator [] */ if (!DEM_PUSH_STR(ddata, "operator[]")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('l', 'e'): /* operator <= */ if (!DEM_PUSH_STR(ddata, "operator<=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('l', 's'): /* operator << */ if (!DEM_PUSH_STR(ddata, "operator<<")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('l', 'S'): /* operator <<= */ if (!DEM_PUSH_STR(ddata, "operator<<=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('l', 't'): /* operator < */ if (!DEM_PUSH_STR(ddata, "operator<")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('m', 'i'): /* operator - */ if (!DEM_PUSH_STR(ddata, "operator-")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('m', 'I'): /* operator -= */ if (!DEM_PUSH_STR(ddata, "operator-=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('m', 'l'): /* operator * */ if (!DEM_PUSH_STR(ddata, "operator*")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('m', 'L'): /* operator *= */ if (!DEM_PUSH_STR(ddata, "operator*=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('m', 'm'): /* operator -- */ if (!DEM_PUSH_STR(ddata, "operator--")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('n', 'a'): /* operator new[] */ if (!DEM_PUSH_STR(ddata, "operator new []")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('n', 'e'): /* operator != */ if (!DEM_PUSH_STR(ddata, "operator!=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('n', 'g'): /* operator - (unary) */ if (!DEM_PUSH_STR(ddata, "operator-")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('n', 't'): /* operator ! */ if (!DEM_PUSH_STR(ddata, "operator!")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('n', 'w'): /* operator new */ if (!DEM_PUSH_STR(ddata, "operator new")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('o', 'o'): /* operator || */ if (!DEM_PUSH_STR(ddata, "operator||")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('o', 'r'): /* operator | */ if (!DEM_PUSH_STR(ddata, "operator|")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('o', 'R'): /* operator |= */ if (!DEM_PUSH_STR(ddata, "operator|=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('p', 'l'): /* operator + */ if (!DEM_PUSH_STR(ddata, "operator+")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('p', 'L'): /* operator += */ if (!DEM_PUSH_STR(ddata, "operator+=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('p', 'm'): /* operator ->* */ if (!DEM_PUSH_STR(ddata, "operator->*")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('p', 'p'): /* operator ++ */ if (!DEM_PUSH_STR(ddata, "operator++")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('p', 's'): /* operator + (unary) */ if (!DEM_PUSH_STR(ddata, "operator+")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('p', 't'): /* operator -> */ if (!DEM_PUSH_STR(ddata, "operator->")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('q', 'u'): /* operator ? */ if (!DEM_PUSH_STR(ddata, "operator?")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('r', 'm'): /* operator % */ if (!DEM_PUSH_STR(ddata, "operator%")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('r', 'M'): /* operator %= */ if (!DEM_PUSH_STR(ddata, "operator%=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('r', 's'): /* operator >> */ if (!DEM_PUSH_STR(ddata, "operator>>")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('r', 'S'): /* operator >>= */ if (!DEM_PUSH_STR(ddata, "operator>>=")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('r', 'z'): /* operator sizeof */ if (!DEM_PUSH_STR(ddata, "operator sizeof ")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('s', 'r'): /* scope resolution operator */ if (!DEM_PUSH_STR(ddata, "scope resolution operator ")) return (0); ddata->cur += 2; return (1); case SIMPLE_HASH('s', 'v'): /* operator sizeof */ if (!DEM_PUSH_STR(ddata, "operator sizeof ")) return (0); ddata->cur += 2; return (1); } /* vendor extened operator */ if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { if (!DEM_PUSH_STR(ddata, "vendor extened operator ")) return (0); if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) return (0); ddata->cur += 2; return (cpp_demangle_read_sname(ddata)); } /* ctor-dtor-name */ switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { case SIMPLE_HASH('C', '1'): case SIMPLE_HASH('C', '2'): case SIMPLE_HASH('C', '3'): if (ddata->last_sname == NULL) return (0); if ((len = strlen(ddata->last_sname)) == 0) return (0); if (!DEM_PUSH_STR(ddata, "::")) return (0); if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) return (0); ddata->cur +=2; return (1); case SIMPLE_HASH('D', '0'): case SIMPLE_HASH('D', '1'): case SIMPLE_HASH('D', '2'): if (ddata->last_sname == NULL) return (0); if ((len = strlen(ddata->last_sname)) == 0) return (0); if (!DEM_PUSH_STR(ddata, "::~")) return (0); if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) return (0); ddata->cur +=2; return (1); } /* source name */ if (ELFTC_ISDIGIT(*ddata->cur) != 0) return (cpp_demangle_read_sname(ddata)); /* local source name */ if (*ddata->cur == 'L') return (cpp_demangle_local_source_name(ddata)); return (1); } /* * Read local source name. * * References: * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 */ static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata) { /* L */ if (ddata == NULL || *ddata->cur != 'L') return (0); ++ddata->cur; /* source name */ if (!cpp_demangle_read_sname(ddata)) return (0); /* discriminator */ if (*ddata->cur == '_') { ++ddata->cur; while (ELFTC_ISDIGIT(*ddata->cur) != 0) ++ddata->cur; } return (1); } static int cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) { if (ddata == NULL) return (0); if (!DEM_PUSH_STR(ddata, "offset : ")) return (0); if (!cpp_demangle_read_offset_number(ddata)) return (0); if (!DEM_PUSH_STR(ddata, "virtual offset : ")) return (0); return (!cpp_demangle_read_offset_number(ddata)); } /* * Decode floating point representation to string * Return new allocated string or NULL * * Todo * Replace these functions to macro. */ static char * decode_fp_to_double(const char *p, size_t len) { double f; size_t rtn_len, limit, i; int byte; char *rtn; if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) return (NULL); memset(&f, 0, sizeof(double)); for (i = 0; i < len / 2; ++i) { byte = hex_to_dec(p[len - i * 2 - 1]) + hex_to_dec(p[len - i * 2 - 2]) * 16; if (byte < 0 || byte > 255) return (NULL); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN ((unsigned char *)&f)[i] = (unsigned char)(byte); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ ((unsigned char *)&f)[sizeof(double) - i - 1] = (unsigned char)(byte); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ } rtn_len = 64; limit = 0; again: if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) return (NULL); if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { free(rtn); if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) return (NULL); rtn_len *= BUFFER_GROWFACTOR; goto again; } return rtn; } static char * decode_fp_to_float(const char *p, size_t len) { size_t i, rtn_len, limit; float f; int byte; char *rtn; if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) return (NULL); memset(&f, 0, sizeof(float)); for (i = 0; i < len / 2; ++i) { byte = hex_to_dec(p[len - i * 2 - 1]) + hex_to_dec(p[len - i * 2 - 2]) * 16; if (byte < 0 || byte > 255) return (NULL); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN ((unsigned char *)&f)[i] = (unsigned char)(byte); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ ((unsigned char *)&f)[sizeof(float) - i - 1] = (unsigned char)(byte); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ } rtn_len = 64; limit = 0; again: if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) return (NULL); if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { free(rtn); if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) return (NULL); rtn_len *= BUFFER_GROWFACTOR; goto again; } return rtn; } static char * decode_fp_to_float128(const char *p, size_t len) { long double f; size_t rtn_len, limit, i; int byte; unsigned char buf[FLOAT_QUADRUPLE_BYTES]; char *rtn; switch(sizeof(long double)) { case FLOAT_QUADRUPLE_BYTES: return (decode_fp_to_long_double(p, len)); case FLOAT_EXTENED_BYTES: if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > FLOAT_QUADRUPLE_BYTES) return (NULL); memset(buf, 0, FLOAT_QUADRUPLE_BYTES); for (i = 0; i < len / 2; ++i) { byte = hex_to_dec(p[len - i * 2 - 1]) + hex_to_dec(p[len - i * 2 - 2]) * 16; if (byte < 0 || byte > 255) return (NULL); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN buf[i] = (unsigned char)(byte); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ buf[FLOAT_QUADRUPLE_BYTES - i -1] = (unsigned char)(byte); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ } memset(&f, 0, FLOAT_EXTENED_BYTES); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN memcpy(&f, buf, FLOAT_EXTENED_BYTES); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ rtn_len = 256; limit = 0; again: if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) return (NULL); if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { free(rtn); if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) return (NULL); rtn_len *= BUFFER_GROWFACTOR; goto again; } return (rtn); default: return (NULL); } } static char * decode_fp_to_float80(const char *p, size_t len) { long double f; size_t rtn_len, limit, i; int byte; unsigned char buf[FLOAT_EXTENED_BYTES]; char *rtn; switch(sizeof(long double)) { case FLOAT_QUADRUPLE_BYTES: if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > FLOAT_EXTENED_BYTES) return (NULL); memset(buf, 0, FLOAT_EXTENED_BYTES); for (i = 0; i < len / 2; ++i) { byte = hex_to_dec(p[len - i * 2 - 1]) + hex_to_dec(p[len - i * 2 - 2]) * 16; if (byte < 0 || byte > 255) return (NULL); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN buf[i] = (unsigned char)(byte); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ buf[FLOAT_EXTENED_BYTES - i -1] = (unsigned char)(byte); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ } memset(&f, 0, FLOAT_QUADRUPLE_BYTES); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN memcpy(&f, buf, FLOAT_EXTENED_BYTES); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ rtn_len = 256; limit = 0; again: if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) return (NULL); if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { free(rtn); if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) return (NULL); rtn_len *= BUFFER_GROWFACTOR; goto again; } return (rtn); case FLOAT_EXTENED_BYTES: return (decode_fp_to_long_double(p, len)); default: return (NULL); } } static char * decode_fp_to_long_double(const char *p, size_t len) { long double f; size_t rtn_len, limit, i; int byte; char *rtn; if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(long double)) return (NULL); memset(&f, 0, sizeof(long double)); for (i = 0; i < len / 2; ++i) { byte = hex_to_dec(p[len - i * 2 - 1]) + hex_to_dec(p[len - i * 2 - 2]) * 16; if (byte < 0 || byte > 255) return (NULL); #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN ((unsigned char *)&f)[i] = (unsigned char)(byte); #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ ((unsigned char *)&f)[sizeof(long double) - i - 1] = (unsigned char)(byte); #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ } rtn_len = 256; limit = 0; again: if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) return (NULL); if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { free(rtn); if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) return (NULL); rtn_len *= BUFFER_GROWFACTOR; goto again; } return (rtn); } /* Simple hex to integer function used by decode_to_* function. */ static int hex_to_dec(char c) { switch (c) { case '0': return (0); case '1': return (1); case '2': return (2); case '3': return (3); case '4': return (4); case '5': return (5); case '6': return (6); case '7': return (7); case '8': return (8); case '9': return (9); case 'a': return (10); case 'b': return (11); case 'c': return (12); case 'd': return (13); case 'e': return (14); case 'f': return (15); default: return (-1); } } /** * @brief Test input string is mangled by IA-64 C++ ABI style. * * Test string heads with "_Z" or "_GLOBAL__I_". * @return Return 0 at false. */ bool is_cpp_mangled_gnu3(const char *org) { size_t len; len = strlen(org); return ((len > 2 && *org == '_' && *(org + 1) == 'Z') || (len > 11 && !strncmp(org, "_GLOBAL__I_", 11))); } static void vector_read_cmd_dest(struct vector_read_cmd *v) { if (v == NULL) return; free(v->r_container); } static struct read_cmd_item * vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) { int i; if (v == NULL || dst == READ_FAIL) return (NULL); for (i = (int) v->size - 1; i >= 0; i--) if (v->r_container[i].cmd == dst) return (&v->r_container[i]); return (NULL); } static int vector_read_cmd_init(struct vector_read_cmd *v) { if (v == NULL) return (0); v->size = 0; v->capacity = VECTOR_DEF_CAPACITY; if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity)) == NULL) return (0); return (1); } static int vector_read_cmd_pop(struct vector_read_cmd *v) { if (v == NULL || v->size == 0) return (0); --v->size; v->r_container[v->size].cmd = READ_FAIL; v->r_container[v->size].data = NULL; return (1); } static int vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data) { struct read_cmd_item *tmp_r_ctn; size_t tmp_cap; size_t i; if (v == NULL) return (0); if (v->size == v->capacity) { - tmp_cap = v->capacity * BUFFER_GROWFACTOR; + tmp_cap = BUFFER_GROW(v->capacity); if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL) return (0); for (i = 0; i < v->size; ++i) tmp_r_ctn[i] = v->r_container[i]; free(v->r_container); v->r_container = tmp_r_ctn; v->capacity = tmp_cap; } v->r_container[v->size].cmd = cmd; v->r_container[v->size].data = data; ++v->size; return (1); } static void vector_type_qualifier_dest(struct vector_type_qualifier *v) { if (v == NULL) return; free(v->q_container); vector_str_dest(&v->ext_name); } /* size, capacity, ext_name */ static int vector_type_qualifier_init(struct vector_type_qualifier *v) { if (v == NULL) return (0); v->size = 0; v->capacity = VECTOR_DEF_CAPACITY; if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) == NULL) return (0); assert(v->q_container != NULL); - if (vector_str_init(&v->ext_name) == false) { + if (!vector_str_init(&v->ext_name)) { free(v->q_container); return (0); } return (1); } static int vector_type_qualifier_push(struct vector_type_qualifier *v, enum type_qualifier t) { enum type_qualifier *tmp_ctn; size_t tmp_cap; size_t i; if (v == NULL) return (0); if (v->size == v->capacity) { - tmp_cap = v->capacity * BUFFER_GROWFACTOR; + tmp_cap = BUFFER_GROW(v->capacity); if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) == NULL) return (0); for (i = 0; i < v->size; ++i) tmp_ctn[i] = v->q_container[i]; free(v->q_container); v->q_container = tmp_ctn; v->capacity = tmp_cap; } v->q_container[v->size] = t; ++v->size; return (1); } Index: stable/11/contrib/elftoolchain/libelftc/libelftc_vstr.c =================================================================== --- stable/11/contrib/elftoolchain/libelftc/libelftc_vstr.c (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/libelftc_vstr.c (revision 367466) @@ -1,359 +1,359 @@ /*- * Copyright (c) 2008 Hyogeol Lee * 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 * in this position and unchanged. * 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 AUTHORS ``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 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 "_libelftc.h" ELFTC_VCSID("$Id: libelftc_vstr.c 3531 2017-06-05 05:08:43Z kaiwang27 $"); /** * @file vector_str.c * @brief Dynamic vector data for string implementation. * * Resemble to std::vector in C++. */ static size_t get_strlen_sum(const struct vector_str *v); static bool vector_str_grow(struct vector_str *v); static size_t get_strlen_sum(const struct vector_str *v) { size_t i, len = 0; if (v == NULL) return (0); assert(v->size > 0); for (i = 0; i < v->size; ++i) len += strlen(v->container[i]); return (len); } /** * @brief Deallocate resource in vector_str. */ void vector_str_dest(struct vector_str *v) { size_t i; if (v == NULL) return; for (i = 0; i < v->size; ++i) free(v->container[i]); free(v->container); } /** * @brief Find string in vector_str. * @param v Destination vector. * @param o String to find. * @param l Length of the string. * @return -1 at failed, 0 at not found, 1 at found. */ int vector_str_find(const struct vector_str *v, const char *o, size_t l) { size_t i; if (v == NULL || o == NULL) return (-1); for (i = 0; i < v->size; ++i) if (strncmp(v->container[i], o, l) == 0) return (1); return (0); } /** * @brief Get new allocated flat string from vector. * * If l is not NULL, return length of the string. * @param v Destination vector. * @param l Length of the string. * @return NULL at failed or NUL terminated new allocated string. */ char * vector_str_get_flat(const struct vector_str *v, size_t *l) { ssize_t elem_pos, elem_size, rtn_size; size_t i; char *rtn; if (v == NULL || v->size == 0) return (NULL); if ((rtn_size = get_strlen_sum(v)) == 0) return (NULL); if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL) return (NULL); elem_pos = 0; for (i = 0; i < v->size; ++i) { elem_size = strlen(v->container[i]); memcpy(rtn + elem_pos, v->container[i], elem_size); elem_pos += elem_size; } rtn[rtn_size] = '\0'; if (l != NULL) *l = rtn_size; return (rtn); } static bool vector_str_grow(struct vector_str *v) { size_t i, tmp_cap; char **tmp_ctn; if (v == NULL) return (false); assert(v->capacity > 0); - tmp_cap = v->capacity * BUFFER_GROWFACTOR; + tmp_cap = BUFFER_GROW(v->capacity); assert(tmp_cap > v->capacity); if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) return (false); for (i = 0; i < v->size; ++i) tmp_ctn[i] = v->container[i]; free(v->container); v->container = tmp_ctn; v->capacity = tmp_cap; return (true); } /** * @brief Initialize vector_str. * @return false at failed, true at success. */ bool vector_str_init(struct vector_str *v) { if (v == NULL) return (false); v->size = 0; v->capacity = VECTOR_DEF_CAPACITY; assert(v->capacity > 0); if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL) return (false); assert(v->container != NULL); return (true); } /** * @brief Remove last element in vector_str. * @return false at failed, true at success. */ bool vector_str_pop(struct vector_str *v) { if (v == NULL) return (false); if (v->size == 0) return (true); --v->size; free(v->container[v->size]); v->container[v->size] = NULL; return (true); } /** * @brief Push back string to vector. * @return false at failed, true at success. */ bool vector_str_push(struct vector_str *v, const char *str, size_t len) { if (v == NULL || str == NULL) return (false); if (v->size == v->capacity && vector_str_grow(v) == false) return (false); if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL) return (false); snprintf(v->container[v->size], len + 1, "%s", str); ++v->size; return (true); } /** * @brief Push front org vector to det vector. * @return false at failed, true at success. */ bool vector_str_push_vector_head(struct vector_str *dst, struct vector_str *org) { size_t i, j, tmp_cap; char **tmp_ctn; if (dst == NULL || org == NULL) return (false); - tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR; + tmp_cap = BUFFER_GROW(dst->size + org->size); if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) return (false); for (i = 0; i < org->size; ++i) if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) { for (j = 0; j < i; ++j) free(tmp_ctn[j]); free(tmp_ctn); return (false); } for (i = 0; i < dst->size; ++i) tmp_ctn[i + org->size] = dst->container[i]; free(dst->container); dst->container = tmp_ctn; dst->capacity = tmp_cap; dst->size += org->size; return (true); } /** * @brief Push org vector to the tail of det vector. * @return false at failed, true at success. */ bool vector_str_push_vector(struct vector_str *dst, struct vector_str *org) { size_t i, j, tmp_cap; char **tmp_ctn; if (dst == NULL || org == NULL) return (false); - tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR; + tmp_cap = BUFFER_GROW(dst->size + org->size); if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) return (false); for (i = 0; i < dst->size; ++i) tmp_ctn[i] = dst->container[i]; for (i = 0; i < org->size; ++i) if ((tmp_ctn[i + dst->size] = strdup(org->container[i])) == NULL) { for (j = 0; j < i + dst->size; ++j) free(tmp_ctn[j]); free(tmp_ctn); return (false); } free(dst->container); dst->container = tmp_ctn; dst->capacity = tmp_cap; dst->size += org->size; return (true); } /** * @brief Get new allocated flat string from vector between begin and end. * * If r_len is not NULL, string length will be returned. * @return NULL at failed or NUL terminated new allocated string. */ char * vector_str_substr(const struct vector_str *v, size_t begin, size_t end, size_t *r_len) { size_t cur, i, len; char *rtn; if (v == NULL || begin > end) return (NULL); len = 0; for (i = begin; i < end + 1; ++i) len += strlen(v->container[i]); if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL) return (NULL); if (r_len != NULL) *r_len = len; cur = 0; for (i = begin; i < end + 1; ++i) { len = strlen(v->container[i]); memcpy(rtn + cur, v->container[i], len); cur += len; } rtn[cur] = '\0'; return (rtn); } Index: stable/11/contrib/elftoolchain/libelftc/make-toolchain-version =================================================================== --- stable/11/contrib/elftoolchain/libelftc/make-toolchain-version (revision 367465) +++ stable/11/contrib/elftoolchain/libelftc/make-toolchain-version (revision 367466) @@ -1,110 +1,113 @@ #!/bin/sh # # This script generates a project-wide version identifier for use by # the `elftc_version()' API. # -# $Id: make-toolchain-version 3414 2016-02-16 22:55:28Z jkoshy $ +# $Id: make-toolchain-version 3731 2019-04-06 14:28:34Z jkoshy $ # # Defaults. # buildhost=`uname -s` elftcname="elftoolchain" options="e:h:o:r:t:" top="" version="HEAD" versionfile="elftc_version.c" progname=`basename ${0}` usage() { exec >&2 # Print a message, if supplied. if [ -n "${*}" ]; then echo "##${@}"; fi echo "Usage: ${progname} [options]" echo " Generate a toolchain-wide version number" echo " -e PROJECTNAME Set the project name [default: ${elftcname}]." echo " -h HOSTOS Set the build OS [default: ${buildhost}]." echo " -o OUTPUT Set the output file [default: ${versionfile}]." echo " -r VERSION Set the version string [default: ${version}]." echo " -t TOPDIR Set the top-of-tree directory [required]." exit 1 } +# Determine the revision number for the source tree. # +# - If CVS is detected, we use the string `unknown'. +# - If SVN is detected, we use the `svninfo' tool to determine the +# in-tree revision number. +# - Otherwise, we use `git --describe'. +get_revision_string() +{ + v="unknown:unknown" + if [ -d CVS ]; then # Look for CVS (NetBSD). + v="cvs:unknown" + elif [ -d .svn ]; then # An SVN checkout (SourceForge or FreeBSD). + svnversion="$(svnversion 2>/dev/null)" + if [ -n "${svnversion}" ]; then + v="svn:${svnversion}" + fi + else # Try git (DragonflyBSD). + gitversion="$(git describe --all --dirty --long 2> /dev/null)" + if [ -n "${gitversion}" ]; then + v="git:${gitversion}" + fi + fi + + echo "${v}" +} + +# # Parse options. # while getopts ${options} option do case ${option} in 'e') elftcname="${OPTARG}" ;; 'h') buildhost="${OPTARG}" ;; 'o') versionfile="${OPTARG}" ;; 'r') version="${OPTARG}" ;; 't') top="${OPTARG}" ;; '?') usage ;; esac done [ -n "${top}" ] || usage -# Try to determine the in-tree revision number. -# -# This script attempts to handle the case where our sources have been -# incorporated into an operating system's base sources. -# -# - If SVN is detected, we use the `svninfo' tool to determine the -# in-tree revision number. -# - If CVS is detected, we use the string `unknown'. -# - Otherwise, we use `git --describe'. - curdir=`pwd` cd ${top} || usage "ERROR: Cannot change directory to \"${top}\"." -if [ -d CVS ]; then # Look for CVS (NetBSD). - versionstring=" cvs:unknown" -else # Try git (DragonFlyBSD). - gitversion="$(git describe --all --dirty --long 2> /dev/null)" - if [ -n "${gitversion}" ]; then - versionstring=" git:${gitversion}" - else # Assume an SVN checkout (SourceForge or FreeBSD). - svnversion="$(svnversion)" - if [ -n "${svnversion}" ]; then - versionstring=" svn:$(svnversion)" - fi - fi -fi - -if [ -z "${versionstring}" ]; then - echo "ERROR: cannot determine a revision number." 1>&2 +# Determine the in-tree revision number. +versionstring="$(get_revision_string)" || { + echo "ERROR: cannot determine a revision number." 1>&2; exit 1 -fi +} cd ${curdir} || usage "Cannot change back to ${curdir}." # # Only replace the source file if its content has changed. # tmpfile=`mktemp ${TMPDIR:-/tmp}/MV.XXXXXXX` trap "rm -f ${tmpfile};" 0 1 2 3 15 cat > ${tmpfile} < #include const char * elftc_version(void) { - return "${elftcname} ${version} ${buildhost}${versionstring}"; + return "${elftcname} ${version} ${buildhost} ${versionstring}"; } EOF if ! cmp -s ${tmpfile} ${versionfile}; then echo "@ ${progname}: building \"${versionfile}\"." cp ${tmpfile} ${versionfile} || exit ${?} fi Index: stable/11/contrib/elftoolchain/libpe/pe_symtab.c =================================================================== --- stable/11/contrib/elftoolchain/libpe/pe_symtab.c (revision 367465) +++ stable/11/contrib/elftoolchain/libpe/pe_symtab.c (revision 367466) @@ -1,86 +1,86 @@ /*- * Copyright (c) 2016 Kai Wang * 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 "_libpe.h" ELFTC_VCSID("$Id: pe_symtab.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); int pe_update_symtab(PE *pe, char *symtab, size_t sz, unsigned int nsym) { - PE_Scn *ps; + PE_Scn *ps, *pstmp; PE_SecBuf *sb; PE_SecHdr *sh; if (pe == NULL || symtab == NULL || sz == 0) { errno = EINVAL; return (-1); } if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { errno = EACCES; return (-1); } /* Remove the old symbol table. */ - STAILQ_FOREACH(ps, &pe->pe_scn, ps_next) { + STAILQ_FOREACH_SAFE(ps, &pe->pe_scn, ps_next, pstmp) { if (ps->ps_ndx == 0xFFFFFFFFU) libpe_release_scn(ps); } /* * Insert the new symbol table. */ if ((ps = libpe_alloc_scn(pe)) == NULL) return (-1); STAILQ_INSERT_TAIL(&pe->pe_scn, ps, ps_next); ps->ps_ndx = 0xFFFFFFFFU; ps->ps_flags |= PE_F_DIRTY; /* * Set the symbol table section offset to the maximum to make sure * that it will be placed in the end of the file during section * layout. */ sh = &ps->ps_sh; sh->sh_rawptr = 0xFFFFFFFFU; sh->sh_rawsize = sz; /* Allocate the buffer. */ if ((sb = libpe_alloc_buffer(ps, 0)) == NULL) return (-1); sb->sb_flags |= PE_F_DIRTY; sb->sb_pb.pb_size = sz; sb->sb_pb.pb_buf = symtab; pe->pe_nsym = nsym; return (0); } Index: stable/11/contrib/elftoolchain/nm/nm.1 =================================================================== --- stable/11/contrib/elftoolchain/nm/nm.1 (revision 367465) +++ stable/11/contrib/elftoolchain/nm/nm.1 (revision 367466) @@ -1,340 +1,340 @@ .\" Copyright (c) 2007 Hyogeol Lee .\" 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 .\" in this position and unchanged. .\" 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 AUTHORS ``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 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: nm.1 3573 2017-09-14 02:06:31Z emaste $ +.\" $Id: nm.1 3642 2018-10-14 14:24:28Z jkoshy $ .\" .Dd September 13, 2017 -.Os .Dt NM 1 +.Os .Sh NAME .Nm nm .Nd display symbolic information in object files .Sh SYNOPSIS .Nm .Op Fl -debug-syms .Op Fl -defined-only .Op Fl -demangle Ns Op = Ns style .Op Fl -dynamic .Op Fl -extern-only .Op Fl -help .Op Fl -line-numbers .Op Fl -no-demangle .Op Fl -no-sort .Op Fl -numeric-sort .Op Fl -print-armap .Op Fl -print-file-name .Op Fl -print-size .Op Fl -radix= Ns Ar format .Op Fl -reverse-sort .Op Fl -size-sort .Op Fl -undefined-only .Op Fl -version .Op Fl A .Op Fl B .Op Fl C Op Ar style .Op Fl D .Op Fl P .Op Fl V .Op Fl a .Op Fl e .Op Fl g .Op Fl h .Op Fl l .Op Fl n .Op Fl o .Op Fl p .Op Fl r .Op Fl S .Op Fl s .Op Fl t Ar format .Op Fl u .Op Fl x .Ar .Sh DESCRIPTION The .Nm utility displays symbolic information in the object files, executables, and object library files named by its arguments. Lack of symbolic information in an otherwise valid input file, is not considered to be an error. If no files are specified on the command line, .Nm will attempt to read .Pa a.out . .Pp The .Nm utility recognizes the following options: .Bl -tag -width ".Fl d Ar argument" .It Fl -debug-syms Display all symbols, including debugger-only symbols. .It Fl -defined-only Display only defined symbols. .It Fl -demangle Ns Op = Ns Ar style Decode (demangle) low-level symbol names into human-readable names. Supported values for argument .Ar style are .Sq auto , .Sq gnu-v2 , .Sq gnu-v3 and .Sq arm. If argument .Ar style is not specified, it is taken to be .Sq auto . .It Fl -dynamic Only display dynamic symbols. This option is only meaningful for shared libraries. .It Fl -extern-only Only display information about global (external) symbols. .It Fl -help Display a help message and exit. .It Fl -format Ns = Ns Ar format Display output in the format specified by argument .Ar format . Supported values for the format argument are .Sq bsd , .Sq sysv , and .Sq posix . The default output format is .Sq bsd . .It Fl -line-numbers Display the filename and line number associated a symbol using any debugging information present in the input file. For defined symbols, look up the line number associated with the address of the symbol. For undefined symbols, look up the line number associated with a relocation entry that refers to the symbol. If line number information can be determined, it is displayed after other symbol information. .It Fl -no-demangle Do not demangle symbol names (default). .It Fl -no-sort Do not sort symbols. .It Fl -numeric-sort Sort symbols numerically by address instead of alphabetically by name. .It Fl -print-armap For .Xr ar 1 archives, include the index of the archive's members. .It Fl -print-file-name Write the full pathname or library name of an object on each line, before the rest of the information for a symbol. If this option is not specified, .Nm will only identify an input file once, before its symbols are listed. .It Fl -print-size Print the size of each symbol instead of its value. .It Fl -radix Ns = Ns Ar radix Print numeric values using the specified radix. Supported values for argument .Ar radix are .Sq d for decimal, .Sq o for octal, and .Sq x for hexadecimal. .It Fl -reverse-sort Reverse the order of the sort. .It Fl -size-sort Sort symbols by size instead of alphabetically by name. .It Fl -undefined-only Display only undefined symbols. .It Fl -version Display the version identifier for .Nm and exit. .It Fl A Equivalent to specifying option .Fl -print-file-name . .It Fl B Equivalent to specifying option .Fl -format= Ns Ar bsd . .It Fl C Op Ar style Equivalent to specifying option .Fl -demangle Ns Op = Ns Ar style . .It Fl D Equivalent to specifying option .Fl -dynamic . .It Fl F Ar format Equivalent to specifying option .Fl -format Ns = Ns Ar format . .It Fl P Equivalent to specifying option .Fl -format Ns = Ns Ar posix . .It Fl S Equivalent to specifying option .Fl -print-size . .It Fl V Equivalent to specifying option .Fl -version . .It Fl a Equivalent to specifying option .Fl -debug-syms . .It Fl e Only display information for global and static symbols. .It Fl f Produce full output (default). .It Fl g Equivalent to specifying option .Fl -extern-only . .It Fl h Equivalent to specifying option .Fl -help . .It Fl l Equivalent to specifying option .Fl -line-numbers . .It Fl n Equivalent to specifying option .Fl -numeric-sort . .It Fl o If POSIX output was specified using the .Fl F Ar posix or .Fl P options, this option is equivalent to specifying .Fl -radix Ns = Ns Sq Ar o . If POSIX output was not specified, this option acts as a synonym for the .Fl -print-file-name option. .It Fl p Equivalent to specifying option .Fl -no-sort . .It Fl v Equivalent to option .Fl n . .It Fl r Equivalent to specifying option .Fl -reverse-sort .It Fl s Equivalent to specifying option .Fl -print-armap . .It Fl t Ar radix Equivalent to specifying option .Fl -radix= Ns Ar radix . .It Fl u Equivalent to specifying option .Fl -undefined-only . .It Fl x Write numeric values in hexadecimal (equivalent to -t x). .El .Sh OUTPUT FORMAT .Pp The .Nm utility can present its information in a number of formats, numeric radices and sort orders. By default .Nm uses BSD style output, a hexadecimal radix, without output sorted alphabetically by name and without demangling of names. .Pp For each symbol listed, .Nm presents the following information: .Bl -bullet -compact .It The library or object name, if options .Fl A or .Fl -print-file-name were specified. .It The symbol name. .It The type of the symbol denoted by a single character as below: .Bl -tag -compact -width indent .It A A global, absolute symbol. .It B A global .Dq bss (uninitialized data) symbol. .It C A .Dq common symbol, representing uninitialized data. .It D A global symbol naming initialized data. .It N A debugger symbol. .It R A read-only data symbol. .It T A global text symbol. .It U An undefined symbol. .It V A weak object. .It W A weak reference. .It a A local absolute symbol. .It b A local .Dq bss (uninitialized data) symbol. .It d A local data symbol. .It r A local read-only data symbol. .It t A local text symbol. .It v A weak object that is undefined. .It w A weak symbol that is undefined. .It ? None of the above. .El .It The value of the symbol. .It The size of the symbol if applicable. .It Line number information, if available and if options .Fl l or .Fl -line-numbers were specified. .El .Sh EXIT STATUS .Ex -std .Sh SEE ALSO .Xr ar 1 , .Xr objdump 1 , .Xr ranlib 1 , .Xr elf 3 .Sh AUTHORS The .Nm utility and this manual page were written by .An Hyogeol Lee Aq Mt hyogeollee@gmail.com . Index: stable/11/contrib/elftoolchain/nm/nm.c =================================================================== --- stable/11/contrib/elftoolchain/nm/nm.c (revision 367465) +++ stable/11/contrib/elftoolchain/nm/nm.c (revision 367466) @@ -1,2123 +1,2124 @@ /*- * Copyright (c) 2007 Hyogeol Lee * 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 * in this position and unchanged. * 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 AUTHORS ``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 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 #include #include #include #include #include #include #include #include #include "_elftc.h" -ELFTC_VCSID("$Id: nm.c 3504 2016-12-17 15:33:16Z kaiwang27 $"); +ELFTC_VCSID("$Id: nm.c 3722 2019-03-23 17:01:58Z jkoshy $"); /* symbol information list */ STAILQ_HEAD(sym_head, sym_entry); struct sym_entry { char *name; GElf_Sym *sym; STAILQ_ENTRY(sym_entry) sym_entries; }; typedef int (*fn_sort)(const void *, const void *); typedef void (*fn_elem_print)(char, const char *, const GElf_Sym *, const char *); typedef void (*fn_sym_print)(const GElf_Sym *); typedef int (*fn_filter)(char, const GElf_Sym *, const char *); /* output filter list */ static SLIST_HEAD(filter_head, filter_entry) nm_out_filter = SLIST_HEAD_INITIALIZER(nm_out_filter); struct filter_entry { fn_filter fn; SLIST_ENTRY(filter_entry) filter_entries; }; struct sym_print_data { struct sym_head *headp; size_t sh_num, list_num; const char *t_table, **s_table, *filename, *objname; }; struct nm_prog_info { const char *name; const char *def_filename; }; /* List for line number information. */ struct line_info_entry { uint64_t addr; /* address */ uint64_t line; /* line number */ char *file; /* file name with path */ SLIST_ENTRY(line_info_entry) entries; }; SLIST_HEAD(line_info_head, line_info_entry); /* List for function line number information. */ struct func_info_entry { char *name; /* function name */ char *file; /* file name with path */ uint64_t lowpc; /* low address */ uint64_t highpc; /* high address */ uint64_t line; /* line number */ SLIST_ENTRY(func_info_entry) entries; }; SLIST_HEAD(func_info_head, func_info_entry); /* List for variable line number information. */ struct var_info_entry { char *name; /* variable name */ char *file; /* file name with path */ uint64_t addr; /* address */ uint64_t line; /* line number */ SLIST_ENTRY(var_info_entry) entries; }; SLIST_HEAD(var_info_head, var_info_entry); /* output numric type */ enum radix { RADIX_OCT, RADIX_HEX, RADIX_DEC }; /* output symbol type, PRINT_SYM_DYN for dynamic symbol only */ enum print_symbol { PRINT_SYM_SYM, PRINT_SYM_DYN }; /* output name type */ enum print_name { PRINT_NAME_NONE, PRINT_NAME_FULL, PRINT_NAME_MULTI }; struct nm_prog_options { enum print_symbol print_symbol; enum print_name print_name; enum radix t; int demangle_type; bool print_debug; bool print_armap; int print_size; bool debug_line; int def_only; bool undef_only; int sort_size; bool sort_reverse; int no_demangle; /* * function pointer to sort symbol list. * possible function - cmp_name, cmp_none, cmp_size, cmp_value */ fn_sort sort_fn; /* * function pointer to print symbol elem. * possible function - sym_elem_print_all * sym_elem_print_all_portable * sym_elem_print_all_sysv */ fn_elem_print elem_print_fn; fn_sym_print value_print_fn; fn_sym_print size_print_fn; }; #define CHECK_SYM_PRINT_DATA(p) (p->headp == NULL || p->sh_num == 0 || \ p->t_table == NULL || p->s_table == NULL || p->filename == NULL) #define IS_SYM_TYPE(t) ((t) == '?' || isalpha((t)) != 0) #define IS_UNDEF_SYM_TYPE(t) ((t) == 'U' || (t) == 'v' || (t) == 'w') #define UNUSED(p) ((void)p) static int cmp_name(const void *, const void *); static int cmp_none(const void *, const void *); static int cmp_size(const void *, const void *); static int cmp_value(const void *, const void *); static void filter_dest(void); static int filter_insert(fn_filter); -static void get_opt(int, char **); +static void get_opt(int *, char ***); static int get_sym(Elf *, struct sym_head *, int, size_t, size_t, const char *, const char **, int); static const char * get_sym_name(Elf *, const GElf_Sym *, size_t, const char **, int); static char get_sym_type(const GElf_Sym *, const char *); static void global_dest(void); static void global_init(void); static bool is_sec_data(GElf_Shdr *); static bool is_sec_debug(const char *); static bool is_sec_nobits(GElf_Shdr *); static bool is_sec_readonly(GElf_Shdr *); static bool is_sec_text(GElf_Shdr *); static void print_ar_index(int, Elf *); static void print_header(const char *, const char *); static void print_version(void); static int read_elf(Elf *, const char *, Elf_Kind); static int read_object(const char *); static int read_files(int, char **); static void set_opt_value_print_fn(enum radix); static int sym_elem_def(char, const GElf_Sym *, const char *); static int sym_elem_global(char, const GElf_Sym *, const char *); static int sym_elem_global_static(char, const GElf_Sym *, const char *); static int sym_elem_nondebug(char, const GElf_Sym *, const char *); static int sym_elem_nonzero_size(char, const GElf_Sym *, const char *); static void sym_elem_print_all(char, const char *, const GElf_Sym *, const char *); static void sym_elem_print_all_portable(char, const char *, const GElf_Sym *, const char *); static void sym_elem_print_all_sysv(char, const char *, const GElf_Sym *, const char *); static int sym_elem_undef(char, const GElf_Sym *, const char *); static void sym_list_dest(struct sym_head *); static int sym_list_insert(struct sym_head *, const char *, const GElf_Sym *); static void sym_list_print(struct sym_print_data *, struct func_info_head *, struct var_info_head *, struct line_info_head *); static void sym_list_print_each(struct sym_entry *, struct sym_print_data *, struct func_info_head *, struct var_info_head *, struct line_info_head *); static struct sym_entry *sym_list_sort(struct sym_print_data *); static void sym_size_oct_print(const GElf_Sym *); static void sym_size_hex_print(const GElf_Sym *); static void sym_size_dec_print(const GElf_Sym *); static void sym_value_oct_print(const GElf_Sym *); static void sym_value_hex_print(const GElf_Sym *); static void sym_value_dec_print(const GElf_Sym *); static void usage(int); static struct nm_prog_info nm_info; static struct nm_prog_options nm_opts; static int nm_elfclass; /* * Point to current sym_print_data to use portable qsort function. * (e.g. There is no qsort_r function in NetBSD.) * * Using in sym_list_sort. */ static struct sym_print_data *nm_print_data; static const struct option nm_longopts[] = { { "debug-syms", no_argument, NULL, 'a' }, { "defined-only", no_argument, &nm_opts.def_only, 1}, { "demangle", optional_argument, NULL, 'C' }, { "dynamic", no_argument, NULL, 'D' }, { "extern-only", no_argument, NULL, 'g' }, { "format", required_argument, NULL, 'F' }, { "help", no_argument, NULL, 'h' }, { "line-numbers", no_argument, NULL, 'l' }, { "no-demangle", no_argument, &nm_opts.no_demangle, 1}, { "no-sort", no_argument, NULL, 'p' }, { "numeric-sort", no_argument, NULL, 'v' }, { "print-armap", no_argument, NULL, 's' }, { "print-file-name", no_argument, NULL, 'A' }, { "print-size", no_argument, NULL, 'S' }, { "radix", required_argument, NULL, 't' }, { "reverse-sort", no_argument, NULL, 'r' }, { "size-sort", no_argument, &nm_opts.sort_size, 1}, { "undefined-only", no_argument, NULL, 'u' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; #if defined(ELFTC_NEED_BYTEORDER_EXTENSIONS) static __inline uint32_t be32dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); } static __inline uint32_t le32dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); } static __inline uint64_t be64dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4)); } static __inline uint64_t le64dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p)); } #endif static int cmp_name(const void *l, const void *r) { assert(l != NULL); assert(r != NULL); assert(((const struct sym_entry *)l)->name != NULL); assert(((const struct sym_entry *)r)->name != NULL); return (strcmp(((const struct sym_entry *)l)->name, ((const struct sym_entry *)r)->name)); } static int cmp_none(const void *l, const void *r) { UNUSED(l); UNUSED(r); return (0); } /* Size comparison. If l and r have same size, compare their name. */ static int cmp_size(const void *lp, const void *rp) { const struct sym_entry *l, *r; l = lp; r = rp; assert(l != NULL); assert(l->name != NULL); assert(l->sym != NULL); assert(r != NULL); assert(r->name != NULL); assert(r->sym != NULL); if (l->sym->st_size == r->sym->st_size) return (strcmp(l->name, r->name)); return (l->sym->st_size - r->sym->st_size); } /* Value comparison. Undefined symbols come first. */ static int cmp_value(const void *lp, const void *rp) { const struct sym_entry *l, *r; const char *ttable; int l_is_undef, r_is_undef; l = lp; r = rp; assert(nm_print_data != NULL); ttable = nm_print_data->t_table; assert(l != NULL); assert(l->name != NULL); assert(l->sym != NULL); assert(r != NULL); assert(r->name != NULL); assert(r->sym != NULL); assert(ttable != NULL); l_is_undef = IS_UNDEF_SYM_TYPE(get_sym_type(l->sym, ttable)) ? 1 : 0; r_is_undef = IS_UNDEF_SYM_TYPE(get_sym_type(r->sym, ttable)) ? 1 : 0; assert(l_is_undef + r_is_undef >= 0); assert(l_is_undef + r_is_undef <= 2); switch (l_is_undef + r_is_undef) { case 0: /* Both defined */ if (l->sym->st_value == r->sym->st_value) return (strcmp(l->name, r->name)); return (l->sym->st_value > r->sym->st_value ? 1 : -1); case 1: /* One undefined */ return (l_is_undef == 0 ? 1 : -1); case 2: /* Both undefined */ return (strcmp(l->name, r->name)); } /* NOTREACHED */ return (l->sym->st_value - r->sym->st_value); } static void filter_dest(void) { struct filter_entry *e; while (!SLIST_EMPTY(&nm_out_filter)) { e = SLIST_FIRST(&nm_out_filter); SLIST_REMOVE_HEAD(&nm_out_filter, filter_entries); free(e); } } static int filter_insert(fn_filter filter_fn) { struct filter_entry *e; assert(filter_fn != NULL); if ((e = malloc(sizeof(struct filter_entry))) == NULL) { warn("malloc"); return (0); } e->fn = filter_fn; SLIST_INSERT_HEAD(&nm_out_filter, e, filter_entries); return (1); } static int parse_demangle_option(const char *opt) { if (opt == NULL) return (ELFTC_DEM_UNKNOWN); else if (!strncasecmp(opt, "gnu-v2", 6)) return (ELFTC_DEM_GNU2); else if (!strncasecmp(opt, "gnu-v3", 6)) return (ELFTC_DEM_GNU3); else if (!strncasecmp(opt, "arm", 3)) return (ELFTC_DEM_ARM); else errx(EXIT_FAILURE, "unknown demangling style '%s'", opt); /* NOTREACHED */ return (0); } static void -get_opt(int argc, char **argv) +get_opt(int *argc, char ***argv) { int ch; bool is_posix, oflag; - if (argc <= 0 || argv == NULL) + if (*argc <= 0 || *argv == NULL) return; oflag = is_posix = false; nm_opts.t = RADIX_HEX; - while ((ch = getopt_long(argc, argv, "ABCDF:PSVaefghlnoprst:uvx", - nm_longopts, NULL)) != -1) { + while ((ch = getopt_long(*argc, *argv, "ABCDF:PSVaefghlnoprst:uvx", + nm_longopts, NULL)) != -1) { switch (ch) { case 'A': nm_opts.print_name = PRINT_NAME_FULL; break; case 'B': nm_opts.elem_print_fn = &sym_elem_print_all; break; case 'C': nm_opts.demangle_type = parse_demangle_option(optarg); break; case 'D': nm_opts.print_symbol = PRINT_SYM_DYN; break; case 'F': /* sysv, bsd, posix */ switch (optarg[0]) { case 'B': case 'b': nm_opts.elem_print_fn = &sym_elem_print_all; break; case 'P': case 'p': is_posix = true; nm_opts.elem_print_fn = &sym_elem_print_all_portable; break; case 'S': case 's': nm_opts.elem_print_fn = &sym_elem_print_all_sysv; break; default: warnx("%s: Invalid format", optarg); usage(1); } break; case 'P': is_posix = true; nm_opts.elem_print_fn = &sym_elem_print_all_portable; break; case 'S': nm_opts.print_size = 1; break; case 'V': print_version(); /* NOTREACHED */ case 'a': nm_opts.print_debug = true; break; case 'e': filter_insert(sym_elem_global_static); break; case 'f': break; case 'g': filter_insert(sym_elem_global); break; case 'h': usage(0); break; case 'l': nm_opts.debug_line = true; break; case 'n': case 'v': nm_opts.sort_fn = &cmp_value; break; case 'o': oflag = true; break; case 'p': nm_opts.sort_fn = &cmp_none; break; case 'r': nm_opts.sort_reverse = true; break; case 's': nm_opts.print_armap = true; break; case 't': /* t require always argument to getopt_long */ switch (optarg[0]) { case 'd': nm_opts.t = RADIX_DEC; break; case 'o': nm_opts.t = RADIX_OCT; break; case 'x': nm_opts.t = RADIX_HEX; break; default: warnx("%s: Invalid radix", optarg); usage(1); } break; case 'u': filter_insert(sym_elem_undef); nm_opts.undef_only = true; break; /* case 'v': see case 'n' above. */ case 'x': nm_opts.t = RADIX_HEX; break; case 0: if (nm_opts.sort_size != 0) { nm_opts.sort_fn = &cmp_size; filter_insert(sym_elem_def); filter_insert(sym_elem_nonzero_size); } if (nm_opts.def_only != 0) filter_insert(sym_elem_def); if (nm_opts.no_demangle != 0) nm_opts.demangle_type = -1; break; default : usage(1); } } + *argc -= optind; + *argv += optind; /* * In POSIX mode, the '-o' option controls the output radix. * In non-POSIX mode, the option is a synonym for the '-A' and * '--print-file-name' options. */ if (oflag) { if (is_posix) nm_opts.t = RADIX_OCT; else nm_opts.print_name = PRINT_NAME_FULL; } assert(nm_opts.sort_fn != NULL && "nm_opts.sort_fn is null"); assert(nm_opts.elem_print_fn != NULL && "nm_opts.elem_print_fn is null"); assert(nm_opts.value_print_fn != NULL && "nm_opts.value_print_fn is null"); set_opt_value_print_fn(nm_opts.t); if (nm_opts.undef_only == true) { if (nm_opts.sort_fn == &cmp_size) errx(EXIT_FAILURE, "--size-sort with -u is meaningless"); if (nm_opts.def_only != 0) errx(EXIT_FAILURE, "-u with --defined-only is meaningless"); } if (nm_opts.print_debug == false) filter_insert(sym_elem_nondebug); if (nm_opts.sort_reverse == true && nm_opts.sort_fn == cmp_none) nm_opts.sort_reverse = false; } /* * Get symbol information from elf. */ static int get_sym(Elf *elf, struct sym_head *headp, int shnum, size_t dynndx, size_t strndx, const char *type_table, const char **sec_table, int sec_table_size) { Elf_Scn *scn; Elf_Data *data; GElf_Shdr shdr; GElf_Sym sym; struct filter_entry *fep; size_t ndx; int rtn; const char *sym_name; char type; bool filter; int i, j; assert(elf != NULL); assert(headp != NULL); rtn = 0; for (i = 1; i < shnum; i++) { if ((scn = elf_getscn(elf, i)) == NULL) { warnx("elf_getscn failed: %s", elf_errmsg(-1)); continue; } if (gelf_getshdr(scn, &shdr) != &shdr) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); continue; } if (shdr.sh_type == SHT_SYMTAB) { if (nm_opts.print_symbol != PRINT_SYM_SYM) continue; } else if (shdr.sh_type == SHT_DYNSYM) { if (nm_opts.print_symbol != PRINT_SYM_DYN) continue; } else continue; ndx = shdr.sh_type == SHT_DYNSYM ? dynndx : strndx; data = NULL; while ((data = elf_getdata(scn, data)) != NULL) { j = 1; while (gelf_getsym(data, j++, &sym) != NULL) { sym_name = get_sym_name(elf, &sym, ndx, sec_table, sec_table_size); filter = false; type = get_sym_type(&sym, type_table); SLIST_FOREACH(fep, &nm_out_filter, filter_entries) { if (!fep->fn(type, &sym, sym_name)) { filter = true; break; } } if (filter == false) { if (sym_list_insert(headp, sym_name, &sym) == 0) return (0); rtn++; } } } } return (rtn); } static const char * get_sym_name(Elf *elf, const GElf_Sym *sym, size_t ndx, const char **sec_table, int sec_table_size) { const char *sym_name; sym_name = NULL; /* Show section name as symbol name for STT_SECTION symbols. */ if (GELF_ST_TYPE(sym->st_info) == STT_SECTION) { if (sec_table != NULL && sym->st_shndx < sec_table_size) sym_name = sec_table[sym->st_shndx]; } else sym_name = elf_strptr(elf, ndx, sym->st_name); if (sym_name == NULL) sym_name = "(null)"; return (sym_name); } static char get_sym_type(const GElf_Sym *sym, const char *type_table) { bool is_local; if (sym == NULL || type_table == NULL) return ('?'); is_local = sym->st_info >> 4 == STB_LOCAL; if (sym->st_shndx == SHN_ABS) /* absolute */ return (is_local ? 'a' : 'A'); if (sym->st_shndx == SHN_COMMON) /* common */ return ('C'); if ((sym->st_info) >> 4 == STB_WEAK) { /* weak */ if ((sym->st_info & 0xf) == STT_OBJECT) return (sym->st_shndx == SHN_UNDEF ? 'v' : 'V'); return (sym->st_shndx == SHN_UNDEF ? 'w' : 'W'); } if (sym->st_shndx == SHN_UNDEF) /* undefined */ return ('U'); return (is_local == true && type_table[sym->st_shndx] != 'N' ? tolower((unsigned char) type_table[sym->st_shndx]) : type_table[sym->st_shndx]); } static void global_dest(void) { filter_dest(); } static void global_init(void) { if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "elf_version error"); nm_info.name = ELFTC_GETPROGNAME(); nm_info.def_filename = "a.out"; nm_opts.print_symbol = PRINT_SYM_SYM; nm_opts.print_name = PRINT_NAME_NONE; nm_opts.demangle_type = -1; nm_opts.print_debug = false; nm_opts.print_armap = false; nm_opts.print_size = 0; nm_opts.debug_line = false; nm_opts.def_only = 0; nm_opts.undef_only = false; nm_opts.sort_size = 0; nm_opts.sort_reverse = false; nm_opts.no_demangle = 0; nm_opts.sort_fn = &cmp_name; nm_opts.elem_print_fn = &sym_elem_print_all; nm_opts.value_print_fn = &sym_value_dec_print; nm_opts.size_print_fn = &sym_size_dec_print; SLIST_INIT(&nm_out_filter); } static bool is_sec_data(GElf_Shdr *s) { assert(s != NULL && "shdr is NULL"); return (((s->sh_flags & SHF_ALLOC) != 0) && s->sh_type != SHT_NOBITS); } static bool is_sec_debug(const char *shname) { const char *dbg_sec[] = { ".debug", ".gnu.linkonce.wi.", ".line", ".rel.debug", ".rela.debug", ".stab", NULL }; const char **p; if (shname == NULL) return (false); for (p = dbg_sec; *p; p++) { if (!strncmp(shname, *p, strlen(*p))) return (true); } return (false); } static bool is_sec_nobits(GElf_Shdr *s) { assert(s != NULL && "shdr is NULL"); return (s->sh_type == SHT_NOBITS); } static bool is_sec_readonly(GElf_Shdr *s) { assert(s != NULL && "shdr is NULL"); return ((s->sh_flags & SHF_WRITE) == 0); } static bool is_sec_text(GElf_Shdr *s) { assert(s != NULL && "shdr is NULL"); return ((s->sh_flags & SHF_EXECINSTR) != 0); } static void print_ar_index(int fd, Elf *arf) { Elf *elf; Elf_Arhdr *arhdr; Elf_Arsym *arsym; Elf_Cmd cmd; off_t start; size_t arsym_size; if (arf == NULL) return; if ((arsym = elf_getarsym(arf, &arsym_size)) == NULL) return; printf("\nArchive index:\n"); start = arsym->as_off; cmd = ELF_C_READ; while (arsym_size > 1) { if (elf_rand(arf, arsym->as_off) == arsym->as_off && (elf = elf_begin(fd, cmd, arf)) != NULL) { if ((arhdr = elf_getarhdr(elf)) != NULL) printf("%s in %s\n", arsym->as_name, arhdr->ar_name != NULL ? arhdr->ar_name : arhdr->ar_rawname); elf_end(elf); } ++arsym; --arsym_size; } elf_rand(arf, start); } #define DEMANGLED_BUFFER_SIZE (8 * 1024) #define PRINT_DEMANGLED_NAME(FORMAT, NAME) do { \ char _demangled[DEMANGLED_BUFFER_SIZE]; \ if (nm_opts.demangle_type < 0 || \ elftc_demangle((NAME), _demangled, sizeof(_demangled), \ nm_opts.demangle_type) < 0) \ printf((FORMAT), (NAME)); \ else \ printf((FORMAT), _demangled); \ } while (0) static void print_header(const char *file, const char *obj) { if (file == NULL) return; if (nm_opts.elem_print_fn == &sym_elem_print_all_sysv) { printf("\n\n%s from %s", nm_opts.undef_only == false ? "Symbols" : "Undefined symbols", file); if (obj != NULL) printf("[%s]", obj); printf(":\n\n"); printf("\ Name Value Class Type Size Line Section\n\n"); } else { /* archive file without -A option and POSIX */ if (nm_opts.print_name != PRINT_NAME_FULL && obj != NULL) { if (nm_opts.elem_print_fn == sym_elem_print_all_portable) printf("%s[%s]:\n", file, obj); else if (nm_opts.elem_print_fn == sym_elem_print_all) printf("\n%s:\n", obj); /* multiple files(not archive) without -A option */ } else if (nm_opts.print_name == PRINT_NAME_MULTI) { if (nm_opts.elem_print_fn == sym_elem_print_all) printf("\n"); printf("%s:\n", file); } } } static void print_version(void) { (void) printf("%s (%s)\n", nm_info.name, elftc_version()); exit(0); } static uint64_t get_block_value(Dwarf_Debug dbg, Dwarf_Block *block) { Elf *elf; GElf_Ehdr eh; Dwarf_Error de; if (dwarf_get_elf(dbg, &elf, &de) != DW_DLV_OK) { warnx("dwarf_get_elf failed: %s", dwarf_errmsg(de)); return (0); } if (gelf_getehdr(elf, &eh) != &eh) { warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); return (0); } if (block->bl_len == 5) { if (eh.e_ident[EI_DATA] == ELFDATA2LSB) return (le32dec((uint8_t *) block->bl_data + 1)); else return (be32dec((uint8_t *) block->bl_data + 1)); } else if (block->bl_len == 9) { if (eh.e_ident[EI_DATA] == ELFDATA2LSB) return (le64dec((uint8_t *) block->bl_data + 1)); else return (be64dec((uint8_t *) block->bl_data + 1)); } return (0); } static char * find_object_name(Dwarf_Debug dbg, Dwarf_Die die) { Dwarf_Die ret_die; Dwarf_Attribute at; Dwarf_Off off; Dwarf_Error de; const char *str; char *name; if (dwarf_attrval_string(die, DW_AT_name, &str, &de) == DW_DLV_OK) { if ((name = strdup(str)) == NULL) { warn("strdup"); return (NULL); } return (name); } if (dwarf_attr(die, DW_AT_specification, &at, &de) != DW_DLV_OK) return (NULL); if (dwarf_global_formref(at, &off, &de) != DW_DLV_OK) return (NULL); if (dwarf_offdie(dbg, off, &ret_die, &de) != DW_DLV_OK) return (NULL); return (find_object_name(dbg, ret_die)); } static void search_line_attr(Dwarf_Debug dbg, struct func_info_head *func_info, struct var_info_head *var_info, Dwarf_Die die, char **src_files, Dwarf_Signed filecount) { Dwarf_Attribute at; Dwarf_Unsigned udata; Dwarf_Half tag; Dwarf_Block *block; Dwarf_Bool flag; Dwarf_Die ret_die; Dwarf_Error de; struct func_info_entry *func; struct var_info_entry *var; int ret; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); goto cont_search; } /* We're interested in DIEs which define functions or variables. */ if (tag != DW_TAG_subprogram && tag != DW_TAG_entry_point && tag != DW_TAG_inlined_subroutine && tag != DW_TAG_variable) goto cont_search; if (tag == DW_TAG_variable) { /* Ignore "artificial" variable. */ if (dwarf_attrval_flag(die, DW_AT_artificial, &flag, &de) == DW_DLV_OK && flag) goto cont_search; /* Ignore pure declaration. */ if (dwarf_attrval_flag(die, DW_AT_declaration, &flag, &de) == DW_DLV_OK && flag) goto cont_search; /* Ignore stack varaibles. */ if (dwarf_attrval_flag(die, DW_AT_external, &flag, &de) != DW_DLV_OK || !flag) goto cont_search; if ((var = calloc(1, sizeof(*var))) == NULL) { warn("calloc failed"); goto cont_search; } if (dwarf_attrval_unsigned(die, DW_AT_decl_file, &udata, &de) == DW_DLV_OK && udata > 0 && (Dwarf_Signed) (udata - 1) < filecount) { var->file = strdup(src_files[udata - 1]); if (var->file == NULL) { warn("strdup"); free(var); goto cont_search; } } if (dwarf_attrval_unsigned(die, DW_AT_decl_line, &udata, &de) == DW_DLV_OK) var->line = udata; var->name = find_object_name(dbg, die); if (var->name == NULL) { if (var->file) free(var->file); free(var); goto cont_search; } if (dwarf_attr(die, DW_AT_location, &at, &de) == DW_DLV_OK && dwarf_formblock(at, &block, &de) == DW_DLV_OK) { /* * Since we ignored stack variables, the rest are the * external varaibles which should always use DW_OP_addr * operator for DW_AT_location value. */ if (*((uint8_t *)block->bl_data) == DW_OP_addr) var->addr = get_block_value(dbg, block); } SLIST_INSERT_HEAD(var_info, var, entries); } else { if ((func = calloc(1, sizeof(*func))) == NULL) { warn("calloc failed"); goto cont_search; } /* * Note that dwarf_attrval_unsigned() handles DW_AT_abstract_origin * internally, so it can retrieve DW_AT_decl_file/DW_AT_decl_line * attributes for inlined functions as well. */ if (dwarf_attrval_unsigned(die, DW_AT_decl_file, &udata, &de) == DW_DLV_OK && udata > 0 && (Dwarf_Signed) (udata - 1) < filecount) { func->file = strdup(src_files[udata - 1]); if (func->file == NULL) { warn("strdup"); free(func); goto cont_search; } } if (dwarf_attrval_unsigned(die, DW_AT_decl_line, &udata, &de) == DW_DLV_OK) func->line = udata; func->name = find_object_name(dbg, die); if (func->name == NULL) { if (func->file) free(func->file); free(func); goto cont_search; } if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &udata, &de) == DW_DLV_OK) func->lowpc = udata; if (dwarf_attrval_unsigned(die, DW_AT_high_pc, &udata, &de) == DW_DLV_OK) func->highpc = udata; SLIST_INSERT_HEAD(func_info, func, entries); } cont_search: /* Search children. */ ret = dwarf_child(die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_child: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) search_line_attr(dbg, func_info, var_info, ret_die, src_files, filecount); /* Search sibling. */ ret = dwarf_siblingof(dbg, die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) search_line_attr(dbg, func_info, var_info, ret_die, src_files, filecount); dwarf_dealloc(dbg, die, DW_DLA_DIE); } /* * Read elf file and collect symbol information, sort them, print. * Return 1 at failed, 0 at success. */ static int read_elf(Elf *elf, const char *filename, Elf_Kind kind) { Dwarf_Debug dbg; Dwarf_Die die; Dwarf_Error de; Dwarf_Half tag; Elf_Arhdr *arhdr; Elf_Scn *scn; GElf_Shdr shdr; - GElf_Half i; Dwarf_Line *lbuf; Dwarf_Unsigned lineno; Dwarf_Signed lcount, filecount; Dwarf_Addr lineaddr; struct sym_print_data p_data; struct sym_head list_head; struct line_info_head *line_info; struct func_info_head *func_info; struct var_info_head *var_info; struct line_info_entry *lie; struct func_info_entry *func; struct var_info_entry *var; const char *shname, *objname; char *type_table, **sec_table, *sfile, **src_files; - size_t shstrndx, shnum, dynndx, strndx; + size_t i, shstrndx, shnum, dynndx, strndx; int ret, rtn, e_err; #define OBJNAME (objname == NULL ? filename : objname) assert(filename != NULL && "filename is null"); STAILQ_INIT(&list_head); type_table = NULL; sec_table = NULL; line_info = NULL; func_info = NULL; var_info = NULL; objname = NULL; dynndx = SHN_UNDEF; strndx = SHN_UNDEF; rtn = 0; nm_elfclass = gelf_getclass(elf); if (kind == ELF_K_AR) { if ((arhdr = elf_getarhdr(elf)) == NULL) goto next_cmd; objname = arhdr->ar_name != NULL ? arhdr->ar_name : arhdr->ar_rawname; } if (!elf_getshnum(elf, &shnum)) { if ((e_err = elf_errno()) != 0) warnx("%s: %s", OBJNAME, "File format not recognized"); else warnx("%s: cannot get section number", OBJNAME); rtn = 1; goto next_cmd; } if (shnum == 0) { warnx("%s: has no section", OBJNAME); rtn = 1; goto next_cmd; } if (!elf_getshstrndx(elf, &shstrndx)) { warnx("%s: cannot get str index", OBJNAME); rtn = 1; goto next_cmd; } /* type_table for type determine */ if ((type_table = malloc(sizeof(char) * shnum)) == NULL) { warn("%s: malloc", OBJNAME); rtn = 1; goto next_cmd; } /* sec_table for section name to display in sysv format */ if ((sec_table = calloc(shnum, sizeof(char *))) == NULL) { warn("%s: calloc", OBJNAME); rtn = 1; goto next_cmd; } type_table[0] = 'U'; if ((sec_table[0] = strdup("*UND*")) == NULL) { warn("strdup"); goto next_cmd; } for (i = 1; i < shnum; ++i) { type_table[i] = 'U'; if ((scn = elf_getscn(elf, i)) == NULL) { if ((e_err = elf_errno()) != 0) warnx("%s: %s", OBJNAME, elf_errmsg(e_err)); else warnx("%s: cannot get section", OBJNAME); rtn = 1; goto next_cmd; } if (gelf_getshdr(scn, &shdr) == NULL) goto next_cmd; /* * Cannot test by type and attribute for dynstr, strtab */ shname = elf_strptr(elf, shstrndx, (size_t) shdr.sh_name); if (shname != NULL) { if ((sec_table[i] = strdup(shname)) == NULL) { warn("strdup"); goto next_cmd; } if (!strncmp(shname, ".dynstr", 7)) { dynndx = elf_ndxscn(scn); if (dynndx == SHN_UNDEF) { warnx("%s: elf_ndxscn failed: %s", OBJNAME, elf_errmsg(-1)); goto next_cmd; } } if (!strncmp(shname, ".strtab", 7)) { strndx = elf_ndxscn(scn); if (strndx == SHN_UNDEF) { warnx("%s: elf_ndxscn failed: %s", OBJNAME, elf_errmsg(-1)); goto next_cmd; } } } else { sec_table[i] = strdup("*UND*"); if (sec_table[i] == NULL) { warn("strdup"); goto next_cmd; } } if (is_sec_text(&shdr)) type_table[i] = 'T'; else if (is_sec_data(&shdr)) { if (is_sec_readonly(&shdr)) type_table[i] = 'R'; else type_table[i] = 'D'; } else if (is_sec_nobits(&shdr)) type_table[i] = 'B'; else if (is_sec_debug(shname)) type_table[i] = 'N'; else if (is_sec_readonly(&shdr) && !is_sec_nobits(&shdr)) type_table[i] = 'n'; } print_header(filename, objname); if ((dynndx == SHN_UNDEF && nm_opts.print_symbol == PRINT_SYM_DYN) || (strndx == SHN_UNDEF && nm_opts.print_symbol == PRINT_SYM_SYM)) { warnx("%s: no symbols", OBJNAME); /* This is not an error case */ goto next_cmd; } STAILQ_INIT(&list_head); if (!nm_opts.debug_line) goto process_sym; /* * Collect dwarf line number information. */ if (dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &de) != DW_DLV_OK) { warnx("dwarf_elf_init failed: %s", dwarf_errmsg(de)); goto process_sym; } line_info = malloc(sizeof(struct line_info_head)); func_info = malloc(sizeof(struct func_info_head)); var_info = malloc(sizeof(struct var_info_head)); if (line_info != NULL) SLIST_INIT(line_info); if (func_info != NULL) SLIST_INIT(func_info); if (var_info != NULL) SLIST_INIT(var_info); if (line_info == NULL || func_info == NULL || var_info == NULL) { warn("malloc"); (void) dwarf_finish(dbg, &de); goto process_sym; } while ((ret = dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, NULL, &de)) == DW_DLV_OK) { die = NULL; while (dwarf_siblingof(dbg, die, &die, &de) == DW_DLV_OK) { if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); continue; } /* XXX: What about DW_TAG_partial_unit? */ if (tag == DW_TAG_compile_unit) break; } if (die == NULL) { warnx("could not find DW_TAG_compile_unit die"); continue; } /* Retrieve source file list. */ ret = dwarf_srcfiles(die, &src_files, &filecount, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_srclines: %s", dwarf_errmsg(de)); if (ret != DW_DLV_OK) continue; /* * Retrieve line number information from .debug_line section. */ ret = dwarf_srclines(die, &lbuf, &lcount, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_srclines: %s", dwarf_errmsg(de)); if (ret != DW_DLV_OK) goto line_attr; for (i = 0; (Dwarf_Signed) i < lcount; i++) { if (dwarf_lineaddr(lbuf[i], &lineaddr, &de)) { warnx("dwarf_lineaddr: %s", dwarf_errmsg(de)); continue; } if (dwarf_lineno(lbuf[i], &lineno, &de)) { warnx("dwarf_lineno: %s", dwarf_errmsg(de)); continue; } if (dwarf_linesrc(lbuf[i], &sfile, &de)) { warnx("dwarf_linesrc: %s", dwarf_errmsg(de)); continue; } if ((lie = malloc(sizeof(*lie))) == NULL) { warn("malloc"); continue; } lie->addr = lineaddr; lie->line = lineno; lie->file = strdup(sfile); if (lie->file == NULL) { warn("strdup"); free(lie); continue; } SLIST_INSERT_HEAD(line_info, lie, entries); } line_attr: /* Retrieve line number information from DIEs. */ search_line_attr(dbg, func_info, var_info, die, src_files, filecount); } (void) dwarf_finish(dbg, &de); process_sym: p_data.list_num = get_sym(elf, &list_head, shnum, dynndx, strndx, type_table, (void *) sec_table, shnum); if (p_data.list_num == 0) goto next_cmd; p_data.headp = &list_head; p_data.sh_num = shnum; p_data.t_table = type_table; p_data.s_table = (void *) sec_table; p_data.filename = filename; p_data.objname = objname; sym_list_print(&p_data, func_info, var_info, line_info); next_cmd: if (nm_opts.debug_line) { if (func_info != NULL) { while (!SLIST_EMPTY(func_info)) { func = SLIST_FIRST(func_info); SLIST_REMOVE_HEAD(func_info, entries); free(func->file); free(func->name); free(func); } free(func_info); func_info = NULL; } if (var_info != NULL) { while (!SLIST_EMPTY(var_info)) { var = SLIST_FIRST(var_info); SLIST_REMOVE_HEAD(var_info, entries); free(var->file); free(var->name); free(var); } free(var_info); var_info = NULL; } if (line_info != NULL) { while (!SLIST_EMPTY(line_info)) { lie = SLIST_FIRST(line_info); SLIST_REMOVE_HEAD(line_info, entries); free(lie->file); free(lie); } free(line_info); line_info = NULL; } } if (sec_table != NULL) for (i = 0; i < shnum; ++i) free(sec_table[i]); free(sec_table); free(type_table); sym_list_dest(&list_head); return (rtn); #undef OBJNAME } static int read_object(const char *filename) { Elf *elf, *arf; Elf_Cmd elf_cmd; Elf_Kind kind; int fd, rtn, e_err; assert(filename != NULL && "filename is null"); if ((fd = open(filename, O_RDONLY)) == -1) { warn("'%s'", filename); return (1); } elf_cmd = ELF_C_READ; if ((arf = elf_begin(fd, elf_cmd, (Elf *) NULL)) == NULL) { if ((e_err = elf_errno()) != 0) warnx("elf_begin error: %s", elf_errmsg(e_err)); else warnx("elf_begin error"); close(fd); return (1); } assert(arf != NULL && "arf is null."); rtn = 0; if ((kind = elf_kind(arf)) == ELF_K_NONE) { warnx("%s: File format not recognized", filename); elf_end(arf); close(fd); return (1); } if (kind == ELF_K_AR) { if (nm_opts.print_name == PRINT_NAME_MULTI && nm_opts.elem_print_fn == sym_elem_print_all) printf("\n%s:\n", filename); if (nm_opts.print_armap == true) print_ar_index(fd, arf); } while ((elf = elf_begin(fd, elf_cmd, arf)) != NULL) { rtn |= read_elf(elf, filename, kind); /* * If file is not archive, elf_next return ELF_C_NULL and * stop the loop. */ elf_cmd = elf_next(elf); elf_end(elf); } elf_end(arf); close(fd); return (rtn); } static int read_files(int argc, char **argv) { int rtn = 0; if (argc < 0 || argv == NULL) return (1); if (argc == 0) rtn |= read_object(nm_info.def_filename); else { if (nm_opts.print_name == PRINT_NAME_NONE && argc > 1) nm_opts.print_name = PRINT_NAME_MULTI; while (argc > 0) { rtn |= read_object(*argv); --argc; ++argv; } } return (rtn); } static void print_lineno(struct sym_entry *ep, struct func_info_head *func_info, struct var_info_head *var_info, struct line_info_head *line_info) { struct func_info_entry *func; struct var_info_entry *var; struct line_info_entry *lie; /* For function symbol, search the function line information list. */ if ((ep->sym->st_info & 0xf) == STT_FUNC && func_info != NULL) { SLIST_FOREACH(func, func_info, entries) { if (func->name != NULL && !strcmp(ep->name, func->name) && ep->sym->st_value >= func->lowpc && ep->sym->st_value < func->highpc) { printf("\t%s:%" PRIu64, func->file, func->line); return; } } } /* For variable symbol, search the variable line information list. */ if ((ep->sym->st_info & 0xf) == STT_OBJECT && var_info != NULL) { SLIST_FOREACH(var, var_info, entries) { if (!strcmp(ep->name, var->name) && ep->sym->st_value == var->addr) { printf("\t%s:%" PRIu64, var->file, var->line); return; } } } /* Otherwise search line number information the .debug_line section. */ if (line_info != NULL) { SLIST_FOREACH(lie, line_info, entries) { if (ep->sym->st_value == lie->addr) { printf("\t%s:%" PRIu64, lie->file, lie->line); return; } } } } static void set_opt_value_print_fn(enum radix t) { switch (t) { case RADIX_OCT: nm_opts.value_print_fn = &sym_value_oct_print; nm_opts.size_print_fn = &sym_size_oct_print; break; case RADIX_DEC: nm_opts.value_print_fn = &sym_value_dec_print; nm_opts.size_print_fn = &sym_size_dec_print; break; case RADIX_HEX: default : nm_opts.value_print_fn = &sym_value_hex_print; nm_opts.size_print_fn = &sym_size_hex_print; } assert(nm_opts.value_print_fn != NULL && "nm_opts.value_print_fn is null"); } static void sym_elem_print_all(char type, const char *sec, const GElf_Sym *sym, const char *name) { if (sec == NULL || sym == NULL || name == NULL || nm_opts.value_print_fn == NULL) return; if (IS_UNDEF_SYM_TYPE(type)) { if (nm_opts.t == RADIX_HEX && nm_elfclass == ELFCLASS32) printf("%-8s", ""); else printf("%-16s", ""); } else { switch ((nm_opts.sort_fn == & cmp_size ? 2 : 0) + nm_opts.print_size) { case 3: if (sym->st_size != 0) { nm_opts.value_print_fn(sym); printf(" "); nm_opts.size_print_fn(sym); } break; case 2: if (sym->st_size != 0) nm_opts.size_print_fn(sym); break; case 1: nm_opts.value_print_fn(sym); if (sym->st_size != 0) { printf(" "); nm_opts.size_print_fn(sym); } break; case 0: default: nm_opts.value_print_fn(sym); } } printf(" %c ", type); PRINT_DEMANGLED_NAME("%s", name); } static void sym_elem_print_all_portable(char type, const char *sec, const GElf_Sym *sym, const char *name) { if (sec == NULL || sym == NULL || name == NULL || nm_opts.value_print_fn == NULL) return; PRINT_DEMANGLED_NAME("%s", name); printf(" %c ", type); if (!IS_UNDEF_SYM_TYPE(type)) { nm_opts.value_print_fn(sym); printf(" "); if (sym->st_size != 0) nm_opts.size_print_fn(sym); } else printf(" "); } static void sym_elem_print_all_sysv(char type, const char *sec, const GElf_Sym *sym, const char *name) { if (sec == NULL || sym == NULL || name == NULL || nm_opts.value_print_fn == NULL) return; PRINT_DEMANGLED_NAME("%-20s|", name); if (IS_UNDEF_SYM_TYPE(type)) printf(" "); else nm_opts.value_print_fn(sym); printf("| %c |", type); switch (sym->st_info & 0xf) { case STT_OBJECT: printf("%18s|", "OBJECT"); break; case STT_FUNC: printf("%18s|", "FUNC"); break; case STT_SECTION: printf("%18s|", "SECTION"); break; case STT_FILE: printf("%18s|", "FILE"); break; case STT_LOPROC: printf("%18s|", "LOPROC"); break; case STT_HIPROC: printf("%18s|", "HIPROC"); break; case STT_NOTYPE: default: printf("%18s|", "NOTYPE"); } if (sym->st_size != 0) nm_opts.size_print_fn(sym); else printf(" "); printf("| |%s", sec); } static int sym_elem_def(char type, const GElf_Sym *sym, const char *name) { assert(IS_SYM_TYPE((unsigned char) type)); UNUSED(sym); UNUSED(name); return (!IS_UNDEF_SYM_TYPE((unsigned char) type)); } static int sym_elem_global(char type, const GElf_Sym *sym, const char *name) { assert(IS_SYM_TYPE((unsigned char) type)); UNUSED(sym); UNUSED(name); /* weak symbols resemble global. */ return (isupper((unsigned char) type) || type == 'w'); } static int sym_elem_global_static(char type, const GElf_Sym *sym, const char *name) { unsigned char info; assert(sym != NULL); UNUSED(type); UNUSED(name); info = sym->st_info >> 4; return (info == STB_LOCAL || info == STB_GLOBAL || info == STB_WEAK); } static int sym_elem_nondebug(char type, const GElf_Sym *sym, const char *name) { assert(sym != NULL); UNUSED(type); UNUSED(name); if (sym->st_value == 0 && (sym->st_info & 0xf) == STT_FILE) return (0); if (sym->st_name == 0) return (0); return (1); } static int sym_elem_nonzero_size(char type, const GElf_Sym *sym, const char *name) { assert(sym != NULL); UNUSED(type); UNUSED(name); return (sym->st_size > 0); } static int sym_elem_undef(char type, const GElf_Sym *sym, const char *name) { assert(IS_SYM_TYPE((unsigned char) type)); UNUSED(sym); UNUSED(name); return (IS_UNDEF_SYM_TYPE((unsigned char) type)); } static void sym_list_dest(struct sym_head *headp) { struct sym_entry *ep, *ep_n; if (headp == NULL) return; ep = STAILQ_FIRST(headp); while (ep != NULL) { ep_n = STAILQ_NEXT(ep, sym_entries); free(ep->sym); free(ep->name); free(ep); ep = ep_n; } } static int sym_list_insert(struct sym_head *headp, const char *name, const GElf_Sym *sym) { struct sym_entry *e; if (headp == NULL || name == NULL || sym == NULL) return (0); if ((e = malloc(sizeof(struct sym_entry))) == NULL) { warn("malloc"); return (0); } if ((e->name = strdup(name)) == NULL) { warn("strdup"); free(e); return (0); } if ((e->sym = malloc(sizeof(GElf_Sym))) == NULL) { warn("malloc"); free(e->name); free(e); return (0); } memcpy(e->sym, sym, sizeof(GElf_Sym)); /* Display size instead of value for common symbol. */ if (sym->st_shndx == SHN_COMMON) e->sym->st_value = sym->st_size; STAILQ_INSERT_TAIL(headp, e, sym_entries); return (1); } /* If file has not .debug_info, line_info will be NULL */ static void sym_list_print(struct sym_print_data *p, struct func_info_head *func_info, struct var_info_head *var_info, struct line_info_head *line_info) { struct sym_entry *e_v; size_t si; int i; if (p == NULL || CHECK_SYM_PRINT_DATA(p)) return; if ((e_v = sym_list_sort(p)) == NULL) return; if (nm_opts.sort_reverse == false) for (si = 0; si != p->list_num; ++si) sym_list_print_each(&e_v[si], p, func_info, var_info, line_info); else for (i = p->list_num - 1; i != -1; --i) sym_list_print_each(&e_v[i], p, func_info, var_info, line_info); free(e_v); } /* If file has not .debug_info, line_info will be NULL */ static void sym_list_print_each(struct sym_entry *ep, struct sym_print_data *p, struct func_info_head *func_info, struct var_info_head *var_info, struct line_info_head *line_info) { const char *sec; char type; if (ep == NULL || CHECK_SYM_PRINT_DATA(p)) return; assert(ep->name != NULL); assert(ep->sym != NULL); type = get_sym_type(ep->sym, p->t_table); if (nm_opts.print_name == PRINT_NAME_FULL) { printf("%s", p->filename); if (nm_opts.elem_print_fn == &sym_elem_print_all_portable) { if (p->objname != NULL) printf("[%s]", p->objname); printf(": "); } else { if (p->objname != NULL) printf(":%s", p->objname); printf(":"); } } switch (ep->sym->st_shndx) { case SHN_LOPROC: /* LOPROC or LORESERVE */ sec = "*LOPROC*"; break; case SHN_HIPROC: sec = "*HIPROC*"; break; case SHN_LOOS: sec = "*LOOS*"; break; case SHN_HIOS: sec = "*HIOS*"; break; case SHN_ABS: sec = "*ABS*"; break; case SHN_COMMON: sec = "*COM*"; break; case SHN_HIRESERVE: /* HIRESERVE or XINDEX */ sec = "*HIRESERVE*"; break; default: if (ep->sym->st_shndx > p->sh_num) return; sec = p->s_table[ep->sym->st_shndx]; break; } nm_opts.elem_print_fn(type, sec, ep->sym, ep->name); if (nm_opts.debug_line == true && !IS_UNDEF_SYM_TYPE(type)) print_lineno(ep, func_info, var_info, line_info); printf("\n"); } static struct sym_entry * sym_list_sort(struct sym_print_data *p) { struct sym_entry *ep, *e_v; int idx; if (p == NULL || CHECK_SYM_PRINT_DATA(p)) return (NULL); if ((e_v = malloc(sizeof(struct sym_entry) * p->list_num)) == NULL) { warn("malloc"); return (NULL); } idx = 0; STAILQ_FOREACH(ep, p->headp, sym_entries) { if (ep->name != NULL && ep->sym != NULL) { e_v[idx].name = ep->name; e_v[idx].sym = ep->sym; ++idx; } } assert((size_t)idx == p->list_num); if (nm_opts.sort_fn != &cmp_none) { nm_print_data = p; assert(nm_print_data != NULL); qsort(e_v, p->list_num, sizeof(struct sym_entry), nm_opts.sort_fn); } return (e_v); } static void sym_size_oct_print(const GElf_Sym *sym) { assert(sym != NULL && "sym is null"); printf("%016" PRIo64, sym->st_size); } static void sym_size_hex_print(const GElf_Sym *sym) { assert(sym != NULL && "sym is null"); if (nm_elfclass == ELFCLASS32) printf("%08" PRIx64, sym->st_size); else printf("%016" PRIx64, sym->st_size); } static void sym_size_dec_print(const GElf_Sym *sym) { assert(sym != NULL && "sym is null"); printf("%016" PRId64, sym->st_size); } static void sym_value_oct_print(const GElf_Sym *sym) { assert(sym != NULL && "sym is null"); printf("%016" PRIo64, sym->st_value); } static void sym_value_hex_print(const GElf_Sym *sym) { assert(sym != NULL && "sym is null"); if (nm_elfclass == ELFCLASS32) printf("%08" PRIx64, sym->st_value); else printf("%016" PRIx64, sym->st_value); } static void sym_value_dec_print(const GElf_Sym *sym) { assert(sym != NULL && "sym is null"); printf("%016" PRId64, sym->st_value); } static void usage(int exitcode) { printf("Usage: %s [options] file ...\ \n Display symbolic information in file.\n\ \n Options: \ \n -A, --print-file-name Write the full pathname or library name of an\ \n object on each line.\ \n -a, --debug-syms Display all symbols include debugger-only\ \n symbols.", nm_info.name); printf("\ \n -B Equivalent to specifying \"--format=bsd\".\ \n -C, --demangle[=style] Decode low-level symbol names.\ \n --no-demangle Do not demangle low-level symbol names.\ \n -D, --dynamic Display only dynamic symbols.\ \n -e Display only global and static symbols."); printf("\ \n -f Produce full output (default).\ \n --format=format Display output in specific format. Allowed\ \n formats are: \"bsd\", \"posix\" and \"sysv\".\ \n -g, --extern-only Display only global symbol information.\ \n -h, --help Show this help message.\ \n -l, --line-numbers Display filename and linenumber using\ \n debugging information.\ \n -n, --numeric-sort Sort symbols numerically by value."); printf("\ \n -o Write numeric values in octal. Equivalent to\ \n specifying \"-t o\".\ \n -p, --no-sort Do not sort symbols.\ \n -P Write information in a portable output format.\ \n Equivalent to specifying \"--format=posix\".\ \n -r, --reverse-sort Reverse the order of the sort.\ \n -S, --print-size Print symbol sizes instead values.\ \n -s, --print-armap Include an index of archive members.\ \n --size-sort Sort symbols by size."); printf("\ \n -t, --radix=format Write each numeric value in the specified\ \n format:\ \n d In decimal,\ \n o In octal,\ \n x In hexadecimal."); printf("\ \n -u, --undefined-only Display only undefined symbols.\ \n --defined-only Display only defined symbols.\ \n -V, --version Show the version identifier for %s.\ \n -v Sort output by value.\ \n -x Write numeric values in hexadecimal.\ \n Equivalent to specifying \"-t x\".", nm_info.name); printf("\n\ \n The default options are: output in bsd format, use a hexadecimal radix,\ \n sort by symbol name, do not demangle names.\n"); exit(exitcode); } /* * Display symbolic information in file. * Return 0 at success, >0 at failed. */ int main(int argc, char **argv) { int rtn; global_init(); - get_opt(argc, argv); - rtn = read_files(argc - optind, argv + optind); + get_opt(&argc, &argv); + rtn = read_files(argc, argv); global_dest(); exit(rtn); } Index: stable/11/contrib/elftoolchain/readelf/readelf.1 =================================================================== --- stable/11/contrib/elftoolchain/readelf/readelf.1 (revision 367465) +++ stable/11/contrib/elftoolchain/readelf/readelf.1 (revision 367466) @@ -1,197 +1,207 @@ .\" Copyright (c) 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 .\" in this position and unchanged. .\" 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 AUTHORS ``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 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: readelf.1 3486 2016-08-22 14:10:05Z emaste $ +.\" $Id: readelf.1 3753 2019-06-28 01:13:13Z emaste $ .\" -.Dd September 13, 2012 -.Os +.Dd October 31, 2020 .Dt READELF 1 +.Os .Sh NAME .Nm readelf .Nd display information about ELF objects .Sh SYNOPSIS .Nm .Op Fl a | Fl -all .Op Fl c | Fl -archive-index .Op Fl d | Fl -dynamic .Op Fl e | Fl -headers .Op Fl g | Fl -section-groups .Op Fl h | Fl -file-header .Op Fl l | Fl -program-headers .Op Fl n | Fl -notes .Op Fl p Ar section | Fl -string-dump Ns = Ns Ar section .Op Fl r | Fl -relocs .Op Fl t | Fl -section-details .Op Fl v | Fl -version .Oo .Fl w Ns Oo Ns Ar afilmoprsFLR Ns Oc | .Fl -debug-dump Ns Op Ns = Ns Ar long-option-name , Ns ... .Oc .Op Fl x Ar section | Fl -hex-dump Ns = Ns Ar section +.Op Fl z | Fl -decompress .Op Fl A | Fl -arch-specific .Op Fl D | Fl -use-dynamic .Op Fl H | Fl -help .Op Fl I | Fl -histogram .Op Fl N | -full-section-name .Op Fl S | Fl -sections | Fl -section-headers .Op Fl V | Fl -version-info .Op Fl W | Fl -wide .Ar file... .Sh DESCRIPTION The .Nm utility displays information about ELF objects and .Xr ar 1 archives. .Pp The .Nm utility recognizes the following options: .Bl -tag -width indent .It Fl a | Fl -all Turn on the following flags: .Fl d , .Fl h , .Fl I , .Fl l , .Fl r , .Fl s , .Fl A , .Fl S and .Fl V . .It Fl c | Fl -archive-index Print the archive symbol table for archives. .It Fl d | Fl -dynamic Print the contents of the .Li SHT_DYNAMIC sections in the ELF object. .It Fl e | Fl -headers Print all program, file and section headers in the ELF object. .It Fl g | Fl -section-groups Print the contents of the section groups in the ELF object. .It Fl h | Fl -file-header Print the file header of the ELF object. .It Fl l | Fl -program-headers Print the content of the program header table for the object. .It Fl n | Fl -notes Print the contents of .Li PT_NOTE segments or .Li SHT_NOTE sections present in the ELF object. .It Fl p Ar section | Fl -string-dump Ns = Ns Ar section Print the contents of the specified section as printable strings. The argument .Ar section should be the name of a section or a numeric section index. .It Fl r | Fl -relocs Print relocation information. .It Fl s | Fl -syms | Fl -symbols Print symbol tables. .It Fl t | Fl -section-details Print additional information about sections, such as the flags fields in section headers. +Implies +.Fl S . .It Fl v | Fl -version Prints a version identifier for .Nm and exits. .It Fl w Ns Oo afilmoprsFLR Oc | Xo .Fl -debug-dump Ns Op Ns = Ns Ar long-option-name , Ns ... .Xc Display DWARF information. The .Fl w option is used with the short options in the following table; the .Fl -debug-dump option is used with a comma-separated list of the corresponding long option names: .Bl -column ".Em Short Option" "aranges|ranges" .It Em Short Option Ta Em Long Option Ta Em Description .It a Ta abbrev Ta Show abbreviation information. .It f Ta frames Ta Show frame information, displaying frame instructions. .It i Ta info Ta Show debugging information entries. .It l Ta rawline Ta Show line information in raw form. .It m Ta macro Ta Show macro information. .It o Ta loc Ta Show location list information. .It p Ta pubnames Ta Show global names. .It r Ta aranges|ranges Ta Show address range information. .It s Ta str Ta Show the debug string table. .It F Ta frames-interp Ta Show frame information, displaying register rules. .It L Ta decodedline Ta Show line information in decoded form. .It R Ta Ranges Ta Show range lists. .El .Pp If no sub-options are specified, the default is to show information corresponding to the .Ar a , f , i, l , o , p , r , s and .Ar R short options. .It Fl x Ar section | Fl -hex-dump Ns = Ns Ar section Display the contents of the specified section in hexadecimal. The argument .Ar section should be the name of a section or a numeric section index. +.It Fl z | Fl -decompress +Decompress contents of sections specified by +.Fl x +or +.Fl p +before displaying. +If the specified section is not compressed, it is displayed as is. .It Fl A | Fl -arch-specific This option is accepted but is currently unimplemented. .It Fl D | Fl -use-dynamic Print the symbol table specified by the .Li DT_SYMTAB entry in the .Dq Li .dynamic section. .It Fl H | Fl -help Print a help message. .It Fl I | Fl -histogram Print information on bucket list lengths for sections of type .Li SHT_HASH and .Li SHT_GNU_HASH . .It Fl N | Fl -full-section-name This option is accepted but is currently unimplemented. .It Fl S | Fl -sections | Fl -section-headers Print information in the section headers for each ELF object. .It Fl V | Fl -version-info Print symbol versioning information. .It Fl W | Fl -wide Print information about ELF structures using one long line per structure. If this option is not specified, .Nm will list information in the headers of 64 bit ELF objects on two separate lines. .El .Sh EXIT STATUS .Ex -std .Sh SEE ALSO .Xr nm 1 , .Xr addr2line 1 , .Xr elfcopy 1 , .Sh AUTHORS The .Nm utility was written by .An Kai Wang Aq Mt kaiwang27@users.sourceforge.net . Index: stable/11/contrib/elftoolchain/readelf/readelf.c =================================================================== --- stable/11/contrib/elftoolchain/readelf/readelf.c (revision 367465) +++ stable/11/contrib/elftoolchain/readelf/readelf.c (revision 367466) @@ -1,7412 +1,7898 @@ /*- * Copyright (c) 2009-2015 Kai Wang * 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 #include +#include #include #include #include #include #include #include +#include #include "_elftc.h" -ELFTC_VCSID("$Id: readelf.c 3580 2017-09-15 23:29:59Z emaste $"); +ELFTC_VCSID("$Id: readelf.c 3769 2019-06-29 15:15:02Z emaste $"); /* Backwards compatability for older FreeBSD releases. */ #ifndef STB_GNU_UNIQUE #define STB_GNU_UNIQUE 10 #endif #ifndef STT_SPARC_REGISTER #define STT_SPARC_REGISTER 13 #endif /* * readelf(1) options. */ #define RE_AA 0x00000001 #define RE_C 0x00000002 #define RE_DD 0x00000004 #define RE_D 0x00000008 #define RE_G 0x00000010 #define RE_H 0x00000020 #define RE_II 0x00000040 #define RE_I 0x00000080 #define RE_L 0x00000100 #define RE_NN 0x00000200 #define RE_N 0x00000400 #define RE_P 0x00000800 #define RE_R 0x00001000 #define RE_SS 0x00002000 #define RE_S 0x00004000 #define RE_T 0x00008000 #define RE_U 0x00010000 #define RE_VV 0x00020000 #define RE_WW 0x00040000 #define RE_W 0x00080000 #define RE_X 0x00100000 +#define RE_Z 0x00200000 /* * dwarf dump options. */ #define DW_A 0x00000001 #define DW_FF 0x00000002 #define DW_F 0x00000004 #define DW_I 0x00000008 #define DW_LL 0x00000010 #define DW_L 0x00000020 #define DW_M 0x00000040 #define DW_O 0x00000080 #define DW_P 0x00000100 #define DW_RR 0x00000200 #define DW_R 0x00000400 #define DW_S 0x00000800 #define DW_DEFAULT_OPTIONS (DW_A | DW_F | DW_I | DW_L | DW_O | DW_P | \ DW_R | DW_RR | DW_S) /* * readelf(1) run control flags. */ #define DISPLAY_FILENAME 0x0001 /* * Internal data structure for sections. */ struct section { const char *name; /* section name */ Elf_Scn *scn; /* section scn */ uint64_t off; /* section offset */ uint64_t sz; /* section size */ uint64_t entsize; /* section entsize */ uint64_t align; /* section alignment */ uint64_t type; /* section type */ uint64_t flags; /* section flags */ uint64_t addr; /* section virtual addr */ uint32_t link; /* section link ndx */ uint32_t info; /* section info ndx */ }; struct dumpop { union { size_t si; /* section index */ const char *sn; /* section name */ } u; enum { DUMP_BY_INDEX = 0, DUMP_BY_NAME } type; /* dump type */ #define HEX_DUMP 0x0001 #define STR_DUMP 0x0002 int op; /* dump operation */ STAILQ_ENTRY(dumpop) dumpop_list; }; struct symver { const char *name; int type; }; /* * Structure encapsulates the global data for readelf(1). */ struct readelf { const char *filename; /* current processing file. */ int options; /* command line options. */ int flags; /* run control flags. */ int dop; /* dwarf dump options. */ Elf *elf; /* underlying ELF descriptor. */ Elf *ar; /* archive ELF descriptor. */ Dwarf_Debug dbg; /* DWARF handle. */ Dwarf_Half cu_psize; /* DWARF CU pointer size. */ Dwarf_Half cu_osize; /* DWARF CU offset size. */ Dwarf_Half cu_ver; /* DWARF CU version. */ GElf_Ehdr ehdr; /* ELF header. */ int ec; /* ELF class. */ size_t shnum; /* #sections. */ struct section *vd_s; /* Verdef section. */ struct section *vn_s; /* Verneed section. */ struct section *vs_s; /* Versym section. */ uint16_t *vs; /* Versym array. */ int vs_sz; /* Versym array size. */ struct symver *ver; /* Version array. */ int ver_sz; /* Size of version array. */ struct section *sl; /* list of sections. */ STAILQ_HEAD(, dumpop) v_dumpop; /* list of dump ops. */ uint64_t (*dw_read)(Elf_Data *, uint64_t *, int); uint64_t (*dw_decode)(uint8_t **, int); }; enum options { OPTION_DEBUG_DUMP }; static struct option longopts[] = { {"all", no_argument, NULL, 'a'}, {"arch-specific", no_argument, NULL, 'A'}, {"archive-index", no_argument, NULL, 'c'}, {"debug-dump", optional_argument, NULL, OPTION_DEBUG_DUMP}, + {"decompress", no_argument, 0, 'z'}, {"dynamic", no_argument, NULL, 'd'}, {"file-header", no_argument, NULL, 'h'}, {"full-section-name", no_argument, NULL, 'N'}, {"headers", no_argument, NULL, 'e'}, {"help", no_argument, 0, 'H'}, {"hex-dump", required_argument, NULL, 'x'}, {"histogram", no_argument, NULL, 'I'}, {"notes", no_argument, NULL, 'n'}, {"program-headers", no_argument, NULL, 'l'}, {"relocs", no_argument, NULL, 'r'}, {"sections", no_argument, NULL, 'S'}, {"section-headers", no_argument, NULL, 'S'}, {"section-groups", no_argument, NULL, 'g'}, {"section-details", no_argument, NULL, 't'}, {"segments", no_argument, NULL, 'l'}, {"string-dump", required_argument, NULL, 'p'}, {"symbols", no_argument, NULL, 's'}, {"syms", no_argument, NULL, 's'}, {"unwind", no_argument, NULL, 'u'}, {"use-dynamic", no_argument, NULL, 'D'}, {"version-info", no_argument, 0, 'V'}, {"version", no_argument, 0, 'v'}, {"wide", no_argument, 0, 'W'}, {NULL, 0, NULL, 0} }; struct eflags_desc { uint64_t flag; const char *desc; }; +struct flag_desc { + uint64_t flag; + const char *desc; +}; + struct mips_option { uint64_t flag; const char *desc; }; +struct loc_at { + Dwarf_Attribute la_at; + Dwarf_Unsigned la_off; + Dwarf_Unsigned la_lowpc; + Dwarf_Half la_cu_psize; + Dwarf_Half la_cu_osize; + Dwarf_Half la_cu_ver; +}; + static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t); static const char *aeabi_adv_simd_arch(uint64_t simd); static const char *aeabi_align_needed(uint64_t an); static const char *aeabi_align_preserved(uint64_t ap); static const char *aeabi_arm_isa(uint64_t ai); static const char *aeabi_cpu_arch(uint64_t arch); static const char *aeabi_cpu_arch_profile(uint64_t pf); static const char *aeabi_div(uint64_t du); static const char *aeabi_enum_size(uint64_t es); static const char *aeabi_fp_16bit_format(uint64_t fp16); static const char *aeabi_fp_arch(uint64_t fp); static const char *aeabi_fp_denormal(uint64_t fd); static const char *aeabi_fp_exceptions(uint64_t fe); static const char *aeabi_fp_hpext(uint64_t fh); static const char *aeabi_fp_number_model(uint64_t fn); static const char *aeabi_fp_optm_goal(uint64_t fog); static const char *aeabi_fp_rounding(uint64_t fr); static const char *aeabi_hardfp(uint64_t hfp); static const char *aeabi_mpext(uint64_t mp); static const char *aeabi_optm_goal(uint64_t og); static const char *aeabi_pcs_config(uint64_t pcs); static const char *aeabi_pcs_got(uint64_t got); static const char *aeabi_pcs_r9(uint64_t r9); static const char *aeabi_pcs_ro(uint64_t ro); static const char *aeabi_pcs_rw(uint64_t rw); static const char *aeabi_pcs_wchar_t(uint64_t wt); static const char *aeabi_t2ee(uint64_t t2ee); static const char *aeabi_thumb_isa(uint64_t ti); static const char *aeabi_fp_user_exceptions(uint64_t fu); static const char *aeabi_unaligned_access(uint64_t ua); static const char *aeabi_vfp_args(uint64_t va); static const char *aeabi_virtual(uint64_t vt); static const char *aeabi_wmmx_arch(uint64_t wmmx); static const char *aeabi_wmmx_args(uint64_t wa); static const char *elf_class(unsigned int class); static const char *elf_endian(unsigned int endian); static const char *elf_machine(unsigned int mach); static const char *elf_osabi(unsigned int abi); static const char *elf_type(unsigned int type); static const char *elf_ver(unsigned int ver); static const char *dt_type(unsigned int mach, unsigned int dtype); static void dump_ar(struct readelf *re, int); static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); static void dump_attributes(struct readelf *re); static uint8_t *dump_compatibility_tag(uint8_t *p, uint8_t *pe); static void dump_dwarf(struct readelf *re); static void dump_dwarf_abbrev(struct readelf *re); static void dump_dwarf_aranges(struct readelf *re); static void dump_dwarf_block(struct readelf *re, uint8_t *b, Dwarf_Unsigned len); static void dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level); static void dump_dwarf_frame(struct readelf *re, int alt); static void dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, Dwarf_Debug dbg); static int dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, Dwarf_Addr pc, Dwarf_Unsigned func_len, Dwarf_Half cie_ra); static void dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt); static void dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info); static void dump_dwarf_macinfo(struct readelf *re); static void dump_dwarf_line(struct readelf *re); static void dump_dwarf_line_decoded(struct readelf *re); static void dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr); static void dump_dwarf_loclist(struct readelf *re); static void dump_dwarf_pubnames(struct readelf *re); static void dump_dwarf_ranges(struct readelf *re); static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base); static void dump_dwarf_str(struct readelf *re); static void dump_eflags(struct readelf *re, uint64_t e_flags); static void dump_elf(struct readelf *re); +static void dump_flags(struct flag_desc *fd, uint64_t flags); static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab); static void dump_dynamic(struct readelf *re); static void dump_liblist(struct readelf *re); static void dump_mips_abiflags(struct readelf *re, struct section *s); static void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe); static void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz); static void dump_mips_options(struct readelf *re, struct section *s); static void dump_mips_option_flags(const char *name, struct mips_option *opt, uint64_t info); static void dump_mips_reginfo(struct readelf *re, struct section *s); static void dump_mips_specific_info(struct readelf *re); static void dump_notes(struct readelf *re); static void dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off); +static void dump_notes_data(struct readelf *re, const char *name, + uint32_t type, const char *buf, size_t sz); static void dump_svr4_hash(struct section *s); static void dump_svr4_hash64(struct readelf *re, struct section *s); static void dump_gnu_hash(struct readelf *re, struct section *s); +static void dump_gnu_property_type_0(struct readelf *re, const char *buf, + size_t sz); static void dump_hash(struct readelf *re); static void dump_phdr(struct readelf *re); static void dump_ppc_attributes(uint8_t *p, uint8_t *pe); static void dump_section_groups(struct readelf *re); static void dump_symtab(struct readelf *re, int i); static void dump_symtabs(struct readelf *re); static uint8_t *dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe); static void dump_ver(struct readelf *re); static void dump_verdef(struct readelf *re, int dump); static void dump_verneed(struct readelf *re, int dump); static void dump_versym(struct readelf *re); static const char *dwarf_reg(unsigned int mach, unsigned int reg); static const char *dwarf_regname(struct readelf *re, unsigned int num); static struct dumpop *find_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t); static int get_ent_count(struct section *s, int *ent_count); static int get_mips_register_size(uint8_t flag); static char *get_regoff_str(struct readelf *re, Dwarf_Half reg, Dwarf_Addr off); static const char *get_string(struct readelf *re, int strtab, size_t off); static const char *get_symbol_name(struct readelf *re, int symtab, int i); static uint64_t get_symbol_value(struct readelf *re, int symtab, int i); static void load_sections(struct readelf *re); +static int loc_at_comparator(const void *la1, const void *la2); static const char *mips_abi_fp(uint64_t fp); static const char *note_type(const char *note_name, unsigned int et, unsigned int nt); static const char *note_type_freebsd(unsigned int nt); static const char *note_type_freebsd_core(unsigned int nt); static const char *note_type_linux_core(unsigned int nt); static const char *note_type_gnu(unsigned int nt); static const char *note_type_netbsd(unsigned int nt); static const char *note_type_openbsd(unsigned int nt); static const char *note_type_unknown(unsigned int nt); static const char *note_type_xen(unsigned int nt); static const char *option_kind(uint8_t kind); static const char *phdr_type(unsigned int mach, unsigned int ptype); static const char *ppc_abi_fp(uint64_t fp); static const char *ppc_abi_vector(uint64_t vec); static void readelf_usage(int status); static void readelf_version(void); static void search_loclist_at(struct readelf *re, Dwarf_Die die, - Dwarf_Unsigned lowpc); + Dwarf_Unsigned lowpc, struct loc_at **la_list, + size_t *la_list_len, size_t *la_list_cap); static void search_ver(struct readelf *re); static const char *section_type(unsigned int mach, unsigned int stype); static void set_cu_context(struct readelf *re, Dwarf_Half psize, Dwarf_Half osize, Dwarf_Half ver); static const char *st_bind(unsigned int sbind); static const char *st_shndx(unsigned int shndx); static const char *st_type(unsigned int mach, unsigned int os, unsigned int stype); static const char *st_vis(unsigned int svis); static const char *top_tag(unsigned int tag); static void unload_sections(struct readelf *re); static uint64_t _read_lsb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read); static uint64_t _read_msb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read); static uint64_t _decode_lsb(uint8_t **data, int bytes_to_read); static uint64_t _decode_msb(uint8_t **data, int bytes_to_read); static int64_t _decode_sleb128(uint8_t **dp, uint8_t *dpe); static uint64_t _decode_uleb128(uint8_t **dp, uint8_t *dpe); static struct eflags_desc arm_eflags_desc[] = { {EF_ARM_RELEXEC, "relocatable executable"}, {EF_ARM_HASENTRY, "has entry point"}, {EF_ARM_SYMSARESORTED, "sorted symbol tables"}, {EF_ARM_DYNSYMSUSESEGIDX, "dynamic symbols use segment index"}, {EF_ARM_MAPSYMSFIRST, "mapping symbols precede others"}, {EF_ARM_BE8, "BE8"}, {EF_ARM_LE8, "LE8"}, {EF_ARM_INTERWORK, "interworking enabled"}, {EF_ARM_APCS_26, "uses APCS/26"}, {EF_ARM_APCS_FLOAT, "uses APCS/float"}, {EF_ARM_PIC, "position independent"}, {EF_ARM_ALIGN8, "8 bit structure alignment"}, {EF_ARM_NEW_ABI, "uses new ABI"}, {EF_ARM_OLD_ABI, "uses old ABI"}, {EF_ARM_SOFT_FLOAT, "software FP"}, {EF_ARM_VFP_FLOAT, "VFP"}, {EF_ARM_MAVERICK_FLOAT, "Maverick FP"}, {0, NULL} }; static struct eflags_desc mips_eflags_desc[] = { {EF_MIPS_NOREORDER, "noreorder"}, {EF_MIPS_PIC, "pic"}, {EF_MIPS_CPIC, "cpic"}, {EF_MIPS_UCODE, "ugen_reserved"}, {EF_MIPS_ABI2, "abi2"}, {EF_MIPS_OPTIONS_FIRST, "odk first"}, {EF_MIPS_ARCH_ASE_MDMX, "mdmx"}, {EF_MIPS_ARCH_ASE_M16, "mips16"}, {0, NULL} }; static struct eflags_desc powerpc_eflags_desc[] = { {EF_PPC_EMB, "emb"}, {EF_PPC_RELOCATABLE, "relocatable"}, {EF_PPC_RELOCATABLE_LIB, "relocatable-lib"}, {0, NULL} }; +static struct eflags_desc riscv_eflags_desc[] = { + {EF_RISCV_RVC, "RVC"}, + {EF_RISCV_RVE, "RVE"}, + {EF_RISCV_TSO, "TSO"}, + {0, NULL} +}; + static struct eflags_desc sparc_eflags_desc[] = { {EF_SPARC_32PLUS, "v8+"}, {EF_SPARC_SUN_US1, "ultrasparcI"}, {EF_SPARC_HAL_R1, "halr1"}, {EF_SPARC_SUN_US3, "ultrasparcIII"}, {0, NULL} }; static const char * elf_osabi(unsigned int abi) { static char s_abi[32]; switch(abi) { case ELFOSABI_NONE: return "NONE"; case ELFOSABI_HPUX: return "HPUX"; case ELFOSABI_NETBSD: return "NetBSD"; case ELFOSABI_GNU: return "GNU"; case ELFOSABI_HURD: return "HURD"; case ELFOSABI_86OPEN: return "86OPEN"; case ELFOSABI_SOLARIS: return "Solaris"; case ELFOSABI_AIX: return "AIX"; case ELFOSABI_IRIX: return "IRIX"; case ELFOSABI_FREEBSD: return "FreeBSD"; case ELFOSABI_TRU64: return "TRU64"; case ELFOSABI_MODESTO: return "MODESTO"; case ELFOSABI_OPENBSD: return "OpenBSD"; case ELFOSABI_OPENVMS: return "OpenVMS"; case ELFOSABI_NSK: return "NSK"; case ELFOSABI_CLOUDABI: return "CloudABI"; case ELFOSABI_ARM_AEABI: return "ARM EABI"; case ELFOSABI_ARM: return "ARM"; case ELFOSABI_STANDALONE: return "StandAlone"; default: snprintf(s_abi, sizeof(s_abi), "", abi); return (s_abi); } }; static const char * elf_machine(unsigned int mach) { static char s_mach[32]; switch (mach) { case EM_NONE: return "Unknown machine"; case EM_M32: return "AT&T WE32100"; case EM_SPARC: return "Sun SPARC"; case EM_386: return "Intel i386"; case EM_68K: return "Motorola 68000"; case EM_IAMCU: return "Intel MCU"; case EM_88K: return "Motorola 88000"; case EM_860: return "Intel i860"; case EM_MIPS: return "MIPS R3000 Big-Endian only"; case EM_S370: return "IBM System/370"; case EM_MIPS_RS3_LE: return "MIPS R3000 Little-Endian"; case EM_PARISC: return "HP PA-RISC"; case EM_VPP500: return "Fujitsu VPP500"; case EM_SPARC32PLUS: return "SPARC v8plus"; case EM_960: return "Intel 80960"; case EM_PPC: return "PowerPC 32-bit"; case EM_PPC64: return "PowerPC 64-bit"; case EM_S390: return "IBM System/390"; case EM_V800: return "NEC V800"; case EM_FR20: return "Fujitsu FR20"; case EM_RH32: return "TRW RH-32"; case EM_RCE: return "Motorola RCE"; case EM_ARM: return "ARM"; case EM_SH: return "Hitachi SH"; case EM_SPARCV9: return "SPARC v9 64-bit"; case EM_TRICORE: return "Siemens TriCore embedded processor"; case EM_ARC: return "Argonaut RISC Core"; case EM_H8_300: return "Hitachi H8/300"; case EM_H8_300H: return "Hitachi H8/300H"; case EM_H8S: return "Hitachi H8S"; case EM_H8_500: return "Hitachi H8/500"; case EM_IA_64: return "Intel IA-64 Processor"; case EM_MIPS_X: return "Stanford MIPS-X"; case EM_COLDFIRE: return "Motorola ColdFire"; case EM_68HC12: return "Motorola M68HC12"; case EM_MMA: return "Fujitsu MMA"; case EM_PCP: return "Siemens PCP"; case EM_NCPU: return "Sony nCPU"; case EM_NDR1: return "Denso NDR1 microprocessor"; case EM_STARCORE: return "Motorola Star*Core processor"; case EM_ME16: return "Toyota ME16 processor"; case EM_ST100: return "STMicroelectronics ST100 processor"; case EM_TINYJ: return "Advanced Logic Corp. TinyJ processor"; case EM_X86_64: return "Advanced Micro Devices x86-64"; case EM_PDSP: return "Sony DSP Processor"; case EM_FX66: return "Siemens FX66 microcontroller"; case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 microcontroller"; case EM_ST7: return "STmicroelectronics ST7 8-bit microcontroller"; case EM_68HC16: return "Motorola MC68HC16 microcontroller"; case EM_68HC11: return "Motorola MC68HC11 microcontroller"; case EM_68HC08: return "Motorola MC68HC08 microcontroller"; case EM_68HC05: return "Motorola MC68HC05 microcontroller"; case EM_SVX: return "Silicon Graphics SVx"; case EM_ST19: return "STMicroelectronics ST19 8-bit mc"; case EM_VAX: return "Digital VAX"; case EM_CRIS: return "Axis Communications 32-bit embedded processor"; case EM_JAVELIN: return "Infineon Tech. 32bit embedded processor"; case EM_FIREPATH: return "Element 14 64-bit DSP Processor"; case EM_ZSP: return "LSI Logic 16-bit DSP Processor"; case EM_MMIX: return "Donald Knuth's educational 64-bit proc"; case EM_HUANY: return "Harvard University MI object files"; case EM_PRISM: return "SiTera Prism"; case EM_AVR: return "Atmel AVR 8-bit microcontroller"; case EM_FR30: return "Fujitsu FR30"; case EM_D10V: return "Mitsubishi D10V"; case EM_D30V: return "Mitsubishi D30V"; case EM_V850: return "NEC v850"; case EM_M32R: return "Mitsubishi M32R"; case EM_MN10300: return "Matsushita MN10300"; case EM_MN10200: return "Matsushita MN10200"; case EM_PJ: return "picoJava"; case EM_OPENRISC: return "OpenRISC 32-bit embedded processor"; case EM_ARC_A5: return "ARC Cores Tangent-A5"; case EM_XTENSA: return "Tensilica Xtensa Architecture"; case EM_VIDEOCORE: return "Alphamosaic VideoCore processor"; case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor"; case EM_NS32K: return "National Semiconductor 32000 series"; case EM_TPC: return "Tenor Network TPC processor"; case EM_SNP1K: return "Trebia SNP 1000 processor"; case EM_ST200: return "STMicroelectronics ST200 microcontroller"; case EM_IP2K: return "Ubicom IP2xxx microcontroller family"; case EM_MAX: return "MAX Processor"; case EM_CR: return "National Semiconductor CompactRISC microprocessor"; case EM_F2MC16: return "Fujitsu F2MC16"; case EM_MSP430: return "TI embedded microcontroller msp430"; case EM_BLACKFIN: return "Analog Devices Blackfin (DSP) processor"; case EM_SE_C33: return "S1C33 Family of Seiko Epson processors"; case EM_SEP: return "Sharp embedded microprocessor"; case EM_ARCA: return "Arca RISC Microprocessor"; case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd"; case EM_AARCH64: return "AArch64"; case EM_RISCV: return "RISC-V"; default: snprintf(s_mach, sizeof(s_mach), "", mach); return (s_mach); } } static const char * elf_class(unsigned int class) { static char s_class[32]; switch (class) { case ELFCLASSNONE: return "none"; case ELFCLASS32: return "ELF32"; case ELFCLASS64: return "ELF64"; default: snprintf(s_class, sizeof(s_class), "", class); return (s_class); } } static const char * elf_endian(unsigned int endian) { static char s_endian[32]; switch (endian) { case ELFDATANONE: return "none"; case ELFDATA2LSB: return "2's complement, little endian"; case ELFDATA2MSB: return "2's complement, big endian"; default: snprintf(s_endian, sizeof(s_endian), "", endian); return (s_endian); } } static const char * elf_type(unsigned int type) { static char s_type[32]; switch (type) { case ET_NONE: return "NONE (None)"; case ET_REL: return "REL (Relocatable file)"; case ET_EXEC: return "EXEC (Executable file)"; case ET_DYN: return "DYN (Shared object file)"; case ET_CORE: return "CORE (Core file)"; default: if (type >= ET_LOPROC) snprintf(s_type, sizeof(s_type), "", type); else if (type >= ET_LOOS && type <= ET_HIOS) snprintf(s_type, sizeof(s_type), "", type); else snprintf(s_type, sizeof(s_type), "", type); return (s_type); } } static const char * elf_ver(unsigned int ver) { static char s_ver[32]; switch (ver) { case EV_CURRENT: return "(current)"; case EV_NONE: return "(none)"; default: snprintf(s_ver, sizeof(s_ver), "", ver); return (s_ver); } } static const char * phdr_type(unsigned int mach, unsigned int ptype) { static char s_ptype[32]; if (ptype >= PT_LOPROC && ptype <= PT_HIPROC) { switch (mach) { case EM_ARM: switch (ptype) { case PT_ARM_ARCHEXT: return "ARM_ARCHEXT"; case PT_ARM_EXIDX: return "ARM_EXIDX"; } break; } snprintf(s_ptype, sizeof(s_ptype), "LOPROC+%#x", ptype - PT_LOPROC); return (s_ptype); } switch (ptype) { case PT_NULL: return "NULL"; case PT_LOAD: return "LOAD"; case PT_DYNAMIC: return "DYNAMIC"; case PT_INTERP: return "INTERP"; case PT_NOTE: return "NOTE"; case PT_SHLIB: return "SHLIB"; case PT_PHDR: return "PHDR"; case PT_TLS: return "TLS"; case PT_GNU_EH_FRAME: return "GNU_EH_FRAME"; case PT_GNU_STACK: return "GNU_STACK"; case PT_GNU_RELRO: return "GNU_RELRO"; + case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE"; + case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED"; + case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA"; default: if (ptype >= PT_LOOS && ptype <= PT_HIOS) snprintf(s_ptype, sizeof(s_ptype), "LOOS+%#x", ptype - PT_LOOS); else snprintf(s_ptype, sizeof(s_ptype), "", ptype); return (s_ptype); } } static const char * section_type(unsigned int mach, unsigned int stype) { static char s_stype[32]; if (stype >= SHT_LOPROC && stype <= SHT_HIPROC) { switch (mach) { case EM_ARM: switch (stype) { case SHT_ARM_EXIDX: return "ARM_EXIDX"; case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP"; case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES"; case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY"; case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION"; } break; case EM_X86_64: switch (stype) { case SHT_X86_64_UNWIND: return "X86_64_UNWIND"; default: break; } break; case EM_MIPS: case EM_MIPS_RS3_LE: switch (stype) { case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST"; case SHT_MIPS_MSYM: return "MIPS_MSYM"; case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT"; case SHT_MIPS_GPTAB: return "MIPS_GPTAB"; case SHT_MIPS_UCODE: return "MIPS_UCODE"; case SHT_MIPS_DEBUG: return "MIPS_DEBUG"; case SHT_MIPS_REGINFO: return "MIPS_REGINFO"; case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE"; case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM"; case SHT_MIPS_RELD: return "MIPS_RELD"; case SHT_MIPS_IFACE: return "MIPS_IFACE"; case SHT_MIPS_CONTENT: return "MIPS_CONTENT"; case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS"; case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM"; case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST"; case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS"; case SHT_MIPS_DWARF: return "MIPS_DWARF"; case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL"; case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB"; case SHT_MIPS_EVENTS: return "MIPS_EVENTS"; case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE"; case SHT_MIPS_PIXIE: return "MIPS_PIXIE"; case SHT_MIPS_XLATE: return "MIPS_XLATE"; case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG"; case SHT_MIPS_WHIRL: return "MIPS_WHIRL"; case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION"; case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD"; case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION"; case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS"; default: break; } break; default: break; } snprintf(s_stype, sizeof(s_stype), "LOPROC+%#x", stype - SHT_LOPROC); return (s_stype); } switch (stype) { case SHT_NULL: return "NULL"; case SHT_PROGBITS: return "PROGBITS"; case SHT_SYMTAB: return "SYMTAB"; case SHT_STRTAB: return "STRTAB"; case SHT_RELA: return "RELA"; case SHT_HASH: return "HASH"; case SHT_DYNAMIC: return "DYNAMIC"; case SHT_NOTE: return "NOTE"; case SHT_NOBITS: return "NOBITS"; case SHT_REL: return "REL"; case SHT_SHLIB: return "SHLIB"; case SHT_DYNSYM: return "DYNSYM"; case SHT_INIT_ARRAY: return "INIT_ARRAY"; case SHT_FINI_ARRAY: return "FINI_ARRAY"; case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY"; case SHT_GROUP: return "GROUP"; case SHT_SYMTAB_SHNDX: return "SYMTAB_SHNDX"; case SHT_SUNW_dof: return "SUNW_dof"; case SHT_SUNW_cap: return "SUNW_cap"; case SHT_GNU_HASH: return "GNU_HASH"; case SHT_SUNW_ANNOTATE: return "SUNW_ANNOTATE"; case SHT_SUNW_DEBUGSTR: return "SUNW_DEBUGSTR"; case SHT_SUNW_DEBUG: return "SUNW_DEBUG"; case SHT_SUNW_move: return "SUNW_move"; case SHT_SUNW_COMDAT: return "SUNW_COMDAT"; case SHT_SUNW_syminfo: return "SUNW_syminfo"; case SHT_SUNW_verdef: return "SUNW_verdef"; case SHT_SUNW_verneed: return "SUNW_verneed"; case SHT_SUNW_versym: return "SUNW_versym"; default: if (stype >= SHT_LOOS && stype <= SHT_HIOS) snprintf(s_stype, sizeof(s_stype), "LOOS+%#x", stype - SHT_LOOS); else if (stype >= SHT_LOUSER) snprintf(s_stype, sizeof(s_stype), "LOUSER+%#x", stype - SHT_LOUSER); else snprintf(s_stype, sizeof(s_stype), "", stype); return (s_stype); } } static const char * dt_type(unsigned int mach, unsigned int dtype) { static char s_dtype[32]; switch (dtype) { case DT_NULL: return "NULL"; case DT_NEEDED: return "NEEDED"; case DT_PLTRELSZ: return "PLTRELSZ"; case DT_PLTGOT: return "PLTGOT"; case DT_HASH: return "HASH"; case DT_STRTAB: return "STRTAB"; case DT_SYMTAB: return "SYMTAB"; case DT_RELA: return "RELA"; case DT_RELASZ: return "RELASZ"; case DT_RELAENT: return "RELAENT"; case DT_STRSZ: return "STRSZ"; case DT_SYMENT: return "SYMENT"; case DT_INIT: return "INIT"; case DT_FINI: return "FINI"; case DT_SONAME: return "SONAME"; case DT_RPATH: return "RPATH"; case DT_SYMBOLIC: return "SYMBOLIC"; case DT_REL: return "REL"; case DT_RELSZ: return "RELSZ"; case DT_RELENT: return "RELENT"; case DT_PLTREL: return "PLTREL"; case DT_DEBUG: return "DEBUG"; case DT_TEXTREL: return "TEXTREL"; case DT_JMPREL: return "JMPREL"; case DT_BIND_NOW: return "BIND_NOW"; case DT_INIT_ARRAY: return "INIT_ARRAY"; case DT_FINI_ARRAY: return "FINI_ARRAY"; case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ"; case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ"; case DT_RUNPATH: return "RUNPATH"; case DT_FLAGS: return "FLAGS"; case DT_PREINIT_ARRAY: return "PREINIT_ARRAY"; case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ"; case DT_MAXPOSTAGS: return "MAXPOSTAGS"; case DT_SUNW_AUXILIARY: return "SUNW_AUXILIARY"; case DT_SUNW_RTLDINF: return "SUNW_RTLDINF"; case DT_SUNW_FILTER: return "SUNW_FILTER"; case DT_SUNW_CAP: return "SUNW_CAP"; case DT_SUNW_ASLR: return "SUNW_ASLR"; case DT_CHECKSUM: return "CHECKSUM"; case DT_PLTPADSZ: return "PLTPADSZ"; case DT_MOVEENT: return "MOVEENT"; case DT_MOVESZ: return "MOVESZ"; case DT_FEATURE: return "FEATURE"; case DT_POSFLAG_1: return "POSFLAG_1"; case DT_SYMINSZ: return "SYMINSZ"; case DT_SYMINENT: return "SYMINENT"; case DT_GNU_HASH: return "GNU_HASH"; case DT_TLSDESC_PLT: return "DT_TLSDESC_PLT"; case DT_TLSDESC_GOT: return "DT_TLSDESC_GOT"; case DT_GNU_CONFLICT: return "GNU_CONFLICT"; case DT_GNU_LIBLIST: return "GNU_LIBLIST"; case DT_CONFIG: return "CONFIG"; case DT_DEPAUDIT: return "DEPAUDIT"; case DT_AUDIT: return "AUDIT"; case DT_PLTPAD: return "PLTPAD"; case DT_MOVETAB: return "MOVETAB"; case DT_SYMINFO: return "SYMINFO"; case DT_VERSYM: return "VERSYM"; case DT_RELACOUNT: return "RELACOUNT"; case DT_RELCOUNT: return "RELCOUNT"; case DT_FLAGS_1: return "FLAGS_1"; case DT_VERDEF: return "VERDEF"; case DT_VERDEFNUM: return "VERDEFNUM"; case DT_VERNEED: return "VERNEED"; case DT_VERNEEDNUM: return "VERNEEDNUM"; case DT_AUXILIARY: return "AUXILIARY"; case DT_USED: return "USED"; case DT_FILTER: return "FILTER"; case DT_GNU_PRELINKED: return "GNU_PRELINKED"; case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ"; case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ"; } if (dtype >= DT_LOPROC && dtype <= DT_HIPROC) { switch (mach) { case EM_ARM: switch (dtype) { case DT_ARM_SYMTABSZ: return "ARM_SYMTABSZ"; default: break; } break; case EM_MIPS: case EM_MIPS_RS3_LE: switch (dtype) { case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION"; case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP"; case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM"; case DT_MIPS_IVERSION: return "MIPS_IVERSION"; case DT_MIPS_FLAGS: return "MIPS_FLAGS"; case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS"; case DT_MIPS_CONFLICT: return "MIPS_CONFLICT"; case DT_MIPS_LIBLIST: return "MIPS_LIBLIST"; case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO"; case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO"; case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO"; case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO"; case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO"; case DT_MIPS_GOTSYM: return "MIPS_GOTSYM"; case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO"; case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP"; case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS"; case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO"; case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE"; case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO"; case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC"; case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO"; case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM"; case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO"; case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM"; case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO"; case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS"; case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT"; case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB"; case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX"; case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX"; case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX"; case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX"; case DT_MIPS_OPTIONS: return "MIPS_OPTIONS"; case DT_MIPS_INTERFACE: return "MIPS_INTERFACE"; case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN"; case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE"; case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR"; case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX"; case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE"; case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE"; case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC"; case DT_MIPS_PLTGOT: return "MIPS_PLTGOT"; case DT_MIPS_RLD_OBJ_UPDATE: return "MIPS_RLD_OBJ_UPDATE"; case DT_MIPS_RWPLT: return "MIPS_RWPLT"; default: break; } break; case EM_SPARC: case EM_SPARC32PLUS: case EM_SPARCV9: switch (dtype) { case DT_SPARC_REGISTER: return "DT_SPARC_REGISTER"; default: break; } break; default: break; } } snprintf(s_dtype, sizeof(s_dtype), "", dtype); return (s_dtype); } static const char * st_bind(unsigned int sbind) { static char s_sbind[32]; switch (sbind) { case STB_LOCAL: return "LOCAL"; case STB_GLOBAL: return "GLOBAL"; case STB_WEAK: return "WEAK"; case STB_GNU_UNIQUE: return "UNIQUE"; default: if (sbind >= STB_LOOS && sbind <= STB_HIOS) return "OS"; else if (sbind >= STB_LOPROC && sbind <= STB_HIPROC) return "PROC"; else snprintf(s_sbind, sizeof(s_sbind), "", sbind); return (s_sbind); } } static const char * st_type(unsigned int mach, unsigned int os, unsigned int stype) { static char s_stype[32]; switch (stype) { case STT_NOTYPE: return "NOTYPE"; case STT_OBJECT: return "OBJECT"; case STT_FUNC: return "FUNC"; case STT_SECTION: return "SECTION"; case STT_FILE: return "FILE"; case STT_COMMON: return "COMMON"; case STT_TLS: return "TLS"; default: if (stype >= STT_LOOS && stype <= STT_HIOS) { if ((os == ELFOSABI_GNU || os == ELFOSABI_FREEBSD) && stype == STT_GNU_IFUNC) return "IFUNC"; snprintf(s_stype, sizeof(s_stype), "OS+%#x", stype - STT_LOOS); } else if (stype >= STT_LOPROC && stype <= STT_HIPROC) { if (mach == EM_SPARCV9 && stype == STT_SPARC_REGISTER) return "REGISTER"; snprintf(s_stype, sizeof(s_stype), "PROC+%#x", stype - STT_LOPROC); } else snprintf(s_stype, sizeof(s_stype), "", stype); return (s_stype); } } static const char * st_vis(unsigned int svis) { static char s_svis[32]; switch(svis) { case STV_DEFAULT: return "DEFAULT"; case STV_INTERNAL: return "INTERNAL"; case STV_HIDDEN: return "HIDDEN"; case STV_PROTECTED: return "PROTECTED"; default: snprintf(s_svis, sizeof(s_svis), "", svis); return (s_svis); } } static const char * st_shndx(unsigned int shndx) { static char s_shndx[32]; switch (shndx) { case SHN_UNDEF: return "UND"; case SHN_ABS: return "ABS"; case SHN_COMMON: return "COM"; default: if (shndx >= SHN_LOPROC && shndx <= SHN_HIPROC) return "PRC"; else if (shndx >= SHN_LOOS && shndx <= SHN_HIOS) return "OS"; else snprintf(s_shndx, sizeof(s_shndx), "%u", shndx); return (s_shndx); } } static struct { const char *ln; char sn; int value; } section_flag[] = { {"WRITE", 'W', SHF_WRITE}, {"ALLOC", 'A', SHF_ALLOC}, {"EXEC", 'X', SHF_EXECINSTR}, {"MERGE", 'M', SHF_MERGE}, {"STRINGS", 'S', SHF_STRINGS}, {"INFO LINK", 'I', SHF_INFO_LINK}, {"OS NONCONF", 'O', SHF_OS_NONCONFORMING}, {"GROUP", 'G', SHF_GROUP}, {"TLS", 'T', SHF_TLS}, {"COMPRESSED", 'C', SHF_COMPRESSED}, {NULL, 0, 0} }; static const char * note_type(const char *name, unsigned int et, unsigned int nt) { if ((strcmp(name, "CORE") == 0 || strcmp(name, "LINUX") == 0) && et == ET_CORE) return note_type_linux_core(nt); else if (strcmp(name, "FreeBSD") == 0) if (et == ET_CORE) return note_type_freebsd_core(nt); else return note_type_freebsd(nt); else if (strcmp(name, "GNU") == 0 && et != ET_CORE) return note_type_gnu(nt); else if (strcmp(name, "NetBSD") == 0 && et != ET_CORE) return note_type_netbsd(nt); else if (strcmp(name, "OpenBSD") == 0 && et != ET_CORE) return note_type_openbsd(nt); else if (strcmp(name, "Xen") == 0 && et != ET_CORE) return note_type_xen(nt); return note_type_unknown(nt); } static const char * note_type_freebsd(unsigned int nt) { switch (nt) { case 1: return "NT_FREEBSD_ABI_TAG"; case 2: return "NT_FREEBSD_NOINIT_TAG"; case 3: return "NT_FREEBSD_ARCH_TAG"; case 4: return "NT_FREEBSD_FEATURE_CTL"; default: return (note_type_unknown(nt)); } } static const char * note_type_freebsd_core(unsigned int nt) { switch (nt) { case 1: return "NT_PRSTATUS"; case 2: return "NT_FPREGSET"; case 3: return "NT_PRPSINFO"; case 7: return "NT_THRMISC"; case 8: return "NT_PROCSTAT_PROC"; case 9: return "NT_PROCSTAT_FILES"; case 10: return "NT_PROCSTAT_VMMAP"; case 11: return "NT_PROCSTAT_GROUPS"; case 12: return "NT_PROCSTAT_UMASK"; case 13: return "NT_PROCSTAT_RLIMIT"; case 14: return "NT_PROCSTAT_OSREL"; case 15: return "NT_PROCSTAT_PSSTRINGS"; case 16: return "NT_PROCSTAT_AUXV"; case 17: return "NT_PTLWPINFO"; + case 0x100: return "NT_PPC_VMX (ppc Altivec registers)"; + case 0x102: return "NT_PPC_VSX (ppc VSX registers)"; case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; case 0x400: return "NT_ARM_VFP (arm VFP registers)"; default: return (note_type_unknown(nt)); } } static const char * note_type_linux_core(unsigned int nt) { switch (nt) { case 1: return "NT_PRSTATUS (Process status)"; case 2: return "NT_FPREGSET (Floating point information)"; case 3: return "NT_PRPSINFO (Process information)"; case 4: return "NT_TASKSTRUCT (Task structure)"; case 6: return "NT_AUXV (Auxiliary vector)"; case 10: return "NT_PSTATUS (Linux process status)"; case 12: return "NT_FPREGS (Linux floating point regset)"; case 13: return "NT_PSINFO (Linux process information)"; case 16: return "NT_LWPSTATUS (Linux lwpstatus_t type)"; case 17: return "NT_LWPSINFO (Linux lwpinfo_t type)"; case 18: return "NT_WIN32PSTATUS (win32_pstatus structure)"; case 0x100: return "NT_PPC_VMX (ppc Altivec registers)"; case 0x102: return "NT_PPC_VSX (ppc VSX registers)"; case 0x202: return "NT_X86_XSTATE (x86 XSAVE extended state)"; case 0x300: return "NT_S390_HIGH_GPRS (s390 upper register halves)"; case 0x301: return "NT_S390_TIMER (s390 timer register)"; case 0x302: return "NT_S390_TODCMP (s390 TOD comparator register)"; case 0x303: return "NT_S390_TODPREG (s390 TOD programmable register)"; case 0x304: return "NT_S390_CTRS (s390 control registers)"; case 0x305: return "NT_S390_PREFIX (s390 prefix register)"; case 0x400: return "NT_ARM_VFP (arm VFP registers)"; case 0x46494c45UL: return "NT_FILE (mapped files)"; case 0x46E62B7FUL: return "NT_PRXFPREG (Linux user_xfpregs structure)"; case 0x53494749UL: return "NT_SIGINFO (siginfo_t data)"; default: return (note_type_unknown(nt)); } } static const char * note_type_gnu(unsigned int nt) { switch (nt) { case 1: return "NT_GNU_ABI_TAG"; case 2: return "NT_GNU_HWCAP (Hardware capabilities)"; case 3: return "NT_GNU_BUILD_ID (Build id set by ld(1))"; case 4: return "NT_GNU_GOLD_VERSION (GNU gold version)"; case 5: return "NT_GNU_PROPERTY_TYPE_0"; default: return (note_type_unknown(nt)); } } static const char * note_type_netbsd(unsigned int nt) { switch (nt) { case 1: return "NT_NETBSD_IDENT"; default: return (note_type_unknown(nt)); } } static const char * note_type_openbsd(unsigned int nt) { switch (nt) { case 1: return "NT_OPENBSD_IDENT"; default: return (note_type_unknown(nt)); } } static const char * note_type_unknown(unsigned int nt) { static char s_nt[32]; snprintf(s_nt, sizeof(s_nt), nt >= 0x100 ? "" : "", nt); return (s_nt); } static const char * note_type_xen(unsigned int nt) { switch (nt) { case 0: return "XEN_ELFNOTE_INFO"; case 1: return "XEN_ELFNOTE_ENTRY"; case 2: return "XEN_ELFNOTE_HYPERCALL_PAGE"; case 3: return "XEN_ELFNOTE_VIRT_BASE"; case 4: return "XEN_ELFNOTE_PADDR_OFFSET"; case 5: return "XEN_ELFNOTE_XEN_VERSION"; case 6: return "XEN_ELFNOTE_GUEST_OS"; case 7: return "XEN_ELFNOTE_GUEST_VERSION"; case 8: return "XEN_ELFNOTE_LOADER"; case 9: return "XEN_ELFNOTE_PAE_MODE"; case 10: return "XEN_ELFNOTE_FEATURES"; case 11: return "XEN_ELFNOTE_BSD_SYMTAB"; case 12: return "XEN_ELFNOTE_HV_START_LOW"; case 13: return "XEN_ELFNOTE_L1_MFN_VALID"; case 14: return "XEN_ELFNOTE_SUSPEND_CANCEL"; case 15: return "XEN_ELFNOTE_INIT_P2M"; case 16: return "XEN_ELFNOTE_MOD_START_PFN"; case 17: return "XEN_ELFNOTE_SUPPORTED_FEATURES"; + case 18: return "XEN_ELFNOTE_PHYS32_ENTRY"; default: return (note_type_unknown(nt)); } } static struct { const char *name; int value; } l_flag[] = { {"EXACT_MATCH", LL_EXACT_MATCH}, {"IGNORE_INT_VER", LL_IGNORE_INT_VER}, {"REQUIRE_MINOR", LL_REQUIRE_MINOR}, {"EXPORTS", LL_EXPORTS}, {"DELAY_LOAD", LL_DELAY_LOAD}, {"DELTA", LL_DELTA}, {NULL, 0} }; static struct mips_option mips_exceptions_option[] = { {OEX_PAGE0, "PAGE0"}, {OEX_SMM, "SMM"}, {OEX_PRECISEFP, "PRECISEFP"}, {OEX_DISMISS, "DISMISS"}, {0, NULL} }; static struct mips_option mips_pad_option[] = { {OPAD_PREFIX, "PREFIX"}, {OPAD_POSTFIX, "POSTFIX"}, {OPAD_SYMBOL, "SYMBOL"}, {0, NULL} }; static struct mips_option mips_hwpatch_option[] = { {OHW_R4KEOP, "R4KEOP"}, {OHW_R8KPFETCH, "R8KPFETCH"}, {OHW_R5KEOP, "R5KEOP"}, {OHW_R5KCVTL, "R5KCVTL"}, {0, NULL} }; static struct mips_option mips_hwa_option[] = { {OHWA0_R4KEOP_CHECKED, "R4KEOP_CHECKED"}, {OHWA0_R4KEOP_CLEAN, "R4KEOP_CLEAN"}, {0, NULL} }; static struct mips_option mips_hwo_option[] = { {OHWO0_FIXADE, "FIXADE"}, {0, NULL} }; static const char * option_kind(uint8_t kind) { static char s_kind[32]; switch (kind) { case ODK_NULL: return "NULL"; case ODK_REGINFO: return "REGINFO"; case ODK_EXCEPTIONS: return "EXCEPTIONS"; case ODK_PAD: return "PAD"; case ODK_HWPATCH: return "HWPATCH"; case ODK_FILL: return "FILL"; case ODK_TAGS: return "TAGS"; case ODK_HWAND: return "HWAND"; case ODK_HWOR: return "HWOR"; case ODK_GP_GROUP: return "GP_GROUP"; case ODK_IDENT: return "IDENT"; default: snprintf(s_kind, sizeof(s_kind), "", kind); return (s_kind); } } static const char * top_tag(unsigned int tag) { static char s_top_tag[32]; switch (tag) { case 1: return "File Attributes"; case 2: return "Section Attributes"; case 3: return "Symbol Attributes"; default: snprintf(s_top_tag, sizeof(s_top_tag), "Unknown tag: %u", tag); return (s_top_tag); } } static const char * aeabi_cpu_arch(uint64_t arch) { static char s_cpu_arch[32]; switch (arch) { case 0: return "Pre-V4"; case 1: return "ARM v4"; case 2: return "ARM v4T"; case 3: return "ARM v5T"; case 4: return "ARM v5TE"; case 5: return "ARM v5TEJ"; case 6: return "ARM v6"; case 7: return "ARM v6KZ"; case 8: return "ARM v6T2"; case 9: return "ARM v6K"; case 10: return "ARM v7"; case 11: return "ARM v6-M"; case 12: return "ARM v6S-M"; case 13: return "ARM v7E-M"; default: snprintf(s_cpu_arch, sizeof(s_cpu_arch), "Unknown (%ju)", (uintmax_t) arch); return (s_cpu_arch); } } static const char * aeabi_cpu_arch_profile(uint64_t pf) { static char s_arch_profile[32]; switch (pf) { case 0: return "Not applicable"; case 0x41: /* 'A' */ return "Application Profile"; case 0x52: /* 'R' */ return "Real-Time Profile"; case 0x4D: /* 'M' */ return "Microcontroller Profile"; case 0x53: /* 'S' */ return "Application or Real-Time Profile"; default: snprintf(s_arch_profile, sizeof(s_arch_profile), "Unknown (%ju)\n", (uintmax_t) pf); return (s_arch_profile); } } static const char * aeabi_arm_isa(uint64_t ai) { static char s_ai[32]; switch (ai) { case 0: return "No"; case 1: return "Yes"; default: snprintf(s_ai, sizeof(s_ai), "Unknown (%ju)\n", (uintmax_t) ai); return (s_ai); } } static const char * aeabi_thumb_isa(uint64_t ti) { static char s_ti[32]; switch (ti) { case 0: return "No"; case 1: return "16-bit Thumb"; case 2: return "32-bit Thumb"; default: snprintf(s_ti, sizeof(s_ti), "Unknown (%ju)\n", (uintmax_t) ti); return (s_ti); } } static const char * aeabi_fp_arch(uint64_t fp) { static char s_fp_arch[32]; switch (fp) { case 0: return "No"; case 1: return "VFPv1"; case 2: return "VFPv2"; case 3: return "VFPv3"; case 4: return "VFPv3-D16"; case 5: return "VFPv4"; case 6: return "VFPv4-D16"; default: snprintf(s_fp_arch, sizeof(s_fp_arch), "Unknown (%ju)", (uintmax_t) fp); return (s_fp_arch); } } static const char * aeabi_wmmx_arch(uint64_t wmmx) { static char s_wmmx[32]; switch (wmmx) { case 0: return "No"; case 1: return "WMMXv1"; case 2: return "WMMXv2"; default: snprintf(s_wmmx, sizeof(s_wmmx), "Unknown (%ju)", (uintmax_t) wmmx); return (s_wmmx); } } static const char * aeabi_adv_simd_arch(uint64_t simd) { static char s_simd[32]; switch (simd) { case 0: return "No"; case 1: return "NEONv1"; case 2: return "NEONv2"; default: snprintf(s_simd, sizeof(s_simd), "Unknown (%ju)", (uintmax_t) simd); return (s_simd); } } static const char * aeabi_pcs_config(uint64_t pcs) { static char s_pcs[32]; switch (pcs) { case 0: return "None"; case 1: return "Bare platform"; case 2: return "Linux"; case 3: return "Linux DSO"; case 4: return "Palm OS 2004"; case 5: return "Palm OS (future)"; case 6: return "Symbian OS 2004"; case 7: return "Symbian OS (future)"; default: snprintf(s_pcs, sizeof(s_pcs), "Unknown (%ju)", (uintmax_t) pcs); return (s_pcs); } } static const char * aeabi_pcs_r9(uint64_t r9) { static char s_r9[32]; switch (r9) { case 0: return "V6"; case 1: return "SB"; case 2: return "TLS pointer"; case 3: return "Unused"; default: snprintf(s_r9, sizeof(s_r9), "Unknown (%ju)", (uintmax_t) r9); return (s_r9); } } static const char * aeabi_pcs_rw(uint64_t rw) { static char s_rw[32]; switch (rw) { case 0: return "Absolute"; case 1: return "PC-relative"; case 2: return "SB-relative"; case 3: return "None"; default: snprintf(s_rw, sizeof(s_rw), "Unknown (%ju)", (uintmax_t) rw); return (s_rw); } } static const char * aeabi_pcs_ro(uint64_t ro) { static char s_ro[32]; switch (ro) { case 0: return "Absolute"; case 1: return "PC-relative"; case 2: return "None"; default: snprintf(s_ro, sizeof(s_ro), "Unknown (%ju)", (uintmax_t) ro); return (s_ro); } } static const char * aeabi_pcs_got(uint64_t got) { static char s_got[32]; switch (got) { case 0: return "None"; case 1: return "direct"; case 2: return "indirect via GOT"; default: snprintf(s_got, sizeof(s_got), "Unknown (%ju)", (uintmax_t) got); return (s_got); } } static const char * aeabi_pcs_wchar_t(uint64_t wt) { static char s_wt[32]; switch (wt) { case 0: return "None"; case 2: return "wchar_t size 2"; case 4: return "wchar_t size 4"; default: snprintf(s_wt, sizeof(s_wt), "Unknown (%ju)", (uintmax_t) wt); return (s_wt); } } static const char * aeabi_enum_size(uint64_t es) { static char s_es[32]; switch (es) { case 0: return "None"; case 1: return "smallest"; case 2: return "32-bit"; case 3: return "visible 32-bit"; default: snprintf(s_es, sizeof(s_es), "Unknown (%ju)", (uintmax_t) es); return (s_es); } } static const char * aeabi_align_needed(uint64_t an) { static char s_align_n[64]; switch (an) { case 0: return "No"; case 1: return "8-byte align"; case 2: return "4-byte align"; case 3: return "Reserved"; default: if (an >= 4 && an <= 12) snprintf(s_align_n, sizeof(s_align_n), "8-byte align" " and up to 2^%ju-byte extended align", (uintmax_t) an); else snprintf(s_align_n, sizeof(s_align_n), "Unknown (%ju)", (uintmax_t) an); return (s_align_n); } } static const char * aeabi_align_preserved(uint64_t ap) { static char s_align_p[128]; switch (ap) { case 0: return "No"; case 1: return "8-byte align"; case 2: return "8-byte align and SP % 8 == 0"; case 3: return "Reserved"; default: if (ap >= 4 && ap <= 12) snprintf(s_align_p, sizeof(s_align_p), "8-byte align" " and SP %% 8 == 0 and up to 2^%ju-byte extended" " align", (uintmax_t) ap); else snprintf(s_align_p, sizeof(s_align_p), "Unknown (%ju)", (uintmax_t) ap); return (s_align_p); } } static const char * aeabi_fp_rounding(uint64_t fr) { static char s_fp_r[32]; switch (fr) { case 0: return "Unused"; case 1: return "Needed"; default: snprintf(s_fp_r, sizeof(s_fp_r), "Unknown (%ju)", (uintmax_t) fr); return (s_fp_r); } } static const char * aeabi_fp_denormal(uint64_t fd) { static char s_fp_d[32]; switch (fd) { case 0: return "Unused"; case 1: return "Needed"; case 2: return "Sign Only"; default: snprintf(s_fp_d, sizeof(s_fp_d), "Unknown (%ju)", (uintmax_t) fd); return (s_fp_d); } } static const char * aeabi_fp_exceptions(uint64_t fe) { static char s_fp_e[32]; switch (fe) { case 0: return "Unused"; case 1: return "Needed"; default: snprintf(s_fp_e, sizeof(s_fp_e), "Unknown (%ju)", (uintmax_t) fe); return (s_fp_e); } } static const char * aeabi_fp_user_exceptions(uint64_t fu) { static char s_fp_u[32]; switch (fu) { case 0: return "Unused"; case 1: return "Needed"; default: snprintf(s_fp_u, sizeof(s_fp_u), "Unknown (%ju)", (uintmax_t) fu); return (s_fp_u); } } static const char * aeabi_fp_number_model(uint64_t fn) { static char s_fp_n[32]; switch (fn) { case 0: return "Unused"; case 1: return "IEEE 754 normal"; case 2: return "RTABI"; case 3: return "IEEE 754"; default: snprintf(s_fp_n, sizeof(s_fp_n), "Unknown (%ju)", (uintmax_t) fn); return (s_fp_n); } } static const char * aeabi_fp_16bit_format(uint64_t fp16) { static char s_fp_16[64]; switch (fp16) { case 0: return "None"; case 1: return "IEEE 754"; case 2: return "VFPv3/Advanced SIMD (alternative format)"; default: snprintf(s_fp_16, sizeof(s_fp_16), "Unknown (%ju)", (uintmax_t) fp16); return (s_fp_16); } } static const char * aeabi_mpext(uint64_t mp) { static char s_mp[32]; switch (mp) { case 0: return "Not allowed"; case 1: return "Allowed"; default: snprintf(s_mp, sizeof(s_mp), "Unknown (%ju)", (uintmax_t) mp); return (s_mp); } } static const char * aeabi_div(uint64_t du) { static char s_du[32]; switch (du) { case 0: return "Yes (V7-R/V7-M)"; case 1: return "No"; case 2: return "Yes (V7-A)"; default: snprintf(s_du, sizeof(s_du), "Unknown (%ju)", (uintmax_t) du); return (s_du); } } static const char * aeabi_t2ee(uint64_t t2ee) { static char s_t2ee[32]; switch (t2ee) { case 0: return "Not allowed"; case 1: return "Allowed"; default: snprintf(s_t2ee, sizeof(s_t2ee), "Unknown(%ju)", (uintmax_t) t2ee); return (s_t2ee); } } static const char * aeabi_hardfp(uint64_t hfp) { static char s_hfp[32]; switch (hfp) { case 0: return "Tag_FP_arch"; case 1: return "only SP"; case 2: return "only DP"; case 3: return "both SP and DP"; default: snprintf(s_hfp, sizeof(s_hfp), "Unknown (%ju)", (uintmax_t) hfp); return (s_hfp); } } static const char * aeabi_vfp_args(uint64_t va) { static char s_va[32]; switch (va) { case 0: return "AAPCS (base variant)"; case 1: return "AAPCS (VFP variant)"; case 2: return "toolchain-specific"; default: snprintf(s_va, sizeof(s_va), "Unknown (%ju)", (uintmax_t) va); return (s_va); } } static const char * aeabi_wmmx_args(uint64_t wa) { static char s_wa[32]; switch (wa) { case 0: return "AAPCS (base variant)"; case 1: return "Intel WMMX"; case 2: return "toolchain-specific"; default: snprintf(s_wa, sizeof(s_wa), "Unknown(%ju)", (uintmax_t) wa); return (s_wa); } } static const char * aeabi_unaligned_access(uint64_t ua) { static char s_ua[32]; switch (ua) { case 0: return "Not allowed"; case 1: return "Allowed"; default: snprintf(s_ua, sizeof(s_ua), "Unknown(%ju)", (uintmax_t) ua); return (s_ua); } } static const char * aeabi_fp_hpext(uint64_t fh) { static char s_fh[32]; switch (fh) { case 0: return "Not allowed"; case 1: return "Allowed"; default: snprintf(s_fh, sizeof(s_fh), "Unknown(%ju)", (uintmax_t) fh); return (s_fh); } } static const char * aeabi_optm_goal(uint64_t og) { static char s_og[32]; switch (og) { case 0: return "None"; case 1: return "Speed"; case 2: return "Speed aggressive"; case 3: return "Space"; case 4: return "Space aggressive"; case 5: return "Debugging"; case 6: return "Best Debugging"; default: snprintf(s_og, sizeof(s_og), "Unknown(%ju)", (uintmax_t) og); return (s_og); } } static const char * aeabi_fp_optm_goal(uint64_t fog) { static char s_fog[32]; switch (fog) { case 0: return "None"; case 1: return "Speed"; case 2: return "Speed aggressive"; case 3: return "Space"; case 4: return "Space aggressive"; case 5: return "Accurary"; case 6: return "Best Accurary"; default: snprintf(s_fog, sizeof(s_fog), "Unknown(%ju)", (uintmax_t) fog); return (s_fog); } } static const char * aeabi_virtual(uint64_t vt) { static char s_virtual[64]; switch (vt) { case 0: return "No"; case 1: return "TrustZone"; case 2: return "Virtualization extension"; case 3: return "TrustZone and virtualization extension"; default: snprintf(s_virtual, sizeof(s_virtual), "Unknown(%ju)", (uintmax_t) vt); return (s_virtual); } } static struct { uint64_t tag; const char *s_tag; const char *(*get_desc)(uint64_t val); } aeabi_tags[] = { {4, "Tag_CPU_raw_name", NULL}, {5, "Tag_CPU_name", NULL}, {6, "Tag_CPU_arch", aeabi_cpu_arch}, {7, "Tag_CPU_arch_profile", aeabi_cpu_arch_profile}, {8, "Tag_ARM_ISA_use", aeabi_arm_isa}, {9, "Tag_THUMB_ISA_use", aeabi_thumb_isa}, {10, "Tag_FP_arch", aeabi_fp_arch}, {11, "Tag_WMMX_arch", aeabi_wmmx_arch}, {12, "Tag_Advanced_SIMD_arch", aeabi_adv_simd_arch}, {13, "Tag_PCS_config", aeabi_pcs_config}, {14, "Tag_ABI_PCS_R9_use", aeabi_pcs_r9}, {15, "Tag_ABI_PCS_RW_data", aeabi_pcs_rw}, {16, "Tag_ABI_PCS_RO_data", aeabi_pcs_ro}, {17, "Tag_ABI_PCS_GOT_use", aeabi_pcs_got}, {18, "Tag_ABI_PCS_wchar_t", aeabi_pcs_wchar_t}, {19, "Tag_ABI_FP_rounding", aeabi_fp_rounding}, {20, "Tag_ABI_FP_denormal", aeabi_fp_denormal}, {21, "Tag_ABI_FP_exceptions", aeabi_fp_exceptions}, {22, "Tag_ABI_FP_user_exceptions", aeabi_fp_user_exceptions}, {23, "Tag_ABI_FP_number_model", aeabi_fp_number_model}, {24, "Tag_ABI_align_needed", aeabi_align_needed}, {25, "Tag_ABI_align_preserved", aeabi_align_preserved}, {26, "Tag_ABI_enum_size", aeabi_enum_size}, {27, "Tag_ABI_HardFP_use", aeabi_hardfp}, {28, "Tag_ABI_VFP_args", aeabi_vfp_args}, {29, "Tag_ABI_WMMX_args", aeabi_wmmx_args}, {30, "Tag_ABI_optimization_goals", aeabi_optm_goal}, {31, "Tag_ABI_FP_optimization_goals", aeabi_fp_optm_goal}, {32, "Tag_compatibility", NULL}, {34, "Tag_CPU_unaligned_access", aeabi_unaligned_access}, {36, "Tag_FP_HP_extension", aeabi_fp_hpext}, {38, "Tag_ABI_FP_16bit_format", aeabi_fp_16bit_format}, {42, "Tag_MPextension_use", aeabi_mpext}, {44, "Tag_DIV_use", aeabi_div}, {64, "Tag_nodefaults", NULL}, {65, "Tag_also_compatible_with", NULL}, {66, "Tag_T2EE_use", aeabi_t2ee}, {67, "Tag_conformance", NULL}, {68, "Tag_Virtualization_use", aeabi_virtual}, {70, "Tag_MPextension_use", aeabi_mpext}, }; static const char * mips_abi_fp(uint64_t fp) { static char s_mips_abi_fp[64]; switch (fp) { case 0: return "N/A"; case 1: return "Hard float (double precision)"; case 2: return "Hard float (single precision)"; case 3: return "Soft float"; case 4: return "64-bit float (-mips32r2 -mfp64)"; default: snprintf(s_mips_abi_fp, sizeof(s_mips_abi_fp), "Unknown(%ju)", (uintmax_t) fp); return (s_mips_abi_fp); } } static const char * ppc_abi_fp(uint64_t fp) { static char s_ppc_abi_fp[64]; switch (fp) { case 0: return "N/A"; case 1: return "Hard float (double precision)"; case 2: return "Soft float"; case 3: return "Hard float (single precision)"; default: snprintf(s_ppc_abi_fp, sizeof(s_ppc_abi_fp), "Unknown(%ju)", (uintmax_t) fp); return (s_ppc_abi_fp); } } static const char * ppc_abi_vector(uint64_t vec) { static char s_vec[64]; switch (vec) { case 0: return "N/A"; case 1: return "Generic purpose registers"; case 2: return "AltiVec registers"; case 3: return "SPE registers"; default: snprintf(s_vec, sizeof(s_vec), "Unknown(%ju)", (uintmax_t) vec); return (s_vec); } } static const char * dwarf_reg(unsigned int mach, unsigned int reg) { switch (mach) { case EM_386: case EM_IAMCU: switch (reg) { case 0: return "eax"; case 1: return "ecx"; case 2: return "edx"; case 3: return "ebx"; case 4: return "esp"; case 5: return "ebp"; case 6: return "esi"; case 7: return "edi"; case 8: return "eip"; case 9: return "eflags"; case 11: return "st0"; case 12: return "st1"; case 13: return "st2"; case 14: return "st3"; case 15: return "st4"; case 16: return "st5"; case 17: return "st6"; case 18: return "st7"; case 21: return "xmm0"; case 22: return "xmm1"; case 23: return "xmm2"; case 24: return "xmm3"; case 25: return "xmm4"; case 26: return "xmm5"; case 27: return "xmm6"; case 28: return "xmm7"; case 29: return "mm0"; case 30: return "mm1"; case 31: return "mm2"; case 32: return "mm3"; case 33: return "mm4"; case 34: return "mm5"; case 35: return "mm6"; case 36: return "mm7"; case 37: return "fcw"; case 38: return "fsw"; case 39: return "mxcsr"; case 40: return "es"; case 41: return "cs"; case 42: return "ss"; case 43: return "ds"; case 44: return "fs"; case 45: return "gs"; case 48: return "tr"; case 49: return "ldtr"; default: return (NULL); } + case EM_RISCV: + switch (reg) { + case 0: return "zero"; + case 1: return "ra"; + case 2: return "sp"; + case 3: return "gp"; + case 4: return "tp"; + case 5: return "t0"; + case 6: return "t1"; + case 7: return "t2"; + case 8: return "s0"; + case 9: return "s1"; + case 10: return "a0"; + case 11: return "a1"; + case 12: return "a2"; + case 13: return "a3"; + case 14: return "a4"; + case 15: return "a5"; + case 16: return "a6"; + case 17: return "a7"; + case 18: return "s2"; + case 19: return "s3"; + case 20: return "s4"; + case 21: return "s5"; + case 22: return "s6"; + case 23: return "s7"; + case 24: return "s8"; + case 25: return "s9"; + case 26: return "s10"; + case 27: return "s11"; + case 28: return "t3"; + case 29: return "t4"; + case 30: return "t5"; + case 31: return "t6"; + case 32: return "ft0"; + case 33: return "ft1"; + case 34: return "ft2"; + case 35: return "ft3"; + case 36: return "ft4"; + case 37: return "ft5"; + case 38: return "ft6"; + case 39: return "ft7"; + case 40: return "fs0"; + case 41: return "fs1"; + case 42: return "fa0"; + case 43: return "fa1"; + case 44: return "fa2"; + case 45: return "fa3"; + case 46: return "fa4"; + case 47: return "fa5"; + case 48: return "fa6"; + case 49: return "fa7"; + case 50: return "fs2"; + case 51: return "fs3"; + case 52: return "fs4"; + case 53: return "fs5"; + case 54: return "fs6"; + case 55: return "fs7"; + case 56: return "fs8"; + case 57: return "fs9"; + case 58: return "fs10"; + case 59: return "fs11"; + case 60: return "ft8"; + case 61: return "ft9"; + case 62: return "ft10"; + case 63: return "ft11"; + default: return (NULL); + } case EM_X86_64: switch (reg) { case 0: return "rax"; case 1: return "rdx"; case 2: return "rcx"; case 3: return "rbx"; case 4: return "rsi"; case 5: return "rdi"; case 6: return "rbp"; case 7: return "rsp"; case 16: return "rip"; case 17: return "xmm0"; case 18: return "xmm1"; case 19: return "xmm2"; case 20: return "xmm3"; case 21: return "xmm4"; case 22: return "xmm5"; case 23: return "xmm6"; case 24: return "xmm7"; case 25: return "xmm8"; case 26: return "xmm9"; case 27: return "xmm10"; case 28: return "xmm11"; case 29: return "xmm12"; case 30: return "xmm13"; case 31: return "xmm14"; case 32: return "xmm15"; case 33: return "st0"; case 34: return "st1"; case 35: return "st2"; case 36: return "st3"; case 37: return "st4"; case 38: return "st5"; case 39: return "st6"; case 40: return "st7"; case 41: return "mm0"; case 42: return "mm1"; case 43: return "mm2"; case 44: return "mm3"; case 45: return "mm4"; case 46: return "mm5"; case 47: return "mm6"; case 48: return "mm7"; case 49: return "rflags"; case 50: return "es"; case 51: return "cs"; case 52: return "ss"; case 53: return "ds"; case 54: return "fs"; case 55: return "gs"; case 58: return "fs.base"; case 59: return "gs.base"; case 62: return "tr"; case 63: return "ldtr"; case 64: return "mxcsr"; case 65: return "fcw"; case 66: return "fsw"; default: return (NULL); } default: return (NULL); } } static void dump_ehdr(struct readelf *re) { size_t phnum, shnum, shstrndx; int i; printf("ELF Header:\n"); /* e_ident[]. */ printf(" Magic: "); for (i = 0; i < EI_NIDENT; i++) printf("%.2x ", re->ehdr.e_ident[i]); putchar('\n'); /* EI_CLASS. */ printf("%-37s%s\n", " Class:", elf_class(re->ehdr.e_ident[EI_CLASS])); /* EI_DATA. */ printf("%-37s%s\n", " Data:", elf_endian(re->ehdr.e_ident[EI_DATA])); /* EI_VERSION. */ printf("%-37s%d %s\n", " Version:", re->ehdr.e_ident[EI_VERSION], elf_ver(re->ehdr.e_ident[EI_VERSION])); /* EI_OSABI. */ printf("%-37s%s\n", " OS/ABI:", elf_osabi(re->ehdr.e_ident[EI_OSABI])); /* EI_ABIVERSION. */ printf("%-37s%d\n", " ABI Version:", re->ehdr.e_ident[EI_ABIVERSION]); /* e_type. */ printf("%-37s%s\n", " Type:", elf_type(re->ehdr.e_type)); /* e_machine. */ printf("%-37s%s\n", " Machine:", elf_machine(re->ehdr.e_machine)); /* e_version. */ printf("%-37s%#x\n", " Version:", re->ehdr.e_version); /* e_entry. */ printf("%-37s%#jx\n", " Entry point address:", (uintmax_t)re->ehdr.e_entry); /* e_phoff. */ printf("%-37s%ju (bytes into file)\n", " Start of program headers:", (uintmax_t)re->ehdr.e_phoff); /* e_shoff. */ printf("%-37s%ju (bytes into file)\n", " Start of section headers:", (uintmax_t)re->ehdr.e_shoff); /* e_flags. */ printf("%-37s%#x", " Flags:", re->ehdr.e_flags); dump_eflags(re, re->ehdr.e_flags); putchar('\n'); /* e_ehsize. */ printf("%-37s%u (bytes)\n", " Size of this header:", re->ehdr.e_ehsize); /* e_phentsize. */ printf("%-37s%u (bytes)\n", " Size of program headers:", re->ehdr.e_phentsize); /* e_phnum. */ printf("%-37s%u", " Number of program headers:", re->ehdr.e_phnum); if (re->ehdr.e_phnum == PN_XNUM) { /* Extended program header numbering is in use. */ if (elf_getphnum(re->elf, &phnum)) printf(" (%zu)", phnum); } putchar('\n'); /* e_shentsize. */ printf("%-37s%u (bytes)\n", " Size of section headers:", re->ehdr.e_shentsize); /* e_shnum. */ printf("%-37s%u", " Number of section headers:", re->ehdr.e_shnum); if (re->ehdr.e_shnum == SHN_UNDEF) { /* Extended section numbering is in use. */ if (elf_getshnum(re->elf, &shnum)) printf(" (%ju)", (uintmax_t)shnum); } putchar('\n'); /* e_shstrndx. */ printf("%-37s%u", " Section header string table index:", re->ehdr.e_shstrndx); if (re->ehdr.e_shstrndx == SHN_XINDEX) { /* Extended section numbering is in use. */ if (elf_getshstrndx(re->elf, &shstrndx)) printf(" (%ju)", (uintmax_t)shstrndx); } putchar('\n'); } static void dump_eflags(struct readelf *re, uint64_t e_flags) { struct eflags_desc *edesc; int arm_eabi; edesc = NULL; switch (re->ehdr.e_machine) { case EM_ARM: arm_eabi = (e_flags & EF_ARM_EABIMASK) >> 24; if (arm_eabi == 0) printf(", GNU EABI"); else if (arm_eabi <= 5) printf(", Version%d EABI", arm_eabi); edesc = arm_eflags_desc; break; case EM_MIPS: case EM_MIPS_RS3_LE: switch ((e_flags & EF_MIPS_ARCH) >> 28) { case 0: printf(", mips1"); break; case 1: printf(", mips2"); break; case 2: printf(", mips3"); break; case 3: printf(", mips4"); break; case 4: printf(", mips5"); break; case 5: printf(", mips32"); break; case 6: printf(", mips64"); break; case 7: printf(", mips32r2"); break; case 8: printf(", mips64r2"); break; default: break; } switch ((e_flags & 0x00FF0000) >> 16) { case 0x81: printf(", 3900"); break; case 0x82: printf(", 4010"); break; case 0x83: printf(", 4100"); break; case 0x85: printf(", 4650"); break; case 0x87: printf(", 4120"); break; case 0x88: printf(", 4111"); break; case 0x8a: printf(", sb1"); break; case 0x8b: printf(", octeon"); break; case 0x8c: printf(", xlr"); break; case 0x91: printf(", 5400"); break; case 0x98: printf(", 5500"); break; case 0x99: printf(", 9000"); break; case 0xa0: printf(", loongson-2e"); break; case 0xa1: printf(", loongson-2f"); break; default: break; } switch ((e_flags & 0x0000F000) >> 12) { case 1: printf(", o32"); break; case 2: printf(", o64"); break; case 3: printf(", eabi32"); break; case 4: printf(", eabi64"); break; default: break; } edesc = mips_eflags_desc; break; - case EM_PPC: case EM_PPC64: + switch (e_flags) { + case 0: printf(", Unspecified or Power ELF V1 ABI"); break; + case 1: printf(", Power ELF V1 ABI"); break; + case 2: printf(", OpenPOWER ELF V2 ABI"); break; + default: break; + } + /* FALLTHROUGH */ + case EM_PPC: edesc = powerpc_eflags_desc; break; + case EM_RISCV: + switch (e_flags & EF_RISCV_FLOAT_ABI_MASK) { + case EF_RISCV_FLOAT_ABI_SOFT: + printf(", soft-float ABI"); + break; + case EF_RISCV_FLOAT_ABI_SINGLE: + printf(", single-float ABI"); + break; + case EF_RISCV_FLOAT_ABI_DOUBLE: + printf(", double-float ABI"); + break; + case EF_RISCV_FLOAT_ABI_QUAD: + printf(", quad-float ABI"); + break; + } + edesc = riscv_eflags_desc; + break; case EM_SPARC: case EM_SPARC32PLUS: case EM_SPARCV9: switch ((e_flags & EF_SPARCV9_MM)) { case EF_SPARCV9_TSO: printf(", tso"); break; case EF_SPARCV9_PSO: printf(", pso"); break; case EF_SPARCV9_MM: printf(", rmo"); break; default: break; } edesc = sparc_eflags_desc; break; default: break; } if (edesc != NULL) { while (edesc->desc != NULL) { if (e_flags & edesc->flag) printf(", %s", edesc->desc); edesc++; } } } static void dump_phdr(struct readelf *re) { const char *rawfile; GElf_Phdr phdr; size_t phnum, size; int i, j; #define PH_HDR "Type", "Offset", "VirtAddr", "PhysAddr", "FileSiz", \ "MemSiz", "Flg", "Align" #define PH_CT phdr_type(re->ehdr.e_machine, phdr.p_type), \ (uintmax_t)phdr.p_offset, (uintmax_t)phdr.p_vaddr, \ (uintmax_t)phdr.p_paddr, (uintmax_t)phdr.p_filesz, \ (uintmax_t)phdr.p_memsz, \ phdr.p_flags & PF_R ? 'R' : ' ', \ phdr.p_flags & PF_W ? 'W' : ' ', \ phdr.p_flags & PF_X ? 'E' : ' ', \ (uintmax_t)phdr.p_align if (elf_getphnum(re->elf, &phnum) == 0) { warnx("elf_getphnum failed: %s", elf_errmsg(-1)); return; } if (phnum == 0) { printf("\nThere are no program headers in this file.\n"); return; } printf("\nElf file type is %s", elf_type(re->ehdr.e_type)); printf("\nEntry point 0x%jx\n", (uintmax_t)re->ehdr.e_entry); printf("There are %ju program headers, starting at offset %ju\n", (uintmax_t)phnum, (uintmax_t)re->ehdr.e_phoff); /* Dump program headers. */ printf("\nProgram Headers:\n"); if (re->ec == ELFCLASS32) printf(" %-15s%-9s%-11s%-11s%-8s%-8s%-4s%s\n", PH_HDR); else if (re->options & RE_WW) printf(" %-15s%-9s%-19s%-19s%-9s%-9s%-4s%s\n", PH_HDR); else printf(" %-15s%-19s%-19s%s\n %-19s%-20s" "%-7s%s\n", PH_HDR); for (i = 0; (size_t) i < phnum; i++) { if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); continue; } /* TODO: Add arch-specific segment type dump. */ if (re->ec == ELFCLASS32) printf(" %-14.14s 0x%6.6jx 0x%8.8jx 0x%8.8jx " "0x%5.5jx 0x%5.5jx %c%c%c %#jx\n", PH_CT); else if (re->options & RE_WW) printf(" %-14.14s 0x%6.6jx 0x%16.16jx 0x%16.16jx " "0x%6.6jx 0x%6.6jx %c%c%c %#jx\n", PH_CT); else printf(" %-14.14s 0x%16.16jx 0x%16.16jx 0x%16.16jx\n" " 0x%16.16jx 0x%16.16jx %c%c%c" " %#jx\n", PH_CT); if (phdr.p_type == PT_INTERP) { if ((rawfile = elf_rawfile(re->elf, &size)) == NULL) { warnx("elf_rawfile failed: %s", elf_errmsg(-1)); continue; } if (phdr.p_offset >= size) { warnx("invalid program header offset"); continue; } printf(" [Requesting program interpreter: %s]\n", rawfile + phdr.p_offset); } } /* Dump section to segment mapping. */ if (re->shnum == 0) return; printf("\n Section to Segment mapping:\n"); printf(" Segment Sections...\n"); for (i = 0; (size_t)i < phnum; i++) { if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); continue; } printf(" %2.2d ", i); /* skip NULL section. */ for (j = 1; (size_t)j < re->shnum; j++) { if (re->sl[j].off < phdr.p_offset) continue; if (re->sl[j].off + re->sl[j].sz > phdr.p_offset + phdr.p_filesz && re->sl[j].type != SHT_NOBITS) continue; if (re->sl[j].addr < phdr.p_vaddr || re->sl[j].addr + re->sl[j].sz > phdr.p_vaddr + phdr.p_memsz) continue; if (phdr.p_type == PT_TLS && (re->sl[j].flags & SHF_TLS) == 0) continue; printf("%s ", re->sl[j].name); } printf("\n"); } #undef PH_HDR #undef PH_CT } static char * section_flags(struct readelf *re, struct section *s) { #define BUF_SZ 256 static char buf[BUF_SZ]; int i, p, nb; p = 0; nb = re->ec == ELFCLASS32 ? 8 : 16; if (re->options & RE_T) { snprintf(buf, BUF_SZ, "[%*.*jx]: ", nb, nb, (uintmax_t)s->flags); p += nb + 4; } for (i = 0; section_flag[i].ln != NULL; i++) { if ((s->flags & section_flag[i].value) == 0) continue; if (re->options & RE_T) { snprintf(&buf[p], BUF_SZ - p, "%s, ", section_flag[i].ln); p += strlen(section_flag[i].ln) + 2; } else buf[p++] = section_flag[i].sn; } if (re->options & RE_T && p > nb + 4) p -= 2; buf[p] = '\0'; return (buf); } static void dump_shdr(struct readelf *re) { struct section *s; int i; #define S_HDR "[Nr] Name", "Type", "Addr", "Off", "Size", "ES", \ "Flg", "Lk", "Inf", "Al" #define S_HDRL "[Nr] Name", "Type", "Address", "Offset", "Size", \ "EntSize", "Flags", "Link", "Info", "Align" #define ST_HDR "[Nr] Name", "Type", "Addr", "Off", "Size", "ES", \ "Lk", "Inf", "Al", "Flags" #define ST_HDRL "[Nr] Name", "Type", "Address", "Offset", "Link", \ "Size", "EntSize", "Info", "Align", "Flags" #define S_CT i, s->name, section_type(re->ehdr.e_machine, s->type), \ (uintmax_t)s->addr, (uintmax_t)s->off, (uintmax_t)s->sz,\ (uintmax_t)s->entsize, section_flags(re, s), \ s->link, s->info, (uintmax_t)s->align #define ST_CT i, s->name, section_type(re->ehdr.e_machine, s->type), \ (uintmax_t)s->addr, (uintmax_t)s->off, (uintmax_t)s->sz,\ (uintmax_t)s->entsize, s->link, s->info, \ (uintmax_t)s->align, section_flags(re, s) #define ST_CTL i, s->name, section_type(re->ehdr.e_machine, s->type), \ (uintmax_t)s->addr, (uintmax_t)s->off, s->link, \ (uintmax_t)s->sz, (uintmax_t)s->entsize, s->info, \ (uintmax_t)s->align, section_flags(re, s) if (re->shnum == 0) { printf("\nThere are no sections in this file.\n"); return; } printf("There are %ju section headers, starting at offset 0x%jx:\n", (uintmax_t)re->shnum, (uintmax_t)re->ehdr.e_shoff); printf("\nSection Headers:\n"); if (re->ec == ELFCLASS32) { if (re->options & RE_T) printf(" %s\n %-16s%-9s%-7s%-7s%-5s%-3s%-4s%s\n" "%12s\n", ST_HDR); else printf(" %-23s%-16s%-9s%-7s%-7s%-3s%-4s%-3s%-4s%s\n", S_HDR); } else if (re->options & RE_WW) { if (re->options & RE_T) printf(" %s\n %-16s%-17s%-7s%-7s%-5s%-3s%-4s%s\n" "%12s\n", ST_HDR); else printf(" %-23s%-16s%-17s%-7s%-7s%-3s%-4s%-3s%-4s%s\n", S_HDR); } else { if (re->options & RE_T) printf(" %s\n %-18s%-17s%-18s%s\n %-18s" "%-17s%-18s%s\n%12s\n", ST_HDRL); else printf(" %-23s%-17s%-18s%s\n %-18s%-17s%-7s%" "-6s%-6s%s\n", S_HDRL); } for (i = 0; (size_t)i < re->shnum; i++) { s = &re->sl[i]; if (re->ec == ELFCLASS32) { if (re->options & RE_T) printf(" [%2d] %s\n %-15.15s %8.8jx" " %6.6jx %6.6jx %2.2jx %2u %3u %2ju\n" " %s\n", ST_CT); else printf(" [%2d] %-17.17s %-15.15s %8.8jx" " %6.6jx %6.6jx %2.2jx %3s %2u %3u %2ju\n", S_CT); } else if (re->options & RE_WW) { if (re->options & RE_T) printf(" [%2d] %s\n %-15.15s %16.16jx" " %6.6jx %6.6jx %2.2jx %2u %3u %2ju\n" " %s\n", ST_CT); else printf(" [%2d] %-17.17s %-15.15s %16.16jx" " %6.6jx %6.6jx %2.2jx %3s %2u %3u %2ju\n", S_CT); } else { if (re->options & RE_T) printf(" [%2d] %s\n %-15.15s %16.16jx" " %16.16jx %u\n %16.16jx %16.16jx" " %-16u %ju\n %s\n", ST_CTL); else printf(" [%2d] %-17.17s %-15.15s %16.16jx" " %8.8jx\n %16.16jx %16.16jx " "%3s %2u %3u %ju\n", S_CT); } } if ((re->options & RE_T) == 0) printf("Key to Flags:\n W (write), A (alloc)," " X (execute), M (merge), S (strings)\n" " I (info), L (link order), G (group), x (unknown)\n" " O (extra OS processing required)" " o (OS specific), p (processor specific)\n"); #undef S_HDR #undef S_HDRL #undef ST_HDR #undef ST_HDRL #undef S_CT #undef ST_CT #undef ST_CTL } /* * Return number of entries in the given section. We'd prefer ent_count be a * size_t *, but libelf APIs already use int for section indices. */ static int get_ent_count(struct section *s, int *ent_count) { if (s->entsize == 0) { warnx("section %s has entry size 0", s->name); return (0); } else if (s->sz / s->entsize > INT_MAX) { warnx("section %s has invalid section count", s->name); return (0); } *ent_count = (int)(s->sz / s->entsize); return (1); } static void dump_dynamic(struct readelf *re) { GElf_Dyn dyn; Elf_Data *d; struct section *s; int elferr, i, is_dynamic, j, jmax, nentries; is_dynamic = 0; for (i = 0; (size_t)i < re->shnum; i++) { s = &re->sl[i]; if (s->type != SHT_DYNAMIC) continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); continue; } if (d->d_size <= 0) continue; is_dynamic = 1; /* Determine the actual number of table entries. */ nentries = 0; if (!get_ent_count(s, &jmax)) continue; for (j = 0; j < jmax; j++) { if (gelf_getdyn(d, j, &dyn) != &dyn) { warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); continue; } nentries ++; if (dyn.d_tag == DT_NULL) break; } printf("\nDynamic section at offset 0x%jx", (uintmax_t)s->off); printf(" contains %u entries:\n", nentries); if (re->ec == ELFCLASS32) printf("%5s%12s%28s\n", "Tag", "Type", "Name/Value"); else printf("%5s%20s%28s\n", "Tag", "Type", "Name/Value"); for (j = 0; j < nentries; j++) { if (gelf_getdyn(d, j, &dyn) != &dyn) continue; /* Dump dynamic entry type. */ if (re->ec == ELFCLASS32) printf(" 0x%8.8jx", (uintmax_t)dyn.d_tag); else printf(" 0x%16.16jx", (uintmax_t)dyn.d_tag); printf(" %-20s", dt_type(re->ehdr.e_machine, dyn.d_tag)); /* Dump dynamic entry value. */ dump_dyn_val(re, &dyn, s->link); } } if (!is_dynamic) printf("\nThere is no dynamic section in this file.\n"); } static char * timestamp(time_t ti) { static char ts[32]; struct tm *t; t = gmtime(&ti); snprintf(ts, sizeof(ts), "%04d-%02d-%02dT%02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); return (ts); } static const char * dyn_str(struct readelf *re, uint32_t stab, uint64_t d_val) { const char *name; if (stab == SHN_UNDEF) name = "ERROR"; else if ((name = elf_strptr(re->elf, stab, d_val)) == NULL) { (void) elf_errno(); /* clear error */ name = "ERROR"; } return (name); } static void dump_arch_dyn_val(struct readelf *re, GElf_Dyn *dyn) { switch (re->ehdr.e_machine) { case EM_MIPS: case EM_MIPS_RS3_LE: switch (dyn->d_tag) { case DT_MIPS_RLD_VERSION: case DT_MIPS_LOCAL_GOTNO: case DT_MIPS_CONFLICTNO: case DT_MIPS_LIBLISTNO: case DT_MIPS_SYMTABNO: case DT_MIPS_UNREFEXTNO: case DT_MIPS_GOTSYM: case DT_MIPS_HIPAGENO: case DT_MIPS_DELTA_CLASS_NO: case DT_MIPS_DELTA_INSTANCE_NO: case DT_MIPS_DELTA_RELOC_NO: case DT_MIPS_DELTA_SYM_NO: case DT_MIPS_DELTA_CLASSSYM_NO: case DT_MIPS_LOCALPAGE_GOTIDX: case DT_MIPS_LOCAL_GOTIDX: case DT_MIPS_HIDDEN_GOTIDX: case DT_MIPS_PROTECTED_GOTIDX: printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); break; case DT_MIPS_ICHECKSUM: case DT_MIPS_FLAGS: case DT_MIPS_BASE_ADDRESS: case DT_MIPS_CONFLICT: case DT_MIPS_LIBLIST: case DT_MIPS_RLD_MAP: case DT_MIPS_DELTA_CLASS: case DT_MIPS_DELTA_INSTANCE: case DT_MIPS_DELTA_RELOC: case DT_MIPS_DELTA_SYM: case DT_MIPS_DELTA_CLASSSYM: case DT_MIPS_CXX_FLAGS: case DT_MIPS_PIXIE_INIT: case DT_MIPS_SYMBOL_LIB: case DT_MIPS_OPTIONS: case DT_MIPS_INTERFACE: case DT_MIPS_DYNSTR_ALIGN: case DT_MIPS_INTERFACE_SIZE: case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: case DT_MIPS_COMPACT_SIZE: case DT_MIPS_GP_VALUE: case DT_MIPS_AUX_DYNAMIC: case DT_MIPS_PLTGOT: case DT_MIPS_RLD_OBJ_UPDATE: case DT_MIPS_RWPLT: printf(" 0x%jx\n", (uintmax_t) dyn->d_un.d_val); break; case DT_MIPS_IVERSION: case DT_MIPS_PERF_SUFFIX: case DT_MIPS_TIME_STAMP: printf(" %s\n", timestamp(dyn->d_un.d_val)); break; default: printf("\n"); break; } break; default: printf("\n"); break; } } static void +dump_flags(struct flag_desc *desc, uint64_t val) +{ + struct flag_desc *fd; + + for (fd = desc; fd->flag != 0; fd++) { + if (val & fd->flag) { + val &= ~fd->flag; + printf(" %s", fd->desc); + } + } + if (val != 0) + printf(" unknown (0x%jx)", (uintmax_t)val); + printf("\n"); +} + +static struct flag_desc dt_flags[] = { + { DF_ORIGIN, "ORIGIN" }, + { DF_SYMBOLIC, "SYMBOLIC" }, + { DF_TEXTREL, "TEXTREL" }, + { DF_BIND_NOW, "BIND_NOW" }, + { DF_STATIC_TLS, "STATIC_TLS" }, + { 0, NULL } +}; + +static struct flag_desc dt_flags_1[] = { + { DF_1_BIND_NOW, "NOW" }, + { DF_1_GLOBAL, "GLOBAL" }, + { 0x4, "GROUP" }, + { DF_1_NODELETE, "NODELETE" }, + { DF_1_LOADFLTR, "LOADFLTR" }, + { 0x20, "INITFIRST" }, + { DF_1_NOOPEN, "NOOPEN" }, + { DF_1_ORIGIN, "ORIGIN" }, + { 0x100, "DIRECT" }, + { DF_1_INTERPOSE, "INTERPOSE" }, + { DF_1_NODEFLIB, "NODEFLIB" }, + { 0x1000, "NODUMP" }, + { 0x2000, "CONFALT" }, + { 0x4000, "ENDFILTEE" }, + { 0x8000, "DISPRELDNE" }, + { 0x10000, "DISPRELPND" }, + { 0x20000, "NODIRECT" }, + { 0x40000, "IGNMULDEF" }, + { 0x80000, "NOKSYMS" }, + { 0x100000, "NOHDR" }, + { 0x200000, "EDITED" }, + { 0x400000, "NORELOC" }, + { 0x800000, "SYMINTPOSE" }, + { 0x1000000, "GLOBAUDIT" }, + { 0x02000000, "SINGLETON" }, + { 0x04000000, "STUB" }, + { DF_1_PIE, "PIE" }, + { 0, NULL } +}; + +static void dump_dyn_val(struct readelf *re, GElf_Dyn *dyn, uint32_t stab) { const char *name; if (dyn->d_tag >= DT_LOPROC && dyn->d_tag <= DT_HIPROC && dyn->d_tag != DT_AUXILIARY && dyn->d_tag != DT_FILTER) { dump_arch_dyn_val(re, dyn); return; } /* These entry values are index into the string table. */ name = NULL; if (dyn->d_tag == DT_AUXILIARY || dyn->d_tag == DT_FILTER || dyn->d_tag == DT_NEEDED || dyn->d_tag == DT_SONAME || dyn->d_tag == DT_RPATH || dyn->d_tag == DT_RUNPATH) name = dyn_str(re, stab, dyn->d_un.d_val); switch(dyn->d_tag) { case DT_NULL: case DT_PLTGOT: case DT_HASH: case DT_STRTAB: case DT_SYMTAB: case DT_RELA: case DT_INIT: case DT_SYMBOLIC: case DT_REL: case DT_DEBUG: case DT_TEXTREL: case DT_JMPREL: case DT_FINI: case DT_VERDEF: case DT_VERNEED: case DT_VERSYM: case DT_GNU_HASH: case DT_GNU_LIBLIST: case DT_GNU_CONFLICT: printf(" 0x%jx\n", (uintmax_t) dyn->d_un.d_val); break; case DT_PLTRELSZ: case DT_RELASZ: case DT_RELAENT: case DT_STRSZ: case DT_SYMENT: case DT_RELSZ: case DT_RELENT: case DT_PREINIT_ARRAYSZ: case DT_INIT_ARRAYSZ: case DT_FINI_ARRAYSZ: case DT_GNU_CONFLICTSZ: case DT_GNU_LIBLISTSZ: printf(" %ju (bytes)\n", (uintmax_t) dyn->d_un.d_val); break; case DT_RELACOUNT: case DT_RELCOUNT: case DT_VERDEFNUM: case DT_VERNEEDNUM: printf(" %ju\n", (uintmax_t) dyn->d_un.d_val); break; case DT_AUXILIARY: printf(" Auxiliary library: [%s]\n", name); break; case DT_FILTER: printf(" Filter library: [%s]\n", name); break; case DT_NEEDED: printf(" Shared library: [%s]\n", name); break; case DT_SONAME: printf(" Library soname: [%s]\n", name); break; case DT_RPATH: printf(" Library rpath: [%s]\n", name); break; case DT_RUNPATH: printf(" Library runpath: [%s]\n", name); break; case DT_PLTREL: printf(" %s\n", dt_type(re->ehdr.e_machine, dyn->d_un.d_val)); break; case DT_GNU_PRELINKED: printf(" %s\n", timestamp(dyn->d_un.d_val)); break; + case DT_FLAGS: + dump_flags(dt_flags, dyn->d_un.d_val); + break; + case DT_FLAGS_1: + dump_flags(dt_flags_1, dyn->d_un.d_val); + break; default: printf("\n"); } } static void dump_rel(struct readelf *re, struct section *s, Elf_Data *d) { GElf_Rel r; const char *symname; uint64_t symval; int i, len; uint32_t type; uint8_t type2, type3; if (s->link >= re->shnum) return; #define REL_HDR "r_offset", "r_info", "r_type", "st_value", "st_name" #define REL_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ elftc_reloc_type_str(re->ehdr.e_machine, \ ELF32_R_TYPE(r.r_info)), (uintmax_t)symval, symname #define REL_CT64 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ elftc_reloc_type_str(re->ehdr.e_machine, type), \ (uintmax_t)symval, symname printf("\nRelocation section (%s):\n", s->name); if (re->ec == ELFCLASS32) printf("%-8s %-8s %-19s %-8s %s\n", REL_HDR); else { if (re->options & RE_WW) printf("%-16s %-16s %-24s %-16s %s\n", REL_HDR); else printf("%-12s %-12s %-19s %-16s %s\n", REL_HDR); } assert(d->d_size == s->sz); if (!get_ent_count(s, &len)) return; for (i = 0; i < len; i++) { if (gelf_getrel(d, i, &r) != &r) { warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); if (re->ec == ELFCLASS32) { r.r_info = ELF32_R_INFO(ELF64_R_SYM(r.r_info), ELF64_R_TYPE(r.r_info)); printf("%8.8jx %8.8jx %-19.19s %8.8jx %s\n", REL_CT32); } else { type = ELF64_R_TYPE(r.r_info); if (re->ehdr.e_machine == EM_MIPS) { type2 = (type >> 8) & 0xFF; type3 = (type >> 16) & 0xFF; type = type & 0xFF; } else { type2 = type3 = 0; } if (re->options & RE_WW) printf("%16.16jx %16.16jx %-24.24s" " %16.16jx %s\n", REL_CT64); else printf("%12.12jx %12.12jx %-19.19s" " %16.16jx %s\n", REL_CT64); if (re->ehdr.e_machine == EM_MIPS) { if (re->options & RE_WW) { printf("%32s: %s\n", "Type2", elftc_reloc_type_str(EM_MIPS, type2)); printf("%32s: %s\n", "Type3", elftc_reloc_type_str(EM_MIPS, type3)); } else { printf("%24s: %s\n", "Type2", elftc_reloc_type_str(EM_MIPS, type2)); printf("%24s: %s\n", "Type3", elftc_reloc_type_str(EM_MIPS, type3)); } } } } #undef REL_HDR #undef REL_CT } static void dump_rela(struct readelf *re, struct section *s, Elf_Data *d) { GElf_Rela r; const char *symname; uint64_t symval; int i, len; uint32_t type; uint8_t type2, type3; if (s->link >= re->shnum) return; #define RELA_HDR "r_offset", "r_info", "r_type", "st_value", \ "st_name + r_addend" #define RELA_CT32 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ elftc_reloc_type_str(re->ehdr.e_machine, \ ELF32_R_TYPE(r.r_info)), (uintmax_t)symval, symname #define RELA_CT64 (uintmax_t)r.r_offset, (uintmax_t)r.r_info, \ elftc_reloc_type_str(re->ehdr.e_machine, type), \ (uintmax_t)symval, symname printf("\nRelocation section with addend (%s):\n", s->name); if (re->ec == ELFCLASS32) printf("%-8s %-8s %-19s %-8s %s\n", RELA_HDR); else { if (re->options & RE_WW) printf("%-16s %-16s %-24s %-16s %s\n", RELA_HDR); else printf("%-12s %-12s %-19s %-16s %s\n", RELA_HDR); } assert(d->d_size == s->sz); if (!get_ent_count(s, &len)) return; for (i = 0; i < len; i++) { if (gelf_getrela(d, i, &r) != &r) { warnx("gelf_getrel failed: %s", elf_errmsg(-1)); continue; } symname = get_symbol_name(re, s->link, GELF_R_SYM(r.r_info)); symval = get_symbol_value(re, s->link, GELF_R_SYM(r.r_info)); if (re->ec == ELFCLASS32) { r.r_info = ELF32_R_INFO(ELF64_R_SYM(r.r_info), ELF64_R_TYPE(r.r_info)); printf("%8.8jx %8.8jx %-19.19s %8.8jx %s", RELA_CT32); printf(" + %x\n", (uint32_t) r.r_addend); } else { type = ELF64_R_TYPE(r.r_info); if (re->ehdr.e_machine == EM_MIPS) { type2 = (type >> 8) & 0xFF; type3 = (type >> 16) & 0xFF; type = type & 0xFF; } else { type2 = type3 = 0; } if (re->options & RE_WW) printf("%16.16jx %16.16jx %-24.24s" " %16.16jx %s", RELA_CT64); else printf("%12.12jx %12.12jx %-19.19s" " %16.16jx %s", RELA_CT64); printf(" + %jx\n", (uintmax_t) r.r_addend); if (re->ehdr.e_machine == EM_MIPS) { if (re->options & RE_WW) { printf("%32s: %s\n", "Type2", elftc_reloc_type_str(EM_MIPS, type2)); printf("%32s: %s\n", "Type3", elftc_reloc_type_str(EM_MIPS, type3)); } else { printf("%24s: %s\n", "Type2", elftc_reloc_type_str(EM_MIPS, type2)); printf("%24s: %s\n", "Type3", elftc_reloc_type_str(EM_MIPS, type3)); } } } } #undef RELA_HDR #undef RELA_CT } static void dump_reloc(struct readelf *re) { struct section *s; Elf_Data *d; int i, elferr; for (i = 0; (size_t)i < re->shnum; i++) { s = &re->sl[i]; if (s->type == SHT_REL || s->type == SHT_RELA) { (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } if (s->type == SHT_REL) dump_rel(re, s, d); else dump_rela(re, s, d); } } } static void dump_symtab(struct readelf *re, int i) { struct section *s; Elf_Data *d; GElf_Sym sym; const char *name; uint32_t stab; int elferr, j, len; uint16_t vs; s = &re->sl[i]; if (s->link >= re->shnum) return; stab = s->link; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size <= 0) return; if (!get_ent_count(s, &len)) return; printf("Symbol table (%s)", s->name); printf(" contains %d entries:\n", len); printf("%7s%9s%14s%5s%8s%6s%9s%5s\n", "Num:", "Value", "Size", "Type", "Bind", "Vis", "Ndx", "Name"); for (j = 0; j < len; j++) { if (gelf_getsym(d, j, &sym) != &sym) { warnx("gelf_getsym failed: %s", elf_errmsg(-1)); continue; } printf("%6d:", j); printf(" %16.16jx", (uintmax_t) sym.st_value); printf(" %5ju", (uintmax_t) sym.st_size); printf(" %-7s", st_type(re->ehdr.e_machine, re->ehdr.e_ident[EI_OSABI], GELF_ST_TYPE(sym.st_info))); printf(" %-6s", st_bind(GELF_ST_BIND(sym.st_info))); printf(" %-8s", st_vis(GELF_ST_VISIBILITY(sym.st_other))); printf(" %3s", st_shndx(sym.st_shndx)); if ((name = elf_strptr(re->elf, stab, sym.st_name)) != NULL) printf(" %s", name); /* Append symbol version string for SHT_DYNSYM symbol table. */ if (s->type == SHT_DYNSYM && re->ver != NULL && re->vs != NULL && re->vs[j] > 1) { vs = re->vs[j] & VERSYM_VERSION; if (vs >= re->ver_sz || re->ver[vs].name == NULL) { warnx("invalid versym version index %u", vs); break; } if (re->vs[j] & VERSYM_HIDDEN || re->ver[vs].type == 0) printf("@%s (%d)", re->ver[vs].name, vs); else printf("@@%s (%d)", re->ver[vs].name, vs); } putchar('\n'); } } static void dump_symtabs(struct readelf *re) { GElf_Dyn dyn; Elf_Data *d; struct section *s; uint64_t dyn_off; int elferr, i, len; /* * If -D is specified, only dump the symbol table specified by * the DT_SYMTAB entry in the .dynamic section. */ dyn_off = 0; if (re->options & RE_DD) { s = NULL; for (i = 0; (size_t)i < re->shnum; i++) if (re->sl[i].type == SHT_DYNAMIC) { s = &re->sl[i]; break; } if (s == NULL) return; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); return; } if (d->d_size <= 0) return; if (!get_ent_count(s, &len)) return; for (i = 0; i < len; i++) { if (gelf_getdyn(d, i, &dyn) != &dyn) { warnx("gelf_getdyn failed: %s", elf_errmsg(-1)); continue; } if (dyn.d_tag == DT_SYMTAB) { dyn_off = dyn.d_un.d_val; break; } } } /* Find and dump symbol tables. */ for (i = 0; (size_t)i < re->shnum; i++) { s = &re->sl[i]; if (s->type == SHT_SYMTAB || s->type == SHT_DYNSYM) { if (re->options & RE_DD) { if (dyn_off == s->addr) { dump_symtab(re, i); break; } } else dump_symtab(re, i); } } } static void dump_svr4_hash(struct section *s) { Elf_Data *d; uint32_t *buf; uint32_t nbucket, nchain; uint32_t *bucket, *chain; uint32_t *bl, *c, maxl, total; int elferr, i, j; /* Read and parse the content of .hash section. */ (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size < 2 * sizeof(uint32_t)) { warnx(".hash section too small"); return; } buf = d->d_buf; nbucket = buf[0]; nchain = buf[1]; if (nbucket <= 0 || nchain <= 0) { warnx("Malformed .hash section"); return; } if (d->d_size != (nbucket + nchain + 2) * sizeof(uint32_t)) { warnx("Malformed .hash section"); return; } bucket = &buf[2]; chain = &buf[2 + nbucket]; maxl = 0; if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) errx(EXIT_FAILURE, "calloc failed"); for (i = 0; (uint32_t)i < nbucket; i++) for (j = bucket[i]; j > 0 && (uint32_t)j < nchain; j = chain[j]) if (++bl[i] > maxl) maxl = bl[i]; if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) errx(EXIT_FAILURE, "calloc failed"); for (i = 0; (uint32_t)i < nbucket; i++) c[bl[i]]++; printf("\nHistogram for bucket list length (total of %u buckets):\n", nbucket); printf(" Length\tNumber\t\t%% of total\tCoverage\n"); total = 0; for (i = 0; (uint32_t)i <= maxl; i++) { total += c[i] * i; printf("%7u\t%-10u\t(%5.1f%%)\t%5.1f%%\n", i, c[i], c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); } free(c); free(bl); } static void dump_svr4_hash64(struct readelf *re, struct section *s) { Elf_Data *d, dst; uint64_t *buf; uint64_t nbucket, nchain; uint64_t *bucket, *chain; uint64_t *bl, *c, maxl, total; int elferr, i, j; /* * ALPHA uses 64-bit hash entries. Since libelf assumes that * .hash section contains only 32-bit entry, an explicit * gelf_xlatetom is needed here. */ (void) elf_errno(); if ((d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(elferr)); return; } d->d_type = ELF_T_XWORD; memcpy(&dst, d, sizeof(Elf_Data)); if (gelf_xlatetom(re->elf, &dst, d, re->ehdr.e_ident[EI_DATA]) != &dst) { warnx("gelf_xlatetom failed: %s", elf_errmsg(-1)); return; } if (dst.d_size < 2 * sizeof(uint64_t)) { warnx(".hash section too small"); return; } buf = dst.d_buf; nbucket = buf[0]; nchain = buf[1]; if (nbucket <= 0 || nchain <= 0) { warnx("Malformed .hash section"); return; } if (d->d_size != (nbucket + nchain + 2) * sizeof(uint32_t)) { warnx("Malformed .hash section"); return; } bucket = &buf[2]; chain = &buf[2 + nbucket]; maxl = 0; if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) errx(EXIT_FAILURE, "calloc failed"); for (i = 0; (uint32_t)i < nbucket; i++) for (j = bucket[i]; j > 0 && (uint32_t)j < nchain; j = chain[j]) if (++bl[i] > maxl) maxl = bl[i]; if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) errx(EXIT_FAILURE, "calloc failed"); for (i = 0; (uint64_t)i < nbucket; i++) c[bl[i]]++; printf("Histogram for bucket list length (total of %ju buckets):\n", (uintmax_t)nbucket); printf(" Length\tNumber\t\t%% of total\tCoverage\n"); total = 0; for (i = 0; (uint64_t)i <= maxl; i++) { total += c[i] * i; printf("%7u\t%-10ju\t(%5.1f%%)\t%5.1f%%\n", i, (uintmax_t)c[i], c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); } free(c); free(bl); } static void dump_gnu_hash(struct readelf *re, struct section *s) { struct section *ds; Elf_Data *d; uint32_t *buf; uint32_t *bucket, *chain; uint32_t nbucket, nchain, symndx, maskwords; uint32_t *bl, *c, maxl, total; int elferr, dynsymcount, i, j; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size < 4 * sizeof(uint32_t)) { warnx(".gnu.hash section too small"); return; } buf = d->d_buf; nbucket = buf[0]; symndx = buf[1]; maskwords = buf[2]; buf += 4; if (s->link >= re->shnum) return; ds = &re->sl[s->link]; if (!get_ent_count(ds, &dynsymcount)) return; if (symndx >= (uint32_t)dynsymcount) { warnx("Malformed .gnu.hash section (symndx out of range)"); return; } nchain = dynsymcount - symndx; if (d->d_size != 4 * sizeof(uint32_t) + maskwords * (re->ec == ELFCLASS32 ? sizeof(uint32_t) : sizeof(uint64_t)) + (nbucket + nchain) * sizeof(uint32_t)) { warnx("Malformed .gnu.hash section"); return; } bucket = buf + (re->ec == ELFCLASS32 ? maskwords : maskwords * 2); chain = bucket + nbucket; maxl = 0; if ((bl = calloc(nbucket, sizeof(*bl))) == NULL) errx(EXIT_FAILURE, "calloc failed"); for (i = 0; (uint32_t)i < nbucket; i++) for (j = bucket[i]; j > 0 && (uint32_t)j - symndx < nchain; j++) { if (++bl[i] > maxl) maxl = bl[i]; if (chain[j - symndx] & 1) break; } if ((c = calloc(maxl + 1, sizeof(*c))) == NULL) errx(EXIT_FAILURE, "calloc failed"); for (i = 0; (uint32_t)i < nbucket; i++) c[bl[i]]++; printf("Histogram for bucket list length (total of %u buckets):\n", nbucket); printf(" Length\tNumber\t\t%% of total\tCoverage\n"); total = 0; for (i = 0; (uint32_t)i <= maxl; i++) { total += c[i] * i; printf("%7u\t%-10u\t(%5.1f%%)\t%5.1f%%\n", i, c[i], c[i] * 100.0 / nbucket, total * 100.0 / (nchain - 1)); } free(c); free(bl); } +static struct flag_desc gnu_property_x86_feature_1_and_bits[] = { + { GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT" }, + { GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK" }, + { 0, NULL } +}; + static void +dump_gnu_property_type_0(struct readelf *re, const char *buf, size_t sz) +{ + size_t i; + uint32_t type, prop_sz; + + printf(" Properties: "); + while (sz > 0) { + if (sz < 8) + goto bad; + + type = *(const uint32_t *)(const void *)buf; + prop_sz = *(const uint32_t *)(const void *)(buf + 4); + buf += 8; + sz -= 8; + + if (prop_sz > sz) + goto bad; + + if (type >= GNU_PROPERTY_LOPROC && + type <= GNU_PROPERTY_HIPROC) { + if (re->ehdr.e_machine != EM_X86_64) { + printf("machine type %x unknown\n", + re->ehdr.e_machine); + goto unknown; + } + switch (type) { + case GNU_PROPERTY_X86_FEATURE_1_AND: + printf("x86 features:"); + if (prop_sz != 4) + goto bad; + dump_flags(gnu_property_x86_feature_1_and_bits, + *(const uint32_t *)(const void *)buf); + break; + } + } + + buf += roundup2(prop_sz, 8); + sz -= roundup2(prop_sz, 8); + } + return; +bad: + printf("corrupt GNU property\n"); +unknown: + printf("remaining description data:"); + for (i = 0; i < sz; i++) + printf(" %02x", (unsigned char)buf[i]); + printf("\n"); +} + +static void dump_hash(struct readelf *re) { struct section *s; int i; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->type == SHT_HASH || s->type == SHT_GNU_HASH) { if (s->type == SHT_GNU_HASH) dump_gnu_hash(re, s); else if (re->ehdr.e_machine == EM_ALPHA && s->entsize == 8) dump_svr4_hash64(re, s); else dump_svr4_hash(s); } } } static void dump_notes(struct readelf *re) { struct section *s; const char *rawfile; GElf_Phdr phdr; Elf_Data *d; size_t filesize, phnum; int i, elferr; if (re->ehdr.e_type == ET_CORE) { /* * Search program headers in the core file for * PT_NOTE entry. */ if (elf_getphnum(re->elf, &phnum) == 0) { warnx("elf_getphnum failed: %s", elf_errmsg(-1)); return; } if (phnum == 0) return; if ((rawfile = elf_rawfile(re->elf, &filesize)) == NULL) { warnx("elf_rawfile failed: %s", elf_errmsg(-1)); return; } for (i = 0; (size_t) i < phnum; i++) { if (gelf_getphdr(re->elf, i, &phdr) != &phdr) { warnx("gelf_getphdr failed: %s", elf_errmsg(-1)); continue; } if (phdr.p_type == PT_NOTE) { if (phdr.p_offset >= filesize || phdr.p_filesz > filesize - phdr.p_offset) { warnx("invalid PHDR offset"); continue; } dump_notes_content(re, rawfile + phdr.p_offset, phdr.p_filesz, phdr.p_offset); } } } else { /* * For objects other than core files, Search for * SHT_NOTE sections. */ for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->type == SHT_NOTE) { (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } dump_notes_content(re, d->d_buf, d->d_size, s->off); } } } } +static struct flag_desc note_feature_ctl_flags[] = { + { NT_FREEBSD_FCTL_ASLR_DISABLE, "ASLR_DISABLE" }, +#ifdef NT_FREEBSD_FCTL_PROTMAX_DISABLE + { NT_FREEBSD_FCTL_PROTMAX_DISABLE, "PROTMAX_DISABLE" }, +#endif +#ifdef NT_FREEBSD_FCTL_STKGAP_DISABLE + { NT_FREEBSD_FCTL_STKGAP_DISABLE, "STKGAP_DISABLE" }, +#endif + { NT_FREEBSD_FCTL_WXNEEDED, "WXNEEDED" }, + { 0, NULL } +}; + +static bool +dump_note_string(const char *description, const char *s, size_t len) +{ + size_t i; + + if (len == 0 || s[--len] != '\0') { + return (false); + } else { + for (i = 0; i < len; i++) + if (!isprint(s[i])) + return (false); + } + + printf(" %s: %s\n", description, s); + return (true); +} + +struct note_desc { + uint32_t type; + const char *description; + bool (*fp)(const char *, const char *, size_t); +}; + +static struct note_desc xen_notes[] = { + { 5, "Xen version", dump_note_string }, + { 6, "Guest OS", dump_note_string }, + { 7, "Guest version", dump_note_string }, + { 8, "Loader", dump_note_string }, + { 9, "PAE mode", dump_note_string }, + { 10, "Features", dump_note_string }, + { 11, "BSD symtab", dump_note_string }, + { 0, NULL, NULL } +}; + static void +dump_notes_data(struct readelf *re, const char *name, uint32_t type, + const char *buf, size_t sz) +{ + struct note_desc *nd; + size_t i; + const uint32_t *ubuf; + + /* Note data is at least 4-byte aligned. */ + if (((uintptr_t)buf & 3) != 0) { + warnx("bad note data alignment"); + goto unknown; + } + ubuf = (const uint32_t *)(const void *)buf; + + if (strcmp(name, "FreeBSD") == 0) { + switch (type) { + case NT_FREEBSD_ABI_TAG: + if (sz != 4) + goto unknown; + printf(" ABI tag: %u\n", ubuf[0]); + return; + /* NT_FREEBSD_NOINIT_TAG carries no data, treat as unknown. */ + case NT_FREEBSD_ARCH_TAG: + if (sz != 4) + goto unknown; + printf(" Arch tag: %x\n", ubuf[0]); + return; + case NT_FREEBSD_FEATURE_CTL: + if (sz != 4) + goto unknown; + printf(" Features:"); + dump_flags(note_feature_ctl_flags, ubuf[0]); + return; + } + } else if (strcmp(name, "GNU") == 0) { + switch (type) { + case NT_GNU_PROPERTY_TYPE_0: + dump_gnu_property_type_0(re, buf, sz); + return; + case NT_GNU_BUILD_ID: + printf(" Build ID: "); + for (i = 0; i < sz; i++) + printf("%02x", (unsigned char)buf[i]); + printf("\n"); + return; + } + } else if (strcmp(name, "Xen") == 0) { + for (nd = xen_notes; nd->description != NULL; nd++) { + if (nd->type == type) { + if (nd->fp(nd->description, buf, sz)) + return; + else + break; + } + } + } +unknown: + printf(" description data:"); + for (i = 0; i < sz; i++) + printf(" %02x", (unsigned char)buf[i]); + printf("\n"); +} + +static void dump_notes_content(struct readelf *re, const char *buf, size_t sz, off_t off) { Elf_Note *note; const char *end, *name; + uint32_t namesz, descsz; printf("\nNotes at offset %#010jx with length %#010jx:\n", (uintmax_t) off, (uintmax_t) sz); printf(" %-13s %-15s %s\n", "Owner", "Data size", "Description"); end = buf + sz; while (buf < end) { if (buf + sizeof(*note) > end) { warnx("invalid note header"); return; } note = (Elf_Note *)(uintptr_t) buf; - name = (char *)(uintptr_t)(note + 1); + namesz = roundup2(note->n_namesz, 4); + descsz = roundup2(note->n_descsz, 4); + if (namesz < note->n_namesz || descsz < note->n_descsz || + buf + namesz + descsz > end) { + warnx("invalid note header"); + return; + } + buf += sizeof(Elf_Note); + name = buf; + buf += namesz; /* * The name field is required to be nul-terminated, and * n_namesz includes the terminating nul in observed * implementations (contrary to the ELF-64 spec). A special * case is needed for cores generated by some older Linux * versions, which write a note named "CORE" without a nul * terminator and n_namesz = 4. */ if (note->n_namesz == 0) name = ""; else if (note->n_namesz == 4 && strncmp(name, "CORE", 4) == 0) name = "CORE"; else if (strnlen(name, note->n_namesz) >= note->n_namesz) name = ""; printf(" %-13s %#010jx", name, (uintmax_t) note->n_descsz); printf(" %s\n", note_type(name, re->ehdr.e_type, note->n_type)); - buf += sizeof(Elf_Note) + roundup2(note->n_namesz, 4) + - roundup2(note->n_descsz, 4); + dump_notes_data(re, name, note->n_type, buf, note->n_descsz); + buf += descsz; } } /* * Symbol versioning sections are the same for 32bit and 64bit * ELF objects. */ #define Elf_Verdef Elf32_Verdef #define Elf_Verdaux Elf32_Verdaux #define Elf_Verneed Elf32_Verneed #define Elf_Vernaux Elf32_Vernaux #define SAVE_VERSION_NAME(x, n, t) \ do { \ while (x >= re->ver_sz) { \ nv = realloc(re->ver, \ sizeof(*re->ver) * re->ver_sz * 2); \ if (nv == NULL) { \ warn("realloc failed"); \ free(re->ver); \ return; \ } \ re->ver = nv; \ for (i = re->ver_sz; i < re->ver_sz * 2; i++) { \ re->ver[i].name = NULL; \ re->ver[i].type = 0; \ } \ re->ver_sz *= 2; \ } \ if (x > 1) { \ re->ver[x].name = n; \ re->ver[x].type = t; \ } \ } while (0) static void dump_verdef(struct readelf *re, int dump) { struct section *s; struct symver *nv; Elf_Data *d; Elf_Verdef *vd; Elf_Verdaux *vda; uint8_t *buf, *end, *buf2; const char *name; int elferr, i, j; if ((s = re->vd_s) == NULL) return; if (s->link >= re->shnum) return; if (re->ver == NULL) { re->ver_sz = 16; if ((re->ver = calloc(re->ver_sz, sizeof(*re->ver))) == NULL) { warn("calloc failed"); return; } re->ver[0].name = "*local*"; re->ver[1].name = "*global*"; } if (dump) printf("\nVersion definition section (%s):\n", s->name); (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size == 0) return; buf = d->d_buf; end = buf + d->d_size; while (buf + sizeof(Elf_Verdef) <= end) { vd = (Elf_Verdef *) (uintptr_t) buf; if (dump) { printf(" 0x%4.4lx", (unsigned long) (buf - (uint8_t *)d->d_buf)); printf(" vd_version: %u vd_flags: %d" " vd_ndx: %u vd_cnt: %u", vd->vd_version, vd->vd_flags, vd->vd_ndx, vd->vd_cnt); } buf2 = buf + vd->vd_aux; j = 0; while (buf2 + sizeof(Elf_Verdaux) <= end && j < vd->vd_cnt) { vda = (Elf_Verdaux *) (uintptr_t) buf2; name = get_string(re, s->link, vda->vda_name); if (j == 0) { if (dump) printf(" vda_name: %s\n", name); SAVE_VERSION_NAME((int)vd->vd_ndx, name, 1); } else if (dump) printf(" 0x%4.4lx parent: %s\n", (unsigned long) (buf2 - (uint8_t *)d->d_buf), name); if (vda->vda_next == 0) break; buf2 += vda->vda_next; j++; } if (vd->vd_next == 0) break; buf += vd->vd_next; } } static void dump_verneed(struct readelf *re, int dump) { struct section *s; struct symver *nv; Elf_Data *d; Elf_Verneed *vn; Elf_Vernaux *vna; uint8_t *buf, *end, *buf2; const char *name; int elferr, i, j; if ((s = re->vn_s) == NULL) return; if (s->link >= re->shnum) return; if (re->ver == NULL) { re->ver_sz = 16; if ((re->ver = calloc(re->ver_sz, sizeof(*re->ver))) == NULL) { warn("calloc failed"); return; } re->ver[0].name = "*local*"; re->ver[1].name = "*global*"; } if (dump) printf("\nVersion needed section (%s):\n", s->name); (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size == 0) return; buf = d->d_buf; end = buf + d->d_size; while (buf + sizeof(Elf_Verneed) <= end) { vn = (Elf_Verneed *) (uintptr_t) buf; if (dump) { printf(" 0x%4.4lx", (unsigned long) (buf - (uint8_t *)d->d_buf)); printf(" vn_version: %u vn_file: %s vn_cnt: %u\n", vn->vn_version, get_string(re, s->link, vn->vn_file), vn->vn_cnt); } buf2 = buf + vn->vn_aux; j = 0; while (buf2 + sizeof(Elf_Vernaux) <= end && j < vn->vn_cnt) { vna = (Elf32_Vernaux *) (uintptr_t) buf2; if (dump) printf(" 0x%4.4lx", (unsigned long) (buf2 - (uint8_t *)d->d_buf)); name = get_string(re, s->link, vna->vna_name); if (dump) printf(" vna_name: %s vna_flags: %u" " vna_other: %u\n", name, vna->vna_flags, vna->vna_other); SAVE_VERSION_NAME((int)vna->vna_other, name, 0); if (vna->vna_next == 0) break; buf2 += vna->vna_next; j++; } if (vn->vn_next == 0) break; buf += vn->vn_next; } } static void dump_versym(struct readelf *re) { int i; uint16_t vs; if (re->vs_s == NULL || re->ver == NULL || re->vs == NULL) return; printf("\nVersion symbol section (%s):\n", re->vs_s->name); for (i = 0; i < re->vs_sz; i++) { if ((i & 3) == 0) { if (i > 0) putchar('\n'); printf(" %03x:", i); } vs = re->vs[i] & VERSYM_VERSION; if (vs >= re->ver_sz || re->ver[vs].name == NULL) { warnx("invalid versym version index %u", re->vs[i]); break; } if (re->vs[i] & VERSYM_HIDDEN) printf(" %3xh %-12s ", vs, re->ver[re->vs[i] & VERSYM_VERSION].name); else printf(" %3x %-12s ", vs, re->ver[re->vs[i]].name); } putchar('\n'); } static void dump_ver(struct readelf *re) { if (re->vs_s && re->ver && re->vs) dump_versym(re); if (re->vd_s) dump_verdef(re, 1); if (re->vn_s) dump_verneed(re, 1); } static void search_ver(struct readelf *re) { struct section *s; Elf_Data *d; int elferr, i; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->type == SHT_SUNW_versym) re->vs_s = s; if (s->type == SHT_SUNW_verneed) re->vn_s = s; if (s->type == SHT_SUNW_verdef) re->vd_s = s; } if (re->vd_s) dump_verdef(re, 0); if (re->vn_s) dump_verneed(re, 0); if (re->vs_s && re->ver != NULL) { (void) elf_errno(); if ((d = elf_getdata(re->vs_s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size == 0) return; re->vs = d->d_buf; re->vs_sz = d->d_size / sizeof(Elf32_Half); } } #undef Elf_Verdef #undef Elf_Verdaux #undef Elf_Verneed #undef Elf_Vernaux #undef SAVE_VERSION_NAME /* * Elf32_Lib and Elf64_Lib are identical. */ #define Elf_Lib Elf32_Lib static void dump_liblist(struct readelf *re) { struct section *s; struct tm *t; time_t ti; char tbuf[20]; Elf_Data *d; Elf_Lib *lib; int i, j, k, elferr, first, len; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->type != SHT_GNU_LIBLIST) continue; if (s->link >= re->shnum) continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } if (d->d_size <= 0) continue; lib = d->d_buf; if (!get_ent_count(s, &len)) continue; printf("\nLibrary list section '%s' ", s->name); printf("contains %d entries:\n", len); printf("%12s%24s%18s%10s%6s\n", "Library", "Time Stamp", "Checksum", "Version", "Flags"); for (j = 0; (uint64_t) j < s->sz / s->entsize; j++) { printf("%3d: ", j); printf("%-20.20s ", get_string(re, s->link, lib->l_name)); ti = lib->l_time_stamp; t = gmtime(&ti); snprintf(tbuf, sizeof(tbuf), "%04d-%02d-%02dT%02d:%02d" ":%2d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); printf("%-19.19s ", tbuf); printf("0x%08x ", lib->l_checksum); printf("%-7d %#x", lib->l_version, lib->l_flags); if (lib->l_flags != 0) { first = 1; putchar('('); for (k = 0; l_flag[k].name != NULL; k++) { if ((l_flag[k].value & lib->l_flags) == 0) continue; if (!first) putchar(','); else first = 0; printf("%s", l_flag[k].name); } putchar(')'); } putchar('\n'); lib++; } } } #undef Elf_Lib static void dump_section_groups(struct readelf *re) { struct section *s; const char *symname; Elf_Data *d; uint32_t *w; int i, j, elferr; size_t n; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->type != SHT_GROUP) continue; if (s->link >= re->shnum) continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } if (d->d_size <= 0) continue; w = d->d_buf; /* We only support COMDAT section. */ #ifndef GRP_COMDAT #define GRP_COMDAT 0x1 #endif if ((*w++ & GRP_COMDAT) == 0) return; if (s->entsize == 0) s->entsize = 4; symname = get_symbol_name(re, s->link, s->info); n = s->sz / s->entsize; if (n-- < 1) return; printf("\nCOMDAT group section [%5d] `%s' [%s] contains %ju" " sections:\n", i, s->name, symname, (uintmax_t)n); printf(" %-10.10s %s\n", "[Index]", "Name"); for (j = 0; (size_t) j < n; j++, w++) { if (*w >= re->shnum) { warnx("invalid section index: %u", *w); continue; } printf(" [%5u] %s\n", *w, re->sl[*w].name); } } } static uint8_t * dump_unknown_tag(uint64_t tag, uint8_t *p, uint8_t *pe) { uint64_t val; /* * According to ARM EABI: For tags > 32, even numbered tags have * a ULEB128 param and odd numbered ones have NUL-terminated * string param. This rule probably also applies for tags <= 32 * if the object arch is not ARM. */ printf(" Tag_unknown_%ju: ", (uintmax_t) tag); if (tag & 1) { printf("%s\n", (char *) p); p += strlen((char *) p) + 1; } else { val = _decode_uleb128(&p, pe); printf("%ju\n", (uintmax_t) val); } return (p); } static uint8_t * dump_compatibility_tag(uint8_t *p, uint8_t *pe) { uint64_t val; val = _decode_uleb128(&p, pe); printf("flag = %ju, vendor = %s\n", (uintmax_t) val, p); p += strlen((char *) p) + 1; return (p); } static void dump_arm_attributes(struct readelf *re, uint8_t *p, uint8_t *pe) { uint64_t tag, val; size_t i; int found, desc; (void) re; while (p < pe) { tag = _decode_uleb128(&p, pe); found = desc = 0; for (i = 0; i < sizeof(aeabi_tags) / sizeof(aeabi_tags[0]); i++) { if (tag == aeabi_tags[i].tag) { found = 1; printf(" %s: ", aeabi_tags[i].s_tag); if (aeabi_tags[i].get_desc) { desc = 1; val = _decode_uleb128(&p, pe); printf("%s\n", aeabi_tags[i].get_desc(val)); } break; } if (tag < aeabi_tags[i].tag) break; } if (!found) { p = dump_unknown_tag(tag, p, pe); continue; } if (desc) continue; switch (tag) { case 4: /* Tag_CPU_raw_name */ case 5: /* Tag_CPU_name */ case 67: /* Tag_conformance */ printf("%s\n", (char *) p); p += strlen((char *) p) + 1; break; case 32: /* Tag_compatibility */ p = dump_compatibility_tag(p, pe); break; case 64: /* Tag_nodefaults */ /* ignored, written as 0. */ (void) _decode_uleb128(&p, pe); printf("True\n"); break; case 65: /* Tag_also_compatible_with */ val = _decode_uleb128(&p, pe); /* Must be Tag_CPU_arch */ if (val != 6) { printf("unknown\n"); break; } val = _decode_uleb128(&p, pe); printf("%s\n", aeabi_cpu_arch(val)); /* Skip NUL terminator. */ p++; break; default: putchar('\n'); break; } } } #ifndef Tag_GNU_MIPS_ABI_FP #define Tag_GNU_MIPS_ABI_FP 4 #endif static void dump_mips_attributes(struct readelf *re, uint8_t *p, uint8_t *pe) { uint64_t tag, val; (void) re; while (p < pe) { tag = _decode_uleb128(&p, pe); switch (tag) { case Tag_GNU_MIPS_ABI_FP: val = _decode_uleb128(&p, pe); printf(" Tag_GNU_MIPS_ABI_FP: %s\n", mips_abi_fp(val)); break; case 32: /* Tag_compatibility */ p = dump_compatibility_tag(p, pe); break; default: p = dump_unknown_tag(tag, p, pe); break; } } } #ifndef Tag_GNU_Power_ABI_FP #define Tag_GNU_Power_ABI_FP 4 #endif #ifndef Tag_GNU_Power_ABI_Vector #define Tag_GNU_Power_ABI_Vector 8 #endif static void dump_ppc_attributes(uint8_t *p, uint8_t *pe) { uint64_t tag, val; while (p < pe) { tag = _decode_uleb128(&p, pe); switch (tag) { case Tag_GNU_Power_ABI_FP: val = _decode_uleb128(&p, pe); printf(" Tag_GNU_Power_ABI_FP: %s\n", ppc_abi_fp(val)); break; case Tag_GNU_Power_ABI_Vector: val = _decode_uleb128(&p, pe); printf(" Tag_GNU_Power_ABI_Vector: %s\n", ppc_abi_vector(val)); break; case 32: /* Tag_compatibility */ p = dump_compatibility_tag(p, pe); break; default: p = dump_unknown_tag(tag, p, pe); break; } } } static void dump_attributes(struct readelf *re) { struct section *s; Elf_Data *d; uint8_t *p, *pe, *sp; size_t len, seclen, nlen, sublen; uint64_t val; int tag, i, elferr; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->type != SHT_GNU_ATTRIBUTES && (re->ehdr.e_machine != EM_ARM || s->type != SHT_LOPROC + 3)) continue; (void) elf_errno(); if ((d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(elferr)); continue; } if (d->d_size <= 0) continue; p = d->d_buf; pe = p + d->d_size; if (*p != 'A') { printf("Unknown Attribute Section Format: %c\n", (char) *p); continue; } len = d->d_size - 1; p++; while (len > 0) { if (len < 4) { warnx("truncated attribute section length"); return; } seclen = re->dw_decode(&p, 4); if (seclen > len) { warnx("invalid attribute section length"); return; } len -= seclen; nlen = strlen((char *) p) + 1; if (nlen + 4 > seclen) { warnx("invalid attribute section name"); return; } printf("Attribute Section: %s\n", (char *) p); p += nlen; seclen -= nlen + 4; while (seclen > 0) { sp = p; tag = *p++; sublen = re->dw_decode(&p, 4); if (sublen > seclen) { warnx("invalid attribute sub-section" " length"); return; } seclen -= sublen; printf("%s", top_tag(tag)); if (tag == 2 || tag == 3) { putchar(':'); for (;;) { val = _decode_uleb128(&p, pe); if (val == 0) break; printf(" %ju", (uintmax_t) val); } } putchar('\n'); if (re->ehdr.e_machine == EM_ARM && s->type == SHT_LOPROC + 3) dump_arm_attributes(re, p, sp + sublen); else if (re->ehdr.e_machine == EM_MIPS || re->ehdr.e_machine == EM_MIPS_RS3_LE) dump_mips_attributes(re, p, sp + sublen); else if (re->ehdr.e_machine == EM_PPC) dump_ppc_attributes(p, sp + sublen); p = sp + sublen; } } } } static void dump_mips_specific_info(struct readelf *re) { struct section *s; int i; s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && (!strcmp(s->name, ".MIPS.options") || (s->type == SHT_MIPS_OPTIONS))) { dump_mips_options(re, s); } } if (s->name != NULL && (!strcmp(s->name, ".MIPS.abiflags") || (s->type == SHT_MIPS_ABIFLAGS))) dump_mips_abiflags(re, s); /* * Dump .reginfo if present (although it will be ignored by an OS if a * .MIPS.options section is present, according to SGI mips64 spec). */ for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && (!strcmp(s->name, ".reginfo") || (s->type == SHT_MIPS_REGINFO))) dump_mips_reginfo(re, s); } } static void dump_mips_abiflags(struct readelf *re, struct section *s) { Elf_Data *d; uint8_t *p; int elferr; uint32_t isa_ext, ases, flags1, flags2; uint16_t version; uint8_t isa_level, isa_rev, gpr_size, cpr1_size, cpr2_size, fp_abi; if ((d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size != 24) { warnx("invalid MIPS abiflags section size"); return; } p = d->d_buf; version = re->dw_decode(&p, 2); printf("MIPS ABI Flags Version: %u", version); if (version != 0) { printf(" (unknown)\n\n"); return; } printf("\n\n"); isa_level = re->dw_decode(&p, 1); isa_rev = re->dw_decode(&p, 1); gpr_size = re->dw_decode(&p, 1); cpr1_size = re->dw_decode(&p, 1); cpr2_size = re->dw_decode(&p, 1); fp_abi = re->dw_decode(&p, 1); isa_ext = re->dw_decode(&p, 4); ases = re->dw_decode(&p, 4); flags1 = re->dw_decode(&p, 4); flags2 = re->dw_decode(&p, 4); printf("ISA: "); if (isa_rev <= 1) printf("MIPS%u\n", isa_level); else printf("MIPS%ur%u\n", isa_level, isa_rev); printf("GPR size: %d\n", get_mips_register_size(gpr_size)); printf("CPR1 size: %d\n", get_mips_register_size(cpr1_size)); printf("CPR2 size: %d\n", get_mips_register_size(cpr2_size)); printf("FP ABI: "); switch (fp_abi) { case 3: printf("Soft float"); break; default: printf("%u", fp_abi); break; } printf("\nISA Extension: %u\n", isa_ext); printf("ASEs: %u\n", ases); printf("FLAGS 1: %08x\n", flags1); printf("FLAGS 2: %08x\n", flags2); } static int get_mips_register_size(uint8_t flag) { switch (flag) { case 0: return 0; case 1: return 32; case 2: return 64; case 3: return 128; default: return -1; } } static void dump_mips_reginfo(struct readelf *re, struct section *s) { Elf_Data *d; int elferr, len; (void) elf_errno(); if ((d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size <= 0) return; if (!get_ent_count(s, &len)) return; printf("\nSection '%s' contains %d entries:\n", s->name, len); dump_mips_odk_reginfo(re, d->d_buf, d->d_size); } static void dump_mips_options(struct readelf *re, struct section *s) { Elf_Data *d; uint32_t info; uint16_t sndx; uint8_t *p, *pe; uint8_t kind, size; int elferr; (void) elf_errno(); if ((d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_rawdata failed: %s", elf_errmsg(elferr)); return; } if (d->d_size == 0) return; printf("\nSection %s contains:\n", s->name); p = d->d_buf; pe = p + d->d_size; while (p < pe) { if (pe - p < 8) { warnx("Truncated MIPS option header"); return; } kind = re->dw_decode(&p, 1); size = re->dw_decode(&p, 1); sndx = re->dw_decode(&p, 2); info = re->dw_decode(&p, 4); if (size < 8 || size - 8 > pe - p) { warnx("Malformed MIPS option header"); return; } size -= 8; switch (kind) { case ODK_REGINFO: dump_mips_odk_reginfo(re, p, size); break; case ODK_EXCEPTIONS: printf(" EXCEPTIONS FPU_MIN: %#x\n", info & OEX_FPU_MIN); printf("%11.11s FPU_MAX: %#x\n", "", info & OEX_FPU_MAX); dump_mips_option_flags("", mips_exceptions_option, info); break; case ODK_PAD: printf(" %-10.10s section: %ju\n", "OPAD", (uintmax_t) sndx); dump_mips_option_flags("", mips_pad_option, info); break; case ODK_HWPATCH: dump_mips_option_flags("HWPATCH", mips_hwpatch_option, info); break; case ODK_HWAND: dump_mips_option_flags("HWAND", mips_hwa_option, info); break; case ODK_HWOR: dump_mips_option_flags("HWOR", mips_hwo_option, info); break; case ODK_FILL: printf(" %-10.10s %#jx\n", "FILL", (uintmax_t) info); break; case ODK_TAGS: printf(" %-10.10s\n", "TAGS"); break; case ODK_GP_GROUP: printf(" %-10.10s GP group number: %#x\n", "GP_GROUP", info & 0xFFFF); if (info & 0x10000) printf(" %-10.10s GP group is " "self-contained\n", ""); break; case ODK_IDENT: printf(" %-10.10s default GP group number: %#x\n", "IDENT", info & 0xFFFF); if (info & 0x10000) printf(" %-10.10s default GP group is " "self-contained\n", ""); break; case ODK_PAGESIZE: printf(" %-10.10s\n", "PAGESIZE"); break; default: break; } p += size; } } static void dump_mips_option_flags(const char *name, struct mips_option *opt, uint64_t info) { int first; first = 1; for (; opt->desc != NULL; opt++) { if (info & opt->flag) { printf(" %-10.10s %s\n", first ? name : "", opt->desc); first = 0; } } } static void dump_mips_odk_reginfo(struct readelf *re, uint8_t *p, size_t sz) { uint32_t ri_gprmask; uint32_t ri_cprmask[4]; uint64_t ri_gp_value; uint8_t *pe; int i; pe = p + sz; while (p < pe) { ri_gprmask = re->dw_decode(&p, 4); /* Skip ri_pad padding field for mips64. */ if (re->ec == ELFCLASS64) re->dw_decode(&p, 4); for (i = 0; i < 4; i++) ri_cprmask[i] = re->dw_decode(&p, 4); if (re->ec == ELFCLASS32) ri_gp_value = re->dw_decode(&p, 4); else ri_gp_value = re->dw_decode(&p, 8); printf(" %s ", option_kind(ODK_REGINFO)); printf("ri_gprmask: 0x%08jx\n", (uintmax_t) ri_gprmask); for (i = 0; i < 4; i++) printf("%11.11s ri_cprmask[%d]: 0x%08jx\n", "", i, (uintmax_t) ri_cprmask[i]); printf("%12.12s", ""); printf("ri_gp_value: %#jx\n", (uintmax_t) ri_gp_value); } } static void dump_arch_specific_info(struct readelf *re) { dump_liblist(re); dump_attributes(re); switch (re->ehdr.e_machine) { case EM_MIPS: case EM_MIPS_RS3_LE: dump_mips_specific_info(re); default: break; } } static const char * dwarf_regname(struct readelf *re, unsigned int num) { static char rx[32]; const char *rn; if ((rn = dwarf_reg(re->ehdr.e_machine, num)) != NULL) return (rn); snprintf(rx, sizeof(rx), "r%u", num); return (rx); } static void dump_dwarf_line(struct readelf *re) { struct section *s; Dwarf_Die die; Dwarf_Error de; Dwarf_Half tag, version, pointer_size; Dwarf_Unsigned offset, endoff, length, hdrlen, dirndx, mtime, fsize; Dwarf_Small minlen, defstmt, lrange, opbase, oplen; Elf_Data *d; char *pn; uint64_t address, file, line, column, isa, opsize, udelta; int64_t sdelta; uint8_t *p, *pe; int8_t lbase; int i, is_stmt, dwarf_size, elferr, ret; printf("\nDump of debug contents of section .debug_line:\n"); s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && !strcmp(s->name, ".debug_line")) break; } if ((size_t) i >= re->shnum) return; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); return; } if (d->d_size <= 0) return; while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, NULL, &de)) == DW_DLV_OK) { die = NULL; while (dwarf_siblingof(re->dbg, die, &die, &de) == DW_DLV_OK) { if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); return; } /* XXX: What about DW_TAG_partial_unit? */ if (tag == DW_TAG_compile_unit) break; } if (die == NULL) { warnx("could not find DW_TAG_compile_unit die"); return; } if (dwarf_attrval_unsigned(die, DW_AT_stmt_list, &offset, &de) != DW_DLV_OK) continue; length = re->dw_read(d, &offset, 4); if (length == 0xffffffff) { dwarf_size = 8; length = re->dw_read(d, &offset, 8); } else dwarf_size = 4; if (length > d->d_size - offset) { warnx("invalid .dwarf_line section"); continue; } endoff = offset + length; pe = (uint8_t *) d->d_buf + endoff; version = re->dw_read(d, &offset, 2); hdrlen = re->dw_read(d, &offset, dwarf_size); minlen = re->dw_read(d, &offset, 1); defstmt = re->dw_read(d, &offset, 1); lbase = re->dw_read(d, &offset, 1); lrange = re->dw_read(d, &offset, 1); opbase = re->dw_read(d, &offset, 1); printf("\n"); printf(" Length:\t\t\t%ju\n", (uintmax_t) length); printf(" DWARF version:\t\t%u\n", version); printf(" Prologue Length:\t\t%ju\n", (uintmax_t) hdrlen); printf(" Minimum Instruction Length:\t%u\n", minlen); printf(" Initial value of 'is_stmt':\t%u\n", defstmt); printf(" Line Base:\t\t\t%d\n", lbase); printf(" Line Range:\t\t\t%u\n", lrange); printf(" Opcode Base:\t\t\t%u\n", opbase); (void) dwarf_get_address_size(re->dbg, &pointer_size, &de); printf(" (Pointer size:\t\t%u)\n", pointer_size); printf("\n"); printf(" Opcodes:\n"); for (i = 1; i < opbase; i++) { oplen = re->dw_read(d, &offset, 1); printf(" Opcode %d has %u args\n", i, oplen); } printf("\n"); printf(" The Directory Table:\n"); p = (uint8_t *) d->d_buf + offset; while (*p != '\0') { printf(" %s\n", (char *) p); p += strlen((char *) p) + 1; } p++; printf("\n"); printf(" The File Name Table:\n"); printf(" Entry\tDir\tTime\tSize\tName\n"); i = 0; while (*p != '\0') { i++; pn = (char *) p; p += strlen(pn) + 1; dirndx = _decode_uleb128(&p, pe); mtime = _decode_uleb128(&p, pe); fsize = _decode_uleb128(&p, pe); printf(" %d\t%ju\t%ju\t%ju\t%s\n", i, (uintmax_t) dirndx, (uintmax_t) mtime, (uintmax_t) fsize, pn); } #define RESET_REGISTERS \ do { \ address = 0; \ file = 1; \ line = 1; \ column = 0; \ is_stmt = defstmt; \ } while(0) #define LINE(x) (lbase + (((x) - opbase) % lrange)) #define ADDRESS(x) ((((x) - opbase) / lrange) * minlen) p++; printf("\n"); printf(" Line Number Statements:\n"); RESET_REGISTERS; while (p < pe) { if (*p == 0) { /* * Extended Opcodes. */ p++; opsize = _decode_uleb128(&p, pe); printf(" Extended opcode %u: ", *p); switch (*p) { case DW_LNE_end_sequence: p++; RESET_REGISTERS; printf("End of Sequence\n"); break; case DW_LNE_set_address: p++; address = re->dw_decode(&p, pointer_size); printf("set Address to %#jx\n", (uintmax_t) address); break; case DW_LNE_define_file: p++; pn = (char *) p; p += strlen(pn) + 1; dirndx = _decode_uleb128(&p, pe); mtime = _decode_uleb128(&p, pe); fsize = _decode_uleb128(&p, pe); printf("define new file: %s\n", pn); break; default: /* Unrecognized extened opcodes. */ p += opsize; printf("unknown opcode\n"); } } else if (*p > 0 && *p < opbase) { /* * Standard Opcodes. */ switch(*p++) { case DW_LNS_copy: printf(" Copy\n"); break; case DW_LNS_advance_pc: udelta = _decode_uleb128(&p, pe) * minlen; address += udelta; printf(" Advance PC by %ju to %#jx\n", (uintmax_t) udelta, (uintmax_t) address); break; case DW_LNS_advance_line: sdelta = _decode_sleb128(&p, pe); line += sdelta; printf(" Advance Line by %jd to %ju\n", (intmax_t) sdelta, (uintmax_t) line); break; case DW_LNS_set_file: file = _decode_uleb128(&p, pe); printf(" Set File to %ju\n", (uintmax_t) file); break; case DW_LNS_set_column: column = _decode_uleb128(&p, pe); printf(" Set Column to %ju\n", (uintmax_t) column); break; case DW_LNS_negate_stmt: is_stmt = !is_stmt; printf(" Set is_stmt to %d\n", is_stmt); break; case DW_LNS_set_basic_block: printf(" Set basic block flag\n"); break; case DW_LNS_const_add_pc: address += ADDRESS(255); printf(" Advance PC by constant %ju" " to %#jx\n", (uintmax_t) ADDRESS(255), (uintmax_t) address); break; case DW_LNS_fixed_advance_pc: udelta = re->dw_decode(&p, 2); address += udelta; printf(" Advance PC by fixed value " "%ju to %#jx\n", (uintmax_t) udelta, (uintmax_t) address); break; case DW_LNS_set_prologue_end: printf(" Set prologue end flag\n"); break; case DW_LNS_set_epilogue_begin: printf(" Set epilogue begin flag\n"); break; case DW_LNS_set_isa: isa = _decode_uleb128(&p, pe); printf(" Set isa to %ju\n", (uintmax_t) isa); break; default: /* Unrecognized extended opcodes. */ printf(" Unknown extended opcode %u\n", *(p - 1)); break; } } else { /* * Special Opcodes. */ line += LINE(*p); address += ADDRESS(*p); printf(" Special opcode %u: advance Address " "by %ju to %#jx and Line by %jd to %ju\n", *p - opbase, (uintmax_t) ADDRESS(*p), (uintmax_t) address, (intmax_t) LINE(*p), (uintmax_t) line); p++; } } } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); #undef RESET_REGISTERS #undef LINE #undef ADDRESS } static void dump_dwarf_line_decoded(struct readelf *re) { Dwarf_Die die; Dwarf_Line *linebuf, ln; Dwarf_Addr lineaddr; Dwarf_Signed linecount, srccount; Dwarf_Unsigned lineno, fn; Dwarf_Error de; const char *dir, *file; char **srcfiles; int i, ret; printf("Decoded dump of debug contents of section .debug_line:\n\n"); while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, NULL, &de)) == DW_DLV_OK) { if (dwarf_siblingof(re->dbg, NULL, &die, &de) != DW_DLV_OK) continue; if (dwarf_attrval_string(die, DW_AT_name, &file, &de) != DW_DLV_OK) file = NULL; if (dwarf_attrval_string(die, DW_AT_comp_dir, &dir, &de) != DW_DLV_OK) dir = NULL; printf("CU: "); if (dir && file && file[0] != '/') printf("%s/", dir); if (file) printf("%s", file); putchar('\n'); printf("%-37s %11s %s\n", "Filename", "Line Number", "Starting Address"); if (dwarf_srclines(die, &linebuf, &linecount, &de) != DW_DLV_OK) continue; if (dwarf_srcfiles(die, &srcfiles, &srccount, &de) != DW_DLV_OK) continue; for (i = 0; i < linecount; i++) { ln = linebuf[i]; if (dwarf_line_srcfileno(ln, &fn, &de) != DW_DLV_OK) continue; if (dwarf_lineno(ln, &lineno, &de) != DW_DLV_OK) continue; if (dwarf_lineaddr(ln, &lineaddr, &de) != DW_DLV_OK) continue; printf("%-37s %11ju %#18jx\n", basename(srcfiles[fn - 1]), (uintmax_t) lineno, (uintmax_t) lineaddr); } putchar('\n'); } } static void dump_dwarf_die(struct readelf *re, Dwarf_Die die, int level) { Dwarf_Attribute *attr_list; Dwarf_Die ret_die; Dwarf_Off dieoff, cuoff, culen, attroff; Dwarf_Unsigned ate, lang, v_udata, v_sig; Dwarf_Signed attr_count, v_sdata; Dwarf_Off v_off; Dwarf_Addr v_addr; Dwarf_Half tag, attr, form; Dwarf_Block *v_block; Dwarf_Bool v_bool, is_info; Dwarf_Sig8 v_sig8; Dwarf_Error de; Dwarf_Ptr v_expr; const char *tag_str, *attr_str, *ate_str, *lang_str; char unk_tag[32], unk_attr[32]; char *v_str; uint8_t *b, *p; int i, j, abc, ret; if (dwarf_dieoffset(die, &dieoff, &de) != DW_DLV_OK) { warnx("dwarf_dieoffset failed: %s", dwarf_errmsg(de)); goto cont_search; } printf(" <%d><%jx>: ", level, (uintmax_t) dieoff); if (dwarf_die_CU_offset_range(die, &cuoff, &culen, &de) != DW_DLV_OK) { warnx("dwarf_die_CU_offset_range failed: %s", dwarf_errmsg(de)); cuoff = 0; } abc = dwarf_die_abbrev_code(die); if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); goto cont_search; } if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { snprintf(unk_tag, sizeof(unk_tag), "[Unknown Tag: %#x]", tag); tag_str = unk_tag; } printf("Abbrev Number: %d (%s)\n", abc, tag_str); if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != DW_DLV_OK) { if (ret == DW_DLV_ERROR) warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); goto cont_search; } for (i = 0; i < attr_count; i++) { if (dwarf_whatform(attr_list[i], &form, &de) != DW_DLV_OK) { warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_AT_name(attr, &attr_str) != DW_DLV_OK) { snprintf(unk_attr, sizeof(unk_attr), "[Unknown AT: %#x]", attr); attr_str = unk_attr; } if (dwarf_attroffset(attr_list[i], &attroff, &de) != DW_DLV_OK) { warnx("dwarf_attroffset failed: %s", dwarf_errmsg(de)); attroff = 0; } printf(" <%jx> %-18s: ", (uintmax_t) attroff, attr_str); switch (form) { case DW_FORM_ref_addr: case DW_FORM_sec_offset: if (dwarf_global_formref(attr_list[i], &v_off, &de) != DW_DLV_OK) { warnx("dwarf_global_formref failed: %s", dwarf_errmsg(de)); continue; } if (form == DW_FORM_ref_addr) printf("<0x%jx>", (uintmax_t) v_off); else printf("0x%jx", (uintmax_t) v_off); break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: if (dwarf_formref(attr_list[i], &v_off, &de) != DW_DLV_OK) { warnx("dwarf_formref failed: %s", dwarf_errmsg(de)); continue; } v_off += cuoff; printf("<0x%jx>", (uintmax_t) v_off); break; case DW_FORM_addr: if (dwarf_formaddr(attr_list[i], &v_addr, &de) != DW_DLV_OK) { warnx("dwarf_formaddr failed: %s", dwarf_errmsg(de)); continue; } printf("%#jx", (uintmax_t) v_addr); break; case DW_FORM_data1: case DW_FORM_data2: case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_udata: if (dwarf_formudata(attr_list[i], &v_udata, &de) != DW_DLV_OK) { warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); continue; } if (attr == DW_AT_high_pc) printf("0x%jx", (uintmax_t) v_udata); else printf("%ju", (uintmax_t) v_udata); break; case DW_FORM_sdata: if (dwarf_formsdata(attr_list[i], &v_sdata, &de) != DW_DLV_OK) { warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); continue; } printf("%jd", (intmax_t) v_sdata); break; case DW_FORM_flag: if (dwarf_formflag(attr_list[i], &v_bool, &de) != DW_DLV_OK) { warnx("dwarf_formflag failed: %s", dwarf_errmsg(de)); continue; } printf("%jd", (intmax_t) v_bool); break; case DW_FORM_flag_present: putchar('1'); break; case DW_FORM_string: case DW_FORM_strp: if (dwarf_formstring(attr_list[i], &v_str, &de) != DW_DLV_OK) { warnx("dwarf_formstring failed: %s", dwarf_errmsg(de)); continue; } if (form == DW_FORM_string) printf("%s", v_str); else printf("(indirect string) %s", v_str); break; case DW_FORM_block: case DW_FORM_block1: case DW_FORM_block2: case DW_FORM_block4: if (dwarf_formblock(attr_list[i], &v_block, &de) != DW_DLV_OK) { warnx("dwarf_formblock failed: %s", dwarf_errmsg(de)); continue; } printf("%ju byte block:", (uintmax_t) v_block->bl_len); b = v_block->bl_data; for (j = 0; (Dwarf_Unsigned) j < v_block->bl_len; j++) printf(" %x", b[j]); printf("\t("); dump_dwarf_block(re, v_block->bl_data, v_block->bl_len); putchar(')'); break; case DW_FORM_exprloc: if (dwarf_formexprloc(attr_list[i], &v_udata, &v_expr, &de) != DW_DLV_OK) { warnx("dwarf_formexprloc failed: %s", dwarf_errmsg(de)); continue; } printf("%ju byte block:", (uintmax_t) v_udata); b = v_expr; for (j = 0; (Dwarf_Unsigned) j < v_udata; j++) printf(" %x", b[j]); printf("\t("); dump_dwarf_block(re, v_expr, v_udata); putchar(')'); break; case DW_FORM_ref_sig8: if (dwarf_formsig8(attr_list[i], &v_sig8, &de) != DW_DLV_OK) { warnx("dwarf_formsig8 failed: %s", dwarf_errmsg(de)); continue; } p = (uint8_t *)(uintptr_t) &v_sig8.signature[0]; v_sig = re->dw_decode(&p, 8); printf("signature: 0x%jx", (uintmax_t) v_sig); } switch (attr) { case DW_AT_encoding: if (dwarf_attrval_unsigned(die, attr, &ate, &de) != DW_DLV_OK) break; if (dwarf_get_ATE_name(ate, &ate_str) != DW_DLV_OK) ate_str = "DW_ATE_UNKNOWN"; printf("\t(%s)", &ate_str[strlen("DW_ATE_")]); break; case DW_AT_language: if (dwarf_attrval_unsigned(die, attr, &lang, &de) != DW_DLV_OK) break; if (dwarf_get_LANG_name(lang, &lang_str) != DW_DLV_OK) break; printf("\t(%s)", &lang_str[strlen("DW_LANG_")]); break; case DW_AT_location: case DW_AT_string_length: case DW_AT_return_addr: case DW_AT_data_member_location: case DW_AT_frame_base: case DW_AT_segment: case DW_AT_static_link: case DW_AT_use_location: case DW_AT_vtable_elem_location: switch (form) { case DW_FORM_data4: case DW_FORM_data8: case DW_FORM_sec_offset: printf("\t(location list)"); break; default: break; } default: break; } putchar('\n'); } cont_search: /* Search children. */ ret = dwarf_child(die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_child: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) dump_dwarf_die(re, ret_die, level + 1); /* Search sibling. */ is_info = dwarf_get_die_infotypes_flag(die); ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) dump_dwarf_die(re, ret_die, level); dwarf_dealloc(re->dbg, die, DW_DLA_DIE); } static void set_cu_context(struct readelf *re, Dwarf_Half psize, Dwarf_Half osize, Dwarf_Half ver) { re->cu_psize = psize; re->cu_osize = osize; re->cu_ver = ver; } static void dump_dwarf_info(struct readelf *re, Dwarf_Bool is_info) { struct section *s; Dwarf_Die die; Dwarf_Error de; Dwarf_Half tag, version, pointer_size, off_size; Dwarf_Off cu_offset, cu_length; Dwarf_Off aboff; Dwarf_Unsigned typeoff; Dwarf_Sig8 sig8; Dwarf_Unsigned sig; uint8_t *p; const char *sn; int i, ret; sn = is_info ? ".debug_info" : ".debug_types"; s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && !strcmp(s->name, sn)) break; } if ((size_t) i >= re->shnum) return; do { printf("\nDump of debug contents of section %s:\n", sn); while ((ret = dwarf_next_cu_header_c(re->dbg, is_info, NULL, &version, &aboff, &pointer_size, &off_size, NULL, &sig8, &typeoff, NULL, &de)) == DW_DLV_OK) { set_cu_context(re, pointer_size, off_size, version); die = NULL; while (dwarf_siblingof_b(re->dbg, die, &die, is_info, &de) == DW_DLV_OK) { if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); continue; } /* XXX: What about DW_TAG_partial_unit? */ if ((is_info && tag == DW_TAG_compile_unit) || (!is_info && tag == DW_TAG_type_unit)) break; } if (die == NULL && is_info) { warnx("could not find DW_TAG_compile_unit " "die"); continue; } else if (die == NULL && !is_info) { warnx("could not find DW_TAG_type_unit die"); continue; } if (dwarf_die_CU_offset_range(die, &cu_offset, &cu_length, &de) != DW_DLV_OK) { warnx("dwarf_die_CU_offset failed: %s", dwarf_errmsg(de)); continue; } cu_length -= off_size == 4 ? 4 : 12; sig = 0; if (!is_info) { p = (uint8_t *)(uintptr_t) &sig8.signature[0]; sig = re->dw_decode(&p, 8); } printf("\n Type Unit @ offset 0x%jx:\n", (uintmax_t) cu_offset); printf(" Length:\t\t%#jx (%d-bit)\n", (uintmax_t) cu_length, off_size == 4 ? 32 : 64); printf(" Version:\t\t%u\n", version); printf(" Abbrev Offset:\t0x%jx\n", (uintmax_t) aboff); printf(" Pointer Size:\t%u\n", pointer_size); if (!is_info) { printf(" Signature:\t\t0x%016jx\n", (uintmax_t) sig); printf(" Type Offset:\t0x%jx\n", (uintmax_t) typeoff); } dump_dwarf_die(re, die, 0); } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); if (is_info) break; } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); } static void dump_dwarf_abbrev(struct readelf *re) { Dwarf_Abbrev ab; Dwarf_Off aboff, atoff; Dwarf_Unsigned length, attr_count; Dwarf_Signed flag, form; Dwarf_Half tag, attr; Dwarf_Error de; const char *tag_str, *attr_str, *form_str; char unk_tag[32], unk_attr[32], unk_form[32]; int i, j, ret; printf("\nContents of section .debug_abbrev:\n\n"); while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, &aboff, NULL, NULL, &de)) == DW_DLV_OK) { printf(" Number TAG\n"); i = 0; while ((ret = dwarf_get_abbrev(re->dbg, aboff, &ab, &length, &attr_count, &de)) == DW_DLV_OK) { if (length == 1) { dwarf_dealloc(re->dbg, ab, DW_DLA_ABBREV); break; } aboff += length; printf("%4d", ++i); if (dwarf_get_abbrev_tag(ab, &tag, &de) != DW_DLV_OK) { warnx("dwarf_get_abbrev_tag failed: %s", dwarf_errmsg(de)); goto next_abbrev; } if (dwarf_get_TAG_name(tag, &tag_str) != DW_DLV_OK) { snprintf(unk_tag, sizeof(unk_tag), "[Unknown Tag: %#x]", tag); tag_str = unk_tag; } if (dwarf_get_abbrev_children_flag(ab, &flag, &de) != DW_DLV_OK) { warnx("dwarf_get_abbrev_children_flag failed:" " %s", dwarf_errmsg(de)); goto next_abbrev; } printf(" %s %s\n", tag_str, flag ? "[has children]" : "[no children]"); for (j = 0; (Dwarf_Unsigned) j < attr_count; j++) { if (dwarf_get_abbrev_entry(ab, (Dwarf_Signed) j, &attr, &form, &atoff, &de) != DW_DLV_OK) { warnx("dwarf_get_abbrev_entry failed:" " %s", dwarf_errmsg(de)); continue; } if (dwarf_get_AT_name(attr, &attr_str) != DW_DLV_OK) { snprintf(unk_attr, sizeof(unk_attr), "[Unknown AT: %#x]", attr); attr_str = unk_attr; } if (dwarf_get_FORM_name(form, &form_str) != DW_DLV_OK) { snprintf(unk_form, sizeof(unk_form), "[Unknown Form: %#x]", (Dwarf_Half) form); form_str = unk_form; } printf(" %-18s %s\n", attr_str, form_str); } next_abbrev: dwarf_dealloc(re->dbg, ab, DW_DLA_ABBREV); } if (ret != DW_DLV_OK) warnx("dwarf_get_abbrev: %s", dwarf_errmsg(de)); } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); } static void dump_dwarf_pubnames(struct readelf *re) { struct section *s; Dwarf_Off die_off; Dwarf_Unsigned offset, length, nt_cu_offset, nt_cu_length; Dwarf_Signed cnt; Dwarf_Global *globs; Dwarf_Half nt_version; Dwarf_Error de; Elf_Data *d; char *glob_name; int i, dwarf_size, elferr; printf("\nContents of the .debug_pubnames section:\n"); s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && !strcmp(s->name, ".debug_pubnames")) break; } if ((size_t) i >= re->shnum) return; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); return; } if (d->d_size <= 0) return; /* Read in .debug_pubnames section table header. */ offset = 0; length = re->dw_read(d, &offset, 4); if (length == 0xffffffff) { dwarf_size = 8; length = re->dw_read(d, &offset, 8); } else dwarf_size = 4; if (length > d->d_size - offset) { warnx("invalid .dwarf_pubnames section"); return; } nt_version = re->dw_read(d, &offset, 2); nt_cu_offset = re->dw_read(d, &offset, dwarf_size); nt_cu_length = re->dw_read(d, &offset, dwarf_size); printf(" Length:\t\t\t\t%ju\n", (uintmax_t) length); printf(" Version:\t\t\t\t%u\n", nt_version); printf(" Offset into .debug_info section:\t%ju\n", (uintmax_t) nt_cu_offset); printf(" Size of area in .debug_info section:\t%ju\n", (uintmax_t) nt_cu_length); if (dwarf_get_globals(re->dbg, &globs, &cnt, &de) != DW_DLV_OK) { warnx("dwarf_get_globals failed: %s", dwarf_errmsg(de)); return; } printf("\n Offset Name\n"); for (i = 0; i < cnt; i++) { if (dwarf_globname(globs[i], &glob_name, &de) != DW_DLV_OK) { warnx("dwarf_globname failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_global_die_offset(globs[i], &die_off, &de) != DW_DLV_OK) { warnx("dwarf_global_die_offset failed: %s", dwarf_errmsg(de)); continue; } printf(" %-11ju %s\n", (uintmax_t) die_off, glob_name); } } static void dump_dwarf_aranges(struct readelf *re) { struct section *s; Dwarf_Arange *aranges; Dwarf_Addr start; Dwarf_Unsigned offset, length, as_cu_offset; Dwarf_Off die_off; Dwarf_Signed cnt; Dwarf_Half as_version, as_addrsz, as_segsz; Dwarf_Error de; Elf_Data *d; int i, dwarf_size, elferr; printf("\nContents of section .debug_aranges:\n"); s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && !strcmp(s->name, ".debug_aranges")) break; } if ((size_t) i >= re->shnum) return; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); return; } if (d->d_size <= 0) return; /* Read in the .debug_aranges section table header. */ offset = 0; length = re->dw_read(d, &offset, 4); if (length == 0xffffffff) { dwarf_size = 8; length = re->dw_read(d, &offset, 8); } else dwarf_size = 4; if (length > d->d_size - offset) { warnx("invalid .dwarf_aranges section"); return; } as_version = re->dw_read(d, &offset, 2); as_cu_offset = re->dw_read(d, &offset, dwarf_size); as_addrsz = re->dw_read(d, &offset, 1); as_segsz = re->dw_read(d, &offset, 1); printf(" Length:\t\t\t%ju\n", (uintmax_t) length); printf(" Version:\t\t\t%u\n", as_version); printf(" Offset into .debug_info:\t%ju\n", (uintmax_t) as_cu_offset); printf(" Pointer Size:\t\t\t%u\n", as_addrsz); printf(" Segment Size:\t\t\t%u\n", as_segsz); if (dwarf_get_aranges(re->dbg, &aranges, &cnt, &de) != DW_DLV_OK) { warnx("dwarf_get_aranges failed: %s", dwarf_errmsg(de)); return; } printf("\n Address Length\n"); for (i = 0; i < cnt; i++) { if (dwarf_get_arange_info(aranges[i], &start, &length, &die_off, &de) != DW_DLV_OK) { warnx("dwarf_get_arange_info failed: %s", dwarf_errmsg(de)); continue; } printf(" %08jx %ju\n", (uintmax_t) start, (uintmax_t) length); } } static void dump_dwarf_ranges_foreach(struct readelf *re, Dwarf_Die die, Dwarf_Addr base) { Dwarf_Attribute *attr_list; Dwarf_Ranges *ranges; Dwarf_Die ret_die; Dwarf_Error de; Dwarf_Addr base0; Dwarf_Half attr; Dwarf_Signed attr_count, cnt; Dwarf_Unsigned off, bytecnt; int i, j, ret; if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != DW_DLV_OK) { if (ret == DW_DLV_ERROR) warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); goto cont_search; } for (i = 0; i < attr_count; i++) { if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); continue; } if (attr != DW_AT_ranges) continue; if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_ranges(re->dbg, (Dwarf_Off) off, &ranges, &cnt, &bytecnt, &de) != DW_DLV_OK) continue; base0 = base; for (j = 0; j < cnt; j++) { printf(" %08jx ", (uintmax_t) off); if (ranges[j].dwr_type == DW_RANGES_END) { printf("%s\n", ""); continue; } else if (ranges[j].dwr_type == DW_RANGES_ADDRESS_SELECTION) { base0 = ranges[j].dwr_addr2; continue; } if (re->ec == ELFCLASS32) printf("%08jx %08jx\n", (uintmax_t) (ranges[j].dwr_addr1 + base0), (uintmax_t) (ranges[j].dwr_addr2 + base0)); else printf("%016jx %016jx\n", (uintmax_t) (ranges[j].dwr_addr1 + base0), (uintmax_t) (ranges[j].dwr_addr2 + base0)); } } cont_search: /* Search children. */ ret = dwarf_child(die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_child: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) dump_dwarf_ranges_foreach(re, ret_die, base); /* Search sibling. */ ret = dwarf_siblingof(re->dbg, die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) dump_dwarf_ranges_foreach(re, ret_die, base); } static void dump_dwarf_ranges(struct readelf *re) { Dwarf_Ranges *ranges; Dwarf_Die die; Dwarf_Signed cnt; Dwarf_Unsigned bytecnt; Dwarf_Half tag; Dwarf_Error de; Dwarf_Unsigned lowpc; int ret; if (dwarf_get_ranges(re->dbg, 0, &ranges, &cnt, &bytecnt, &de) != DW_DLV_OK) return; printf("Contents of the .debug_ranges section:\n\n"); if (re->ec == ELFCLASS32) printf(" %-8s %-8s %s\n", "Offset", "Begin", "End"); else printf(" %-8s %-16s %s\n", "Offset", "Begin", "End"); while ((ret = dwarf_next_cu_header(re->dbg, NULL, NULL, NULL, NULL, NULL, &de)) == DW_DLV_OK) { die = NULL; if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) continue; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); continue; } /* XXX: What about DW_TAG_partial_unit? */ lowpc = 0; if (tag == DW_TAG_compile_unit) { if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lowpc, &de) != DW_DLV_OK) lowpc = 0; } dump_dwarf_ranges_foreach(re, die, (Dwarf_Addr) lowpc); } putchar('\n'); } static void dump_dwarf_macinfo(struct readelf *re) { Dwarf_Unsigned offset; Dwarf_Signed cnt; Dwarf_Macro_Details *md; Dwarf_Error de; const char *mi_str; char unk_mi[32]; int i; #define _MAX_MACINFO_ENTRY 65535 printf("\nContents of section .debug_macinfo:\n\n"); offset = 0; while (dwarf_get_macro_details(re->dbg, offset, _MAX_MACINFO_ENTRY, &cnt, &md, &de) == DW_DLV_OK) { for (i = 0; i < cnt; i++) { offset = md[i].dmd_offset + 1; if (md[i].dmd_type == 0) break; if (dwarf_get_MACINFO_name(md[i].dmd_type, &mi_str) != DW_DLV_OK) { snprintf(unk_mi, sizeof(unk_mi), "[Unknown MACINFO: %#x]", md[i].dmd_type); mi_str = unk_mi; } printf(" %s", mi_str); switch (md[i].dmd_type) { case DW_MACINFO_define: case DW_MACINFO_undef: printf(" - lineno : %jd macro : %s\n", (intmax_t) md[i].dmd_lineno, md[i].dmd_macro); break; case DW_MACINFO_start_file: printf(" - lineno : %jd filenum : %jd\n", (intmax_t) md[i].dmd_lineno, (intmax_t) md[i].dmd_fileindex); break; default: putchar('\n'); break; } } } #undef _MAX_MACINFO_ENTRY } static void dump_dwarf_frame_inst(struct readelf *re, Dwarf_Cie cie, uint8_t *insts, Dwarf_Unsigned len, Dwarf_Unsigned caf, Dwarf_Signed daf, Dwarf_Addr pc, Dwarf_Debug dbg) { Dwarf_Frame_Op *oplist; Dwarf_Signed opcnt, delta; Dwarf_Small op; Dwarf_Error de; const char *op_str; char unk_op[32]; int i; if (dwarf_expand_frame_instructions(cie, insts, len, &oplist, &opcnt, &de) != DW_DLV_OK) { warnx("dwarf_expand_frame_instructions failed: %s", dwarf_errmsg(de)); return; } for (i = 0; i < opcnt; i++) { if (oplist[i].fp_base_op != 0) op = oplist[i].fp_base_op << 6; else op = oplist[i].fp_extended_op; if (dwarf_get_CFA_name(op, &op_str) != DW_DLV_OK) { snprintf(unk_op, sizeof(unk_op), "[Unknown CFA: %#x]", op); op_str = unk_op; } printf(" %s", op_str); switch (op) { case DW_CFA_advance_loc: delta = oplist[i].fp_offset * caf; pc += delta; printf(": %ju to %08jx", (uintmax_t) delta, (uintmax_t) pc); break; case DW_CFA_offset: case DW_CFA_offset_extended: case DW_CFA_offset_extended_sf: delta = oplist[i].fp_offset * daf; printf(": r%u (%s) at cfa%+jd", oplist[i].fp_register, dwarf_regname(re, oplist[i].fp_register), (intmax_t) delta); break; case DW_CFA_restore: printf(": r%u (%s)", oplist[i].fp_register, dwarf_regname(re, oplist[i].fp_register)); break; case DW_CFA_set_loc: pc = oplist[i].fp_offset; printf(": to %08jx", (uintmax_t) pc); break; case DW_CFA_advance_loc1: case DW_CFA_advance_loc2: case DW_CFA_advance_loc4: pc += oplist[i].fp_offset; printf(": %jd to %08jx", (intmax_t) oplist[i].fp_offset, (uintmax_t) pc); break; case DW_CFA_def_cfa: printf(": r%u (%s) ofs %ju", oplist[i].fp_register, dwarf_regname(re, oplist[i].fp_register), (uintmax_t) oplist[i].fp_offset); break; case DW_CFA_def_cfa_sf: printf(": r%u (%s) ofs %jd", oplist[i].fp_register, dwarf_regname(re, oplist[i].fp_register), (intmax_t) (oplist[i].fp_offset * daf)); break; case DW_CFA_def_cfa_register: printf(": r%u (%s)", oplist[i].fp_register, dwarf_regname(re, oplist[i].fp_register)); break; case DW_CFA_def_cfa_offset: printf(": %ju", (uintmax_t) oplist[i].fp_offset); break; case DW_CFA_def_cfa_offset_sf: printf(": %jd", (intmax_t) (oplist[i].fp_offset * daf)); break; default: break; } putchar('\n'); } dwarf_dealloc(dbg, oplist, DW_DLA_FRAME_BLOCK); } static char * get_regoff_str(struct readelf *re, Dwarf_Half reg, Dwarf_Addr off) { static char rs[16]; if (reg == DW_FRAME_UNDEFINED_VAL || reg == DW_FRAME_REG_INITIAL_VALUE) snprintf(rs, sizeof(rs), "%c", 'u'); else if (reg == DW_FRAME_CFA_COL) snprintf(rs, sizeof(rs), "c%+jd", (intmax_t) off); else snprintf(rs, sizeof(rs), "%s%+jd", dwarf_regname(re, reg), (intmax_t) off); return (rs); } static int dump_dwarf_frame_regtable(struct readelf *re, Dwarf_Fde fde, Dwarf_Addr pc, Dwarf_Unsigned func_len, Dwarf_Half cie_ra) { Dwarf_Regtable rt; Dwarf_Addr row_pc, end_pc, pre_pc, cur_pc; Dwarf_Error de; char *vec; int i; #define BIT_SET(v, n) (v[(n)>>3] |= 1U << ((n) & 7)) #define BIT_CLR(v, n) (v[(n)>>3] &= ~(1U << ((n) & 7))) #define BIT_ISSET(v, n) (v[(n)>>3] & (1U << ((n) & 7))) #define RT(x) rt.rules[(x)] vec = calloc((DW_REG_TABLE_SIZE + 7) / 8, 1); if (vec == NULL) err(EXIT_FAILURE, "calloc failed"); pre_pc = ~((Dwarf_Addr) 0); cur_pc = pc; end_pc = pc + func_len; for (; cur_pc < end_pc; cur_pc++) { if (dwarf_get_fde_info_for_all_regs(fde, cur_pc, &rt, &row_pc, &de) != DW_DLV_OK) { + free(vec); warnx("dwarf_get_fde_info_for_all_regs failed: %s\n", dwarf_errmsg(de)); return (-1); } if (row_pc == pre_pc) continue; pre_pc = row_pc; for (i = 1; i < DW_REG_TABLE_SIZE; i++) { if (rt.rules[i].dw_regnum != DW_FRAME_REG_INITIAL_VALUE) BIT_SET(vec, i); } } printf(" LOC CFA "); for (i = 1; i < DW_REG_TABLE_SIZE; i++) { if (BIT_ISSET(vec, i)) { if ((Dwarf_Half) i == cie_ra) printf("ra "); else printf("%-5s", dwarf_regname(re, (unsigned int) i)); } } putchar('\n'); pre_pc = ~((Dwarf_Addr) 0); cur_pc = pc; end_pc = pc + func_len; for (; cur_pc < end_pc; cur_pc++) { if (dwarf_get_fde_info_for_all_regs(fde, cur_pc, &rt, &row_pc, &de) != DW_DLV_OK) { + free(vec); warnx("dwarf_get_fde_info_for_all_regs failed: %s\n", dwarf_errmsg(de)); return (-1); } if (row_pc == pre_pc) continue; pre_pc = row_pc; printf("%08jx ", (uintmax_t) row_pc); printf("%-8s ", get_regoff_str(re, RT(0).dw_regnum, RT(0).dw_offset)); for (i = 1; i < DW_REG_TABLE_SIZE; i++) { if (BIT_ISSET(vec, i)) { printf("%-5s", get_regoff_str(re, RT(i).dw_regnum, RT(i).dw_offset)); } } putchar('\n'); } free(vec); return (0); #undef BIT_SET #undef BIT_CLR #undef BIT_ISSET #undef RT } static void dump_dwarf_frame_section(struct readelf *re, struct section *s, int alt) { Dwarf_Cie *cie_list, cie, pre_cie; Dwarf_Fde *fde_list, fde; Dwarf_Off cie_offset, fde_offset; Dwarf_Unsigned cie_length, fde_instlen; Dwarf_Unsigned cie_caf, cie_daf, cie_instlen, func_len, fde_length; Dwarf_Signed cie_count, fde_count, cie_index; Dwarf_Addr low_pc; Dwarf_Half cie_ra; Dwarf_Small cie_version; Dwarf_Ptr fde_addr, fde_inst, cie_inst; char *cie_aug, c; int i, eh_frame; Dwarf_Error de; printf("\nThe section %s contains:\n\n", s->name); if (!strcmp(s->name, ".debug_frame")) { eh_frame = 0; if (dwarf_get_fde_list(re->dbg, &cie_list, &cie_count, &fde_list, &fde_count, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_list failed: %s", dwarf_errmsg(de)); return; } } else if (!strcmp(s->name, ".eh_frame")) { eh_frame = 1; if (dwarf_get_fde_list_eh(re->dbg, &cie_list, &cie_count, &fde_list, &fde_count, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_list_eh failed: %s", dwarf_errmsg(de)); return; } } else return; pre_cie = NULL; for (i = 0; i < fde_count; i++) { if (dwarf_get_fde_n(fde_list, i, &fde, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_n failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_addr, &fde_length, &cie_offset, &cie_index, &fde_offset, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_range failed: %s", dwarf_errmsg(de)); continue; } if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_instlen, &de) != DW_DLV_OK) { warnx("dwarf_get_fde_instr_bytes failed: %s", dwarf_errmsg(de)); continue; } if (pre_cie == NULL || cie != pre_cie) { pre_cie = cie; if (dwarf_get_cie_info(cie, &cie_length, &cie_version, &cie_aug, &cie_caf, &cie_daf, &cie_ra, &cie_inst, &cie_instlen, &de) != DW_DLV_OK) { warnx("dwarf_get_cie_info failed: %s", dwarf_errmsg(de)); continue; } printf("%08jx %08jx %8.8jx CIE", (uintmax_t) cie_offset, (uintmax_t) cie_length, (uintmax_t) (eh_frame ? 0 : ~0U)); if (!alt) { putchar('\n'); printf(" Version:\t\t\t%u\n", cie_version); printf(" Augmentation:\t\t\t\""); while ((c = *cie_aug++) != '\0') putchar(c); printf("\"\n"); printf(" Code alignment factor:\t%ju\n", (uintmax_t) cie_caf); printf(" Data alignment factor:\t%jd\n", (intmax_t) cie_daf); printf(" Return address column:\t%ju\n", (uintmax_t) cie_ra); putchar('\n'); dump_dwarf_frame_inst(re, cie, cie_inst, cie_instlen, cie_caf, cie_daf, 0, re->dbg); putchar('\n'); } else { printf(" \""); while ((c = *cie_aug++) != '\0') putchar(c); putchar('"'); printf(" cf=%ju df=%jd ra=%ju\n", (uintmax_t) cie_caf, (uintmax_t) cie_daf, (uintmax_t) cie_ra); dump_dwarf_frame_regtable(re, fde, low_pc, 1, cie_ra); putchar('\n'); } } printf("%08jx %08jx %08jx FDE cie=%08jx pc=%08jx..%08jx\n", (uintmax_t) fde_offset, (uintmax_t) fde_length, (uintmax_t) cie_offset, (uintmax_t) (eh_frame ? fde_offset + 4 - cie_offset : cie_offset), (uintmax_t) low_pc, (uintmax_t) (low_pc + func_len)); if (!alt) dump_dwarf_frame_inst(re, cie, fde_inst, fde_instlen, cie_caf, cie_daf, low_pc, re->dbg); else dump_dwarf_frame_regtable(re, fde, low_pc, func_len, cie_ra); putchar('\n'); } } static void dump_dwarf_frame(struct readelf *re, int alt) { struct section *s; int i; (void) dwarf_set_frame_cfa_value(re->dbg, DW_FRAME_CFA_COL); for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && (!strcmp(s->name, ".debug_frame") || !strcmp(s->name, ".eh_frame"))) dump_dwarf_frame_section(re, s, alt); } } static void dump_dwarf_str(struct readelf *re) { struct section *s; Elf_Data *d; unsigned char *p; int elferr, end, i, j; printf("\nContents of section .debug_str:\n"); s = NULL; for (i = 0; (size_t) i < re->shnum; i++) { s = &re->sl[i]; if (s->name != NULL && !strcmp(s->name, ".debug_str")) break; } if ((size_t) i >= re->shnum) return; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(-1)); return; } if (d->d_size <= 0) return; for (i = 0, p = d->d_buf; (size_t) i < d->d_size; i += 16) { printf(" 0x%08x", (unsigned int) i); if ((size_t) i + 16 > d->d_size) end = d->d_size; else end = i + 16; for (j = i; j < i + 16; j++) { if ((j - i) % 4 == 0) putchar(' '); if (j >= end) { printf(" "); continue; } printf("%02x", (uint8_t) p[j]); } putchar(' '); for (j = i; j < end; j++) { if (isprint(p[j])) putchar(p[j]); else if (p[j] == 0) putchar('.'); else putchar(' '); } putchar('\n'); } } -struct loc_at { - Dwarf_Attribute la_at; - Dwarf_Unsigned la_off; - Dwarf_Unsigned la_lowpc; - Dwarf_Half la_cu_psize; - Dwarf_Half la_cu_osize; - Dwarf_Half la_cu_ver; - TAILQ_ENTRY(loc_at) la_next; -}; +static int +loc_at_comparator(const void *la1, const void *la2) +{ + const struct loc_at *left, *right; -static TAILQ_HEAD(, loc_at) lalist = TAILQ_HEAD_INITIALIZER(lalist); + left = (const struct loc_at *)la1; + right = (const struct loc_at *)la2; + if (left->la_off > right->la_off) + return (1); + else if (left->la_off < right->la_off) + return (-1); + else + return (0); +} + static void -search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc) +search_loclist_at(struct readelf *re, Dwarf_Die die, Dwarf_Unsigned lowpc, + struct loc_at **la_list, size_t *la_list_len, size_t *la_list_cap) { + struct loc_at *la; Dwarf_Attribute *attr_list; Dwarf_Die ret_die; Dwarf_Unsigned off; Dwarf_Off ref; Dwarf_Signed attr_count; Dwarf_Half attr, form; Dwarf_Bool is_info; Dwarf_Error de; - struct loc_at *la, *nla; int i, ret; is_info = dwarf_get_die_infotypes_flag(die); if ((ret = dwarf_attrlist(die, &attr_list, &attr_count, &de)) != DW_DLV_OK) { if (ret == DW_DLV_ERROR) warnx("dwarf_attrlist failed: %s", dwarf_errmsg(de)); goto cont_search; } for (i = 0; i < attr_count; i++) { if (dwarf_whatattr(attr_list[i], &attr, &de) != DW_DLV_OK) { warnx("dwarf_whatattr failed: %s", dwarf_errmsg(de)); continue; } if (attr != DW_AT_location && attr != DW_AT_string_length && attr != DW_AT_return_addr && attr != DW_AT_data_member_location && attr != DW_AT_frame_base && attr != DW_AT_segment && attr != DW_AT_static_link && attr != DW_AT_use_location && attr != DW_AT_vtable_elem_location) continue; if (dwarf_whatform(attr_list[i], &form, &de) != DW_DLV_OK) { warnx("dwarf_whatform failed: %s", dwarf_errmsg(de)); continue; } if (form == DW_FORM_data4 || form == DW_FORM_data8) { if (dwarf_formudata(attr_list[i], &off, &de) != DW_DLV_OK) { warnx("dwarf_formudata failed: %s", dwarf_errmsg(de)); continue; } } else if (form == DW_FORM_sec_offset) { if (dwarf_global_formref(attr_list[i], &ref, &de) != DW_DLV_OK) { warnx("dwarf_global_formref failed: %s", dwarf_errmsg(de)); continue; } off = ref; } else continue; - TAILQ_FOREACH(la, &lalist, la_next) { - if (off == la->la_off) - break; - if (off < la->la_off) { - if ((nla = malloc(sizeof(*nla))) == NULL) - err(EXIT_FAILURE, "malloc failed"); - nla->la_at = attr_list[i]; - nla->la_off = off; - nla->la_lowpc = lowpc; - nla->la_cu_psize = re->cu_psize; - nla->la_cu_osize = re->cu_osize; - nla->la_cu_ver = re->cu_ver; - TAILQ_INSERT_BEFORE(la, nla, la_next); - break; - } + if (*la_list_cap == *la_list_len) { + *la_list = realloc(*la_list, + *la_list_cap * 2 * sizeof(**la_list)); + if (*la_list == NULL) + err(EXIT_FAILURE, "realloc failed"); + *la_list_cap *= 2; } - if (la == NULL) { - if ((nla = malloc(sizeof(*nla))) == NULL) - err(EXIT_FAILURE, "malloc failed"); - nla->la_at = attr_list[i]; - nla->la_off = off; - nla->la_lowpc = lowpc; - nla->la_cu_psize = re->cu_psize; - nla->la_cu_osize = re->cu_osize; - nla->la_cu_ver = re->cu_ver; - TAILQ_INSERT_TAIL(&lalist, nla, la_next); - } + la = &((*la_list)[*la_list_len]); + la->la_at = attr_list[i]; + la->la_off = off; + la->la_lowpc = lowpc; + la->la_cu_psize = re->cu_psize; + la->la_cu_osize = re->cu_osize; + la->la_cu_ver = re->cu_ver; + (*la_list_len)++; } cont_search: /* Search children. */ ret = dwarf_child(die, &ret_die, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_child: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) - search_loclist_at(re, ret_die, lowpc); + search_loclist_at(re, ret_die, lowpc, la_list, + la_list_len, la_list_cap); /* Search sibling. */ ret = dwarf_siblingof_b(re->dbg, die, &ret_die, is_info, &de); if (ret == DW_DLV_ERROR) warnx("dwarf_siblingof: %s", dwarf_errmsg(de)); else if (ret == DW_DLV_OK) - search_loclist_at(re, ret_die, lowpc); + search_loclist_at(re, ret_die, lowpc, la_list, + la_list_len, la_list_cap); } static void dump_dwarf_loc(struct readelf *re, Dwarf_Loc *lr) { const char *op_str; char unk_op[32]; uint8_t *b, n; int i; if (dwarf_get_OP_name(lr->lr_atom, &op_str) != DW_DLV_OK) { snprintf(unk_op, sizeof(unk_op), "[Unknown OP: %#x]", lr->lr_atom); op_str = unk_op; } printf("%s", op_str); switch (lr->lr_atom) { case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3: case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7: case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11: case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15: case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19: case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23: case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27: case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31: printf(" (%s)", dwarf_regname(re, lr->lr_atom - DW_OP_reg0)); break; case DW_OP_deref: case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: case DW_OP_lit3: case DW_OP_lit4: case DW_OP_lit5: case DW_OP_lit6: case DW_OP_lit7: case DW_OP_lit8: case DW_OP_lit9: case DW_OP_lit10: case DW_OP_lit11: case DW_OP_lit12: case DW_OP_lit13: case DW_OP_lit14: case DW_OP_lit15: case DW_OP_lit16: case DW_OP_lit17: case DW_OP_lit18: case DW_OP_lit19: case DW_OP_lit20: case DW_OP_lit21: case DW_OP_lit22: case DW_OP_lit23: case DW_OP_lit24: case DW_OP_lit25: case DW_OP_lit26: case DW_OP_lit27: case DW_OP_lit28: case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: case DW_OP_dup: case DW_OP_drop: case DW_OP_over: case DW_OP_swap: case DW_OP_rot: case DW_OP_xderef: case DW_OP_abs: case DW_OP_and: case DW_OP_div: case DW_OP_minus: case DW_OP_mod: case DW_OP_mul: case DW_OP_neg: case DW_OP_not: case DW_OP_or: case DW_OP_plus: case DW_OP_shl: case DW_OP_shr: case DW_OP_shra: case DW_OP_xor: case DW_OP_eq: case DW_OP_ge: case DW_OP_gt: case DW_OP_le: case DW_OP_lt: case DW_OP_ne: case DW_OP_nop: case DW_OP_push_object_address: case DW_OP_form_tls_address: case DW_OP_call_frame_cfa: case DW_OP_stack_value: case DW_OP_GNU_push_tls_address: case DW_OP_GNU_uninit: break; case DW_OP_const1u: case DW_OP_pick: case DW_OP_deref_size: case DW_OP_xderef_size: case DW_OP_const2u: case DW_OP_bra: case DW_OP_skip: case DW_OP_const4u: case DW_OP_const8u: case DW_OP_constu: case DW_OP_plus_uconst: case DW_OP_regx: case DW_OP_piece: printf(": %ju", (uintmax_t) lr->lr_number); break; case DW_OP_const1s: case DW_OP_const2s: case DW_OP_const4s: case DW_OP_const8s: case DW_OP_consts: printf(": %jd", (intmax_t) lr->lr_number); break; case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3: case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7: case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11: case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15: case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19: case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23: case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27: case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31: printf(" (%s): %jd", dwarf_regname(re, lr->lr_atom - DW_OP_breg0), (intmax_t) lr->lr_number); break; case DW_OP_fbreg: printf(": %jd", (intmax_t) lr->lr_number); break; case DW_OP_bregx: printf(": %ju (%s) %jd", (uintmax_t) lr->lr_number, dwarf_regname(re, (unsigned int) lr->lr_number), (intmax_t) lr->lr_number2); break; case DW_OP_addr: case DW_OP_GNU_encoded_addr: printf(": %#jx", (uintmax_t) lr->lr_number); break; case DW_OP_GNU_implicit_pointer: printf(": <0x%jx> %jd", (uintmax_t) lr->lr_number, (intmax_t) lr->lr_number2); break; case DW_OP_implicit_value: printf(": %ju byte block:", (uintmax_t) lr->lr_number); b = (uint8_t *)(uintptr_t) lr->lr_number2; for (i = 0; (Dwarf_Unsigned) i < lr->lr_number; i++) printf(" %x", b[i]); break; case DW_OP_GNU_entry_value: printf(": ("); dump_dwarf_block(re, (uint8_t *)(uintptr_t) lr->lr_number2, lr->lr_number); putchar(')'); break; case DW_OP_GNU_const_type: printf(": <0x%jx> ", (uintmax_t) lr->lr_number); b = (uint8_t *)(uintptr_t) lr->lr_number2; n = *b; for (i = 1; (uint8_t) i < n; i++) printf(" %x", b[i]); break; case DW_OP_GNU_regval_type: printf(": %ju (%s) <0x%jx>", (uintmax_t) lr->lr_number, dwarf_regname(re, (unsigned int) lr->lr_number), (uintmax_t) lr->lr_number2); break; case DW_OP_GNU_convert: case DW_OP_GNU_deref_type: case DW_OP_GNU_parameter_ref: case DW_OP_GNU_reinterpret: printf(": <0x%jx>", (uintmax_t) lr->lr_number); break; default: break; } } static void dump_dwarf_block(struct readelf *re, uint8_t *b, Dwarf_Unsigned len) { Dwarf_Locdesc *llbuf; Dwarf_Signed lcnt; Dwarf_Error de; int i; if (dwarf_loclist_from_expr_b(re->dbg, b, len, re->cu_psize, re->cu_osize, re->cu_ver, &llbuf, &lcnt, &de) != DW_DLV_OK) { warnx("dwarf_loclist_form_expr_b: %s", dwarf_errmsg(de)); return; } for (i = 0; (Dwarf_Half) i < llbuf->ld_cents; i++) { dump_dwarf_loc(re, &llbuf->ld_s[i]); if (i < llbuf->ld_cents - 1) printf("; "); } dwarf_dealloc(re->dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(re->dbg, llbuf, DW_DLA_LOCDESC); } static void dump_dwarf_loclist(struct readelf *re) { Dwarf_Die die; Dwarf_Locdesc **llbuf; Dwarf_Unsigned lowpc; Dwarf_Signed lcnt; Dwarf_Half tag, version, pointer_size, off_size; Dwarf_Error de; - struct loc_at *la; + struct loc_at *la_list, *left, *right, *la; + size_t la_list_len, la_list_cap; + unsigned int duplicates, k; int i, j, ret, has_content; + la_list_len = 0; + la_list_cap = 200; + if ((la_list = calloc(la_list_cap, sizeof(struct loc_at))) == NULL) + errx(EXIT_FAILURE, "calloc failed"); /* Search .debug_info section. */ while ((ret = dwarf_next_cu_header_b(re->dbg, NULL, &version, NULL, &pointer_size, &off_size, NULL, NULL, &de)) == DW_DLV_OK) { set_cu_context(re, pointer_size, off_size, version); die = NULL; if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) continue; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); continue; } /* XXX: What about DW_TAG_partial_unit? */ lowpc = 0; if (tag == DW_TAG_compile_unit) { if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lowpc, &de) != DW_DLV_OK) lowpc = 0; } /* Search attributes for reference to .debug_loc section. */ - search_loclist_at(re, die, lowpc); + search_loclist_at(re, die, lowpc, &la_list, + &la_list_len, &la_list_cap); } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); /* Search .debug_types section. */ do { while ((ret = dwarf_next_cu_header_c(re->dbg, 0, NULL, &version, NULL, &pointer_size, &off_size, NULL, NULL, NULL, NULL, &de)) == DW_DLV_OK) { set_cu_context(re, pointer_size, off_size, version); die = NULL; if (dwarf_siblingof(re->dbg, die, &die, &de) != DW_DLV_OK) continue; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { warnx("dwarf_tag failed: %s", dwarf_errmsg(de)); continue; } lowpc = 0; if (tag == DW_TAG_type_unit) { if (dwarf_attrval_unsigned(die, DW_AT_low_pc, &lowpc, &de) != DW_DLV_OK) lowpc = 0; } /* * Search attributes for reference to .debug_loc * section. */ - search_loclist_at(re, die, lowpc); + search_loclist_at(re, die, lowpc, &la_list, + &la_list_len, &la_list_cap); } if (ret == DW_DLV_ERROR) warnx("dwarf_next_cu_header: %s", dwarf_errmsg(de)); } while (dwarf_next_types_section(re->dbg, &de) == DW_DLV_OK); - if (TAILQ_EMPTY(&lalist)) + if (la_list_len == 0) { + free(la_list); return; + } + /* Sort la_list using loc_at_comparator. */ + qsort(la_list, la_list_len, sizeof(struct loc_at), loc_at_comparator); + + /* Get rid of the duplicates in la_list. */ + duplicates = 0; + for (k = 1; k < la_list_len; ++k) { + left = &la_list[k - 1 - duplicates]; + right = &la_list[k]; + + if (left->la_off == right->la_off) + duplicates++; + else + la_list[k - duplicates] = *right; + } + la_list_len -= duplicates; + has_content = 0; - TAILQ_FOREACH(la, &lalist, la_next) { + for (k = 0; k < la_list_len; ++k) { + la = &la_list[k]; if ((ret = dwarf_loclist_n(la->la_at, &llbuf, &lcnt, &de)) != DW_DLV_OK) { if (ret != DW_DLV_NO_ENTRY) warnx("dwarf_loclist_n failed: %s", dwarf_errmsg(de)); continue; } if (!has_content) { has_content = 1; printf("\nContents of section .debug_loc:\n"); printf(" Offset Begin End Expression\n"); } set_cu_context(re, la->la_cu_psize, la->la_cu_osize, la->la_cu_ver); for (i = 0; i < lcnt; i++) { printf(" %8.8jx ", (uintmax_t) la->la_off); if (llbuf[i]->ld_lopc == 0 && llbuf[i]->ld_hipc == 0) { printf("\n"); continue; } /* TODO: handle base selection entry. */ printf("%8.8jx %8.8jx ", (uintmax_t) (la->la_lowpc + llbuf[i]->ld_lopc), (uintmax_t) (la->la_lowpc + llbuf[i]->ld_hipc)); putchar('('); for (j = 0; (Dwarf_Half) j < llbuf[i]->ld_cents; j++) { dump_dwarf_loc(re, &llbuf[i]->ld_s[j]); if (j < llbuf[i]->ld_cents - 1) printf("; "); } putchar(')'); if (llbuf[i]->ld_lopc == llbuf[i]->ld_hipc) printf(" (start == end)"); putchar('\n'); } for (i = 0; i < lcnt; i++) { dwarf_dealloc(re->dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); dwarf_dealloc(re->dbg, llbuf[i], DW_DLA_LOCDESC); } dwarf_dealloc(re->dbg, llbuf, DW_DLA_LIST); } if (!has_content) printf("\nSection '.debug_loc' has no debugging data.\n"); + + free(la_list); } /* * Retrieve a string using string table section index and the string offset. */ static const char* get_string(struct readelf *re, int strtab, size_t off) { const char *name; if ((name = elf_strptr(re->elf, strtab, off)) == NULL) return (""); return (name); } /* * Retrieve the name of a symbol using the section index of the symbol * table and the index of the symbol within that table. */ static const char * get_symbol_name(struct readelf *re, int symtab, int i) { struct section *s; const char *name; GElf_Sym sym; Elf_Data *data; int elferr; s = &re->sl[symtab]; if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) return (""); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return (""); } if (gelf_getsym(data, i, &sym) != &sym) return (""); /* Return section name for STT_SECTION symbol. */ if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) { if (sym.st_shndx < re->shnum && re->sl[sym.st_shndx].name != NULL) return (re->sl[sym.st_shndx].name); return (""); } if (s->link >= re->shnum || (name = elf_strptr(re->elf, s->link, sym.st_name)) == NULL) return (""); return (name); } static uint64_t get_symbol_value(struct readelf *re, int symtab, int i) { struct section *s; GElf_Sym sym; Elf_Data *data; int elferr; s = &re->sl[symtab]; if (s->type != SHT_SYMTAB && s->type != SHT_DYNSYM) return (0); (void) elf_errno(); if ((data = elf_getdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); return (0); } if (gelf_getsym(data, i, &sym) != &sym) return (0); return (sym.st_value); } +/* + * Decompress a data section if needed (using ZLIB). + * Returns true if sucessful, false otherwise. + */ +static bool decompress_section(struct section *s, + unsigned char *compressed_data_buffer, size_t compressed_size, + unsigned char **ret_buf, size_t *ret_sz) +{ + GElf_Shdr sh; + + if (gelf_getshdr(s->scn, &sh) == NULL) + errx(EXIT_FAILURE, "gelf_getshdr() failed: %s", elf_errmsg(-1)); + + if (sh.sh_flags & SHF_COMPRESSED) { + int ret; + GElf_Chdr chdr; + Elf64_Xword inflated_size; + unsigned char *uncompressed_data_buffer = NULL; + Elf64_Xword uncompressed_size; + z_stream strm; + + if (gelf_getchdr(s->scn, &chdr) == NULL) + errx(EXIT_FAILURE, "gelf_getchdr() failed: %s", elf_errmsg(-1)); + if (chdr.ch_type != ELFCOMPRESS_ZLIB) { + warnx("unknown compression type: %d", chdr.ch_type); + return (false); + } + + inflated_size = 0; + uncompressed_size = chdr.ch_size; + uncompressed_data_buffer = malloc(uncompressed_size); + compressed_data_buffer += sizeof(chdr); + compressed_size -= sizeof(chdr); + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = compressed_size; + strm.avail_out = uncompressed_size; + ret = inflateInit(&strm); + + if (ret != Z_OK) + goto fail; + /* + * The section can contain several compressed buffers, + * so decompress in a loop until all data is inflated. + */ + while (inflated_size < compressed_size) { + strm.next_in = compressed_data_buffer + inflated_size; + strm.next_out = uncompressed_data_buffer + inflated_size; + ret = inflate(&strm, Z_FINISH); + if (ret != Z_STREAM_END) + goto fail; + inflated_size = uncompressed_size - strm.avail_out; + ret = inflateReset(&strm); + if (ret != Z_OK) + goto fail; + } + if (strm.avail_out != 0) + warnx("Warning: wrong info in compression header."); + ret = inflateEnd(&strm); + if (ret != Z_OK) + goto fail; + *ret_buf = uncompressed_data_buffer; + *ret_sz = uncompressed_size; + return (true); +fail: + inflateEnd(&strm); + if (strm.msg) + warnx("%s", strm.msg); + else + warnx("ZLIB error: %d", ret); + free(uncompressed_data_buffer); + return (false); + } + return (false); +} + static void hex_dump(struct readelf *re) { struct section *s; Elf_Data *d; - uint8_t *buf; + uint8_t *buf, *new_buf; size_t sz, nbytes; uint64_t addr; int elferr, i, j; for (i = 1; (size_t) i < re->shnum; i++) { + new_buf = NULL; s = &re->sl[i]; if (find_dumpop(re, (size_t) i, s->name, HEX_DUMP, -1) == NULL) continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL && (d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } (void) elf_errno(); if (d->d_size <= 0 || d->d_buf == NULL) { printf("\nSection '%s' has no data to dump.\n", s->name); continue; } buf = d->d_buf; sz = d->d_size; addr = s->addr; + if (re->options & RE_Z) { + if (decompress_section(s, d->d_buf, d->d_size, + &new_buf, &sz)) + buf = new_buf; + } printf("\nHex dump of section '%s':\n", s->name); while (sz > 0) { printf(" 0x%8.8jx ", (uintmax_t)addr); nbytes = sz > 16? 16 : sz; for (j = 0; j < 16; j++) { if ((size_t)j < nbytes) printf("%2.2x", buf[j]); else printf(" "); if ((j & 3) == 3) printf(" "); } for (j = 0; (size_t)j < nbytes; j++) { if (isprint(buf[j])) printf("%c", buf[j]); else printf("."); } printf("\n"); buf += nbytes; addr += nbytes; sz -= nbytes; } + free(new_buf); } } static void str_dump(struct readelf *re) { struct section *s; Elf_Data *d; - unsigned char *start, *end, *buf_end; + unsigned char *start, *end, *buf_end, *new_buf; unsigned int len; + size_t sz; int i, j, elferr, found; for (i = 1; (size_t) i < re->shnum; i++) { + new_buf = NULL; s = &re->sl[i]; if (find_dumpop(re, (size_t) i, s->name, STR_DUMP, -1) == NULL) continue; (void) elf_errno(); if ((d = elf_getdata(s->scn, NULL)) == NULL && (d = elf_rawdata(s->scn, NULL)) == NULL) { elferr = elf_errno(); if (elferr != 0) warnx("elf_getdata failed: %s", elf_errmsg(elferr)); continue; } (void) elf_errno(); if (d->d_size <= 0 || d->d_buf == NULL) { printf("\nSection '%s' has no data to dump.\n", s->name); continue; } - buf_end = (unsigned char *) d->d_buf + d->d_size; - start = (unsigned char *) d->d_buf; found = 0; + start = d->d_buf; + sz = d->d_size; + if (re->options & RE_Z) { + if (decompress_section(s, d->d_buf, d->d_size, + &new_buf, &sz)) + start = new_buf; + } + buf_end = start + sz; printf("\nString dump of section '%s':\n", s->name); for (;;) { while (start < buf_end && !isprint(*start)) start++; if (start >= buf_end) break; end = start + 1; while (end < buf_end && isprint(*end)) end++; printf(" [%6lx] ", (long) (start - (unsigned char *) d->d_buf)); len = end - start; for (j = 0; (unsigned int) j < len; j++) putchar(start[j]); putchar('\n'); found = 1; if (end >= buf_end) break; start = end + 1; } + free(new_buf); if (!found) printf(" No strings found in this section."); putchar('\n'); } } static void load_sections(struct readelf *re) { struct section *s; const char *name; Elf_Scn *scn; GElf_Shdr sh; size_t shstrndx, ndx; int elferr; /* Allocate storage for internal section list. */ if (!elf_getshnum(re->elf, &re->shnum)) { warnx("elf_getshnum failed: %s", elf_errmsg(-1)); return; } if (re->sl != NULL) free(re->sl); if ((re->sl = calloc(re->shnum, sizeof(*re->sl))) == NULL) err(EXIT_FAILURE, "calloc failed"); /* Get the index of .shstrtab section. */ if (!elf_getshstrndx(re->elf, &shstrndx)) { warnx("elf_getshstrndx failed: %s", elf_errmsg(-1)); return; } if ((scn = elf_getscn(re->elf, 0)) == NULL) return; (void) elf_errno(); do { if (gelf_getshdr(scn, &sh) == NULL) { warnx("gelf_getshdr failed: %s", elf_errmsg(-1)); (void) elf_errno(); continue; } if ((name = elf_strptr(re->elf, shstrndx, sh.sh_name)) == NULL) { (void) elf_errno(); name = ""; } if ((ndx = elf_ndxscn(scn)) == SHN_UNDEF) { if ((elferr = elf_errno()) != 0) { warnx("elf_ndxscn failed: %s", elf_errmsg(elferr)); continue; } } if (ndx >= re->shnum) { warnx("section index of '%s' out of range", name); continue; } if (sh.sh_link >= re->shnum) warnx("section link %llu of '%s' out of range", (unsigned long long)sh.sh_link, name); s = &re->sl[ndx]; s->name = name; s->scn = scn; s->off = sh.sh_offset; s->sz = sh.sh_size; s->entsize = sh.sh_entsize; s->align = sh.sh_addralign; s->type = sh.sh_type; s->flags = sh.sh_flags; s->addr = sh.sh_addr; s->link = sh.sh_link; s->info = sh.sh_info; } while ((scn = elf_nextscn(re->elf, scn)) != NULL); elferr = elf_errno(); if (elferr != 0) warnx("elf_nextscn failed: %s", elf_errmsg(elferr)); } static void unload_sections(struct readelf *re) { if (re->sl != NULL) { free(re->sl); re->sl = NULL; } re->shnum = 0; re->vd_s = NULL; re->vn_s = NULL; re->vs_s = NULL; re->vs = NULL; re->vs_sz = 0; if (re->ver != NULL) { free(re->ver); re->ver = NULL; re->ver_sz = 0; } } static void dump_elf(struct readelf *re) { /* Fetch ELF header. No need to continue if it fails. */ if (gelf_getehdr(re->elf, &re->ehdr) == NULL) { warnx("gelf_getehdr failed: %s", elf_errmsg(-1)); return; } if ((re->ec = gelf_getclass(re->elf)) == ELFCLASSNONE) { warnx("gelf_getclass failed: %s", elf_errmsg(-1)); return; } if (re->ehdr.e_ident[EI_DATA] == ELFDATA2MSB) { re->dw_read = _read_msb; re->dw_decode = _decode_msb; } else { re->dw_read = _read_lsb; re->dw_decode = _decode_lsb; } if (re->options & ~RE_H) load_sections(re); if ((re->options & RE_VV) || (re->options & RE_S)) search_ver(re); if (re->options & RE_H) dump_ehdr(re); if (re->options & RE_L) dump_phdr(re); if (re->options & RE_SS) dump_shdr(re); if (re->options & RE_G) dump_section_groups(re); if (re->options & RE_D) dump_dynamic(re); if (re->options & RE_R) dump_reloc(re); if (re->options & RE_S) dump_symtabs(re); if (re->options & RE_N) dump_notes(re); if (re->options & RE_II) dump_hash(re); if (re->options & RE_X) hex_dump(re); if (re->options & RE_P) str_dump(re); if (re->options & RE_VV) dump_ver(re); if (re->options & RE_AA) dump_arch_specific_info(re); if (re->options & RE_W) dump_dwarf(re); if (re->options & ~RE_H) unload_sections(re); } static void dump_dwarf(struct readelf *re) { - struct loc_at *la, *_la; Dwarf_Error de; int error; if (dwarf_elf_init(re->elf, DW_DLC_READ, NULL, NULL, &re->dbg, &de)) { if ((error = dwarf_errno(de)) != DW_DLE_DEBUG_INFO_NULL) errx(EXIT_FAILURE, "dwarf_elf_init failed: %s", dwarf_errmsg(de)); return; } if (re->dop & DW_A) dump_dwarf_abbrev(re); if (re->dop & DW_L) dump_dwarf_line(re); if (re->dop & DW_LL) dump_dwarf_line_decoded(re); if (re->dop & DW_I) { dump_dwarf_info(re, 0); dump_dwarf_info(re, 1); } if (re->dop & DW_P) dump_dwarf_pubnames(re); if (re->dop & DW_R) dump_dwarf_aranges(re); if (re->dop & DW_RR) dump_dwarf_ranges(re); if (re->dop & DW_M) dump_dwarf_macinfo(re); if (re->dop & DW_F) dump_dwarf_frame(re, 0); else if (re->dop & DW_FF) dump_dwarf_frame(re, 1); if (re->dop & DW_S) dump_dwarf_str(re); if (re->dop & DW_O) dump_dwarf_loclist(re); - TAILQ_FOREACH_SAFE(la, &lalist, la_next, _la) { - TAILQ_REMOVE(&lalist, la, la_next); - free(la); - } - dwarf_finish(re->dbg, &de); } static void dump_ar(struct readelf *re, int fd) { Elf_Arsym *arsym; Elf_Arhdr *arhdr; Elf_Cmd cmd; Elf *e; size_t sz; off_t off; int i; re->ar = re->elf; if (re->options & RE_C) { if ((arsym = elf_getarsym(re->ar, &sz)) == NULL) { warnx("elf_getarsym() failed: %s", elf_errmsg(-1)); goto process_members; } printf("Index of archive %s: (%ju entries)\n", re->filename, (uintmax_t) sz - 1); off = 0; for (i = 0; (size_t) i < sz; i++) { if (arsym[i].as_name == NULL) break; if (arsym[i].as_off != off) { off = arsym[i].as_off; if (elf_rand(re->ar, off) != off) { warnx("elf_rand() failed: %s", elf_errmsg(-1)); continue; } if ((e = elf_begin(fd, ELF_C_READ, re->ar)) == NULL) { warnx("elf_begin() failed: %s", elf_errmsg(-1)); continue; } if ((arhdr = elf_getarhdr(e)) == NULL) { warnx("elf_getarhdr() failed: %s", elf_errmsg(-1)); elf_end(e); continue; } printf("Binary %s(%s) contains:\n", re->filename, arhdr->ar_name); + elf_end(e); } printf("\t%s\n", arsym[i].as_name); } if (elf_rand(re->ar, SARMAG) != SARMAG) { warnx("elf_rand() failed: %s", elf_errmsg(-1)); return; } } process_members: if ((re->options & ~RE_C) == 0) return; cmd = ELF_C_READ; while ((re->elf = elf_begin(fd, cmd, re->ar)) != NULL) { if ((arhdr = elf_getarhdr(re->elf)) == NULL) { warnx("elf_getarhdr() failed: %s", elf_errmsg(-1)); goto next_member; } if (strcmp(arhdr->ar_name, "/") == 0 || strcmp(arhdr->ar_name, "//") == 0 || strcmp(arhdr->ar_name, "__.SYMDEF") == 0) goto next_member; printf("\nFile: %s(%s)\n", re->filename, arhdr->ar_name); dump_elf(re); next_member: cmd = elf_next(re->elf); elf_end(re->elf); } re->elf = re->ar; } static void -dump_object(struct readelf *re) +dump_object(struct readelf *re, int fd) { - int fd; - - if ((fd = open(re->filename, O_RDONLY)) == -1) { - warn("open %s failed", re->filename); - return; - } - if ((re->flags & DISPLAY_FILENAME) != 0) printf("\nFile: %s\n", re->filename); if ((re->elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) { warnx("elf_begin() failed: %s", elf_errmsg(-1)); - return; + goto done; } switch (elf_kind(re->elf)) { case ELF_K_NONE: warnx("Not an ELF file."); - return; + goto done; case ELF_K_ELF: dump_elf(re); break; case ELF_K_AR: dump_ar(re, fd); break; default: warnx("Internal: libelf returned unknown elf kind."); - return; } +done: elf_end(re->elf); } static void add_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t) { struct dumpop *d; if ((d = find_dumpop(re, si, sn, -1, t)) == NULL) { if ((d = calloc(1, sizeof(*d))) == NULL) err(EXIT_FAILURE, "calloc failed"); if (t == DUMP_BY_INDEX) d->u.si = si; else d->u.sn = sn; d->type = t; d->op = op; STAILQ_INSERT_TAIL(&re->v_dumpop, d, dumpop_list); } else d->op |= op; } static struct dumpop * find_dumpop(struct readelf *re, size_t si, const char *sn, int op, int t) { struct dumpop *d; STAILQ_FOREACH(d, &re->v_dumpop, dumpop_list) { if ((op == -1 || op & d->op) && (t == -1 || (unsigned) t == d->type)) { if ((d->type == DUMP_BY_INDEX && d->u.si == si) || (d->type == DUMP_BY_NAME && !strcmp(d->u.sn, sn))) return (d); } } return (NULL); } static struct { const char *ln; char sn; int value; } dwarf_op[] = { {"rawline", 'l', DW_L}, {"decodedline", 'L', DW_LL}, {"info", 'i', DW_I}, {"abbrev", 'a', DW_A}, {"pubnames", 'p', DW_P}, {"aranges", 'r', DW_R}, {"ranges", 'r', DW_R}, {"Ranges", 'R', DW_RR}, {"macro", 'm', DW_M}, {"frames", 'f', DW_F}, {"frames-interp", 'F', DW_FF}, {"str", 's', DW_S}, {"loc", 'o', DW_O}, {NULL, 0, 0} }; static void parse_dwarf_op_short(struct readelf *re, const char *op) { int i; if (op == NULL) { re->dop |= DW_DEFAULT_OPTIONS; return; } for (; *op != '\0'; op++) { for (i = 0; dwarf_op[i].ln != NULL; i++) { if (dwarf_op[i].sn == *op) { re->dop |= dwarf_op[i].value; break; } } } } static void parse_dwarf_op_long(struct readelf *re, const char *op) { char *p, *token, *bp; int i; if (op == NULL) { re->dop |= DW_DEFAULT_OPTIONS; return; } if ((p = strdup(op)) == NULL) err(EXIT_FAILURE, "strdup failed"); bp = p; while ((token = strsep(&p, ",")) != NULL) { for (i = 0; dwarf_op[i].ln != NULL; i++) { if (!strcmp(token, dwarf_op[i].ln)) { re->dop |= dwarf_op[i].value; break; } } } free(bp); } static uint64_t _read_lsb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) { uint64_t ret; uint8_t *src; src = (uint8_t *) d->d_buf + *offsetp; ret = 0; switch (bytes_to_read) { case 8: ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; /* FALLTHROUGH */ case 4: ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; /* FALLTHROUGH */ case 2: ret |= ((uint64_t) src[1]) << 8; /* FALLTHROUGH */ case 1: ret |= src[0]; break; default: return (0); } *offsetp += bytes_to_read; return (ret); } static uint64_t _read_msb(Elf_Data *d, uint64_t *offsetp, int bytes_to_read) { uint64_t ret; uint8_t *src; src = (uint8_t *) d->d_buf + *offsetp; switch (bytes_to_read) { case 1: ret = src[0]; break; case 2: ret = src[1] | ((uint64_t) src[0]) << 8; break; case 4: ret = src[3] | ((uint64_t) src[2]) << 8; ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; break; case 8: ret = src[7] | ((uint64_t) src[6]) << 8; ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; break; default: return (0); } *offsetp += bytes_to_read; return (ret); } static uint64_t _decode_lsb(uint8_t **data, int bytes_to_read) { uint64_t ret; uint8_t *src; src = *data; ret = 0; switch (bytes_to_read) { case 8: ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; /* FALLTHROUGH */ case 4: ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; /* FALLTHROUGH */ case 2: ret |= ((uint64_t) src[1]) << 8; /* FALLTHROUGH */ case 1: ret |= src[0]; break; default: return (0); } *data += bytes_to_read; return (ret); } static uint64_t _decode_msb(uint8_t **data, int bytes_to_read) { uint64_t ret; uint8_t *src; src = *data; ret = 0; switch (bytes_to_read) { case 1: ret = src[0]; break; case 2: ret = src[1] | ((uint64_t) src[0]) << 8; break; case 4: ret = src[3] | ((uint64_t) src[2]) << 8; ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; break; case 8: ret = src[7] | ((uint64_t) src[6]) << 8; ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; break; default: return (0); break; } *data += bytes_to_read; return (ret); } static int64_t _decode_sleb128(uint8_t **dp, uint8_t *dpe) { int64_t ret = 0; uint8_t b = 0; int shift = 0; uint8_t *src = *dp; do { if (src >= dpe) break; b = *src++; ret |= ((b & 0x7f) << shift); shift += 7; } while ((b & 0x80) != 0); if (shift < 32 && (b & 0x40) != 0) ret |= (-1 << shift); *dp = src; return (ret); } static uint64_t _decode_uleb128(uint8_t **dp, uint8_t *dpe) { uint64_t ret = 0; uint8_t b; int shift = 0; uint8_t *src = *dp; do { if (src >= dpe) break; b = *src++; ret |= ((b & 0x7f) << shift); shift += 7; } while ((b & 0x80) != 0); *dp = src; return (ret); } static void readelf_version(void) { (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); exit(EXIT_SUCCESS); } #define USAGE_MESSAGE "\ Usage: %s [options] file...\n\ Display information about ELF objects and ar(1) archives.\n\n\ Options:\n\ -a | --all Equivalent to specifying options '-dhIlrsASV'.\n\ -c | --archive-index Print the archive symbol table for archives.\n\ -d | --dynamic Print the contents of SHT_DYNAMIC sections.\n\ -e | --headers Print all headers in the object.\n\ -g | --section-groups Print the contents of the section groups.\n\ -h | --file-header Print the file header for the object.\n\ -l | --program-headers Print the PHDR table for the object.\n\ -n | --notes Print the contents of SHT_NOTE sections.\n\ -p INDEX | --string-dump=INDEX\n\ Print the contents of section at index INDEX.\n\ -r | --relocs Print relocation information.\n\ -s | --syms | --symbols Print symbol tables.\n\ -t | --section-details Print additional information about sections.\n\ -v | --version Print a version identifier and exit.\n\ -w[afilmoprsFLR] | --debug-dump={abbrev,aranges,decodedline,frames,\n\ frames-interp,info,loc,macro,pubnames,\n\ ranges,Ranges,rawline,str}\n\ Display DWARF information.\n\ -x INDEX | --hex-dump=INDEX\n\ Display contents of a section as hexadecimal.\n\ + -z | --decompress Decompress the contents of a section before displaying it.\n\ -A | --arch-specific (accepted, but ignored)\n\ -D | --use-dynamic Print the symbol table specified by the DT_SYMTAB\n\ entry in the \".dynamic\" section.\n\ -H | --help Print a help message.\n\ -I | --histogram Print information on bucket list lengths for \n\ hash sections.\n\ -N | --full-section-name (accepted, but ignored)\n\ -S | --sections | --section-headers\n\ Print information about section headers.\n\ -V | --version-info Print symbol versoning information.\n\ -W | --wide Print information without wrapping long lines.\n" static void readelf_usage(int status) { fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(status); } int main(int argc, char **argv) { struct readelf *re, re_storage; unsigned long si; - int opt, i; + int fd, opt, i; char *ep; re = &re_storage; memset(re, 0, sizeof(*re)); STAILQ_INIT(&re->v_dumpop); - while ((opt = getopt_long(argc, argv, "AacDdegHhIi:lNnp:rSstuVvWw::x:", + while ((opt = getopt_long(argc, argv, "AacDdegHhIi:lNnp:rSstuVvWw::x:z", longopts, NULL)) != -1) { switch(opt) { case '?': readelf_usage(EXIT_SUCCESS); break; case 'A': re->options |= RE_AA; break; case 'a': re->options |= RE_AA | RE_D | RE_G | RE_H | RE_II | RE_L | RE_R | RE_SS | RE_S | RE_VV; break; case 'c': re->options |= RE_C; break; case 'D': re->options |= RE_DD; break; case 'd': re->options |= RE_D; break; case 'e': re->options |= RE_H | RE_L | RE_SS; break; case 'g': re->options |= RE_G; break; case 'H': readelf_usage(EXIT_SUCCESS); break; case 'h': re->options |= RE_H; break; case 'I': re->options |= RE_II; break; case 'i': /* Not implemented yet. */ break; case 'l': re->options |= RE_L; break; case 'N': re->options |= RE_NN; break; case 'n': re->options |= RE_N; break; case 'p': re->options |= RE_P; si = strtoul(optarg, &ep, 10); if (*ep == '\0') add_dumpop(re, (size_t) si, NULL, STR_DUMP, DUMP_BY_INDEX); else add_dumpop(re, 0, optarg, STR_DUMP, DUMP_BY_NAME); break; case 'r': re->options |= RE_R; break; case 'S': re->options |= RE_SS; break; case 's': re->options |= RE_S; break; case 't': - re->options |= RE_T; + re->options |= RE_SS | RE_T; break; case 'u': re->options |= RE_U; break; case 'V': re->options |= RE_VV; break; case 'v': readelf_version(); break; case 'W': re->options |= RE_WW; break; case 'w': re->options |= RE_W; parse_dwarf_op_short(re, optarg); break; case 'x': re->options |= RE_X; si = strtoul(optarg, &ep, 10); if (*ep == '\0') add_dumpop(re, (size_t) si, NULL, HEX_DUMP, DUMP_BY_INDEX); else add_dumpop(re, 0, optarg, HEX_DUMP, DUMP_BY_NAME); break; + case 'z': + re->options |= RE_Z; + break; case OPTION_DEBUG_DUMP: re->options |= RE_W; parse_dwarf_op_long(re, optarg); } } argv += optind; argc -= optind; if (argc == 0 || re->options == 0) readelf_usage(EXIT_FAILURE); if (argc > 1) re->flags |= DISPLAY_FILENAME; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "ELF library initialization failed: %s", elf_errmsg(-1)); for (i = 0; i < argc; i++) { re->filename = argv[i]; - dump_object(re); + fd = open(re->filename, O_RDONLY); + if (fd < 0) { + warn("open %s failed", re->filename); + } else { + dump_object(re, fd); + close(fd); + } } exit(EXIT_SUCCESS); } Index: stable/11/contrib/elftoolchain/size/size.c =================================================================== --- stable/11/contrib/elftoolchain/size/size.c (revision 367465) +++ stable/11/contrib/elftoolchain/size/size.c (revision 367466) @@ -1,929 +1,930 @@ /*- * Copyright (c) 2007 S.Sam Arun Raj * 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 "_elftc.h" ELFTC_VCSID("$Id: size.c 3458 2016-05-09 15:01:25Z emaste $"); #define BUF_SIZE 1024 #define ELF_ALIGN(val,x) (((val)+(x)-1) & ~((x)-1)) #define SIZE_VERSION_STRING "size 1.0" enum return_code { RETURN_OK, RETURN_NOINPUT, RETURN_DATAERR, RETURN_USAGE }; enum output_style { STYLE_BERKELEY, STYLE_SYSV }; enum radix_style { RADIX_OCTAL, RADIX_DECIMAL, RADIX_HEX }; static uint64_t bss_size, data_size, text_size, total_size; static uint64_t bss_size_total, data_size_total, text_size_total; static int show_totals; static int size_option; static enum radix_style radix = RADIX_DECIMAL; static enum output_style style = STYLE_BERKELEY; static const char *default_args[2] = { "a.out", NULL }; static struct { int row; int col; int *width; char ***tbl; } *tb; enum { OPT_FORMAT, OPT_RADIX }; static struct option size_longopts[] = { { "format", required_argument, &size_option, OPT_FORMAT }, { "help", no_argument, NULL, 'h' }, { "radix", required_argument, &size_option, OPT_RADIX }, { "totals", no_argument, NULL, 't' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; static void berkeley_calc(GElf_Shdr *); static void berkeley_footer(const char *, const char *, const char *); static void berkeley_header(void); static void berkeley_totals(void); static int handle_core(char const *, Elf *elf, GElf_Ehdr *); static void handle_core_note(Elf *, GElf_Ehdr *, GElf_Phdr *, char **); static int handle_elf(char const *); static void handle_phdr(Elf *, GElf_Ehdr *, GElf_Phdr *, uint32_t, const char *); static void show_version(void); static void sysv_header(const char *, Elf_Arhdr *); static void sysv_footer(void); static void sysv_calc(Elf *, GElf_Ehdr *, GElf_Shdr *); static void usage(void); static void tbl_new(int); static void tbl_print(const char *, int); static void tbl_print_num(uint64_t, enum radix_style, int); static void tbl_append(void); static void tbl_flush(void); /* * size utility using elf(3) and gelf(3) API to list section sizes and * total in elf files. Supports only elf files (core dumps in elf * included) that can be opened by libelf, other formats are not supported. */ int main(int argc, char **argv) { int ch, r, rc; const char **files, *fn; rc = RETURN_OK; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "ELF library initialization failed: %s", elf_errmsg(-1)); while ((ch = getopt_long(argc, argv, "ABVdhotx", size_longopts, NULL)) != -1) switch((char)ch) { case 'A': style = STYLE_SYSV; break; case 'B': style = STYLE_BERKELEY; break; case 'V': show_version(); break; case 'd': radix = RADIX_DECIMAL; break; case 'o': radix = RADIX_OCTAL; break; case 't': show_totals = 1; break; case 'x': radix = RADIX_HEX; break; case 0: switch (size_option) { case OPT_FORMAT: if (*optarg == 's' || *optarg == 'S') style = STYLE_SYSV; else if (*optarg == 'b' || *optarg == 'B') style = STYLE_BERKELEY; else { warnx("unrecognized format \"%s\".", optarg); usage(); } break; case OPT_RADIX: r = strtol(optarg, NULL, 10); if (r == 8) radix = RADIX_OCTAL; else if (r == 10) radix = RADIX_DECIMAL; else if (r == 16) radix = RADIX_HEX; else { warnx("unsupported radix \"%s\".", optarg); usage(); } break; default: err(EXIT_FAILURE, "Error in option handling."); /*NOTREACHED*/ } break; case 'h': case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; files = (argc == 0) ? default_args : (void *) argv; while ((fn = *files) != NULL) { rc = handle_elf(fn); if (rc != RETURN_OK) warnx(rc == RETURN_NOINPUT ? "'%s': No such file" : "%s: File format not recognized", fn); files++; } if (style == STYLE_BERKELEY) { if (show_totals) berkeley_totals(); tbl_flush(); } return (rc); } -static Elf_Data * +static int xlatetom(Elf *elf, GElf_Ehdr *elfhdr, void *_src, void *_dst, Elf_Type type, size_t size) { Elf_Data src, dst; src.d_buf = _src; src.d_type = type; src.d_version = elfhdr->e_version; src.d_size = size; dst.d_buf = _dst; dst.d_version = elfhdr->e_version; dst.d_size = size; - return (gelf_xlatetom(elf, &dst, &src, elfhdr->e_ident[EI_DATA])); + return (gelf_xlatetom(elf, &dst, &src, elfhdr->e_ident[EI_DATA]) != + NULL ? 0 : 1); } #define NOTE_OFFSET_32(nhdr, namesz, offset) \ ((char *)nhdr + sizeof(Elf32_Nhdr) + \ ELF_ALIGN((int32_t)namesz, 4) + offset) #define NOTE_OFFSET_64(nhdr, namesz, offset) \ ((char *)nhdr + sizeof(Elf32_Nhdr) + \ ELF_ALIGN((int32_t)namesz, 8) + offset) #define PID32(nhdr, namesz, offset) \ (pid_t)*((int *)((uintptr_t)NOTE_OFFSET_32(nhdr, \ namesz, offset))); #define PID64(nhdr, namesz, offset) \ (pid_t)*((int *)((uintptr_t)NOTE_OFFSET_64(nhdr, \ namesz, offset))); #define NEXT_NOTE(elfhdr, descsz, namesz, offset) do { \ if (elfhdr->e_ident[EI_CLASS] == ELFCLASS32) { \ offset += ELF_ALIGN((int32_t)descsz, 4) + \ sizeof(Elf32_Nhdr) + \ ELF_ALIGN((int32_t)namesz, 4); \ } else { \ offset += ELF_ALIGN((int32_t)descsz, 8) + \ sizeof(Elf32_Nhdr) + \ ELF_ALIGN((int32_t)namesz, 8); \ } \ } while (0) /* * Parse individual note entries inside a PT_NOTE segment. */ static void handle_core_note(Elf *elf, GElf_Ehdr *elfhdr, GElf_Phdr *phdr, char **cmd_line) { size_t max_size, segment_end; uint64_t raw_size; GElf_Off offset; static pid_t pid; uintptr_t ver; Elf32_Nhdr *nhdr, nhdr_l; static int reg_pseudo = 0, reg2_pseudo = 0 /*, regxfp_pseudo = 0*/; char buf[BUF_SIZE], *data, *name; if (elf == NULL || elfhdr == NULL || phdr == NULL) return; data = elf_rawfile(elf, &max_size); offset = phdr->p_offset; if (offset >= max_size || phdr->p_filesz > max_size - offset) { warnx("invalid PHDR offset"); return; } segment_end = phdr->p_offset + phdr->p_filesz; while (data != NULL && offset + sizeof(Elf32_Nhdr) < segment_end) { nhdr = (Elf32_Nhdr *)(uintptr_t)((char*)data + offset); memset(&nhdr_l, 0, sizeof(Elf32_Nhdr)); - if (!xlatetom(elf, elfhdr, &nhdr->n_type, &nhdr_l.n_type, - ELF_T_WORD, sizeof(Elf32_Word)) || - !xlatetom(elf, elfhdr, &nhdr->n_descsz, &nhdr_l.n_descsz, - ELF_T_WORD, sizeof(Elf32_Word)) || - !xlatetom(elf, elfhdr, &nhdr->n_namesz, &nhdr_l.n_namesz, - ELF_T_WORD, sizeof(Elf32_Word))) + if (xlatetom(elf, elfhdr, &nhdr->n_type, &nhdr_l.n_type, + ELF_T_WORD, sizeof(Elf32_Word)) != 0 || + xlatetom(elf, elfhdr, &nhdr->n_descsz, &nhdr_l.n_descsz, + ELF_T_WORD, sizeof(Elf32_Word)) != 0 || + xlatetom(elf, elfhdr, &nhdr->n_namesz, &nhdr_l.n_namesz, + ELF_T_WORD, sizeof(Elf32_Word)) != 0) break; if (offset + sizeof(Elf32_Nhdr) + ELF_ALIGN(nhdr_l.n_namesz, 4) + ELF_ALIGN(nhdr_l.n_descsz, 4) >= segment_end) { warnx("invalid note header"); return; } name = (char *)((char *)nhdr + sizeof(Elf32_Nhdr)); switch (nhdr_l.n_type) { case NT_PRSTATUS: { raw_size = 0; if (elfhdr->e_ident[EI_OSABI] == ELFOSABI_FREEBSD && nhdr_l.n_namesz == 0x8 && !strcmp(name,"FreeBSD")) { if (elfhdr->e_ident[EI_CLASS] == ELFCLASS32) { raw_size = (uint64_t)*((uint32_t *) (uintptr_t)(name + ELF_ALIGN((int32_t) nhdr_l.n_namesz, 4) + 8)); ver = (uintptr_t)NOTE_OFFSET_32(nhdr, nhdr_l.n_namesz,0); if (*((int *)ver) == 1) pid = PID32(nhdr, nhdr_l.n_namesz, 24); } else { raw_size = *((uint64_t *)(uintptr_t) (name + ELF_ALIGN((int32_t) nhdr_l.n_namesz, 8) + 16)); ver = (uintptr_t)NOTE_OFFSET_64(nhdr, nhdr_l.n_namesz,0); if (*((int *)ver) == 1) pid = PID64(nhdr, nhdr_l.n_namesz, 40); } - xlatetom(elf, elfhdr, &raw_size, &raw_size, - ELF_T_WORD, sizeof(uint64_t)); - xlatetom(elf, elfhdr, &pid, &pid, ELF_T_WORD, - sizeof(pid_t)); + (void)xlatetom(elf, elfhdr, &raw_size, + &raw_size, ELF_T_WORD, sizeof(uint64_t)); + (void)xlatetom(elf, elfhdr, &pid, &pid, + ELF_T_WORD, sizeof(pid_t)); } if (raw_size != 0 && style == STYLE_SYSV) { (void) snprintf(buf, BUF_SIZE, "%s/%d", ".reg", pid); tbl_append(); tbl_print(buf, 0); tbl_print_num(raw_size, radix, 1); tbl_print_num(0, radix, 2); if (!reg_pseudo) { tbl_append(); tbl_print(".reg", 0); tbl_print_num(raw_size, radix, 1); tbl_print_num(0, radix, 2); reg_pseudo = 1; text_size_total += raw_size; } text_size_total += raw_size; } } break; case NT_FPREGSET: /* same as NT_PRFPREG */ if (style == STYLE_SYSV) { (void) snprintf(buf, BUF_SIZE, "%s/%d", ".reg2", pid); tbl_append(); tbl_print(buf, 0); tbl_print_num(nhdr_l.n_descsz, radix, 1); tbl_print_num(0, radix, 2); if (!reg2_pseudo) { tbl_append(); tbl_print(".reg2", 0); tbl_print_num(nhdr_l.n_descsz, radix, 1); tbl_print_num(0, radix, 2); reg2_pseudo = 1; text_size_total += nhdr_l.n_descsz; } text_size_total += nhdr_l.n_descsz; } break; #if 0 case NT_AUXV: if (style == STYLE_SYSV) { tbl_append(); tbl_print(".auxv", 0); tbl_print_num(nhdr_l.n_descsz, radix, 1); tbl_print_num(0, radix, 2); text_size_total += nhdr_l.n_descsz; } break; case NT_PRXFPREG: if (style == STYLE_SYSV) { (void) snprintf(buf, BUF_SIZE, "%s/%d", ".reg-xfp", pid); tbl_append(); tbl_print(buf, 0); tbl_print_num(nhdr_l.n_descsz, radix, 1); tbl_print_num(0, radix, 2); if (!regxfp_pseudo) { tbl_append(); tbl_print(".reg-xfp", 0); tbl_print_num(nhdr_l.n_descsz, radix, 1); tbl_print_num(0, radix, 2); regxfp_pseudo = 1; text_size_total += nhdr_l.n_descsz; } text_size_total += nhdr_l.n_descsz; } break; case NT_PSINFO: #endif case NT_PRPSINFO: { /* FreeBSD 64-bit */ if (nhdr_l.n_descsz == 0x78 && !strcmp(name,"FreeBSD")) { *cmd_line = strdup(NOTE_OFFSET_64(nhdr, nhdr_l.n_namesz, 33)); /* FreeBSD 32-bit */ } else if (nhdr_l.n_descsz == 0x6c && !strcmp(name,"FreeBSD")) { *cmd_line = strdup(NOTE_OFFSET_32(nhdr, nhdr_l.n_namesz, 25)); } /* Strip any trailing spaces */ if (*cmd_line != NULL) { char *s; s = *cmd_line + strlen(*cmd_line); while (s > *cmd_line) { if (*(s-1) != 0x20) break; s--; } *s = 0; } break; } #if 0 case NT_PSTATUS: case NT_LWPSTATUS: #endif default: break; } NEXT_NOTE(elfhdr, nhdr_l.n_descsz, nhdr_l.n_namesz, offset); } } /* * Handles program headers except for PT_NOTE, when sysv output style is * chosen, prints out the segment name and length. For berkely output * style only PT_LOAD segments are handled, and text, * data, bss size is calculated for them. */ static void handle_phdr(Elf *elf, GElf_Ehdr *elfhdr, GElf_Phdr *phdr, uint32_t idx, const char *name) { uint64_t addr, size; int split; char buf[BUF_SIZE]; if (elf == NULL || elfhdr == NULL || phdr == NULL) return; split = (phdr->p_memsz > 0) && (phdr->p_filesz > 0) && (phdr->p_memsz > phdr->p_filesz); if (style == STYLE_SYSV) { (void) snprintf(buf, BUF_SIZE, "%s%d%s", name, idx, (split ? "a" : "")); tbl_append(); tbl_print(buf, 0); tbl_print_num(phdr->p_filesz, radix, 1); tbl_print_num(phdr->p_vaddr, radix, 2); text_size_total += phdr->p_filesz; if (split) { size = phdr->p_memsz - phdr->p_filesz; addr = phdr->p_vaddr + phdr->p_filesz; (void) snprintf(buf, BUF_SIZE, "%s%d%s", name, idx, "b"); text_size_total += phdr->p_memsz - phdr->p_filesz; tbl_append(); tbl_print(buf, 0); tbl_print_num(size, radix, 1); tbl_print_num(addr, radix, 2); } } else { if (phdr->p_type != PT_LOAD) return; if ((phdr->p_flags & PF_W) && !(phdr->p_flags & PF_X)) { data_size += phdr->p_filesz; if (split) data_size += phdr->p_memsz - phdr->p_filesz; } else { text_size += phdr->p_filesz; if (split) text_size += phdr->p_memsz - phdr->p_filesz; } } } /* * Given a core dump file, this function maps program headers to segments. */ static int handle_core(char const *name, Elf *elf, GElf_Ehdr *elfhdr) { GElf_Phdr phdr; uint32_t i; char *core_cmdline; const char *seg_name; if (name == NULL || elf == NULL || elfhdr == NULL) return (RETURN_DATAERR); if (elfhdr->e_shnum != 0 || elfhdr->e_type != ET_CORE) return (RETURN_DATAERR); seg_name = core_cmdline = NULL; if (style == STYLE_SYSV) sysv_header(name, NULL); else berkeley_header(); for (i = 0; i < elfhdr->e_phnum; i++) { if (gelf_getphdr(elf, i, &phdr) != NULL) { if (phdr.p_type == PT_NOTE) { handle_phdr(elf, elfhdr, &phdr, i, "note"); handle_core_note(elf, elfhdr, &phdr, &core_cmdline); } else { switch(phdr.p_type) { case PT_NULL: seg_name = "null"; break; case PT_LOAD: seg_name = "load"; break; case PT_DYNAMIC: seg_name = "dynamic"; break; case PT_INTERP: seg_name = "interp"; break; case PT_SHLIB: seg_name = "shlib"; break; case PT_PHDR: seg_name = "phdr"; break; case PT_GNU_EH_FRAME: seg_name = "eh_frame_hdr"; break; case PT_GNU_STACK: seg_name = "stack"; break; default: seg_name = "segment"; } handle_phdr(elf, elfhdr, &phdr, i, seg_name); } } } if (style == STYLE_BERKELEY) { if (core_cmdline != NULL) { berkeley_footer(core_cmdline, name, "core file invoked as"); } else { berkeley_footer(core_cmdline, name, "core file"); } } else { sysv_footer(); if (core_cmdline != NULL) { (void) printf(" (core file invoked as %s)\n\n", core_cmdline); } else { (void) printf(" (core file)\n\n"); } } free(core_cmdline); return (RETURN_OK); } /* * Given an elf object,ar(1) filename, and based on the output style * and radix format the various sections and their length will be printed * or the size of the text, data, bss sections will be printed out. */ static int handle_elf(char const *name) { GElf_Ehdr elfhdr; GElf_Shdr shdr; Elf *elf, *elf1; Elf_Arhdr *arhdr; Elf_Scn *scn; Elf_Cmd elf_cmd; int exit_code, fd; if (name == NULL) return (RETURN_NOINPUT); if ((fd = open(name, O_RDONLY, 0)) < 0) return (RETURN_NOINPUT); elf_cmd = ELF_C_READ; elf1 = elf_begin(fd, elf_cmd, NULL); while ((elf = elf_begin(fd, elf_cmd, elf1)) != NULL) { arhdr = elf_getarhdr(elf); if (elf_kind(elf) == ELF_K_NONE && arhdr == NULL) { (void) elf_end(elf); (void) elf_end(elf1); (void) close(fd); return (RETURN_DATAERR); } if (elf_kind(elf) != ELF_K_ELF || (gelf_getehdr(elf, &elfhdr) == NULL)) { elf_cmd = elf_next(elf); (void) elf_end(elf); warnx("%s: File format not recognized", arhdr != NULL ? arhdr->ar_name : name); continue; } /* Core dumps are handled separately */ if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { exit_code = handle_core(name, elf, &elfhdr); (void) elf_end(elf); (void) elf_end(elf1); (void) close(fd); return (exit_code); } else { scn = NULL; if (style == STYLE_BERKELEY) { berkeley_header(); while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != NULL) berkeley_calc(&shdr); } } else { sysv_header(name, arhdr); scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) != NULL) sysv_calc(elf, &elfhdr, &shdr); } } if (style == STYLE_BERKELEY) { if (arhdr != NULL) { berkeley_footer(name, arhdr->ar_name, "ex"); } else { berkeley_footer(name, NULL, "ex"); } } else { sysv_footer(); } } elf_cmd = elf_next(elf); (void) elf_end(elf); } (void) elf_end(elf1); (void) close(fd); return (RETURN_OK); } /* * Sysv formatting helper functions. */ static void sysv_header(const char *name, Elf_Arhdr *arhdr) { text_size_total = 0; if (arhdr != NULL) (void) printf("%s (ex %s):\n", arhdr->ar_name, name); else (void) printf("%s :\n", name); tbl_new(3); tbl_append(); tbl_print("section", 0); tbl_print("size", 1); tbl_print("addr", 2); } static void sysv_calc(Elf *elf, GElf_Ehdr *elfhdr, GElf_Shdr *shdr) { char *section_name; section_name = elf_strptr(elf, elfhdr->e_shstrndx, (size_t) shdr->sh_name); if ((shdr->sh_type == SHT_SYMTAB || shdr->sh_type == SHT_STRTAB || shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL) && shdr->sh_addr == 0) return; tbl_append(); tbl_print(section_name, 0); tbl_print_num(shdr->sh_size, radix, 1); tbl_print_num(shdr->sh_addr, radix, 2); text_size_total += shdr->sh_size; } static void sysv_footer(void) { tbl_append(); tbl_print("Total", 0); tbl_print_num(text_size_total, radix, 1); tbl_flush(); putchar('\n'); } /* * berkeley style output formatting helper functions. */ static void berkeley_header(void) { static int printed; text_size = data_size = bss_size = 0; if (!printed) { tbl_new(6); tbl_append(); tbl_print("text", 0); tbl_print("data", 1); tbl_print("bss", 2); if (radix == RADIX_OCTAL) tbl_print("oct", 3); else tbl_print("dec", 3); tbl_print("hex", 4); tbl_print("filename", 5); printed = 1; } } static void berkeley_calc(GElf_Shdr *shdr) { if (shdr != NULL) { if (!(shdr->sh_flags & SHF_ALLOC)) return; if ((shdr->sh_flags & SHF_ALLOC) && ((shdr->sh_flags & SHF_EXECINSTR) || !(shdr->sh_flags & SHF_WRITE))) text_size += shdr->sh_size; else if ((shdr->sh_flags & SHF_ALLOC) && (shdr->sh_flags & SHF_WRITE) && (shdr->sh_type != SHT_NOBITS)) data_size += shdr->sh_size; else bss_size += shdr->sh_size; } } static void berkeley_totals(void) { uint64_t grand_total; grand_total = text_size_total + data_size_total + bss_size_total; tbl_append(); tbl_print_num(text_size_total, radix, 0); tbl_print_num(data_size_total, radix, 1); tbl_print_num(bss_size_total, radix, 2); if (radix == RADIX_OCTAL) tbl_print_num(grand_total, RADIX_OCTAL, 3); else tbl_print_num(grand_total, RADIX_DECIMAL, 3); tbl_print_num(grand_total, RADIX_HEX, 4); } static void berkeley_footer(const char *name, const char *ar_name, const char *msg) { char buf[BUF_SIZE]; total_size = text_size + data_size + bss_size; if (show_totals) { text_size_total += text_size; bss_size_total += bss_size; data_size_total += data_size; } tbl_append(); tbl_print_num(text_size, radix, 0); tbl_print_num(data_size, radix, 1); tbl_print_num(bss_size, radix, 2); if (radix == RADIX_OCTAL) tbl_print_num(total_size, RADIX_OCTAL, 3); else tbl_print_num(total_size, RADIX_DECIMAL, 3); tbl_print_num(total_size, RADIX_HEX, 4); if (ar_name != NULL && name != NULL) (void) snprintf(buf, BUF_SIZE, "%s (%s %s)", ar_name, msg, name); else if (ar_name != NULL && name == NULL) (void) snprintf(buf, BUF_SIZE, "%s (%s)", ar_name, msg); else (void) snprintf(buf, BUF_SIZE, "%s", name); tbl_print(buf, 5); } static void tbl_new(int col) { assert(tb == NULL); assert(col > 0); if ((tb = calloc(1, sizeof(*tb))) == NULL) err(EXIT_FAILURE, "calloc"); if ((tb->tbl = calloc(col, sizeof(*tb->tbl))) == NULL) err(EXIT_FAILURE, "calloc"); if ((tb->width = calloc(col, sizeof(*tb->width))) == NULL) err(EXIT_FAILURE, "calloc"); tb->col = col; tb->row = 0; } static void tbl_print(const char *s, int col) { int len; assert(tb != NULL && tb->col > 0 && tb->row > 0 && col < tb->col); assert(s != NULL && tb->tbl[col][tb->row - 1] == NULL); if ((tb->tbl[col][tb->row - 1] = strdup(s)) == NULL) err(EXIT_FAILURE, "strdup"); len = strlen(s); if (len > tb->width[col]) tb->width[col] = len; } static void tbl_print_num(uint64_t num, enum radix_style rad, int col) { char buf[BUF_SIZE]; (void) snprintf(buf, BUF_SIZE, (rad == RADIX_DECIMAL ? "%ju" : ((rad == RADIX_OCTAL) ? "0%jo" : "0x%jx")), (uintmax_t) num); tbl_print(buf, col); } static void tbl_append(void) { int i; assert(tb != NULL && tb->col > 0); tb->row++; for (i = 0; i < tb->col; i++) { tb->tbl[i] = realloc(tb->tbl[i], sizeof(*tb->tbl[i]) * tb->row); if (tb->tbl[i] == NULL) err(EXIT_FAILURE, "realloc"); tb->tbl[i][tb->row - 1] = NULL; } } static void tbl_flush(void) { const char *str; int i, j; if (tb == NULL) return; assert(tb->col > 0); for (i = 0; i < tb->row; i++) { if (style == STYLE_BERKELEY) printf(" "); for (j = 0; j < tb->col; j++) { str = (tb->tbl[j][i] != NULL ? tb->tbl[j][i] : ""); if (style == STYLE_SYSV && j == 0) printf("%-*s", tb->width[j], str); else if (style == STYLE_BERKELEY && j == tb->col - 1) printf("%s", str); else printf("%*s", tb->width[j], str); if (j == tb->col -1) putchar('\n'); else printf(" "); } } for (i = 0; i < tb->col; i++) { for (j = 0; j < tb->row; j++) { if (tb->tbl[i][j]) free(tb->tbl[i][j]); } free(tb->tbl[i]); } free(tb->tbl); free(tb->width); free(tb); tb = NULL; } #define USAGE_MESSAGE "\ Usage: %s [options] file ...\n\ Display sizes of ELF sections.\n\n\ Options:\n\ --format=format Display output in specified format. Supported\n\ values are `berkeley' and `sysv'.\n\ --help Display this help message and exit.\n\ --radix=radix Display numeric values in the specified radix.\n\ Supported values are: 8, 10 and 16.\n\ --totals Show cumulative totals of section sizes.\n\ --version Display a version identifier and exit.\n\ -A Equivalent to `--format=sysv'.\n\ -B Equivalent to `--format=berkeley'.\n\ -V Equivalent to `--version'.\n\ -d Equivalent to `--radix=10'.\n\ -h Same as option --help.\n\ -o Equivalent to `--radix=8'.\n\ -t Equivalent to option --totals.\n\ -x Equivalent to `--radix=16'.\n" static void usage(void) { (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } static void show_version(void) { (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); exit(EXIT_SUCCESS); } Index: stable/11/contrib/elftoolchain/strings/strings.c =================================================================== --- stable/11/contrib/elftoolchain/strings/strings.c (revision 367465) +++ stable/11/contrib/elftoolchain/strings/strings.c (revision 367466) @@ -1,448 +1,450 @@ /*- * Copyright (c) 2007 S.Sam Arun Raj * 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 #include #include #include #include #include #include "_elftc.h" -ELFTC_VCSID("$Id: strings.c 3571 2017-09-14 02:04:50Z emaste $"); +ELFTC_VCSID("$Id: strings.c 3648 2018-11-22 23:26:43Z emaste $"); enum radix_style { RADIX_DECIMAL, RADIX_HEX, RADIX_OCTAL }; enum encoding_style { ENCODING_7BIT, ENCODING_8BIT, ENCODING_16BIT_BIG, ENCODING_16BIT_LITTLE, ENCODING_32BIT_BIG, ENCODING_32BIT_LITTLE }; #define PRINTABLE(c) \ - ((c) >= 0 && (c) <= 255 && \ + ((c) >= 0 && (c) <= 255 && \ ((c) == '\t' || isprint((c)) || \ (encoding == ENCODING_8BIT && (c) > 127))) static int encoding_size, entire_file, show_filename, show_loc; static enum encoding_style encoding; static enum radix_style radix; static intmax_t min_len; static struct option strings_longopts[] = { { "all", no_argument, NULL, 'a'}, { "bytes", required_argument, NULL, 'n'}, { "encoding", required_argument, NULL, 'e'}, { "help", no_argument, NULL, 'h'}, { "print-file-name", no_argument, NULL, 'f'}, { "radix", required_argument, NULL, 't'}, { "version", no_argument, NULL, 'v'}, { NULL, 0, NULL, 0 } }; -long getcharacter(void); +int getcharacter(FILE *, long *); int handle_file(const char *); -int handle_elf(const char *, int); -int handle_binary(const char *, int); -int find_strings(const char *, off_t, off_t); +int handle_elf(const char *, FILE *); +int handle_binary(const char *, FILE *, size_t); +int find_strings(const char *, FILE *, off_t, off_t); void show_version(void); void usage(void); /* * strings(1) extracts text(contiguous printable characters) * from elf and binary files. */ int main(int argc, char **argv) { int ch, rc; rc = 0; min_len = 0; encoding_size = 1; if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "ELF library initialization failed: %s", elf_errmsg(-1)); while ((ch = getopt_long(argc, argv, "1234567890ae:fhn:ot:Vv", - strings_longopts, NULL)) != -1) - switch((char)ch) { + strings_longopts, NULL)) != -1) { + switch ((char)ch) { case 'a': entire_file = 1; break; case 'e': if (*optarg == 's') { encoding = ENCODING_7BIT; } else if (*optarg == 'S') { encoding = ENCODING_8BIT; } else if (*optarg == 'b') { encoding = ENCODING_16BIT_BIG; encoding_size = 2; } else if (*optarg == 'B') { encoding = ENCODING_32BIT_BIG; encoding_size = 4; } else if (*optarg == 'l') { encoding = ENCODING_16BIT_LITTLE; encoding_size = 2; } else if (*optarg == 'L') { encoding = ENCODING_32BIT_LITTLE; encoding_size = 4; } else usage(); /* NOTREACHED */ break; case 'f': show_filename = 1; break; case 'n': min_len = strtoimax(optarg, (char**)NULL, 10); if (min_len <= 0) errx(EX_USAGE, "option -n should specify a " "positive decimal integer."); break; case 'o': show_loc = 1; radix = RADIX_OCTAL; break; case 't': show_loc = 1; if (*optarg == 'd') radix = RADIX_DECIMAL; else if (*optarg == 'o') radix = RADIX_OCTAL; else if (*optarg == 'x') radix = RADIX_HEX; else usage(); /* NOTREACHED */ break; case 'v': case 'V': show_version(); /* NOTREACHED */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': min_len *= 10; min_len += ch - '0'; break; case 'h': case '?': default: usage(); /* NOTREACHED */ } + } argc -= optind; argv += optind; - if (!min_len) + if (min_len == 0) min_len = 4; - if (!*argv) - rc = find_strings("{standard input}", 0, 0); - else while (*argv) { + if (*argv == NULL) + rc = find_strings("{standard input}", stdin, 0, 0); + else while (*argv != NULL) { if (handle_file(*argv) != 0) rc = 1; argv++; } return (rc); } int handle_file(const char *name) { - int fd, rt; + FILE *pfile; + int rt; if (name == NULL) return (1); - if (freopen(name, "rb", stdin) == NULL) { + pfile = fopen(name, "rb"); + if (pfile == NULL) { warnx("'%s': %s", name, strerror(errno)); return (1); } - fd = fileno(stdin); - if (fd < 0) - return (1); - rt = handle_elf(name, fd); + rt = handle_elf(name, pfile); + fclose(pfile); return (rt); } /* * Files not understood by handle_elf, will be passed off here and will * treated as a binary file. This would include text file, core dumps ... */ int -handle_binary(const char *name, int fd) +handle_binary(const char *name, FILE *pfile, size_t size) { - struct stat buf; - memset(&buf, 0, sizeof(struct stat)); - (void) lseek(fd, (off_t)0, SEEK_SET); - if (!fstat(fd, &buf)) - return (find_strings(name, (off_t)0, buf.st_size)); - return (1); + (void)fseeko(pfile, 0, SEEK_SET); + return (find_strings(name, pfile, 0, size)); } /* * Will analyse a file to see if it ELF, other files including ar(1), * core dumps are passed off and treated as flat binary files. Unlike * GNU size in FreeBSD this routine will not treat ELF object from * different archs as flat binary files(has to overridden using -a). */ int -handle_elf(const char *name, int fd) +handle_elf(const char *name, FILE *pfile) { + struct stat buf; GElf_Ehdr elfhdr; GElf_Shdr shdr; Elf *elf; Elf_Scn *scn; - int rc; + int rc, fd; rc = 0; + fd = fileno(pfile); + if (fstat(fd, &buf) < 0) + return (1); + /* If entire file is chosen, treat it as a binary file */ if (entire_file) - return (handle_binary(name, fd)); + return (handle_binary(name, pfile, buf.st_size)); - (void) lseek(fd, (off_t)0, SEEK_SET); + (void)lseek(fd, 0, SEEK_SET); elf = elf_begin(fd, ELF_C_READ, NULL); if (elf_kind(elf) != ELF_K_ELF) { - (void) elf_end(elf); - return (handle_binary(name, fd)); + (void)elf_end(elf); + return (handle_binary(name, pfile, buf.st_size)); } if (gelf_getehdr(elf, &elfhdr) == NULL) { - (void) elf_end(elf); + (void)elf_end(elf); warnx("%s: ELF file could not be processed", name); return (1); } if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { - (void) elf_end(elf); - return (handle_binary(name, fd)); + (void)elf_end(elf); + return (handle_binary(name, pfile, buf.st_size)); } else { scn = NULL; while ((scn = elf_nextscn(elf, scn)) != NULL) { if (gelf_getshdr(scn, &shdr) == NULL) continue; if (shdr.sh_type != SHT_NOBITS && (shdr.sh_flags & SHF_ALLOC) != 0) { - rc = find_strings(name, shdr.sh_offset, + rc = find_strings(name, pfile, shdr.sh_offset, shdr.sh_size); } } } - (void) elf_end(elf); + (void)elf_end(elf); return (rc); } /* * Retrieves a character from input stream based on the encoding * type requested. */ -long -getcharacter(void) +int +getcharacter(FILE *pfile, long *rt) { - long rt; - int i; - char buf[4], c; + int i, c; + char buf[4]; - rt = EOF; for(i = 0; i < encoding_size; i++) { - c = getc(stdin); - if (feof(stdin)) - return (EOF); + c = getc(pfile); + if (c == EOF) + return (-1); buf[i] = c; } - switch(encoding) { + switch (encoding) { case ENCODING_7BIT: case ENCODING_8BIT: - rt = buf[0]; + *rt = buf[0]; break; case ENCODING_16BIT_BIG: - rt = (buf[0] << 8) | buf[1]; + *rt = (buf[0] << 8) | buf[1]; break; case ENCODING_16BIT_LITTLE: - rt = buf[0] | (buf[1] << 8); - break; + *rt = buf[0] | (buf[1] << 8); + break; case ENCODING_32BIT_BIG: - rt = ((long) buf[0] << 24) | ((long) buf[1] << 16) | - ((long) buf[2] << 8) | buf[3]; - break; + *rt = ((long) buf[0] << 24) | ((long) buf[1] << 16) | + ((long) buf[2] << 8) | buf[3]; + break; case ENCODING_32BIT_LITTLE: - rt = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | - ((long) buf[3] << 24); - break; + *rt = buf[0] | ((long) buf[1] << 8) | ((long) buf[2] << 16) | + ((long) buf[3] << 24); + break; + default: + return (-1); } - return (rt); + + return (0); } /* - * Input stream stdin is read until the end of file is reached or until + * Input stream is read until the end of file is reached or until * the section size is reached in case of ELF files. Contiguous * characters of >= min_size(default 4) will be displayed. */ int -find_strings(const char *name, off_t offset, off_t size) +find_strings(const char *name, FILE *pfile, off_t offset, off_t size) { off_t cur_off, start_off; char *obuf; long c; int i; if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { - (void) fprintf(stderr, "Unable to allocate memory: %s\n", - strerror(errno)); + fprintf(stderr, "Unable to allocate memory: %s\n", + strerror(errno)); return (1); } - (void) fseeko(stdin, offset, SEEK_SET); + (void)fseeko(pfile, offset, SEEK_SET); cur_off = offset; start_off = 0; - while(1) { + for (;;) { if ((offset + size) && (cur_off >= offset + size)) break; start_off = cur_off; - memset(obuf, 0, min_len+1); + memset(obuf, 0, min_len + 1); for(i = 0; i < min_len; i++) { - c = getcharacter(); - if (c == EOF && feof(stdin)) + if (getcharacter(pfile, &c) < 0) goto _exit1; - if (PRINTABLE(c)) { - obuf[i] = c; - obuf[i+1] = 0; - cur_off += encoding_size; - } else { + if (PRINTABLE(c)) { + obuf[i] = c; + obuf[i + 1] = 0; + cur_off += encoding_size; + } else { if (encoding == ENCODING_8BIT && (uint8_t)c > 127) { - obuf[i] = c; - obuf[i+1] = 0; - cur_off += encoding_size; - continue; - } - cur_off += encoding_size; - break; - } + obuf[i] = c; + obuf[i + 1] = 0; + cur_off += encoding_size; + continue; + } + cur_off += encoding_size; + break; + } } if (i >= min_len && ((cur_off <= offset + size) || !(offset + size))) { if (show_filename) - printf ("%s: ", name); + printf("%s: ", name); if (show_loc) { - switch(radix) { + switch (radix) { case RADIX_DECIMAL: - (void) printf("%7ju ", - (uintmax_t)start_off); + printf("%7ju ", (uintmax_t)start_off); break; case RADIX_HEX: - (void) printf("%7jx ", - (uintmax_t)start_off); + printf("%7jx ", (uintmax_t)start_off); break; case RADIX_OCTAL: - (void) printf("%7jo ", - (uintmax_t)start_off); + printf("%7jo ", (uintmax_t)start_off); break; } } printf("%s", obuf); - while(1) { + for (;;) { if ((offset + size) && (cur_off >= offset + size)) break; - c = getcharacter(); + if (getcharacter(pfile, &c) < 0) + break; cur_off += encoding_size; if (encoding == ENCODING_8BIT && (uint8_t)c > 127) { - putchar(c); - continue; - } - if (!PRINTABLE(c) || c == EOF) + putchar(c); + continue; + } + if (!PRINTABLE(c)) break; putchar(c); } putchar('\n'); } } _exit1: free(obuf); return (0); } #define USAGE_MESSAGE "\ Usage: %s [options] [file...]\n\ Print contiguous sequences of printable characters.\n\n\ Options:\n\ -a | --all Scan the entire file for strings.\n\ -e ENC | --encoding=ENC Select the character encoding to use.\n\ -f | --print-file-name Print the file name before each string.\n\ -h | --help Print a help message and exit.\n\ -n N | --bytes=N | -N Print sequences with 'N' or more characters.\n\ -o Print offsets in octal.\n\ -t R | --radix=R Print offsets using the radix named by 'R'.\n\ -v | --version Print a version identifier and exit.\n" void usage(void) { - (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); + + fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); exit(EXIT_FAILURE); } void show_version(void) { - (void) printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); + + printf("%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); exit(EXIT_SUCCESS); } Index: stable/11/lib/libelf/Makefile =================================================================== --- stable/11/lib/libelf/Makefile (revision 367465) +++ stable/11/lib/libelf/Makefile (revision 367466) @@ -1,193 +1,203 @@ # $FreeBSD$ PACKAGE=lib${LIB} SHLIBDIR?= /lib .include ELFTCDIR=${SRCTOP}/contrib/elftoolchain SRCDIR= ${ELFTCDIR}/libelf .PATH: ${SRCDIR} 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_open.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_chdr.c \ gelf_checksum.c \ gelf_dyn.c \ gelf_ehdr.c \ gelf_getclass.c \ gelf_fsize.c \ gelf_mips64el.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_chdr.c \ libelf_checksum.c \ libelf_data.c \ libelf_ehdr.c \ + libelf_elfmachine.c \ libelf_extended.c \ libelf_memory.c \ libelf_open.c \ libelf_phdr.c \ libelf_shdr.c \ libelf_xlate.c \ ${GENSRCS} INCS= libelf.h gelf.h # This same hack is in lib/libdwarf/Makefile and usr.bin/readelf/Makefile # We need to link against the correct version of these files. One # solution is to include ../../sys in the include path. This causes # problems when a header file in sys depends on a file in another # part of the tree, e.g. a machine dependent header. # SRCS+= sys/elf32.h sys/elf64.h sys/elf_common.h + +# Allow bootstrapping elftoolchain on Linux: +.if defined(BOOTSTRAPPING) && ${.MAKE.OS} == "Linux" +native-elf-format.h: + ${ELFTCDIR}/common/native-elf-format > ${.TARGET} || rm ${.TARGET} +SRCS+= native-elf-format.h +.endif GENSRCS= libelf_fsize.c libelf_msize.c libelf_convert.c CLEANFILES= ${GENSRCS} CLEANDIRS= sys CFLAGS+= -I. -I${SRCDIR} -I${ELFTCDIR}/common sys/elf32.h sys/elf64.h sys/elf_common.h: ${SRCTOP}/sys/${.TARGET} .NOMETA mkdir -p ${.OBJDIR}/sys ln -sf ${.ALLSRC} ${.TARGET} SHLIB_MAJOR= 2 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_open.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 \ elf_open.3 elf_openmemory.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 VERSION_MAP= ${SRCDIR}/Version.map 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 # Keep the .SUFFIXES line after the include of bsd.lib.mk .SUFFIXES: .m4 .c .m4.c: m4 -D SRCDIR=${SRCDIR} ${M4FLAGS} ${.IMPSRC} > ${.TARGET} Index: stable/11/lib/libelftc/Makefile =================================================================== --- stable/11/lib/libelftc/Makefile (revision 367465) +++ stable/11/lib/libelftc/Makefile (revision 367466) @@ -1,54 +1,67 @@ # $FreeBSD$ .include PACKAGE=lib${LIB} INTERNALLIB= ELFTCDIR= ${SRCTOP}/contrib/elftoolchain .PATH: ${ELFTCDIR}/libelftc LIB= elftc SRCS= elftc_bfdtarget.c \ elftc_copyfile.c \ elftc_demangle.c \ elftc_reloc_type_str.c \ elftc_set_timestamps.c \ elftc_string_table.c \ elftc_timestamp.c \ elftc_version.c \ libelftc_bfdtarget.c \ libelftc_dem_arm.c \ libelftc_dem_gnu2.c \ libelftc_dem_gnu3.c \ libelftc_hash.c \ libelftc_vstr.c INCS= libelftc.h CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common MAN+= elftc.3 \ elftc_bfd_find_target.3 \ elftc_copyfile.3 \ elftc_demangle.3 \ elftc_reloc_type_str.3 \ elftc_set_timestamps.3 \ elftc_timestamp.3 \ elftc_string_table_create.3 \ elftc_version.3 +MLINKS+= \ + elftc_bfd_find_target.3 elftc_bfd_target_class.3 \ + elftc_bfd_find_target.3 elftc_bfd_target_byteorder.3 \ + elftc_bfd_find_target.3 elftc_bfd_target_flavor.3 \ + elftc_bfd_find_target.3 elftc_bfd_target_machine.3 \ + elftc_string_table_create.3 elftc_string_table_destroy.3 \ + elftc_string_table_create.3 elftc_string_table_from_section.3 \ + elftc_string_table_create.3 elftc_string_table_image.3 \ + elftc_string_table_create.3 elftc_string_table_insert.3 \ + elftc_string_table_create.3 elftc_string_table_lookup.3 \ + elftc_string_table_create.3 elftc_string_table_remove.3 \ + elftc_string_table_create.3 elftc_string_table_to_string.3 + # This same hack is in lib/libelf/Makefile and usr.bin/readelf/Makefile # We need to link against the correct version of these files. One # solution is to include ../../sys in the include path. This causes # problems when a header file in sys depends on a file in another # part of the tree, e.g. a machine dependent header. # SRCS+= sys/elf_common.h CLEANDIRS= sys CFLAGS+= -I. sys/elf_common.h: ${SRCTOP}/sys/${.TARGET} .NOMETA mkdir -p ${.OBJDIR}/sys ln -sf ${.ALLSRC} ${.TARGET} .include Index: stable/11/lib/libelftc/elftc_version.c =================================================================== --- stable/11/lib/libelftc/elftc_version.c (revision 367465) +++ stable/11/lib/libelftc/elftc_version.c (revision 367466) @@ -1,10 +1,10 @@ /* $FreeBSD$ */ #include #include const char * elftc_version(void) { - return "elftoolchain r3614M"; + return "elftoolchain r3769"; } Index: stable/11/sys/sys/elf_common.h =================================================================== --- stable/11/sys/sys/elf_common.h (revision 367465) +++ stable/11/sys/sys/elf_common.h (revision 367466) @@ -1,1371 +1,1396 @@ /*- * Copyright (c) 2017 Dell EMC * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien * Copyright (c) 1998 John D. Polstra. * 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. * * $FreeBSD$ */ #ifndef _SYS_ELF_COMMON_H_ #define _SYS_ELF_COMMON_H_ 1 /* * ELF definitions that are independent of architecture or word size. */ /* * Note header. The ".note" section contains an array of notes. Each * begins with this header, aligned to a word boundary. Immediately * following the note header is n_namesz bytes of name, padded to the * next word boundary. Then comes n_descsz bytes of descriptor, again * padded to a word boundary. The values of n_namesz and n_descsz do * not include the padding. */ typedef struct { u_int32_t n_namesz; /* Length of name. */ u_int32_t n_descsz; /* Length of descriptor. */ u_int32_t n_type; /* Type of this note. */ } Elf_Note; /* * Option kinds. */ #define ODK_NULL 0 /* undefined */ #define ODK_REGINFO 1 /* register usage info */ #define ODK_EXCEPTIONS 2 /* exception processing info */ #define ODK_PAD 3 /* section padding */ #define ODK_HWPATCH 4 /* hardware patch applied */ #define ODK_FILL 5 /* fill value used by the linker */ #define ODK_TAGS 6 /* reserved space for tools */ #define ODK_HWAND 7 /* hardware AND patch applied */ #define ODK_HWOR 8 /* hardware OR patch applied */ #define ODK_GP_GROUP 9 /* GP group for text/data sections */ #define ODK_IDENT 10 /* ID information */ #define ODK_PAGESIZE 11 /* page size information */ /* * ODK_EXCEPTIONS info field masks. */ #define OEX_FPU_MIN 0x0000001f /* min FPU exception required */ #define OEX_FPU_MAX 0x00001f00 /* max FPU exception allowed */ #define OEX_PAGE0 0x00010000 /* page zero must be mapped */ #define OEX_SMM 0x00020000 /* run in sequential memory mode */ #define OEX_PRECISEFP 0x00040000 /* run in precise FP exception mode */ #define OEX_DISMISS 0x00080000 /* dismiss invalid address traps */ /* * ODK_PAD info field masks. */ #define OPAD_PREFIX 0x0001 #define OPAD_POSTFIX 0x0002 #define OPAD_SYMBOL 0x0004 /* * ODK_HWPATCH info field masks. */ #define OHW_R4KEOP 0x00000001 /* patch for R4000 branch at end-of-page bug */ #define OHW_R8KPFETCH 0x00000002 /* R8000 prefetch bug may occur */ #define OHW_R5KEOP 0x00000004 /* patch for R5000 branch at end-of-page bug */ #define OHW_R5KCVTL 0x00000008 /* R5000 cvt.[ds].l bug: clean == 1 */ #define OHW_R10KLDL 0x00000010UL /* need patch for R10000 misaligned load */ /* * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks. */ #define OHWA0_R4KEOP_CHECKED 0x00000001 /* object checked for R4000 end-of-page bug */ #define OHWA0_R4KEOP_CLEAN 0x00000002 /* object verified clean for R4000 end-of-page bug */ #define OHWO0_FIXADE 0x00000001 /* object requires call to fixade */ /* * ODK_IDENT/ODK_GP_GROUP info field masks. */ #define OGP_GROUP 0x0000ffff /* GP group number */ #define OGP_SELF 0x00010000 /* GP group is self-contained */ /* * The header for GNU-style hash sections. */ typedef struct { u_int32_t gh_nbuckets; /* Number of hash buckets. */ u_int32_t gh_symndx; /* First visible symbol in .dynsym. */ u_int32_t gh_maskwords; /* #maskwords used in bloom filter. */ u_int32_t gh_shift2; /* Bloom filter shift count. */ } Elf_GNU_Hash_Header; /* Indexes into the e_ident array. Keep synced with http://www.sco.com/developers/gabi/latest/ch4.eheader.html */ #define EI_MAG0 0 /* Magic number, byte 0. */ #define EI_MAG1 1 /* Magic number, byte 1. */ #define EI_MAG2 2 /* Magic number, byte 2. */ #define EI_MAG3 3 /* Magic number, byte 3. */ #define EI_CLASS 4 /* Class of machine. */ #define EI_DATA 5 /* Data format. */ #define EI_VERSION 6 /* ELF format version. */ #define EI_OSABI 7 /* Operating system / ABI identification */ #define EI_ABIVERSION 8 /* ABI version */ #define OLD_EI_BRAND 8 /* Start of architecture identification. */ #define EI_PAD 9 /* Start of padding (per SVR4 ABI). */ #define EI_NIDENT 16 /* Size of e_ident array. */ /* Values for the magic number bytes. */ #define ELFMAG0 0x7f #define ELFMAG1 'E' #define ELFMAG2 'L' #define ELFMAG3 'F' #define ELFMAG "\177ELF" /* magic string */ #define SELFMAG 4 /* magic string size */ /* Values for e_ident[EI_VERSION] and e_version. */ #define EV_NONE 0 #define EV_CURRENT 1 /* Values for e_ident[EI_CLASS]. */ #define ELFCLASSNONE 0 /* Unknown class. */ #define ELFCLASS32 1 /* 32-bit architecture. */ #define ELFCLASS64 2 /* 64-bit architecture. */ /* Values for e_ident[EI_DATA]. */ #define ELFDATANONE 0 /* Unknown data format. */ #define ELFDATA2LSB 1 /* 2's complement little-endian. */ #define ELFDATA2MSB 2 /* 2's complement big-endian. */ /* Values for e_ident[EI_OSABI]. */ #define ELFOSABI_NONE 0 /* UNIX System V ABI */ #define ELFOSABI_HPUX 1 /* HP-UX operating system */ #define ELFOSABI_NETBSD 2 /* NetBSD */ #define ELFOSABI_LINUX 3 /* GNU/Linux */ #define ELFOSABI_HURD 4 /* GNU/Hurd */ #define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */ #define ELFOSABI_SOLARIS 6 /* Solaris */ #define ELFOSABI_AIX 7 /* AIX */ #define ELFOSABI_IRIX 8 /* IRIX */ #define ELFOSABI_FREEBSD 9 /* FreeBSD */ #define ELFOSABI_TRU64 10 /* TRU64 UNIX */ #define ELFOSABI_MODESTO 11 /* Novell Modesto */ #define ELFOSABI_OPENBSD 12 /* OpenBSD */ #define ELFOSABI_OPENVMS 13 /* Open VMS */ #define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */ #define ELFOSABI_AROS 15 /* Amiga Research OS */ #define ELFOSABI_FENIXOS 16 /* FenixOS */ #define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */ #define ELFOSABI_ARM_AEABI 64 /* ARM EABI */ #define ELFOSABI_ARM 97 /* ARM */ #define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ #define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */ #define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */ #define ELFOSABI_GNU ELFOSABI_LINUX /* e_ident */ #define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \ (ehdr).e_ident[EI_MAG3] == ELFMAG3) /* Values for e_type. */ #define ET_NONE 0 /* Unknown type. */ #define ET_REL 1 /* Relocatable. */ #define ET_EXEC 2 /* Executable. */ #define ET_DYN 3 /* Shared object. */ #define ET_CORE 4 /* Core file. */ #define ET_LOOS 0xfe00 /* First operating system specific. */ #define ET_HIOS 0xfeff /* Last operating system-specific. */ #define ET_LOPROC 0xff00 /* First processor-specific. */ #define ET_HIPROC 0xffff /* Last processor-specific. */ /* Values for e_machine. */ #define EM_NONE 0 /* Unknown machine. */ #define EM_M32 1 /* AT&T WE32100. */ #define EM_SPARC 2 /* Sun SPARC. */ #define EM_386 3 /* Intel i386. */ #define EM_68K 4 /* Motorola 68000. */ #define EM_88K 5 /* Motorola 88000. */ #define EM_IAMCU 6 /* Intel MCU. */ #define EM_860 7 /* Intel i860. */ #define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */ #define EM_S370 9 /* IBM System/370. */ #define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */ #define EM_PARISC 15 /* HP PA-RISC. */ #define EM_VPP500 17 /* Fujitsu VPP500. */ #define EM_SPARC32PLUS 18 /* SPARC v8plus. */ #define EM_960 19 /* Intel 80960. */ #define EM_PPC 20 /* PowerPC 32-bit. */ #define EM_PPC64 21 /* PowerPC 64-bit. */ #define EM_S390 22 /* IBM System/390. */ #define EM_V800 36 /* NEC V800. */ #define EM_FR20 37 /* Fujitsu FR20. */ #define EM_RH32 38 /* TRW RH-32. */ #define EM_RCE 39 /* Motorola RCE. */ #define EM_ARM 40 /* ARM. */ #define EM_SH 42 /* Hitachi SH. */ #define EM_SPARCV9 43 /* SPARC v9 64-bit. */ #define EM_TRICORE 44 /* Siemens TriCore embedded processor. */ #define EM_ARC 45 /* Argonaut RISC Core. */ #define EM_H8_300 46 /* Hitachi H8/300. */ #define EM_H8_300H 47 /* Hitachi H8/300H. */ #define EM_H8S 48 /* Hitachi H8S. */ #define EM_H8_500 49 /* Hitachi H8/500. */ #define EM_IA_64 50 /* Intel IA-64 Processor. */ #define EM_MIPS_X 51 /* Stanford MIPS-X. */ #define EM_COLDFIRE 52 /* Motorola ColdFire. */ #define EM_68HC12 53 /* Motorola M68HC12. */ #define EM_MMA 54 /* Fujitsu MMA. */ #define EM_PCP 55 /* Siemens PCP. */ #define EM_NCPU 56 /* Sony nCPU. */ #define EM_NDR1 57 /* Denso NDR1 microprocessor. */ #define EM_STARCORE 58 /* Motorola Star*Core processor. */ #define EM_ME16 59 /* Toyota ME16 processor. */ #define EM_ST100 60 /* STMicroelectronics ST100 processor. */ #define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */ #define EM_X86_64 62 /* Advanced Micro Devices x86-64 */ #define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */ #define EM_PDSP 63 /* Sony DSP Processor. */ #define EM_FX66 66 /* Siemens FX66 microcontroller. */ #define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 microcontroller. */ #define EM_ST7 68 /* STmicroelectronics ST7 8-bit microcontroller. */ #define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */ #define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */ #define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */ #define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */ #define EM_SVX 73 /* Silicon Graphics SVx. */ #define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */ #define EM_VAX 75 /* Digital VAX. */ #define EM_CRIS 76 /* Axis Communications 32-bit embedded processor. */ #define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor. */ #define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */ #define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */ #define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */ #define EM_HUANY 81 /* Harvard University machine-independent object files. */ #define EM_PRISM 82 /* SiTera Prism. */ #define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */ #define EM_FR30 84 /* Fujitsu FR30. */ #define EM_D10V 85 /* Mitsubishi D10V. */ #define EM_D30V 86 /* Mitsubishi D30V. */ #define EM_V850 87 /* NEC v850. */ #define EM_M32R 88 /* Mitsubishi M32R. */ #define EM_MN10300 89 /* Matsushita MN10300. */ #define EM_MN10200 90 /* Matsushita MN10200. */ #define EM_PJ 91 /* picoJava. */ #define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */ #define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */ #define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */ #define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor. */ #define EM_NS32K 97 /* National Semiconductor 32000 series. */ #define EM_TPC 98 /* Tenor Network TPC processor. */ #define EM_SNP1K 99 /* Trebia SNP 1000 processor. */ #define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */ #define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */ #define EM_MAX 102 /* MAX Processor. */ #define EM_CR 103 /* National Semiconductor CompactRISC microprocessor. */ #define EM_F2MC16 104 /* Fujitsu F2MC16. */ #define EM_MSP430 105 /* Texas Instruments embedded microcontroller msp430. */ #define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */ #define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */ #define EM_SEP 108 /* Sharp embedded microprocessor. */ #define EM_ARCA 109 /* Arca RISC Microprocessor. */ #define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */ #define EM_AARCH64 183 /* AArch64 (64-bit ARM) */ #define EM_RISCV 243 /* RISC-V */ /* Non-standard or deprecated. */ #define EM_486 6 /* Intel i486. */ #define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */ #define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */ #define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */ /** * e_flags */ #define EF_ARM_RELEXEC 0x1 #define EF_ARM_HASENTRY 0x2 #define EF_ARM_SYMSARESORTED 0x4 #define EF_ARM_DYNSYMSUSESEGIDX 0x8 #define EF_ARM_MAPSYMSFIRST 0x10 #define EF_ARM_LE8 0x00400000 #define EF_ARM_BE8 0x00800000 #define EF_ARM_EABIMASK 0xFF000000 #define EF_ARM_EABI_UNKNOWN 0x00000000 #define EF_ARM_EABI_VER1 0x01000000 #define EF_ARM_EABI_VER2 0x02000000 #define EF_ARM_EABI_VER3 0x03000000 #define EF_ARM_EABI_VER4 0x04000000 #define EF_ARM_EABI_VER5 0x05000000 #define EF_ARM_INTERWORK 0x00000004 #define EF_ARM_APCS_26 0x00000008 #define EF_ARM_APCS_FLOAT 0x00000010 #define EF_ARM_PIC 0x00000020 #define EF_ARM_ALIGN8 0x00000040 #define EF_ARM_NEW_ABI 0x00000080 #define EF_ARM_OLD_ABI 0x00000100 #define EF_ARM_ABI_FLOAT_SOFT 0x00000200 #define EF_ARM_SOFT_FLOAT EF_ARM_ABI_FLOAT_SOFT /* Pre-V5 ABI name */ #define EF_ARM_ABI_FLOAT_HARD 0x00000400 #define EF_ARM_VFP_FLOAT EF_ARM_ABI_FLOAT_HARD /* Pre-V5 ABI name */ #define EF_ARM_MAVERICK_FLOAT 0x00000800 #define EF_MIPS_NOREORDER 0x00000001 #define EF_MIPS_PIC 0x00000002 /* Contains PIC code */ #define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */ #define EF_MIPS_UCODE 0x00000010 #define EF_MIPS_ABI2 0x00000020 /* N32 */ #define EF_MIPS_OPTIONS_FIRST 0x00000080 #define EF_MIPS_ARCH_ASE 0x0F000000 /* Architectural extensions */ #define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* MDMX multimedia extension */ #define EF_MIPS_ARCH_ASE_M16 0x04000000 /* MIPS-16 ISA extensions */ #define EF_MIPS_ARCH 0xF0000000 /* Architecture field */ #define EF_PPC_EMB 0x80000000 #define EF_PPC_RELOCATABLE 0x00010000 #define EF_PPC_RELOCATABLE_LIB 0x00008000 +#define EF_RISCV_RVC 0x00000001 +#define EF_RISCV_FLOAT_ABI_MASK 0x00000006 +#define EF_RISCV_FLOAT_ABI_SOFT 0x00000000 +#define EF_RISCV_FLOAT_ABI_SINGLE 0x000002 +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x000004 +#define EF_RISCV_FLOAT_ABI_QUAD 0x00000006 +#define EF_RISCV_RVE 0x00000008 +#define EF_RISCV_TSO 0x00000010 + #define EF_SPARC_EXT_MASK 0x00ffff00 #define EF_SPARC_32PLUS 0x00000100 #define EF_SPARC_SUN_US1 0x00000200 #define EF_SPARC_HAL_R1 0x00000200 #define EF_SPARC_SUN_US3 0x00000800 #define EF_SPARCV9_MM 0x00000003 #define EF_SPARCV9_TSO 0x00000000 #define EF_SPARCV9_PSO 0x00000001 #define EF_SPARCV9_RMO 0x00000002 /* Special section indexes. */ #define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */ #define SHN_LORESERVE 0xff00 /* First of reserved range. */ #define SHN_LOPROC 0xff00 /* First processor-specific. */ #define SHN_HIPROC 0xff1f /* Last processor-specific. */ #define SHN_LOOS 0xff20 /* First operating system-specific. */ #define SHN_FBSD_CACHED SHN_LOOS /* Transient, for sys/kern/link_elf_obj linker only: Cached global in local symtab. */ #define SHN_HIOS 0xff3f /* Last operating system-specific. */ #define SHN_ABS 0xfff1 /* Absolute values. */ #define SHN_COMMON 0xfff2 /* Common data. */ #define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */ #define SHN_HIRESERVE 0xffff /* Last of reserved range. */ /* sh_type */ #define SHT_NULL 0 /* inactive */ #define SHT_PROGBITS 1 /* program defined information */ #define SHT_SYMTAB 2 /* symbol table section */ #define SHT_STRTAB 3 /* string table section */ #define SHT_RELA 4 /* relocation section with addends */ #define SHT_HASH 5 /* symbol hash table section */ #define SHT_DYNAMIC 6 /* dynamic section */ #define SHT_NOTE 7 /* note section */ #define SHT_NOBITS 8 /* no space section */ #define SHT_REL 9 /* relocation section - no addends */ #define SHT_SHLIB 10 /* reserved - purpose unknown */ #define SHT_DYNSYM 11 /* dynamic symbol table section */ #define SHT_INIT_ARRAY 14 /* Initialization function pointers. */ #define SHT_FINI_ARRAY 15 /* Termination function pointers. */ #define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */ #define SHT_GROUP 17 /* Section group. */ #define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */ #define SHT_LOOS 0x60000000 /* First of OS specific semantics */ #define SHT_LOSUNW 0x6ffffff4 #define SHT_SUNW_dof 0x6ffffff4 #define SHT_SUNW_cap 0x6ffffff5 #define SHT_GNU_ATTRIBUTES 0x6ffffff5 #define SHT_SUNW_SIGNATURE 0x6ffffff6 #define SHT_GNU_HASH 0x6ffffff6 #define SHT_GNU_LIBLIST 0x6ffffff7 #define SHT_SUNW_ANNOTATE 0x6ffffff7 #define SHT_SUNW_DEBUGSTR 0x6ffffff8 #define SHT_SUNW_DEBUG 0x6ffffff9 #define SHT_SUNW_move 0x6ffffffa #define SHT_SUNW_COMDAT 0x6ffffffb #define SHT_SUNW_syminfo 0x6ffffffc #define SHT_SUNW_verdef 0x6ffffffd #define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */ #define SHT_SUNW_verneed 0x6ffffffe #define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */ #define SHT_SUNW_versym 0x6fffffff #define SHT_GNU_versym 0x6fffffff /* Symbol version table */ #define SHT_HISUNW 0x6fffffff #define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ #define SHT_LOPROC 0x70000000 /* reserved range for processor */ #define SHT_X86_64_UNWIND 0x70000001 /* unwind information */ #define SHT_AMD64_UNWIND SHT_X86_64_UNWIND #define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */ #define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking pre-emption map. */ #define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility attributes. */ #define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */ #define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */ #define SHT_MIPS_LIBLIST 0x70000000 #define SHT_MIPS_MSYM 0x70000001 #define SHT_MIPS_CONFLICT 0x70000002 #define SHT_MIPS_GPTAB 0x70000003 #define SHT_MIPS_UCODE 0x70000004 #define SHT_MIPS_DEBUG 0x70000005 #define SHT_MIPS_REGINFO 0x70000006 #define SHT_MIPS_PACKAGE 0x70000007 #define SHT_MIPS_PACKSYM 0x70000008 #define SHT_MIPS_RELD 0x70000009 #define SHT_MIPS_IFACE 0x7000000b #define SHT_MIPS_CONTENT 0x7000000c #define SHT_MIPS_OPTIONS 0x7000000d #define SHT_MIPS_DELTASYM 0x7000001b #define SHT_MIPS_DELTAINST 0x7000001c #define SHT_MIPS_DELTACLASS 0x7000001d #define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */ #define SHT_MIPS_DELTADECL 0x7000001f #define SHT_MIPS_SYMBOL_LIB 0x70000020 #define SHT_MIPS_EVENTS 0x70000021 #define SHT_MIPS_TRANSLATE 0x70000022 #define SHT_MIPS_PIXIE 0x70000023 #define SHT_MIPS_XLATE 0x70000024 #define SHT_MIPS_XLATE_DEBUG 0x70000025 #define SHT_MIPS_WHIRL 0x70000026 #define SHT_MIPS_EH_REGION 0x70000027 #define SHT_MIPS_XLATE_OLD 0x70000028 #define SHT_MIPS_PDR_EXCEPTION 0x70000029 #define SHT_MIPS_ABIFLAGS 0x7000002a #define SHT_SPARC_GOTDATA 0x70000000 #define SHTORDERED #define SHT_HIPROC 0x7fffffff /* specific section header types */ #define SHT_LOUSER 0x80000000 /* reserved range for application */ #define SHT_HIUSER 0xffffffff /* specific indexes */ /* Flags for sh_flags. */ #define SHF_WRITE 0x1 /* Section contains writable data. */ #define SHF_ALLOC 0x2 /* Section occupies memory. */ #define SHF_EXECINSTR 0x4 /* Section contains instructions. */ #define SHF_MERGE 0x10 /* Section may be merged. */ #define SHF_STRINGS 0x20 /* Section contains strings. */ #define SHF_INFO_LINK 0x40 /* sh_info holds section index. */ #define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */ #define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */ #define SHF_GROUP 0x200 /* Member of section group. */ #define SHF_TLS 0x400 /* Section contains TLS data. */ #define SHF_COMPRESSED 0x800 /* Section contains compressed data. */ #define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */ #define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */ /* Flags for section groups. */ #define GRP_COMDAT 0x1 /* COMDAT semantics. */ /* * Flags / mask for .gnu.versym sections. */ #define VERSYM_VERSION 0x7fff #define VERSYM_HIDDEN 0x8000 /* Values for p_type. */ #define PT_NULL 0 /* Unused entry. */ #define PT_LOAD 1 /* Loadable segment. */ #define PT_DYNAMIC 2 /* Dynamic linking information segment. */ #define PT_INTERP 3 /* Pathname of interpreter. */ #define PT_NOTE 4 /* Auxiliary information. */ #define PT_SHLIB 5 /* Reserved (not used). */ #define PT_PHDR 6 /* Location of program header itself. */ #define PT_TLS 7 /* Thread local storage segment */ #define PT_LOOS 0x60000000 /* First OS-specific. */ #define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */ #define PT_GNU_EH_FRAME 0x6474e550 #define PT_GNU_STACK 0x6474e551 #define PT_GNU_RELRO 0x6474e552 #define PT_DUMP_DELTA 0x6fb5d000 /* va->pa map for kernel dumps (currently arm). */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */ #define PT_SUNWDTRACE 0x6ffffffc /* private */ #define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */ #define PT_HISUNW 0x6fffffff #define PT_HIOS 0x6fffffff /* Last OS-specific. */ #define PT_LOPROC 0x70000000 /* First processor-specific type. */ #define PT_ARM_ARCHEXT 0x70000000 /* ARM arch compat information. */ #define PT_ARM_EXIDX 0x70000001 /* ARM exception unwind tables. */ #define PT_MIPS_REGINFO 0x70000000 /* MIPS register usage info */ #define PT_MIPS_RTPROC 0x70000001 /* MIPS runtime procedure tbl */ #define PT_MIPS_OPTIONS 0x70000002 /* MIPS e_flags value*/ #define PT_MIPS_ABIFLAGS 0x70000003 /* MIPS fp mode */ #define PT_HIPROC 0x7fffffff /* Last processor-specific type. */ +#define PT_OPENBSD_RANDOMIZE 0x65A3DBE6 /* OpenBSD random data segment */ +#define PT_OPENBSD_WXNEEDED 0x65A3DBE7 /* OpenBSD EXEC/WRITE pages needed */ +#define PT_OPENBSD_BOOTDATA 0x65A41BE6 /* OpenBSD section for boot args */ + /* Values for p_flags. */ #define PF_X 0x1 /* Executable. */ #define PF_W 0x2 /* Writable. */ #define PF_R 0x4 /* Readable. */ #define PF_MASKOS 0x0ff00000 /* Operating system-specific. */ #define PF_MASKPROC 0xf0000000 /* Processor-specific. */ /* Extended program header index. */ #define PN_XNUM 0xffff /* Values for d_tag. */ #define DT_NULL 0 /* Terminating entry. */ #define DT_NEEDED 1 /* String table offset of a needed shared library. */ #define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */ #define DT_PLTGOT 3 /* Processor-dependent address. */ #define DT_HASH 4 /* Address of symbol hash table. */ #define DT_STRTAB 5 /* Address of string table. */ #define DT_SYMTAB 6 /* Address of symbol table. */ #define DT_RELA 7 /* Address of ElfNN_Rela relocations. */ #define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */ #define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */ #define DT_STRSZ 10 /* Size of string table. */ #define DT_SYMENT 11 /* Size of each symbol table entry. */ #define DT_INIT 12 /* Address of initialization function. */ #define DT_FINI 13 /* Address of finalization function. */ #define DT_SONAME 14 /* String table offset of shared object name. */ #define DT_RPATH 15 /* String table offset of library path. [sup] */ #define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */ #define DT_REL 17 /* Address of ElfNN_Rel relocations. */ #define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */ #define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */ #define DT_PLTREL 20 /* Type of relocation used for PLT. */ #define DT_DEBUG 21 /* Reserved (not used). */ #define DT_TEXTREL 22 /* Indicates there may be relocations in non-writable segments. [sup] */ #define DT_JMPREL 23 /* Address of PLT relocations. */ #define DT_BIND_NOW 24 /* [sup] */ #define DT_INIT_ARRAY 25 /* Address of the array of pointers to initialization functions */ #define DT_FINI_ARRAY 26 /* Address of the array of pointers to termination functions */ #define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of initialization functions. */ #define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of termination functions. */ #define DT_RUNPATH 29 /* String table offset of a null-terminated library search path string. */ #define DT_FLAGS 30 /* Object specific flag values. */ #define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING and less than DT_LOOS follow the rules for the interpretation of the d_un union as follows: even == 'd_ptr', odd == 'd_val' or none */ #define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to pre-initialization functions. */ #define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of pre-initialization functions. */ #define DT_MAXPOSTAGS 34 /* number of positive tags */ #define DT_LOOS 0x6000000d /* First OS-specific */ #define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */ #define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */ #define DT_SUNW_FILTER 0x6000000f /* symbol filter name */ #define DT_SUNW_CAP 0x60000010 /* hardware/software */ #define DT_SUNW_ASLR 0x60000023 /* ASLR control */ #define DT_HIOS 0x6ffff000 /* Last OS-specific */ /* * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the * Dyn.d_un.d_val field of the Elf*_Dyn structure. */ #define DT_VALRNGLO 0x6ffffd00 #define DT_GNU_PRELINKED 0x6ffffdf5 /* prelinking timestamp */ #define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* size of conflict section */ #define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* size of library list */ #define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */ #define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */ #define DT_MOVEENT 0x6ffffdfa /* move table entry size */ #define DT_MOVESZ 0x6ffffdfb /* move table size */ #define DT_FEATURE 0x6ffffdfc /* feature holder */ #define DT_FEATURE_1 DT_FEATURE #define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */ /* the following DT_* entry. */ /* See DF_P1_* definitions */ #define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */ #define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */ #define DT_VALRNGHI 0x6ffffdff /* * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the * Dyn.d_un.d_ptr field of the Elf*_Dyn structure. * * If any adjustment is made to the ELF object after it has been * built, these entries will need to be adjusted. */ #define DT_ADDRRNGLO 0x6ffffe00 #define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */ #define DT_TLSDESC_PLT 0x6ffffef6 /* loc. of PLT for tlsdesc resolver */ #define DT_TLSDESC_GOT 0x6ffffef7 /* loc. of GOT for tlsdesc resolver */ #define DT_GNU_CONFLICT 0x6ffffef8 /* address of conflict section */ #define DT_GNU_LIBLIST 0x6ffffef9 /* address of library list */ #define DT_CONFIG 0x6ffffefa /* configuration information */ #define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */ #define DT_AUDIT 0x6ffffefc /* object auditing */ #define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */ #define DT_MOVETAB 0x6ffffefe /* move table */ #define DT_SYMINFO 0x6ffffeff /* syminfo table */ #define DT_ADDRRNGHI 0x6ffffeff #define DT_VERSYM 0x6ffffff0 /* Address of versym section. */ #define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */ #define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */ #define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */ #define DT_VERDEF 0x6ffffffc /* Address of verdef section. */ #define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */ #define DT_VERNEED 0x6ffffffe /* Address of verneed section. */ #define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */ #define DT_LOPROC 0x70000000 /* First processor-specific type. */ #define DT_ARM_SYMTABSZ 0x70000001 #define DT_ARM_PREEMPTMAP 0x70000002 #define DT_SPARC_REGISTER 0x70000001 #define DT_DEPRECATED_SPARC_REGISTER 0x7000001 #define DT_MIPS_RLD_VERSION 0x70000001 #define DT_MIPS_TIME_STAMP 0x70000002 #define DT_MIPS_ICHECKSUM 0x70000003 #define DT_MIPS_IVERSION 0x70000004 #define DT_MIPS_FLAGS 0x70000005 #define DT_MIPS_BASE_ADDRESS 0x70000006 #define DT_MIPS_CONFLICT 0x70000008 #define DT_MIPS_LIBLIST 0x70000009 #define DT_MIPS_LOCAL_GOTNO 0x7000000a #define DT_MIPS_CONFLICTNO 0x7000000b #define DT_MIPS_LIBLISTNO 0x70000010 #define DT_MIPS_SYMTABNO 0x70000011 #define DT_MIPS_UNREFEXTNO 0x70000012 #define DT_MIPS_GOTSYM 0x70000013 #define DT_MIPS_HIPAGENO 0x70000014 #define DT_MIPS_RLD_MAP 0x70000016 #define DT_MIPS_DELTA_CLASS 0x70000017 #define DT_MIPS_DELTA_CLASS_NO 0x70000018 #define DT_MIPS_DELTA_INSTANCE 0x70000019 #define DT_MIPS_DELTA_INSTANCE_NO 0x7000001A #define DT_MIPS_DELTA_RELOC 0x7000001B #define DT_MIPS_DELTA_RELOC_NO 0x7000001C #define DT_MIPS_DELTA_SYM 0x7000001D #define DT_MIPS_DELTA_SYM_NO 0x7000001E #define DT_MIPS_DELTA_CLASSSYM 0x70000020 #define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 #define DT_MIPS_CXX_FLAGS 0x70000022 #define DT_MIPS_PIXIE_INIT 0x70000023 #define DT_MIPS_SYMBOL_LIB 0x70000024 #define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 #define DT_MIPS_LOCAL_GOTIDX 0x70000026 #define DT_MIPS_HIDDEN_GOTIDX 0x70000027 #define DT_MIPS_PROTECTED_GOTIDX 0x70000028 #define DT_MIPS_OPTIONS 0x70000029 #define DT_MIPS_INTERFACE 0x7000002A #define DT_MIPS_DYNSTR_ALIGN 0x7000002B #define DT_MIPS_INTERFACE_SIZE 0x7000002C #define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002D #define DT_MIPS_PERF_SUFFIX 0x7000002E #define DT_MIPS_COMPACT_SIZE 0x7000002F #define DT_MIPS_GP_VALUE 0x70000030 #define DT_MIPS_AUX_DYNAMIC 0x70000031 #define DT_MIPS_PLTGOT 0x70000032 #define DT_MIPS_RLD_OBJ_UPDATE 0x70000033 #define DT_MIPS_RWPLT 0x70000034 #define DT_PPC_GOT 0x70000000 #define DT_PPC_TLSOPT 0x70000001 #define DT_PPC64_GLINK 0x70000000 #define DT_PPC64_OPD 0x70000001 #define DT_PPC64_OPDSZ 0x70000002 #define DT_PPC64_TLSOPT 0x70000003 #define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */ #define DT_USED 0x7ffffffe /* ignored - same as needed */ #define DT_FILTER 0x7fffffff /* shared library filter name */ #define DT_HIPROC 0x7fffffff /* Last processor-specific type. */ /* Values for DT_FLAGS */ #define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may make reference to the $ORIGIN substitution string */ #define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */ #define DF_TEXTREL 0x0004 /* Indicates there may be relocations in non-writable segments. */ #define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should process all relocations for the object containing this entry before transferring control to the program. */ #define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or executable contains code using a static thread-local storage scheme. */ /* Values for DT_FLAGS_1 */ #define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */ #define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */ #define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */ #define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */ #define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */ #define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */ #define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */ #define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */ #define DF_1_PIE 0x08000000 /* Is position-independent executable */ /* Values for l_flags. */ #define LL_NONE 0x0 /* no flags */ #define LL_EXACT_MATCH 0x1 /* require an exact match */ #define LL_IGNORE_INT_VER 0x2 /* ignore version incompatibilities */ #define LL_REQUIRE_MINOR 0x4 #define LL_EXPORTS 0x8 #define LL_DELAY_LOAD 0x10 #define LL_DELTA 0x20 /* Values for n_type used in executables. */ #define NT_FREEBSD_ABI_TAG 1 #define NT_FREEBSD_NOINIT_TAG 2 #define NT_FREEBSD_ARCH_TAG 3 #define NT_FREEBSD_FEATURE_CTL 4 /* NT_FREEBSD_FEATURE_CTL desc[0] bits */ #define NT_FREEBSD_FCTL_ASLR_DISABLE 0x00000001 +#define NT_FREEBSD_FCTL_WXNEEDED 0x00000008 /* Values for n_type. Used in core files. */ #define NT_PRSTATUS 1 /* Process status. */ #define NT_FPREGSET 2 /* Floating point registers. */ #define NT_PRPSINFO 3 /* Process state info. */ #define NT_THRMISC 7 /* Thread miscellaneous info. */ #define NT_PROCSTAT_PROC 8 /* Procstat proc data. */ #define NT_PROCSTAT_FILES 9 /* Procstat files data. */ #define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */ #define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */ #define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */ #define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */ #define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ #define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ #define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */ #define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */ #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */ #define NT_ARM_VFP 0x400 /* ARM VFP registers */ /* GNU note types. */ #define NT_GNU_ABI_TAG 1 #define NT_GNU_HWCAP 2 #define NT_GNU_BUILD_ID 3 #define NT_GNU_GOLD_VERSION 4 #define NT_GNU_PROPERTY_TYPE_0 5 #define GNU_PROPERTY_LOPROC 0xc0000000 #define GNU_PROPERTY_HIPROC 0xdfffffff #define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 #define GNU_PROPERTY_X86_FEATURE_1_IBT 0x00000001 #define GNU_PROPERTY_X86_FEATURE_1_SHSTK 0x00000002 /* Symbol Binding - ELFNN_ST_BIND - st_info */ #define STB_LOCAL 0 /* Local symbol */ #define STB_GLOBAL 1 /* Global symbol */ #define STB_WEAK 2 /* like global - lower precedence */ #define STB_LOOS 10 /* Start of operating system reserved range. */ #define STB_GNU_UNIQUE 10 /* Unique symbol (GNU) */ #define STB_HIOS 12 /* End of operating system reserved range. */ #define STB_LOPROC 13 /* reserved range for processor */ #define STB_HIPROC 15 /* specific semantics. */ /* Symbol type - ELFNN_ST_TYPE - st_info */ #define STT_NOTYPE 0 /* Unspecified type. */ #define STT_OBJECT 1 /* Data object. */ #define STT_FUNC 2 /* Function. */ #define STT_SECTION 3 /* Section. */ #define STT_FILE 4 /* Source file. */ #define STT_COMMON 5 /* Uninitialized common block. */ #define STT_TLS 6 /* TLS object. */ #define STT_NUM 7 #define STT_LOOS 10 /* Reserved range for operating system */ #define STT_GNU_IFUNC 10 #define STT_HIOS 12 /* specific semantics. */ #define STT_LOPROC 13 /* Start of processor reserved range. */ #define STT_SPARC_REGISTER 13 /* SPARC register information. */ #define STT_HIPROC 15 /* End of processor reserved range. */ /* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ #define STV_DEFAULT 0x0 /* Default visibility (see binding). */ #define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */ #define STV_HIDDEN 0x2 /* Not visible. */ #define STV_PROTECTED 0x3 /* Visible but not preemptible. */ #define STV_EXPORTED 0x4 #define STV_SINGLETON 0x5 #define STV_ELIMINATE 0x6 /* Special symbol table indexes. */ #define STN_UNDEF 0 /* Undefined symbol index. */ /* Symbol versioning flags. */ #define VER_DEF_CURRENT 1 #define VER_DEF_IDX(x) VER_NDX(x) #define VER_FLG_BASE 0x01 #define VER_FLG_WEAK 0x02 #define VER_NEED_CURRENT 1 #define VER_NEED_WEAK (1u << 15) #define VER_NEED_HIDDEN VER_NDX_HIDDEN #define VER_NEED_IDX(x) VER_NDX(x) #define VER_NDX_LOCAL 0 #define VER_NDX_GLOBAL 1 #define VER_NDX_GIVEN 2 #define VER_NDX_HIDDEN (1u << 15) #define VER_NDX(x) ((x) & ~(1u << 15)) #define CA_SUNW_NULL 0 #define CA_SUNW_HW_1 1 /* first hardware capabilities entry */ #define CA_SUNW_SF_1 2 /* first software capabilities entry */ /* * Syminfo flag values */ #define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */ /* to object containing defn. */ #define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */ #define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */ #define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */ /* lazily-loaded */ #define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */ /* object containing defn. */ #define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */ /* directly bind to this symbol */ #define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */ #define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */ /* * Syminfo.si_boundto values. */ #define SYMINFO_BT_SELF 0xffff /* symbol bound to self */ #define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */ #define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */ #define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */ #define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */ /* * Syminfo version values. */ #define SYMINFO_NONE 0 /* Syminfo version */ #define SYMINFO_CURRENT 1 #define SYMINFO_NUM 2 /* Values for ch_type (compressed section headers). */ #define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE */ #define ELFCOMPRESS_LOOS 0x60000000 /* OS-specific */ #define ELFCOMPRESS_HIOS 0x6fffffff #define ELFCOMPRESS_LOPROC 0x70000000 /* Processor-specific */ #define ELFCOMPRESS_HIPROC 0x7fffffff /* * Relocation types. * * All machine architectures are defined here to allow tools on one to * handle others. */ #define R_386_NONE 0 /* No relocation. */ #define R_386_32 1 /* Add symbol value. */ #define R_386_PC32 2 /* Add PC-relative symbol value. */ #define R_386_GOT32 3 /* Add PC-relative GOT offset. */ #define R_386_PLT32 4 /* Add PC-relative PLT offset. */ #define R_386_COPY 5 /* Copy data from shared object. */ #define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */ #define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */ #define R_386_RELATIVE 8 /* Add load address of shared object. */ #define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */ #define R_386_GOTPC 10 /* Add PC-relative GOT table address. */ #define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */ #define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */ #define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */ #define R_386_TLS_LE 17 /* Negative offset relative to static TLS */ #define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */ #define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */ #define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */ #define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */ #define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */ #define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */ #define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */ #define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */ #define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */ #define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */ #define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */ #define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */ #define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */ #define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */ #define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */ #define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */ #define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */ #define R_AARCH64_NONE 0 /* No relocation */ #define R_AARCH64_ABS64 257 /* Absolute offset */ #define R_AARCH64_ABS32 258 /* Absolute, 32-bit overflow check */ #define R_AARCH64_ABS16 259 /* Absolute, 16-bit overflow check */ #define R_AARCH64_PREL64 260 /* PC relative */ #define R_AARCH64_PREL32 261 /* PC relative, 32-bit overflow check */ #define R_AARCH64_PREL16 262 /* PC relative, 16-bit overflow check */ #define R_AARCH64_COPY 1024 /* Copy data from shared object */ #define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address */ #define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address */ #define R_AARCH64_RELATIVE 1027 /* Add load address of shared object */ #define R_AARCH64_TLS_DTPREL64 1028 #define R_AARCH64_TLS_DTPMOD64 1029 #define R_AARCH64_TLS_TPREL64 1030 #define R_AARCH64_TLSDESC 1031 /* Identify the TLS descriptor */ #define R_AARCH64_IRELATIVE 1032 #define R_ARM_NONE 0 /* No relocation. */ #define R_ARM_PC24 1 #define R_ARM_ABS32 2 #define R_ARM_REL32 3 #define R_ARM_PC13 4 #define R_ARM_ABS16 5 #define R_ARM_ABS12 6 #define R_ARM_THM_ABS5 7 #define R_ARM_ABS8 8 #define R_ARM_SBREL32 9 #define R_ARM_THM_PC22 10 #define R_ARM_THM_PC8 11 #define R_ARM_AMP_VCALL9 12 #define R_ARM_SWI24 13 #define R_ARM_THM_SWI8 14 #define R_ARM_XPC25 15 #define R_ARM_THM_XPC22 16 /* TLS relocations */ #define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ #define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ #define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ #define R_ARM_COPY 20 /* Copy data from shared object. */ #define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */ #define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */ #define R_ARM_RELATIVE 23 /* Add load address of shared object. */ #define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */ #define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */ #define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */ #define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */ #define R_ARM_GNU_VTENTRY 100 #define R_ARM_GNU_VTINHERIT 101 #define R_ARM_RSBREL32 250 #define R_ARM_THM_RPC22 251 #define R_ARM_RREL32 252 #define R_ARM_RABS32 253 #define R_ARM_RPC24 254 #define R_ARM_RBASE 255 /* Name Value Field Calculation */ #define R_IA_64_NONE 0 /* None */ #define R_IA_64_IMM14 0x21 /* immediate14 S + A */ #define R_IA_64_IMM22 0x22 /* immediate22 S + A */ #define R_IA_64_IMM64 0x23 /* immediate64 S + A */ #define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */ #define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */ #define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */ #define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */ #define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */ #define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */ #define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */ #define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */ #define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */ #define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */ #define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */ #define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */ #define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */ #define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */ #define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */ #define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */ #define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */ #define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */ #define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */ #define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */ #define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */ #define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */ #define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */ #define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */ #define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */ #define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */ #define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */ #define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */ #define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */ #define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */ #define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */ #define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */ #define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */ #define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */ #define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */ #define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */ #define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */ #define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */ #define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */ #define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */ #define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */ #define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */ #define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */ #define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */ #define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */ #define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */ #define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */ #define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */ #define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */ #define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */ #define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */ #define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */ #define R_IA_64_SUB 0x85 /* immediate64 A - S */ #define R_IA_64_LTOFF22X 0x86 /* immediate22 special */ #define R_IA_64_LDXMOV 0x87 /* immediate22 special */ #define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */ #define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */ #define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */ #define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */ #define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */ #define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */ #define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */ #define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */ #define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */ #define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */ #define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */ #define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */ #define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */ #define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */ #define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */ #define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */ #define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */ #define R_MIPS_NONE 0 /* No reloc */ #define R_MIPS_16 1 /* Direct 16 bit */ #define R_MIPS_32 2 /* Direct 32 bit */ #define R_MIPS_REL32 3 /* PC relative 32 bit */ #define R_MIPS_26 4 /* Direct 26 bit shifted */ #define R_MIPS_HI16 5 /* High 16 bit */ #define R_MIPS_LO16 6 /* Low 16 bit */ #define R_MIPS_GPREL16 7 /* GP relative 16 bit */ #define R_MIPS_LITERAL 8 /* 16 bit literal entry */ #define R_MIPS_GOT16 9 /* 16 bit GOT entry */ #define R_MIPS_PC16 10 /* PC relative 16 bit */ #define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ #define R_MIPS_GPREL32 12 /* GP relative 32 bit */ #define R_MIPS_64 18 /* Direct 64 bit */ #define R_MIPS_GOT_DISP 19 #define R_MIPS_GOT_PAGE 20 #define R_MIPS_GOT_OFST 21 #define R_MIPS_GOT_HI16 22 /* GOT HI 16 bit */ #define R_MIPS_GOT_LO16 23 /* GOT LO 16 bit */ #define R_MIPS_SUB 24 #define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */ #define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */ #define R_MIPS_JALR 37 #define R_MIPS_TLS_GD 42 #define R_PPC_NONE 0 /* No relocation. */ #define R_PPC_ADDR32 1 #define R_PPC_ADDR24 2 #define R_PPC_ADDR16 3 #define R_PPC_ADDR16_LO 4 #define R_PPC_ADDR16_HI 5 #define R_PPC_ADDR16_HA 6 #define R_PPC_ADDR14 7 #define R_PPC_ADDR14_BRTAKEN 8 #define R_PPC_ADDR14_BRNTAKEN 9 #define R_PPC_REL24 10 #define R_PPC_REL14 11 #define R_PPC_REL14_BRTAKEN 12 #define R_PPC_REL14_BRNTAKEN 13 #define R_PPC_GOT16 14 #define R_PPC_GOT16_LO 15 #define R_PPC_GOT16_HI 16 #define R_PPC_GOT16_HA 17 #define R_PPC_PLTREL24 18 #define R_PPC_COPY 19 #define R_PPC_GLOB_DAT 20 #define R_PPC_JMP_SLOT 21 #define R_PPC_RELATIVE 22 #define R_PPC_LOCAL24PC 23 #define R_PPC_UADDR32 24 #define R_PPC_UADDR16 25 #define R_PPC_REL32 26 #define R_PPC_PLT32 27 #define R_PPC_PLTREL32 28 #define R_PPC_PLT16_LO 29 #define R_PPC_PLT16_HI 30 #define R_PPC_PLT16_HA 31 #define R_PPC_SDAREL16 32 #define R_PPC_SECTOFF 33 #define R_PPC_SECTOFF_LO 34 #define R_PPC_SECTOFF_HI 35 #define R_PPC_SECTOFF_HA 36 /* * 64-bit relocations */ #define R_PPC64_ADDR64 38 #define R_PPC64_ADDR16_HIGHER 39 #define R_PPC64_ADDR16_HIGHERA 40 #define R_PPC64_ADDR16_HIGHEST 41 #define R_PPC64_ADDR16_HIGHESTA 42 #define R_PPC64_UADDR64 43 #define R_PPC64_REL64 44 #define R_PPC64_PLT64 45 #define R_PPC64_PLTREL64 46 #define R_PPC64_TOC16 47 #define R_PPC64_TOC16_LO 48 #define R_PPC64_TOC16_HI 49 #define R_PPC64_TOC16_HA 50 #define R_PPC64_TOC 51 #define R_PPC64_DTPMOD64 68 #define R_PPC64_TPREL64 73 #define R_PPC64_DTPREL64 78 /* * TLS relocations */ #define R_PPC_TLS 67 #define R_PPC_DTPMOD32 68 #define R_PPC_TPREL16 69 #define R_PPC_TPREL16_LO 70 #define R_PPC_TPREL16_HI 71 #define R_PPC_TPREL16_HA 72 #define R_PPC_TPREL32 73 #define R_PPC_DTPREL16 74 #define R_PPC_DTPREL16_LO 75 #define R_PPC_DTPREL16_HI 76 #define R_PPC_DTPREL16_HA 77 #define R_PPC_DTPREL32 78 #define R_PPC_GOT_TLSGD16 79 #define R_PPC_GOT_TLSGD16_LO 80 #define R_PPC_GOT_TLSGD16_HI 81 #define R_PPC_GOT_TLSGD16_HA 82 #define R_PPC_GOT_TLSLD16 83 #define R_PPC_GOT_TLSLD16_LO 84 #define R_PPC_GOT_TLSLD16_HI 85 #define R_PPC_GOT_TLSLD16_HA 86 #define R_PPC_GOT_TPREL16 87 #define R_PPC_GOT_TPREL16_LO 88 #define R_PPC_GOT_TPREL16_HI 89 #define R_PPC_GOT_TPREL16_HA 90 /* * The remaining relocs are from the Embedded ELF ABI, and are not in the * SVR4 ELF ABI. */ #define R_PPC_EMB_NADDR32 101 #define R_PPC_EMB_NADDR16 102 #define R_PPC_EMB_NADDR16_LO 103 #define R_PPC_EMB_NADDR16_HI 104 #define R_PPC_EMB_NADDR16_HA 105 #define R_PPC_EMB_SDAI16 106 #define R_PPC_EMB_SDA2I16 107 #define R_PPC_EMB_SDA2REL 108 #define R_PPC_EMB_SDA21 109 #define R_PPC_EMB_MRKREF 110 #define R_PPC_EMB_RELSEC16 111 #define R_PPC_EMB_RELST_LO 112 #define R_PPC_EMB_RELST_HI 113 #define R_PPC_EMB_RELST_HA 114 #define R_PPC_EMB_BIT_FLD 115 #define R_PPC_EMB_RELSDA 116 /* * RISC-V relocation types. */ /* Relocation types used by the dynamic linker. */ #define R_RISCV_NONE 0 #define R_RISCV_32 1 #define R_RISCV_64 2 #define R_RISCV_RELATIVE 3 #define R_RISCV_COPY 4 #define R_RISCV_JUMP_SLOT 5 #define R_RISCV_TLS_DTPMOD32 6 #define R_RISCV_TLS_DTPMOD64 7 #define R_RISCV_TLS_DTPREL32 8 #define R_RISCV_TLS_DTPREL64 9 #define R_RISCV_TLS_TPREL32 10 #define R_RISCV_TLS_TPREL64 11 /* Relocation types not used by the dynamic linker. */ #define R_RISCV_BRANCH 16 #define R_RISCV_JAL 17 #define R_RISCV_CALL 18 #define R_RISCV_CALL_PLT 19 #define R_RISCV_GOT_HI20 20 #define R_RISCV_TLS_GOT_HI20 21 #define R_RISCV_TLS_GD_HI20 22 #define R_RISCV_PCREL_HI20 23 #define R_RISCV_PCREL_LO12_I 24 #define R_RISCV_PCREL_LO12_S 25 #define R_RISCV_HI20 26 #define R_RISCV_LO12_I 27 #define R_RISCV_LO12_S 28 #define R_RISCV_TPREL_HI20 29 #define R_RISCV_TPREL_LO12_I 30 #define R_RISCV_TPREL_LO12_S 31 #define R_RISCV_TPREL_ADD 32 #define R_RISCV_ADD8 33 #define R_RISCV_ADD16 34 #define R_RISCV_ADD32 35 #define R_RISCV_ADD64 36 #define R_RISCV_SUB8 37 #define R_RISCV_SUB16 38 #define R_RISCV_SUB32 39 #define R_RISCV_SUB64 40 #define R_RISCV_GNU_VTINHERIT 41 #define R_RISCV_GNU_VTENTRY 42 #define R_RISCV_ALIGN 43 #define R_RISCV_RVC_BRANCH 44 #define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 #define R_SPARC_NONE 0 #define R_SPARC_8 1 #define R_SPARC_16 2 #define R_SPARC_32 3 #define R_SPARC_DISP8 4 #define R_SPARC_DISP16 5 #define R_SPARC_DISP32 6 #define R_SPARC_WDISP30 7 #define R_SPARC_WDISP22 8 #define R_SPARC_HI22 9 #define R_SPARC_22 10 #define R_SPARC_13 11 #define R_SPARC_LO10 12 #define R_SPARC_GOT10 13 #define R_SPARC_GOT13 14 #define R_SPARC_GOT22 15 #define R_SPARC_PC10 16 #define R_SPARC_PC22 17 #define R_SPARC_WPLT30 18 #define R_SPARC_COPY 19 #define R_SPARC_GLOB_DAT 20 #define R_SPARC_JMP_SLOT 21 #define R_SPARC_RELATIVE 22 #define R_SPARC_UA32 23 #define R_SPARC_PLT32 24 #define R_SPARC_HIPLT22 25 #define R_SPARC_LOPLT10 26 #define R_SPARC_PCPLT32 27 #define R_SPARC_PCPLT22 28 #define R_SPARC_PCPLT10 29 #define R_SPARC_10 30 #define R_SPARC_11 31 #define R_SPARC_64 32 #define R_SPARC_OLO10 33 #define R_SPARC_HH22 34 #define R_SPARC_HM10 35 #define R_SPARC_LM22 36 #define R_SPARC_PC_HH22 37 #define R_SPARC_PC_HM10 38 #define R_SPARC_PC_LM22 39 #define R_SPARC_WDISP16 40 #define R_SPARC_WDISP19 41 #define R_SPARC_GLOB_JMP 42 #define R_SPARC_7 43 #define R_SPARC_5 44 #define R_SPARC_6 45 #define R_SPARC_DISP64 46 #define R_SPARC_PLT64 47 #define R_SPARC_HIX22 48 #define R_SPARC_LOX10 49 #define R_SPARC_H44 50 #define R_SPARC_M44 51 #define R_SPARC_L44 52 #define R_SPARC_REGISTER 53 #define R_SPARC_UA64 54 #define R_SPARC_UA16 55 #define R_SPARC_TLS_GD_HI22 56 #define R_SPARC_TLS_GD_LO10 57 #define R_SPARC_TLS_GD_ADD 58 #define R_SPARC_TLS_GD_CALL 59 #define R_SPARC_TLS_LDM_HI22 60 #define R_SPARC_TLS_LDM_LO10 61 #define R_SPARC_TLS_LDM_ADD 62 #define R_SPARC_TLS_LDM_CALL 63 #define R_SPARC_TLS_LDO_HIX22 64 #define R_SPARC_TLS_LDO_LOX10 65 #define R_SPARC_TLS_LDO_ADD 66 #define R_SPARC_TLS_IE_HI22 67 #define R_SPARC_TLS_IE_LO10 68 #define R_SPARC_TLS_IE_LD 69 #define R_SPARC_TLS_IE_LDX 70 #define R_SPARC_TLS_IE_ADD 71 #define R_SPARC_TLS_LE_HIX22 72 #define R_SPARC_TLS_LE_LOX10 73 #define R_SPARC_TLS_DTPMOD32 74 #define R_SPARC_TLS_DTPMOD64 75 #define R_SPARC_TLS_DTPOFF32 76 #define R_SPARC_TLS_DTPOFF64 77 #define R_SPARC_TLS_TPOFF32 78 #define R_SPARC_TLS_TPOFF64 79 #define R_X86_64_NONE 0 /* No relocation. */ #define R_X86_64_64 1 /* Add 64 bit symbol value. */ #define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */ #define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */ #define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */ #define R_X86_64_COPY 5 /* Copy data from shared object. */ #define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */ #define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */ #define R_X86_64_RELATIVE 8 /* Add load address of shared object. */ #define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */ #define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */ #define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */ #define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */ #define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */ #define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */ #define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */ #define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ #define R_X86_64_DTPOFF64 17 /* Offset in TLS block */ #define R_X86_64_TPOFF64 18 /* Offset in static TLS block */ #define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */ #define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */ #define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ #define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */ #define R_X86_64_TPOFF32 23 /* Offset in static TLS block */ #define R_X86_64_PC64 24 /* PC-relative 64 bit signed sym value. */ #define R_X86_64_GOTOFF64 25 #define R_X86_64_GOTPC32 26 #define R_X86_64_GOT64 27 #define R_X86_64_GOTPCREL64 28 #define R_X86_64_GOTPC64 29 #define R_X86_64_GOTPLT64 30 #define R_X86_64_PLTOFF64 31 #define R_X86_64_SIZE32 32 #define R_X86_64_SIZE64 33 #define R_X86_64_GOTPC32_TLSDESC 34 #define R_X86_64_TLSDESC_CALL 35 #define R_X86_64_TLSDESC 36 #define R_X86_64_IRELATIVE 37 #endif /* !_SYS_ELF_COMMON_H_ */ Index: stable/11/usr.bin/readelf/Makefile =================================================================== --- stable/11/usr.bin/readelf/Makefile (revision 367465) +++ stable/11/usr.bin/readelf/Makefile (revision 367466) @@ -1,28 +1,28 @@ # $FreeBSD$ ELFTCDIR= ${SRCTOP}/contrib/elftoolchain READELFDIR= ${ELFTCDIR}/readelf .PATH: ${READELFDIR} PROG= readelf SRCS= readelf.c -LIBADD= dwarf elftc elf +LIBADD= dwarf elftc elf z CFLAGS+=-I${ELFTCDIR}/libelftc -I${ELFTCDIR}/common # This same hack is in lib/libelf/Makefile and lib/libdwarf/Makefile # We need to link against the correct version of these files. One # solution is to include SRCTOP/sys in the include path. This causes # problems when a header file in sys depends on a file in another # part of the tree, e.g. a machine dependent header. # SRCS+= sys/elf32.h sys/elf64.h sys/elf_common.h CLEANDIRS= sys CFLAGS+= -I. sys/elf32.h sys/elf64.h sys/elf_common.h: ${SRCTOP}/sys/${.TARGET} .NOMETA mkdir -p ${.OBJDIR}/sys ln -sf ${.ALLSRC} ${.TARGET} .include Index: stable/11 =================================================================== --- stable/11 (revision 367465) +++ stable/11 (revision 367466) Property changes on: stable/11 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,2 ## Merged /stable/12:r358778 Merged /head:r308465,317626,340746,340750,342918,343592-343593,343614,343665,343669,345360-345362,345364,345431,345593,345646,346323,346327,348347,348430-348431,348443-348444,348652,348654-348655,348657,348776,349420-349424,349481-349483,349510,349562-349563,349577,349730,350432,350511,350679,352875,352878,352908,354544,354842,355413,357450,357462,357531-357542,357826,357844,357862,358499,358631,358637,358639,358685,358706,358708,358713,359166,359172-359176,359189,361104,361662,365489,366977,367209,367238,367322