diff --git a/.gitignore b/.gitignore index c375384..4bda3f1 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ /install-sh /depcomp /ar-lib +/ltmain.sh ABOUT-NLS # autotools generated files @@ -20,6 +21,7 @@ ABOUT-NLS /*.cache Makefile Doxyfile +/libtool # Compilation output *.o diff --git a/ChangeLog b/ChangeLog index ca892d4..626ca86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2015-04-09 André Colomb + + * Rework the build system, fixing several usage and portability + problems. Integrate GNU libtool for building libraries. + * Fix a problem with iterating through symbol lists caused by an + uninitialized local variable. + * Rename the option --byte-size to --field-size and add another + option --section-size. + * Fix offset output for the --strings option to point at the + length prefix byte. + * Abuse the --symbols option to generate more machine-readable + (non-localized) output for --strings and --section-size. + * Adjust help output to exclude unavailable options and reflect + the actually used default values. + * Fix error handling when an expected ELF section could not be + found. + * Handle unprintable characters in custom_known_fields.c example. + * Validate argument in custom_options.c example for --set-serial. + * Revised README document for new features and minor corrections. + + * Release version 0.4. + 2014-08-08 André Colomb * Clean up build system for more stability and better user diff --git a/Doxyfile.in b/Doxyfile.in index bfdad67..4cf429f 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -1,4 +1,4 @@ -# Doxyfile 1.8.6 +# Doxyfile 1.8.8 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -51,14 +51,14 @@ PROJECT_BRIEF = "Analyze, transform and manipulate binary data based on # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doxygen +OUTPUT_DIRECTORY = @builddir@/doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = doxygen CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. @@ -154,7 +162,7 @@ FULL_PATH_NAMES = YES # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. -STRIP_FROM_PATH = +STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which @@ -163,7 +171,7 @@ STRIP_FROM_PATH = # specify the list of include paths that are normally passed to the compiler # using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't @@ -230,13 +238,13 @@ TAB_SIZE = 8 # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. -ALIASES = +ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. -TCL_SUBST = +TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For @@ -271,16 +279,19 @@ OPTIMIZE_OUTPUT_VHDL = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -616,7 +627,7 @@ GENERATE_DEPRECATEDLIST= YES # sections, marked by \if ... \endif and \cond # ... \endcond blocks. -ENABLED_SECTIONS = +ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the @@ -658,7 +669,7 @@ SHOW_NAMESPACES = YES # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated @@ -671,7 +682,7 @@ FILE_VERSION_FILTER = # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. -LAYOUT_FILE = +LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib @@ -679,10 +690,9 @@ LAYOUT_FILE = # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. +# search path. See also \cite for info how to create references. -CITE_BIB_FILES = +CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages @@ -741,7 +751,7 @@ WARN_FORMAT = "$file:$line: $text" # messages should be written. If left blank the output is written to standard # error (stderr). -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -753,7 +763,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = src +INPUT = @top_srcdir@/src # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -829,7 +839,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -845,7 +855,7 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -856,13 +866,13 @@ EXCLUDE_PATTERNS = # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -882,7 +892,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = +IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -899,7 +909,7 @@ IMAGE_PATH = # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. -INPUT_FILTER = +INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the @@ -908,7 +918,7 @@ INPUT_FILTER = # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. -FILTER_PATTERNS = +FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER ) will also be used to filter the input files that are used for @@ -923,14 +933,14 @@ FILTER_SOURCE_FILES = NO # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. -FILTER_SOURCE_PATTERNS = +FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. -USE_MDFILE_AS_MAINPAGE = +USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing @@ -1018,6 +1028,25 @@ USE_HTAGS = NO VERBATIM_HEADERS = YES +# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# compiled with the --with-libclang option. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- @@ -1042,7 +1071,7 @@ COLS_IN_ALPHA_INDEX = 5 # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output @@ -1086,7 +1115,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = +HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1096,7 +1125,7 @@ HTML_HEADER = # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = +HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of @@ -1108,18 +1137,20 @@ HTML_FOOTER = # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_STYLESHEET = +HTML_STYLESHEET = -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra stylesheet files is of importance (e.g. the last +# stylesheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = +HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1129,7 +1160,7 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the stylesheet and background images according to @@ -1257,7 +1288,7 @@ GENERATE_HTMLHELP = NO # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_FILE = +CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler ( hhc.exe). If non-empty @@ -1265,7 +1296,7 @@ CHM_FILE = # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -HHC_LOCATION = +HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated ( # YES) or that it should be included in the master .chm file ( NO). @@ -1278,10 +1309,11 @@ GENERATE_CHI = NO # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. +# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1308,7 +1340,7 @@ GENERATE_QHP = NO # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. -QCH_FILE = +QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace @@ -1333,7 +1365,7 @@ QHP_VIRTUAL_FOLDER = doc # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom @@ -1341,21 +1373,21 @@ QHP_CUST_FILTER_NAME = # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. -QHG_LOCATION = +QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To @@ -1488,7 +1520,7 @@ MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site @@ -1496,7 +1528,7 @@ MATHJAX_EXTENSIONS = # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. -MATHJAX_CODEFILE = +MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and @@ -1521,11 +1553,11 @@ SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. @@ -1556,7 +1588,7 @@ EXTERNAL_SEARCH = NO # Searching" for details. # This tag requires that the tag SEARCHENGINE is set to YES. -SEARCHENGINE_URL = +SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the @@ -1572,7 +1604,7 @@ SEARCHDATA_FILE = searchdata.xml # projects and redirect the results back to the right project. # This tag requires that the tag SEARCHENGINE is set to YES. -EXTERNAL_SEARCH_ID = +EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are @@ -1582,7 +1614,7 @@ EXTERNAL_SEARCH_ID = # EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... # This tag requires that the tag SEARCHENGINE is set to YES. -EXTRA_SEARCH_MAPPINGS = +EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # Configuration options related to the LaTeX output @@ -1643,7 +1675,7 @@ PAPER_TYPE = a4 # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. -EXTRA_PACKAGES = +EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for the # generated LaTeX document. The header should contain everything until the first @@ -1653,22 +1685,24 @@ EXTRA_PACKAGES = # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string, +# for the replacement values of the other commands the user is refered to +# HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_HEADER = +LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_FOOTER = +LATEX_FOOTER = # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output @@ -1676,7 +1710,7 @@ LATEX_FOOTER = # markers available. # This tag requires that the tag GENERATE_LATEX is set to YES. -LATEX_EXTRA_FILES = +LATEX_EXTRA_FILES = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is # prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will @@ -1687,7 +1721,7 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate # the PDF file directly from the LaTeX files. Set this option to YES to get a # higher quality PDF documentation. # The default value is: YES. @@ -1776,14 +1810,14 @@ RTF_HYPERLINKS = NO # default style sheet that doxygen normally uses. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is # similar to doxygen's config file. A template extensions file can be generated # using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # Configuration options related to the man page output @@ -1813,6 +1847,13 @@ MAN_OUTPUT = man MAN_EXTENSION = .3 +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without @@ -1840,18 +1881,6 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - # If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size @@ -1879,6 +1908,15 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -1927,7 +1965,7 @@ PERLMOD_PRETTY = YES # overwrite each other's variables. # This tag requires that the tag GENERATE_PERLMOD is set to YES. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor @@ -1968,7 +2006,7 @@ SEARCH_INCLUDES = YES # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = +INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -1976,7 +2014,7 @@ INCLUDE_PATH = # used. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that are # defined before the preprocessor is started (similar to the -D option of e.g. @@ -1986,7 +2024,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -1995,12 +2033,12 @@ PREDEFINED = # definition found in the source code. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -2020,17 +2058,17 @@ SKIP_FUNCTION_MACROS = YES # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include +# Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create a # tag file that is based on the input files it reads. See section "Linking to # external documentation" for more information about the usage of tag files. -GENERATE_TAGFILE = +GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external class will be listed in the # class index. If set to NO only the inherited external classes will be listed. @@ -2078,14 +2116,14 @@ CLASS_DIAGRAMS = NO # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. # If left empty dia is assumed to be found in the default search path. -DIA_PATH = +DIA_PATH = # If set to YES, the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. @@ -2098,7 +2136,7 @@ HIDE_UNDOC_RELATIONS = YES # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO -# The default value is: NO. +# The default value is: YES. HAVE_DOT = YES @@ -2112,7 +2150,7 @@ HAVE_DOT = YES DOT_NUM_THREADS = 0 -# When you want a differently looking font n the dot files that doxygen +# When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by @@ -2134,7 +2172,7 @@ DOT_FONTSIZE = 10 # the path where dot can find it using this tag. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTPATH = +DOT_FONTPATH = # If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for # each documented class showing the direct and indirect inheritance relations. @@ -2250,7 +2288,9 @@ DIRECTORY_GRAPH = YES # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, jpg, gif and svg. +# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, +# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, +# gif:cairo:gd, gif:gd, gif:gd:gd and svg. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2272,26 +2312,35 @@ INTERACTIVE_SVG = NO # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_PATH = +DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile # command). # This tag requires that the tag HAVE_DOT is set to YES. -DOTFILE_DIRS = +DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the \mscfile # command). -MSCFILE_DIRS = +MSCFILE_DIRS = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile # command). -DIAFILE_DIRS = +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. +# This tag requires that the tag HAVE_DOT is set to YES. + +PLANTUML_JAR_PATH = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes diff --git a/Makefile.am b/Makefile.am index d9ba297..b0ef9bd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,3 @@ -# Hey Emacs, this is a -*- makefile -*- - # Copyright (C) 2014 Andre Colomb # # This file is part of elf-mangle. diff --git a/README.md b/README.md index 4ba7739..3f70a1a 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,11 @@ based on ELF symbol tables. Author: André Colomb + License ------- -Copyright (C) 2014 André Colomb +Copyright (C) 2014, 2015 André Colomb elf-mangle is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published @@ -35,11 +36,13 @@ binary code to be run on a CPU or embedded microprocessor. After these tools have finished their job, sometimes it is necessary to alter some bits of information inside these binary files. The most common modern executable file format (at least in the *NIX world) is -ELF, the Executable and Linkable Format. +**ELF**, the _E_xecutable and _L_inkable _F_ormat. The *elf-mangle* tool exists to examine and alter (thus *mangle*) these ELF executable and binary data images, for example when you need -an embedded serial number or calibration data which is unique. +an embedded serial number or calibration data which is unique. It +allows you to process the data using associated ELF files as "lenses" +or maps describing the information layout and possibly semantics. The use-case why the tool was written is an embedded controller for a mechanical system whose firmware contains a serial number in the @@ -58,7 +61,7 @@ storage layout, and written back to an image file ready for flashing. * Specified on the command line * Loaded from an existing binary data image (blob) + Modular support for different input / output image formats: - * Intel Hex encoding (requires [libcintelhex][4]) + * Intel Hex encoding (requires [libcintelhex][ihex-fork]) * Raw binary data + Load a second ELF object to transcribe matching symbols between input and output layout. @@ -75,9 +78,9 @@ storage layout, and written back to an image file ready for flashing. Installation ------------ -The elf-mangle build system uses the GNU autotools - autoconf, -automake, gettext, ... When using the release version archives, it's -as simple as the usual: +The elf-mangle build system uses the *GNU autotools* - `autoconf`, +`automake`, `gettext`, ... When using the release version archives, +it's as simple as the usual: ./configure make @@ -93,16 +96,18 @@ bootstrapping needs to be carried out. ### Bootstrapping ### Setting up the build system from the repository contents needs -additional tools installed. The following versions are tested: +additional developer tools installed. The following versions are +tested: - GNU autoconf 2.69 -- GNU automake 1.14 -- GNU gettext 0.18.3 +- GNU automake 1.14.1 +- GNU libtool 2.4.2 +- GNU gettext 0.19.2 To fully generate the build system, run these two commands in order: gnulib-tool --update # optional, see portability notes below - autoreconf -i + autoreconf -i -f ### Compilation ### @@ -140,7 +145,8 @@ implementations are available, with varying licenses. Michael Riepe has written an excellent *LGPL*-licensed implementation, found at [www.mr511.de][libelf-lgpl]. This is the one *elf-mangle* is developed and tested with. It is [included][libelfg0] in most -*Debian*-based Linux distributions and can be compiled under Win32. +*Debian*-based Linux distributions as well as *Cygwin* and can be +compiled under Win32 using *MinGW*. [libelf-lgpl]: http://www.mr511.de/software/ "libelf LGPL'ed" [libelfg0]: https://packages.debian.org/stable/libelfg0-dev "libelf in Debian" @@ -161,7 +167,7 @@ Either implementation should work if it supports the BSD *GElf* API. Just make sure the compiler finds the required headers and library. If not installed in a standard location, suitable flags should be passed through the `CPPFLAGS` and `LDFLAGS` environment variables when -running `./configure`. +running `configure`. #### Optional: libcintelhex #### @@ -174,7 +180,7 @@ therefore not compatible yet. The library should be cloned from GitHub and built before configuring *elf-mangle*. If it is not installed system-wide, the `CPPFLAGS` and -`LDFLAGS` environment variables may be used to point `./configure` to +`LDFLAGS` environment variables may be used to point `configure` to the right location. The command-line option `--with-cintelhex=` accepts an installation prefix to correctly set up the flags variables automatically. To force building without *Intel Hex* support, specify @@ -195,15 +201,15 @@ pointing at the forked repository. Initialize and use it with Some functionality provided by the *GNU C Library* and used by *elf-mangle* is not available on other platforms. The compatibility layer [GNU Gnulib][gnulib] can be used to replace the missing bits. -The tarball includes the relevant Gnulib sources, so this step can be -skipped. +The tarball includes the relevant *Gnulib* sources, so the following +step is only necessary when building from the repository. A configuration file for *gnulib-tool* is available in the repository. -If you have a Gnulib source checkout, copy the needed modules with the -following commands: +If you have a *Gnulib* source checkout, copy the needed modules with +the following commands: gnulib-tool --update - autoreconf -i + autoreconf -i -f [gnulib]: http://www.gnu.org/software/gnulib/ "Gnulib home page" @@ -231,18 +237,22 @@ be overridden using the `--section=SECTION` option. Other useful section names might be `.data` or `.rodata` for example--wherever the compiler has placed interesting information. -Given just an input ELF file name, *elf-mangle* just tries to parse +Given only an input ELF file name, *elf-mangle* just tries to parse the symbol table and then exits. To display the symbols found, use -the `--print` option. It defaults to `pretty`, calling any print +the `--print` option. It defaults to `pretty` mode, calling any print function *elf-mangle* has for known symbols (see the section "Application Extensions" below for how to use them). Since by default no symbol has a known special meaning, only the symbol names are listed. Use `--print=hex` to generate a hex dump of the data content for each symbol. -The options `--addresses` and `--byte-size` may be used to show +The options `--addresses` and `--field-size` may be used to show additional information about the data offset within the section and -the size in bytes for each symbol. +the size in bytes for each symbol. Add the `--section-size` option to +print out the byte size of all data in the examined section. The +`--symbols` option causes the symbol names to be displayed, even for +known symbols with a description. It also sets the `--section-size` +output prefix to simply `total: ` (not localized). ### Input Blob ### @@ -281,7 +291,7 @@ data as contained in the ELF object specified as `OUT_MAP`. By use of the `--print` option, the transformed contents can be examined. Note that the displayed symbol list now concerns the **output** file, in contrast to the previous use-case when the `OUT_MAP` argument was -omitted. +omitted. This applies to the `--section-size` option as well. In general, *elf-mangle* without an `OUT_MAP` argument behaves just as if the same file was given for `IN_MAP` and `OUT_MAP`. @@ -379,7 +389,9 @@ constructed strings within the input blob data. It may be followed by a byte count specifying the minimum string length to look out for. Only strings matching the above description with a length greater than or equal to the given minimum will be listed, including their offset -within the image and actual length. +within the image and actual length. The `--symbols` option, as a side +effect, forces a consistent output format starting with `lpstring`, +which is not localized and thus suitable for further processing. The string searching algorithm is similar to the standard UNIX `strings` utility. The latter however does not handle the special @@ -410,6 +422,12 @@ respective application. To ease later upgrades and track changes in *elf-mangle* development, these changes should be maintained within a git branch for example. +When building and installing a customized, application-specific +version of *elf-mangle*, the `--program-prefix` option to `configure` +may come in handy to install the custom program binary with a +different name. This way, the original *elf-mangle* binary can +coexist nicely. + ### Describing Known Fields ### @@ -462,8 +480,8 @@ option handling with separate parsers for different groups of options. To implement application-specific command line extensions, a function named `get_custom_options()` should be provided in `custom_options.c`, returning a pointer to an `argp_child` structure, as described in the -glibc manual. This child parser will be added to the program's own -options handling. +[glibc][glibc] manual. This child parser will be added to the +program's own options handling. One of the most obvious use-cases for these extensions is to provide options for overriding single fields, but not with a string of hex @@ -487,7 +505,7 @@ Generate blob `out.bin` from `in_map.elf` with default contents: Copy values from blob `in.hex` to `out.hex` with layout of `out_map.elf`, but override `nvm_unique` field with given hex data: - elf-mangle in_map.elf out_map.elf -i in.hex -s nvm_unique=1a0002 -o out.hex + elf-mangle in_map.elf out_map.elf -i in.hex -D nvm_unique=1a0002 -o out.hex Print field values from blob `in.hex` according to layout of `in_map.elf`: @@ -502,4 +520,4 @@ Print default field values from `in_map.elf` converted to Look for string structures with a minimum length of 12 bytes within `in_map.elf`, looking at the `.data` section: - elf-mangle in_map.elf -l12 -j .text + elf-mangle in_map.elf -l12 -j .data diff --git a/configure.ac b/configure.ac index 034f00d..bf7bff5 100644 --- a/configure.ac +++ b/configure.ac @@ -17,14 +17,18 @@ # . -AC_INIT([elf-mangle], [0.3], [src@andre.colomb.de]) -AC_CONFIG_AUX_DIR([.]) +AC_INIT([elf-mangle], [0.4], [src@andre.colomb.de]) +AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([src/elf-mangle.c]) +AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE([foreign -Wall -Werror]) + + +# Checks for programs. AC_USE_SYSTEM_EXTENSIONS AC_PROG_CC_C99 -AC_PROG_RANLIB AM_PROG_AR +LT_INIT # Use GNU Gnulib if required macros are present m4_ifdef([gl_EARLY], @@ -32,11 +36,11 @@ m4_ifdef([gl_EARLY], gnulib=1], [gnulib=0]) AM_CONDITIONAL([USE_GNULIB], [test "x$gnulib" = x1]) -AC_TYPE_SIZE_T -AC_TYPE_SSIZE_T + +# Checks for libraries. m4_ifdef([gl_INIT], [gl_INIT]) -AC_FUNC_MMAP -AC_CHECK_LIB([elf], [elf_version], [], +AC_CHECK_LIB([elf], [elf_version], + [AC_SUBST([LIBS_ELF], [-lelf])], [AC_MSG_ERROR([Libelf is needed to compile this software. Specify LDFLAGS if necessary.])]) AC_CHECK_HEADERS([gelf.h], [], @@ -46,7 +50,6 @@ AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_NEED([need-formatstring-macros]) AM_GNU_GETTEXT_VERSION([0.18.3]) - # Use installed libcintelhex or fall back to embedded copy cintelhex=0 cintelhex_internal=0 @@ -63,12 +66,15 @@ AC_ARG_WITH([cintelhex], [cintelhex=1], [cintelhex_internal=1])], [cintelhex_internal=1])], [internal], [cintelhex_internal=1], - [LDFLAGS="-L$with_cintelhex/lib $LDFLAGS" + [saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I$with_cintelhex/include $CPPFLAGS" AC_CHECK_HEADERS([cintelhex.h], - [AC_CHECK_LIB([cintelhex], [ihex_byte_copy], - [EXT_LIB_PATH="-L$with_cintelhex/lib $EXT_LIB_PATH" - cintelhex=1])]) + [saved_LDFLAGS="$LDFLAGS" + LDFLAGS="-L$with_cintelhex/lib $LDFLAGS" + AC_CHECK_LIB([cintelhex], [ihex_byte_copy], + [cintelhex=1], + [LDFLAGS="$saved_LDFLAGS"])], + [CPPFLAGS="$saved_CPPFLAGS"]) ]) ], [AC_MSG_RESULT([--with-cintelhex not specified]) @@ -80,21 +86,52 @@ AC_ARG_WITH([cintelhex], AS_IF([test "x$cintelhex_internal" = x1], [AC_MSG_NOTICE([Trying embedded internal copy of libcintelhex]) - LDFLAGS="-Llibcintelhex/lib -Llibcintelhex/bin $LDFLAGS" - CPPFLAGS="-Ilibcintelhex/include $CPPFLAGS" AS_UNSET([ac_cv_header_cintelhex_h]) + CPPFLAGS="-I${srcdir}/libcintelhex/include $CPPFLAGS" AC_CHECK_HEADERS([cintelhex.h], - [cintelhex=1], [cintelhex_internal=0]) - ]) + [cintelhex=1], + [cintelhex_internal=0]) + CPPFLAGS="$saved_CPPFLAGS" + ], + [AS_IF([test x$cintelhex = x1], AC_SUBST([LIBS_CINTELHEX], [-lcintelhex]))]) AM_CONDITIONAL([HAVE_INTELHEX], [test x$cintelhex = x1]) AM_CONDITIONAL([HAVE_INTELHEX_INTERNAL], [test x$cintelhex_internal = x1]) AC_DEFINE_UNQUOTED([HAVE_INTELHEX], [$cintelhex], [Define if you have libcintelhex]) -AS_IF([test "x$cintelhex" = x1], +AM_COND_IF([HAVE_INTELHEX], [AC_MSG_NOTICE([Including support for Intel Hex format files.])], [AC_MSG_WARN([Intel Hex format files will not be supported.])]) +# Checks for header files. +AC_CHECK_HEADERS([fcntl.h]) +AC_CHECK_HEADERS([locale.h]) +AC_CHECK_HEADERS([stddef.h]) +AC_CHECK_HEADERS([libintl.h]) + + +# Checks for typedefs +AC_TYPE_SIZE_T +AC_TYPE_SSIZE_T +AC_TYPE_OFF_T +AC_TYPE_UINT16_T +AC_TYPE_UINT32_T +AC_TYPE_UINT8_T + + + +# Checks for library functions. +AC_CHECK_FUNCS([ftruncate]) +AC_CHECK_FUNCS([munmap]) +AC_CHECK_FUNCS([setlocale]) +AC_CHECK_FUNCS([strerror]) +AC_FUNC_MALLOC +AC_FUNC_REALLOC +AC_FUNC_MMAP + + + +# Checks for optional feature requests AC_MSG_CHECKING([whether extension module for custom options should be built]) AC_ARG_ENABLE([custom-options], [AS_HELP_STRING([--enable-custom-options], @@ -123,9 +160,10 @@ AC_MSG_RESULT([${custom_fields}]) AM_CONDITIONAL([CUSTOM_FIELDS], [test "x$custom_fields" = xyes]) +# Ouput definitions AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile Doxyfile src/Makefile po/Makefile.in]) -AS_IF([test "x$cintelhex_internal" = x1], +AM_COND_IF([HAVE_INTELHEX_INTERNAL], [AC_CONFIG_SUBDIRS([libcintelhex])]) m4_ifdef([gl_INIT], [AC_CONFIG_FILES([gnulib/Makefile])]) diff --git a/gnulib/.gitignore b/gnulib/.gitignore index e69de29..8a87339 100644 --- a/gnulib/.gitignore +++ b/gnulib/.gitignore @@ -0,0 +1,74 @@ +/alloca.c +/alloca.in.h +/argp-ba.c +/argp-eexst.c +/argp-fmtstream.c +/argp-fmtstream.h +/argp-fs-xinl.c +/argp.h +/argp-help.c +/argp-namefrob.h +/argp-parse.c +/argp-pin.c +/argp-pv.c +/argp-pvh.c +/argp-xinl.c +/asnprintf.c +/basename-lgpl.c +/dirname.h +/dirname-lgpl.c +/dosname.h +/errno.in.h +/float.c +/float+.h +/float.in.h +/getopt1.c +/getopt.c +/getopt.in.h +/getopt_int.h +/getsubopt.c +/gettext.h +/intprops.h +/itold.c +/Makefile.am +/malloc.c +/memchr.c +/memchr.valgrind +/mempcpy.c +/printf-args.c +/printf-args.h +/printf-parse.c +/printf-parse.h +/rawmemchr.c +/rawmemchr.valgrind +/size_max.h +/sleep.c +/stdalign.in.h +/stdbool.in.h +/stddef.in.h +/stdint.in.h +/stdio.in.h +/stdlib.in.h +/strcasecmp.c +/strchrnul.c +/strchrnul.valgrind +/strerror.c +/strerror-override.c +/strerror-override.h +/string.in.h +/strings.in.h +/stripslash.c +/strncasecmp.c +/strndup.c +/strnlen.c +/sysexits.in.h +/sys_types.in.h +/unistd.c +/unistd.in.h +/vasnprintf.c +/vasnprintf.h +/verify.h +/vsnprintf.c +/wchar.in.h +/xsize.c +/xsize.h diff --git a/libcintelhex b/libcintelhex index 8bbfda7..2f66227 160000 --- a/libcintelhex +++ b/libcintelhex @@ -1 +1 @@ -Subproject commit 8bbfda738acf829c82e8b90ef609abd41b9f5bad +Subproject commit 2f66227585200b3b27a9e6464bbd552e7eb7c3cb diff --git a/m4/.gitignore b/m4/.gitignore index d2c4591..2ac4607 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,31 +1,88 @@ -codeset.m4 -fcntl-o.m4 -gettext.m4 -glibc2.m4 -glibc21.m4 -iconv.m4 -intdiv0.m4 -intl.m4 -intldir.m4 -intlmacosx.m4 -intmax.m4 -inttypes-pri.m4 -inttypes_h.m4 -lcmessage.m4 -lib-ld.m4 -lib-link.m4 -lib-prefix.m4 -lock.m4 -longlong.m4 -nls.m4 -po.m4 -printf-posix.m4 -progtest.m4 -size_max.m4 -stdint_h.m4 -threadlib.m4 -uintmax_t.m4 -visibility.m4 -wchar_t.m4 -wint_t.m4 -xsize.m4 +/00gnulib.m4 +/absolute-header.m4 +/alloca.m4 +/argp.m4 +/codeset.m4 +/dirname.m4 +/double-slash-root.m4 +/errno_h.m4 +/exponentd.m4 +/extensions.m4 +/extern-inline.m4 +/fcntl-o.m4 +/float_h.m4 +/getopt.m4 +/getsubopt.m4 +/gettext.m4 +/glibc21.m4 +/glibc2.m4 +/gnulib-common.m4 +/gnulib-comp.m4 +/gnulib-tool.m4 +/iconv.m4 +/include_next.m4 +/intdiv0.m4 +/intldir.m4 +/intl.m4 +/intlmacosx.m4 +/intmax.m4 +/intmax_t.m4 +/inttypes_h.m4 +/inttypes-pri.m4 +/lcmessage.m4 +/lib-ld.m4 +/lib-link.m4 +/lib-prefix.m4 +/libtool.m4 +/lock.m4 +/longlong.m4 +/ltoptions.m4 +/ltsugar.m4 +/ltversion.m4 +/lt~obsolete.m4 +/malloc.m4 +/math_h.m4 +/memchr.m4 +/mempcpy.m4 +/mmap-anon.m4 +/multiarch.m4 +/nls.m4 +/nocrash.m4 +/off_t.m4 +/onceonly.m4 +/po.m4 +/printf.m4 +/printf-posix.m4 +/progtest.m4 +/rawmemchr.m4 +/size_max.m4 +/sleep.m4 +/ssize_t.m4 +/stdalign.m4 +/stdbool.m4 +/stddef_h.m4 +/stdint_h.m4 +/stdint.m4 +/stdio_h.m4 +/stdlib_h.m4 +/strcase.m4 +/strchrnul.m4 +/strerror.m4 +/string_h.m4 +/strings_h.m4 +/strndup.m4 +/strnlen.m4 +/sysexits.m4 +/sys_socket_h.m4 +/sys_types_h.m4 +/threadlib.m4 +/uintmax_t.m4 +/unistd_h.m4 +/vasnprintf.m4 +/visibility.m4 +/vsnprintf.m4 +/warn-on-use.m4 +/wchar_h.m4 +/wchar_t.m4 +/wint_t.m4 +/xsize.m4 diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index f807e5e..f025be7 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -27,7 +27,7 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --lgpl --conditional-dependencies --no-libtool --macro-prefix=gl argp getsubopt +# gnulib-tool --import --dir=. --lib=libgnu --source-base=gnulib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --lgpl --conditional-dependencies --libtool --macro-prefix=gl argp getsubopt # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) @@ -45,6 +45,7 @@ gl_LIB([libgnu]) gl_LGPL gl_MAKEFILE_NAME([]) gl_CONDITIONAL_DEPENDENCIES +gl_LIBTOOL gl_MACRO_PREFIX([gl]) gl_PO_DOMAIN([]) gl_WITNESS_C_MACRO([]) diff --git a/po/.gitignore b/po/.gitignore index 68a0a0c..771e96f 100644 --- a/po/.gitignore +++ b/po/.gitignore @@ -13,3 +13,4 @@ remove-potcdate.sed stamp-po *.gmo +*.mo diff --git a/po/POTFILES.in b/po/POTFILES.in index eb1376d..110e093 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,8 +2,10 @@ src/custom_known_fields.c src/custom_options.c src/field_print.c +src/find_string.c src/image_formats.c -src/image_ihex.c +src/image_ihex_input.c +src/image_ihex_output.c src/image_raw.c src/nvm_field.c src/options.c diff --git a/po/de.po b/po/de.po index 74b2950..f48abfe 100644 --- a/po/de.po +++ b/po/de.po @@ -7,9 +7,9 @@ msgid "" msgstr "" "Project-Id-Version: elf-mangle 0.1\n" "Report-Msgid-Bugs-To: src@andre.colomb.de\n" -"POT-Creation-Date: 2014-08-08 11:11+0200\n" -"PO-Revision-Date: 2014-08-08 11:13+0200\n" -"Last-Translator: André Colomb \n" +"POT-Creation-Date: 2015-04-09 14:08+0200\n" +"PO-Revision-Date: 2015-04-09 14:03+0100\n" +"Last-Translator: Andre Colomb \n" "Language-Team: German\n" "Language: de\n" "MIME-Version: 1.0\n" @@ -20,43 +20,48 @@ msgstr "" "X-Poedit-Basepath: .\n" "X-Poedit-SearchPath-0: ..\n" -#: src/custom_known_fields.c:94 +#: src/custom_known_fields.c:95 msgid "Prototype system" msgstr "Protoypsystem" -#: src/custom_known_fields.c:95 +#: src/custom_known_fields.c:96 msgid "Production system" msgstr "Produktionssystem" -#: src/custom_known_fields.c:96 +#: src/custom_known_fields.c:97 msgid "invalid hardware" msgstr "ungültige Hardware" -#: src/custom_known_fields.c:97 +#: src/custom_known_fields.c:98 msgid "unknown hardware" msgstr "unbekannte Hardware" -#: src/custom_known_fields.c:150 +#: src/custom_known_fields.c:156 #, c-format msgid " (%zu of % bytes missing)" msgstr " (%zu von % Byte fehlen)" -#: src/custom_known_fields.c:153 +#: src/custom_known_fields.c:159 #, c-format msgid " (% bytes)" msgstr " (% Byte)" -#: src/custom_known_fields.c:157 +#: src/custom_known_fields.c:163 #, c-format msgid " missing NUL termination!" msgstr " kein NUL-Terminator!" -#: src/custom_known_fields.c:160 +#: src/custom_known_fields.c:166 +#, c-format +msgid " (% unprintable bytes replaced by %c)" +msgstr " (% nicht druckbare Zeichen durch %c ersetzt)" + +#: src/custom_known_fields.c:170 #, c-format msgid " (% bytes)" msgstr " (% Byte)" -#: src/custom_known_fields.c:192 +#: src/custom_known_fields.c:202 #, c-format msgid "" "WARNING: %s changed to match target hardware type!\n" @@ -67,11 +72,11 @@ msgstr "" "\t\t%02 (%s) in Zielobjekt\n" "\t\t%02 (%s) aus Abbild gelesen\n" -#: src/custom_known_fields.c:209 +#: src/custom_known_fields.c:219 msgid "Unique system identification" msgstr "Eindeutige Systemkennung" -#: src/custom_known_fields.c:211 +#: src/custom_known_fields.c:221 msgid "System firmware version" msgstr "Firmwareversion des Systems" @@ -83,7 +88,12 @@ msgstr "NUMMER" msgid "Override system serial number in output" msgstr "System-Seriennummer in Ausgabe überschreiben" -#: src/custom_options.c:121 +#: src/custom_options.c:104 +#, c-format +msgid "Invalid serial number `%s' specified." +msgstr "Ungültige Seriennummer '%s' angegeben." + +#: src/custom_options.c:125 msgid "Example-specific options:" msgstr "Optionen spezifisch für Beispiel:" @@ -92,99 +102,108 @@ msgstr "Optionen spezifisch für Beispiel:" msgid "\tMissing %zu of %zu data bytes!" msgstr "\t%zu von %zu Datenbytes fehlen!" -#: src/image_formats.c:57 +#: src/find_string.c:97 +#, c-format +msgid "" +"Length prefixed string at offset [%04zx] (%zu bytes + NUL):\n" +"\t\"%s\"\n" +msgstr "" +"Zeichenkette mit Längenpräfix an Position [%04zx] (%zu Byte + NUL):\n" +"\t\"%s\"\n" + +#: src/image_formats.c:56 #, c-format msgid "Image file \"%s\" is not in Intel Hex format, trying raw binary.\n" msgstr "" "Abbilddatei \"%s\" ist nicht im Intel-Hex-Format, versuche Binärformat.\n" -#: src/image_formats.c:71 +#: src/image_formats.c:70 #, c-format msgid "Invalid input image file format.\n" msgstr "Ungültiges Format für Binärabbild.\n" -#: src/image_formats.c:100 +#: src/image_formats.c:95 #, c-format msgid "Invalid output image file format specified.\n" msgstr "Ungültiges Ausgabeformat für Binärabbild.\n" -#: src/image_ihex.c:81 src/image_raw.c:171 src/image_raw.c:219 +#: src/image_ihex_input.c:77 src/image_raw.c:168 src/image_raw.c:216 #, c-format msgid "Cannot open image \"%s\" (%s)\n" msgstr "Abbilddatei \"%s\" kann nicht geöffnet werden (%s)\n" -#: src/image_ihex.c:86 +#: src/image_ihex_input.c:82 #, c-format msgid "Could not determine data range in Intel Hex file \"%s\" (%s)\n" msgstr "" "Konnte Datenbereich in der Intel-Hex-Datei \"%s\" nicht ermitteln (%s)\n" -#: src/image_ihex.c:90 src/image_raw.c:176 +#: src/image_ihex_input.c:86 src/image_raw.c:173 #, c-format msgid "Image file \"%s\" is empty\n" msgstr "Abbilddatei \"%s\" ist leer\n" -#: src/image_ihex.c:97 src/image_raw.c:179 +#: src/image_ihex_input.c:91 src/image_raw.c:176 #, c-format msgid "Image file \"%s\" is too small, %zu of %zu bytes missing\n" msgstr "Abbilddatei \"%s\" ist zu klein, %zu von %zu Byte fehlen\n" -#: src/image_ihex.c:105 src/image_ihex.c:110 +#: src/image_ihex_input.c:99 src/image_ihex_input.c:104 #, c-format msgid "Could not copy data from Intel Hex file \"%s\" (%s)\n" msgstr "Konnte keine Daten aus der Intel-Hex-Datei \"%s\" kopieren (%s)\n" -#: src/image_ihex.c:234 +#: src/image_ihex_output.c:145 #, c-format msgid "Cannot open output image \"%s\" (%s)\n" msgstr "Abbilddatei \"%s\" für Ausgabe kann nicht geöffnet werden (%s)\n" -#: src/image_raw.c:107 +#: src/image_raw.c:105 #, c-format msgid "%s: copy %zu bytes from file offset %zu to %p\n" msgstr "%s: Kopiere %zu Byte von Dateiposition %zu nach %p\n" -#: src/image_raw.c:118 +#: src/image_raw.c:115 #, c-format msgid "Failed to read %s (%zu bytes) from file offset %zu to %p (%s)\n" msgstr "" "Fehler beim Lesen von %s (%zu Byte) von Dateiposition %zu nach %p (%s)\n" -#: src/image_raw.c:222 +#: src/image_raw.c:219 #, c-format msgid "Cannot resize image file \"%s\" to %zu bytes (%s)\n" msgstr "Abbilddatei \"%s\" kann nicht auf %zu Bytes vergrößert werden (%s)\n" -#: src/image_raw.c:230 +#: src/image_raw.c:227 #, c-format msgid "Cannot write image file \"%s\" (%s)\n" msgstr "Abbilddatei \"%s\" kann nicht geschrieben werden (%s)\n" -#: src/options.c:60 +#: src/options.c:62 msgid "Input / output options:" msgstr "Ein- / Ausgabeoptionen:" -#: src/options.c:61 +#: src/options.c:63 msgid "SECTION" msgstr "SEKTION" -#: src/options.c:62 -msgid "Use SECTION from ELF file instead of default" -msgstr "Benutze SEKTION aus der ELF-Datei" +#: src/options.c:64 +msgid "Use SECTION from ELF file instead of the default (" +msgstr "Benutze SEKTION aus der ELF-Datei anstatt der Standardsektion (" -#: src/options.c:63 src/options.c:70 +#: src/options.c:66 src/options.c:77 msgid "FILE" msgstr "DATEI" -#: src/options.c:64 +#: src/options.c:67 msgid "Read binary input data from image FILE" msgstr "Lese Eingabe-Binärdaten aus der Abbild-DATEI" -#: src/options.c:67 src/options.c:74 src/options.c:85 +#: src/options.c:70 src/options.c:81 src/options.c:92 msgid "FORMAT" msgstr "FORMAT" -#: src/options.c:68 +#: src/options.c:71 msgid "" "Format of input image file. FORMAT can be either \"raw\", \"ihex\" or \"auto" "\" (default)" @@ -192,11 +211,11 @@ msgstr "" "Format der Eingabe-Abbilddatei. Unterstützte FORMATe: \"raw\", \"ihex\" " "oder \"auto\" (standard)" -#: src/options.c:71 +#: src/options.c:78 msgid "Write binary data to output image FILE" msgstr "Binärdaten in Ausgabe-Abbilddatei DATEI schreiben" -#: src/options.c:75 +#: src/options.c:82 msgid "" "Format of output image file. FORMAT can be either \"raw\" or \"ihex" "\" (default)" @@ -204,11 +223,11 @@ msgstr "" "Format der Ausgabe-Abbilddatei. Unterstützte FORMATe: \"raw\" oder \"ihex" "\" (standard)" -#: src/options.c:77 +#: src/options.c:84 msgid "FIELD=BYTES,..." msgstr "FELD=BYTES,..." -#: src/options.c:78 +#: src/options.c:85 msgid "" "Override the given fields' values (comma-separated pairs).\n" "Each FIELD symbol name must be followed by an equal sign and the data BYTES " @@ -220,134 +239,154 @@ msgstr "" "Hexadezimal-Kodierung stehen. Nicht spezifizierte Bytes bleiben " "unverändert, zu viele führen zum Fehler." -#: src/options.c:84 +#: src/options.c:91 msgid "Display information from parsed files:" msgstr "Information aus analysierten Dateien auflisten:" -#: src/options.c:86 +#: src/options.c:93 msgid "" "Print field values. FORMAT can be either \"pretty\" (default) or \"hex\"" msgstr "" "Werte der Felder ausgeben. Unterstützte FORMATe: \"pretty\" (standard) oder " "\"hex\"" -#: src/options.c:89 +#: src/options.c:96 msgid "Print symbol address for each field" msgstr "Symboladresse für jedes Feld ausgeben" -#: src/options.c:91 +#: src/options.c:98 msgid "Show object symbol names instead of field decriptions" msgstr "Symbolnamen anstatt Feldbeschreibungen anzeigen" -#: src/options.c:93 +#: src/options.c:100 msgid "Print size in bytes for each field" msgstr "Größe in Byte für jedes Feld ausgeben" -#: src/options.c:94 +#: src/options.c:102 +msgid "Print size in bytes for the whole image" +msgstr "Größe in Byte für das gesamte Abbild ausgeben" + +#: src/options.c:103 msgid "MIN-LEN" msgstr "ANZAHL" -#: src/options.c:95 -msgid "Locate strings of at least MIN-LEN bytes in input" -msgstr "Zeichenketten mit mindestens ANZAHL Byte in Eingabe suchen" +#: src/options.c:104 +#, fuzzy +msgid "" +"Locate strings of at least MIN-LEN bytes in input (argument defaults to " +msgstr "" +"Zeichenketten mit mindestens ANZAHL Byte in Eingabe suchen (falls nicht " +"angegeben " -#: src/options.c:102 +#: src/options.c:113 msgid "IN_MAP [OUT_MAP]" msgstr "EINGABE_ELF [AUSGABE_ELF]" -#: src/options.c:106 +#: src/options.c:117 msgid "" "Analyze, transform and manipulate binary data based on ELF symbol tables." msgstr "" "Analyse, Umwandlung und Manipulation von Binärdaten anhand von ELF-" "Symboltabellen." -#: src/options.c:151 src/options.c:158 +#: src/options.c:164 src/options.c:171 #, c-format msgid "Invalid binary image format `%s' specified." msgstr "Ungültiges Format '%s' für Binärabbild angegeben." -#: src/options.c:169 +#: src/options.c:182 #, c-format msgid "Minimum string length %d out of range." msgstr "Minimale Zeichenkettenlänge %d außerhalb des gültigen Bereichs." -#: src/options.c:178 +#: src/options.c:191 #, c-format msgid "Unknown print format `%s' specified." msgstr "Unbekanntes Ausgabeformat '%s' angegeben." -#: src/options.c:196 +#: src/options.c:213 +#, c-format msgid "Too many map file arguments." msgstr "Zu viele Dateien für Symbolzuordnung." -#: src/options.c:201 +#: src/options.c:218 +#, c-format msgid "Missing file name." msgstr "Dateiname fehlt." -#: src/override.c:77 +#: src/override.c:74 #, c-format msgid "%s: Override directive truncated during append.\n" msgstr "%s: Zuweisungsliste beim Anhängen abgeschnitten.\n" -#: src/override.c:85 +#: src/override.c:80 #, c-format msgid "Could not append override directive \"" msgstr "Konnte Zuweisungsliste \"" -#: src/override.c:87 +#: src/override.c:82 #, c-format msgid "\".\n" msgstr "\" nicht anhängen.\n" -#: src/override.c:120 +#: src/override.c:113 #, c-format msgid "Failed after parsing %d hex bytes with \"%s\" remaining (%s)\n" msgstr "Fehler nach %d verarbeiteten Hex-Byte, Restdaten: \"%s\" (%s)\n" -#: src/override.c:139 +#: src/override.c:131 #, c-format msgid "%s: \"%s\"\n" msgstr "%s: \"%s\"\n" -#: src/override.c:146 +#: src/override.c:137 #, c-format msgid "Missing symbol name in list member %d\n" msgstr "Symbolname fehlt im Listeneintrag %d\n" -#: src/override.c:159 +#: src/override.c:149 #, c-format msgid "Parsed %d bytes for field %s\n" msgstr "%d Byte für Feld %s geparsed\n" -#: src/override.c:164 +#: src/override.c:153 msgid "Could not parse byte data" msgstr "Konnte Byte-Inhalte nicht parsen" -#: src/override.c:165 +#: src/override.c:154 msgid "Field not found" msgstr "Feld nicht gefunden" -#: src/override.c:166 +#: src/override.c:155 #, c-format msgid "Unable to parse override `%.*s' (%s)\n" msgstr "Kann Zuweisung '%.*s' nicht parsen (%s)\n" -#: src/symbol_map.c:93 +#: src/symbol_map.c:92 #, c-format msgid "Could not access section header string table: %s\n" msgstr "Kann nicht auf Sektions-Header-Stringtabelle zugreifen: %s\n" -#: src/symbol_map.c:103 +#: src/symbol_map.c:101 #, c-format msgid "%s: [%zu] %s\n" msgstr "%s: [%zu] %s\n" -#: src/symbol_map.c:116 +#: src/symbol_map.c:113 #, c-format msgid "Header of ELF section %zu inaccessible: %s\n" msgstr "Header der ELF-Sektion %zu unlesbar: %s\n" +#: src/symbol_map.c:117 +#, c-format +msgid "No ELF symbol table found\n" +msgstr "Keine ELF-Symboltabelle gefunden\n" + +#: src/symbol_map.c:118 +#, c-format +msgid "No ELF section named '%s' found\n" +msgstr "Keine ELF-Sektion namens '%s' gefunden\n" + #: src/symbol_map.c:136 #, c-format msgid "Could not allocate image data: %s\n" @@ -362,12 +401,17 @@ msgstr "Kein ELF-Objekt" msgid "Cannot open symbol map \"%s\" (%s)\n" msgstr "Symbolzuordnung \"%s\" kann nicht geöffnet werden (%s)\n" -#: src/transform.c:66 +#: src/symbol_map.c:295 +#, c-format +msgid "Section image size: %zu bytes\n" +msgstr "Größe der Sektion: %zu Byte\n" + +#: src/transform.c:64 #, c-format msgid "%s: Target `%s' (%p) matches source symbol %p\n" msgstr "%s: Ziel '%s' (%p) entspricht Symbol %p in Quelle\n" -#: src/transform.c:74 +#: src/transform.c:70 #, c-format msgid "%s: %zu of %zu bytes copied\n" msgstr "%s: %zu von %zu Byte kopiert\n" diff --git a/snippet/.gitignore b/snippet/.gitignore new file mode 100644 index 0000000..2a3a2f9 --- /dev/null +++ b/snippet/.gitignore @@ -0,0 +1,4 @@ +/_Noreturn.h +/arg-nonnull.h +/c++defs.h +/warn-on-use.h diff --git a/src/.gitignore b/src/.gitignore index d0cad4f..d844ba2 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1,4 +1,8 @@ *.elf *.bin *.eep +*.lo +*.la /elf-mangle +/.deps +/.libs diff --git a/src/Makefile.am b/src/Makefile.am index 4629a14..d2e6c74 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,3 @@ -# Hey Emacs, this is a -*- makefile -*- - # Copyright (C) 2014 Andre Colomb # # This file is part of elf-mangle. @@ -21,47 +19,65 @@ AM_CPPFLAGS = -D_POSIX $(CPPFLAGS_INTELHEX_INTERNAL) $(CPPFLAGS_GNULIB) AM_CFLAGS = -Wall -Wstrict-prototypes -Wextra -fgnu89-inline -AM_LDFLAGS = $(LDFLAGS_INTELHEX_INTERNAL) DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ if HAVE_INTELHEX_INTERNAL CPPFLAGS_INTELHEX_INTERNAL = -I$(top_srcdir)/libcintelhex/include -LDFLAGS_INTELHEX_INTERNAL = -L$(top_builddir)/libcintelhex/bin -static +LIBS_CINTELHEX += $(top_builddir)/libcintelhex/src/libcintelhex.la endif if USE_GNULIB CPPFLAGS_GNULIB = -I$(top_builddir)/gnulib -I$(top_srcdir)/gnulib +LIBS_GNULIB = $(top_builddir)/gnulib/libgnu.la endif -noinst_LIBRARIES = libfallback.a +noinst_LTLIBRARIES = libfallback.la bin_PROGRAMS = elf-mangle +EXTRA_DIST = include_order.txt -libfallback_a_SOURCES = \ +libfallback_la_SOURCES = \ fallback_options.c \ fallback_known_fields.c elf_mangle_SOURCES = \ elf-mangle.c \ options.c \ + options.h \ override.c \ + override.h \ print_symbols.c \ + print_symbols.h \ transform.c \ + transform.h \ image_formats.c \ - $(IMAGE_IHEX) \ + image_formats.h \ + $(IMAGE_IHEX_INPUT) \ + image_ihex_output.c \ + image_ihex.h \ image_raw.c \ + image_raw.h \ symbol_map.c \ + symbol_map.h \ symbol_list.c \ + symbol_list.h \ + known_fields.h \ field_print.c \ + field_print.h \ field_list.c \ + field_list.h \ nvm_field.c \ - find_string.c + nvm_field.h \ + find_string.c \ + find_string.h \ + intl.h \ + gettext.h if HAVE_INTELHEX -IMAGE_IHEX = image_ihex.c -LIBS_CINTELHEX = -lcintelhex +IMAGE_IHEX_INPUT = \ + image_ihex_input.c endif if CUSTOM_OPTIONS @@ -73,9 +89,5 @@ elf_mangle_SOURCES += \ custom_known_fields.c endif -if USE_GNULIB -LIBS_GNULIB = $(top_builddir)/gnulib/libgnu.a -endif - -elf_mangle_LDADD = $(LIBS_CINTELHEX) $(LIBS_GNULIB) @LIBINTL@ -elf_mangle_LDADD += libfallback.a +elf_mangle_LDADD = $(LIBS_CINTELHEX) $(LIBS_GNULIB) $(LIBS_ELF) $(LTLIBINTL) +elf_mangle_LDADD += libfallback.la diff --git a/src/Makefile.simple b/src/Makefile.simple index d92ec12..3170f05 100644 --- a/src/Makefile.simple +++ b/src/Makefile.simple @@ -26,7 +26,8 @@ elf_mangle_SRC = \ print_symbols.c \ transform.c \ image_formats.c \ - image_ihex.c \ + image_ihex_input.c \ + image_ihex_output.c \ image_raw.c \ symbol_map.c \ symbol_list.c \ diff --git a/src/custom_known_fields.c b/src/custom_known_fields.c index 5838063..78d2f57 100644 --- a/src/custom_known_fields.c +++ b/src/custom_known_fields.c @@ -42,6 +42,7 @@ #include #include +#include #include @@ -127,8 +128,8 @@ static void print_version(const char *data, size_t size) { /// Length of the version string field including the NUL terminator - uint8_t version_length = 0; - const char *version_string = NULL; + uint8_t version_length = 0, unprintable = 0; + const char *version_string = NULL, placeholder = '.'; if (size >= version_length_offset + sizeof(version_length)) { version_length = convert_uint8(data + version_length_offset); @@ -143,7 +144,12 @@ print_version(const char *data, size_t size) // Abort when given string length is reached or string is NUL-terminated if (version_string >= data + version_string_offset + version_length || *version_string == '\0') break; - putchar(*version_string); + if (isprint((int) *version_string)) { + putchar(*version_string); + } else { + putchar(placeholder); + ++unprintable; + } ++version_string; } if (size < version_string_offset + version_length) { @@ -156,6 +162,10 @@ print_version(const char *data, size_t size) || *version_string != '\0') { printf(_(" missing NUL termination!")); } + if (unprintable > 0) { + printf(_(" (%" PRIu8 " unprintable bytes replaced by %c)"), + unprintable, placeholder); + } } else { //no valid data printf(_(" (%" PRIu8 " bytes)"), version_length); } diff --git a/src/custom_options.c b/src/custom_options.c index 52c2d48..62ace55 100644 --- a/src/custom_options.c +++ b/src/custom_options.c @@ -41,9 +41,9 @@ #include "intl.h" #include -#include #include #include +#include @@ -66,20 +66,23 @@ static const struct argp_option dummy_options[] = -/// Helper to byteswap one word +/// Translate serial number argument to a symbol override static inline int -swap_endian(int input) +parse_serial(char **overrides, const char *arg) { - int output; -#ifndef _XOPEN_SOURCE - char *in_bytes = (void*) &input, *out_bytes = (void*) &output; - out_bytes[0] = in_bytes[1]; - out_bytes[1] = in_bytes[0]; -#else - swab(&input, &output, sizeof(output)); -#endif - - return output; + int serial = 0; + + switch (sscanf(arg, "%d", &serial)) { + case 1: + if (serial <= 0 || serial > UINT16_MAX) return -1; + *overrides = override_append(*overrides, "nvm_unique=%02x%02x", + (serial >> 0) & 0xFFU, + (serial >> 8) & 0xFFU); + return 0; + + default: + return -1; + } } @@ -97,8 +100,9 @@ dummy_parse_opt( switch (key) { case OPT_SET_SERIAL: - tool->overrides = override_append(tool->overrides, "nvm_unique=%04x", - swap_endian(atoi(arg))); + if (0 != parse_serial(&tool->overrides, arg)) { + argp_error(state, _("Invalid serial number `%s' specified."), arg); + } break; default: diff --git a/src/elf-mangle.c b/src/elf-mangle.c index 9105202..f89157c 100644 --- a/src/elf-mangle.c +++ b/src/elf-mangle.c @@ -1,6 +1,6 @@ ///@file -///@brief Compile-time configuration constants -///@copyright Copyright (C) 2014 Andre Colomb +///@brief Main program logic +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle, a tool to analyze, transform and /// manipulate binary data based on ELF symbol tables. @@ -42,18 +42,14 @@ -/// Default ELF section to use -#define DEFAULT_SECTION ".eeprom" - - - ///@brief Process symbol maps and binary data according to application arguments -static void +///@return Zero for success or no symbols, negative on error +static int process_maps(const tool_config *config) { nvm_symbol_map_source *map_in = NULL, *map_out = NULL, *map_write = NULL; nvm_symbol *symbols_in = NULL, *symbols_out = NULL; - int num_in, num_out; + int num_in, num_out, ret_code = 0; // Read input symbol layout and associated image data map_in = symbol_map_open_file(config->map_files[0]); @@ -66,7 +62,7 @@ process_maps(const tool_config *config) // Scan for strings if requested if (config->locate_strings >= 0) nvm_string_list( symbol_map_blob_address(map_in), symbol_map_blob_size(map_in), - config->locate_strings); + config->locate_strings, config->show_fields & showSymbol); // Translate data from input to output layout if supplied map_out = symbol_map_open_file(config->map_files[1]); @@ -82,12 +78,15 @@ process_maps(const tool_config *config) // Incorporate symbol overrides parse_overrides(config->overrides, symbols_out, num_out); //FIXME // Print out information if requested + if (config->show_size) symbol_map_print_size(map_write, config->show_fields & showSymbol); print_symbol_list(symbols_out, num_out, config->show_fields, config->print_content); // Store output image to file if (config->image_out) image_write_file( config->image_out, symbol_map_blob_address(map_write), symbol_map_blob_size(map_write), config->format_out); + } else { + ret_code = num_in; //propagate error code or no symbols } free(symbols_in); @@ -95,6 +94,7 @@ process_maps(const tool_config *config) symbol_map_close(map_in); symbol_map_close(map_out); + return ret_code; } @@ -103,10 +103,11 @@ process_maps(const tool_config *config) int main(int argc, char **argv) { - int ret_code = 0; + int ret_code; tool_config config = { .section = DEFAULT_SECTION, .locate_strings = -1, + .show_size = 0, .show_fields = showNone, .print_content = printNone, .format_out = formatIntelHex, @@ -122,7 +123,7 @@ main(int argc, char **argv) if (ret_code != 0) return ret_code; // Process specified actions - process_maps(&config); + ret_code = -process_maps(&config); free(config.overrides); diff --git a/src/field_list.c b/src/field_list.c index ab849da..020d878 100644 --- a/src/field_list.c +++ b/src/field_list.c @@ -1,6 +1,6 @@ ///@file ///@brief Linked list of field descriptors -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -30,9 +30,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -56,9 +55,7 @@ field_list_find(const char *symbol, const nvm_field_list *list) for (entry = list->start; entry; entry = entry->next) { comp = strcmp(entry->field.symbol, symbol); -#ifdef DEBUG - printf("%s: (%s; %s) = %d\n", __func__, entry->field.symbol, symbol, comp); -#endif + if (DEBUG) printf("%s: (%s; %s) = %d\n", __func__, entry->field.symbol, symbol, comp); if (comp == 0) return &entry->field; else if (comp > 0) break; } diff --git a/src/find_string.c b/src/find_string.c index 387c52c..f0785fd 100644 --- a/src/find_string.c +++ b/src/find_string.c @@ -1,6 +1,6 @@ ///@file ///@brief Locate special strings in binary images -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -24,20 +24,15 @@ #include "config.h" #include "find_string.h" +#include "intl.h" #include #include #include #include -#ifdef DEBUG -#undef DEBUG -#endif - - - -/// Default minimum length of strings to locate -#define MIN_LENGTH_DEFAULT (4) +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -58,38 +53,28 @@ nvm_string_find(const char* blob, size_t size, uint8_t min_length) const char *c; uint8_t printable = 0; - if (min_length == 0) min_length = MIN_LENGTH_DEFAULT; + if (min_length == 0) min_length = FIND_STRING_DEFAULT_LENGTH; - for (c = blob + 1; c < blob + size; ++c) { -#ifdef DEBUG - printf("[%04zx] ", c - blob); -#endif + for (c = blob + 1; c < blob + size; ++c) { //skip first possible length byte + if (DEBUG) printf("[%04zx] ", c - blob); if (*c == '\0') { //string ends at NUL terminator -#ifdef DEBUG - puts("NUL"); -#endif + if (DEBUG) puts("NUL"); while (printable >= min_length) { -#ifdef DEBUG - printf("\tprintable=%u length=%hhu\n", printable, c[-printable - 1]); -#endif - if (printable + 1 == (uint8_t) c[-printable - 1]) return c - printable; + if (DEBUG) printf("\tprintable=%u length=%hhu\n", printable, c[-printable - 1]); + if (printable + 1 //number of printable characters plus NUL + == (uint8_t) c[-printable - 1]) //matches length byte value + return c - printable; --printable; } printable = 0; } else if (isprint((int) *c)) { //printable character, might be part of string if (printable < UINT8_MAX) ++printable; -#ifdef DEBUG - printf("'%c'", *c); -#endif + if (DEBUG) printf("'%c'", *c); } else { printable = 0; -#ifdef DEBUG - printf("<%03hhu>", *c); -#endif + if (DEBUG) printf("<%03hhu>", *c); } -#ifdef DEBUG - printf("\tprintable=%u\n", printable); -#endif + if (DEBUG) printf("\tprintable=%u\n", printable); } return NULL; } @@ -99,15 +84,19 @@ nvm_string_find(const char* blob, size_t size, uint8_t min_length) /// Strings are located by repeatedly calling nvm_string_find(), /// skipping over any previous match. void -nvm_string_list(const char* blob, size_t size, uint8_t min_length) +nvm_string_list(const char* blob, size_t size, uint8_t min_length, int parseable) { const char *next; while (size) { next = nvm_string_find(blob, size, min_length); if (! next) break; - printf("String at offset [%04zx] (%zu bytes + NUL):\n\t" - "\"%s\"\n", next - blob, strlen(next), next); + printf(parseable + ? ("lpstring [%04zx] (%zu bytes + NUL):\n\t" + "\"%s\"\n") + : _("Length prefixed string at offset [%04zx] (%zu bytes + NUL):\n\t" + "\"%s\"\n"), + next - 1 - blob, strlen(next), next); next += strlen(next) + 1; size -= next - blob; blob = next; diff --git a/src/find_string.h b/src/find_string.h index 3e8d2f5..88d911d 100644 --- a/src/find_string.h +++ b/src/find_string.h @@ -28,6 +28,10 @@ #include +/// Default minimum length of strings to locate +#define FIND_STRING_DEFAULT_LENGTH 4 + + ///@brief Find strings prefixed with single-byte length specification ///@return Start of string or NULL if none found const char* nvm_string_find( @@ -40,7 +44,8 @@ const char* nvm_string_find( void nvm_string_list( const char* blob, ///< [in] Binary data to search in size_t size, ///< [in] Size of binary data - uint8_t min_length ///< [in] Minimum string length passed to nvm_string_find() + uint8_t min_length, ///< [in] Minimum string length passed to nvm_string_find() + int parseable ///< [in] Avoid localized output ); #endif //FIND_STRING_H_ diff --git a/src/image_formats.c b/src/image_formats.c index e1ba13d..a88ed67 100644 --- a/src/image_formats.c +++ b/src/image_formats.c @@ -1,6 +1,6 @@ ///@file ///@brief Handling of different binary image formats -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -30,9 +30,8 @@ #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -81,19 +80,15 @@ image_write_file(const char *filename, { if (! filename || ! blob || ! blob_size) return; -#ifdef DEBUG - printf("%s: Output file \"%s\" format %d\n", __func__, filename, format); -#endif + if (DEBUG) printf("%s: Output file \"%s\" format %d\n", __func__, filename, format); switch (format) { case formatRawBinary: image_raw_write_file(filename, blob, blob_size); break; -#if HAVE_INTELHEX case formatIntelHex: image_ihex_write_file(filename, blob, blob_size); break; -#endif case formatNone: default: diff --git a/src/image_ihex_input.c b/src/image_ihex_input.c new file mode 100644 index 0000000..efa4f05 --- /dev/null +++ b/src/image_ihex_input.c @@ -0,0 +1,115 @@ +///@file +///@brief Handle input of blob data from Intel Hex files +///@copyright Copyright (C) 2014, 2015 Andre Colomb +/// +/// This file is part of elf-mangle. +/// +/// This file is free software: you can redistribute it and/or modify +/// it under the terms of the GNU Lesser General Public License as +/// published by the Free Software Foundation, either version 3 of the +/// License, or (at your option) any later version. +/// +/// elf-mangle is distributed in the hope that it will be useful, but +/// WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +/// Lesser General Public License for more details. +/// +/// You should have received a copy of the GNU Lesser General Public +/// License along with this program. If not, see +/// . +/// +///@author Andre Colomb + + +#include "config.h" + +#include "image_ihex.h" +#include "image_raw.h" +#include "intl.h" + +#include + +#include +#include +#include + +/// Compile diagnostic output messages? +#define DEBUG 0 + + + +int +image_ihex_merge_file(const char *filename, + const nvm_symbol *list, int list_size, + size_t blob_size) +{ + ihex_recordset_t *rs; + uint32_t start, end; + char *blob; + int symbols = 0; + + if (! filename || ! blob_size) return -1; //invalid parameters + + rs = ihex_rs_from_file(filename); + if (! rs) { + switch (ihex_errno()) { + case IHEX_ERR_INCORRECT_CHECKSUM: + case IHEX_ERR_NO_EOF: + case IHEX_ERR_PARSE_ERROR: + case IHEX_ERR_WRONG_RECORD_LENGTH: + case IHEX_ERR_UNKNOWN_RECORD_TYPE: + // Parse error, not a well-formed Intel Hex file + return 0; + + case IHEX_ERR_NO_INPUT: + case IHEX_ERR_MMAP_FAILED: + case IHEX_ERR_READ_FAILED: + // File not accessible + symbols = -2; + break; + + case IHEX_ERR_MALLOC_FAILED: + default: + // System error + symbols = -3; + break; + } + fprintf(stderr, _("Cannot open image \"%s\" (%s)\n"), filename, ihex_error()); + return symbols; + } + + if (0 != ihex_rs_get_address_range(rs, &start, &end)) { + fprintf(stderr, _("Could not determine data range in Intel Hex file \"%s\" (%s)\n"), + filename, ihex_error()); + symbols = -4; + } else if (rs->ihrs_count == 0 || start >= end) { + fprintf(stderr, _("Image file \"%s\" is empty\n"), filename); + } else { + if (DEBUG) printf("%s: %s contains range 0x%04" PRIx32 " to 0x%04" PRIx32 "\n", + __func__, filename, start, end > 0 ? end - 1 : 0); + if (blob_size > end) { + fprintf(stderr, _("Image file \"%s\" is too small, %zu of %zu bytes missing\n"), + filename, blob_size - end, blob_size); + blob_size = end; + } + + // Allocate and initialize memory for needed ihex content + blob = calloc(1, blob_size); + if (! blob) { + fprintf(stderr, _("Could not copy data from Intel Hex file \"%s\" (%s)\n"), + filename, strerror(errno)); + symbols = -3; + } else { + if (0 != ihex_byte_copy(rs, (void*) blob, blob_size, 0)) { + fprintf(stderr, _("Could not copy data from Intel Hex file \"%s\" (%s)\n"), + filename, ihex_error()); + symbols = -4; + } else { + symbols = image_raw_merge_mem(blob, list, list_size, blob_size); + } + free(blob); + } + } + ihex_rs_free(rs); + return symbols; +} diff --git a/src/image_ihex.c b/src/image_ihex_output.c similarity index 61% rename from src/image_ihex.c rename to src/image_ihex_output.c index d36e846..74edd4f 100644 --- a/src/image_ihex.c +++ b/src/image_ihex_output.c @@ -1,6 +1,6 @@ ///@file -///@brief Handle input and output of blob data to Intel Hex files -///@copyright Copyright (C) 2014 Andre Colomb +///@brief Handle output of blob data to Intel Hex files +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -24,101 +24,14 @@ #include "config.h" #include "image_ihex.h" -#include "image_raw.h" #include "intl.h" -#include - -#include -#include #include -#include #include #include -#ifdef DEBUG -#undef DEBUG -#endif - - - -int -image_ihex_merge_file(const char *filename, - const nvm_symbol *list, int list_size, - size_t blob_size) -{ - ihex_recordset_t *rs; - uint32_t start, end; - char *blob; - int symbols = 0; - - if (! filename || ! blob_size) return -1; //invalid parameters - - rs = ihex_rs_from_file(filename); - if (! rs) { - switch (ihex_errno()) { - case IHEX_ERR_INCORRECT_CHECKSUM: - case IHEX_ERR_NO_EOF: - case IHEX_ERR_PARSE_ERROR: - case IHEX_ERR_WRONG_RECORD_LENGTH: - case IHEX_ERR_UNKNOWN_RECORD_TYPE: - // Parse error, not a well-formed Intel Hex file - return 0; - - case IHEX_ERR_NO_INPUT: - case IHEX_ERR_MMAP_FAILED: - case IHEX_ERR_READ_FAILED: - // File not accessible - symbols = -2; - break; - - case IHEX_ERR_MALLOC_FAILED: - default: - // System error - symbols = -3; - break; - } - fprintf(stderr, _("Cannot open image \"%s\" (%s)\n"), filename, ihex_error()); - return symbols; - } - - if (0 != ihex_rs_get_address_range(rs, &start, &end)) { - fprintf(stderr, _("Could not determine data range in Intel Hex file \"%s\" (%s)\n"), - filename, ihex_error()); - symbols = -4; - } else if (rs->ihrs_count == 0 || start >= end) { - fprintf(stderr, _("Image file \"%s\" is empty\n"), filename); - } else { -#ifdef DEBUG - printf("%s: %s contains range 0x%04" PRIx32 " to 0x%04" PRIx32 "\n", - __func__, filename, start, end > 0 ? end - 1 : 0); -#endif - if (blob_size > end) { - fprintf(stderr, _("Image file \"%s\" is too small, %zu of %zu bytes missing\n"), - filename, blob_size - end, blob_size); - blob_size = end; - } - - // Allocate and initialize memory for needed ihex content - blob = calloc(1, blob_size); - if (! blob) { - fprintf(stderr, _("Could not copy data from Intel Hex file \"%s\" (%s)\n"), - filename, strerror(errno)); - symbols = -3; - } else { - if (0 != ihex_byte_copy(rs, (void*) blob, blob_size, 0)) { - fprintf(stderr, _("Could not copy data from Intel Hex file \"%s\" (%s)\n"), - filename, ihex_error()); - symbols = -4; - } else { - symbols = image_raw_merge_mem(blob, list, list_size, blob_size); - } - free(blob); - } - } - ihex_rs_free(rs); - return symbols; -} +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -188,10 +101,8 @@ ihex_write( else reclen = default_length; // Limit to current segment if (load_offset + reclen > segment_length) reclen = segment_length - load_offset; -#ifdef DEBUG - printf("%s: Record len=%zu source=%p rest=%zu USBA=%" PRIu32 "\n", - __func__, reclen, blob, blob_size, segment_base); -#endif + if (DEBUG) printf("%s: Record len=%zu source=%p rest=%zu USBA=%" PRIu32 "\n", + __func__, reclen, blob, blob_size, segment_base); // Write record data if (reclen) ihex_write_single_record(out, reclen, load_offset, rec_data, blob); diff --git a/src/image_raw.c b/src/image_raw.c index 5eb23fd..88d7872 100644 --- a/src/image_raw.c +++ b/src/image_raw.c @@ -1,6 +1,6 @@ ///@file ///@brief Handle input and output of blob data to raw binary files -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -39,9 +39,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 // Default to seek-based implementation #ifndef HAVE_MMAP @@ -103,10 +102,8 @@ read_symbol_seek_iterator( if (symbol->blob_address) { //destination ok if (symbol->offset == (size_t) lseek(conf->source.fd, symbol->offset, SEEK_SET)) { -#ifdef DEBUG - fprintf(stderr, _("%s: copy %zu bytes from file offset %zu to %p\n"), __func__, - symbol->size, symbol->offset, symbol->blob_address); -#endif + if (DEBUG) printf(_("%s: copy %zu bytes from file offset %zu to %p\n"), + __func__, symbol->size, symbol->offset, symbol->blob_address); while (rest > 0) { bytes_read = read(conf->source.fd, symbol->blob_address + (symbol->size - rest), rest); diff --git a/src/nvm_field.c b/src/nvm_field.c index a1adfb2..16b4216 100644 --- a/src/nvm_field.c +++ b/src/nvm_field.c @@ -1,6 +1,6 @@ ///@file ///@brief Helper functions to handle data field descriptors -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -29,9 +29,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -44,9 +43,7 @@ find_field(const char *symbol, for (field = fields; field < fields + num_fields; ++field) { comp = strcmp(field->symbol, symbol); -#ifdef DEBUG - printf("%s: (%s; %s) = %d\n", __func__, field->symbol, symbol, comp); -#endif + if (DEBUG) printf("%s: (%s; %s) = %d\n", __func__, field->symbol, symbol, comp); if (comp == 0) return field; else if (comp > 0) break; } diff --git a/src/options.c b/src/options.c index 3eaeb32..8594b8a 100644 --- a/src/options.c +++ b/src/options.c @@ -1,6 +1,6 @@ ///@file ///@brief Command line parsing -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -25,16 +25,13 @@ #include "options.h" #include "override.h" +#include "find_string.h" #include "intl.h" #include #include #include -#ifdef DEBUG -#undef DEBUG -#endif - ///@name Option keys @@ -49,28 +46,38 @@ #define OPT_PRINT 'p' #define OPT_ADDRESSES 'a' #define OPT_SYMBOLS 'S' -#define OPT_BYTE_SIZE 'b' +#define OPT_FIELD_SIZE 'F' +#define OPT_SECTION_SIZE 's' ///@} +/// Helper macro to show number literals in option help +#define _STR_MACRO(x) _STR(x) +#define _STR(x) #x + /// Supported command-line arguments definition static const struct argp_option options[] = { { NULL, 0, NULL, 0, - N_("Input / output options:"), 0 }, + N_("Input / output options:"), 0 }, { "section", OPT_SECTION, N_("SECTION"), 0, - N_("Use SECTION from ELF file instead of default"), 0 }, + N_("Use SECTION from ELF file instead of the default (" + DEFAULT_SECTION ")"), 0 }, { "input", OPT_INPUT, N_("FILE"), 0, N_("Read binary input data from image FILE"), 0 }, { "input-image", OPT_INPUT, NULL, OPTION_ALIAS | OPTION_HIDDEN, - NULL, 0 }, + NULL, 0 }, { "input-format", OPT_IN_FORMAT, N_("FORMAT"), 0, N_("Format of input image file. FORMAT can be either" - " \"raw\", \"ihex\" or \"auto\" (default)"), 0 }, + " \"raw\"" +#if HAVE_INTELHEX + ", \"ihex\"" +#endif + " or \"auto\" (default)"), 0 }, { "output", OPT_OUTPUT, N_("FILE"), 0, N_("Write binary data to output image FILE"), 0 }, { "output-image", OPT_OUTPUT, NULL, OPTION_ALIAS | OPTION_HIDDEN, - NULL, 0 }, + NULL, 0 }, { "output-format", OPT_OUT_FORMAT, N_("FORMAT"), 0, N_("Format of output image file. FORMAT can be either" " \"raw\" or \"ihex\" (default)"), 0 }, @@ -78,7 +85,7 @@ static const struct argp_option options[] = { N_("Override the given fields' values (comma-separated pairs).\n" "Each FIELD symbol name must be followed by an equal sign and the data" " BYTES encoded in hexadecimal. Missing bytes are left unchanged," - " extra data generates an error."), 0 }, + " extra data generates an error."), 0 }, { NULL, 0, NULL, 0, N_("Display information from parsed files:"), 0 }, @@ -89,10 +96,14 @@ static const struct argp_option options[] = { N_("Print symbol address for each field"), 0 }, { "symbols", OPT_SYMBOLS, NULL, 0, N_("Show object symbol names instead of field decriptions"), 0 }, - { "byte-size", OPT_BYTE_SIZE, NULL, 0, + { "field-size", OPT_FIELD_SIZE, NULL, 0, N_("Print size in bytes for each field"), 0 }, + { "section-size", OPT_SECTION_SIZE, NULL, 0, + N_("Print size in bytes for the whole image"), 0 }, { "strings", OPT_STRINGS, N_("MIN-LEN"), OPTION_ARG_OPTIONAL, - N_("Locate strings of at least MIN-LEN bytes in input"), 0 }, + N_("Locate strings of at least MIN-LEN bytes in input" + " (argument defaults to " _STR_MACRO(FIND_STRING_DEFAULT_LENGTH) + " if omitted)"), 0 }, { 0 } }; @@ -147,7 +158,9 @@ parse_opt( if (arg == NULL) return EINVAL; else if (strcmp(arg, "auto") == 0) tool->format_in = formatNone; else if (strcmp(arg, "raw") == 0) tool->format_in = formatRawBinary; +#if HAVE_INTELHEX else if (strcmp(arg, "ihex") == 0) tool->format_in = formatIntelHex; +#endif else argp_error(state, _("Invalid binary image format `%s' specified."), arg); break; @@ -186,10 +199,14 @@ parse_opt( tool->show_fields |= showSymbol; break; - case OPT_BYTE_SIZE: + case OPT_FIELD_SIZE: tool->show_fields |= showByteSize; break; + case OPT_SECTION_SIZE: + tool->show_size = 1; + break; + case ARGP_KEY_ARG: /* non-option -> input / output file name */ // Check number of non-option arguments if (state->arg_num >= sizeof(tool->map_files) / sizeof(*tool->map_files)) diff --git a/src/options.h b/src/options.h index ce97c88..dada761 100644 --- a/src/options.h +++ b/src/options.h @@ -29,6 +29,10 @@ #include "find_string.h" +/// Default ELF section to use +#define DEFAULT_SECTION ".eeprom" + + /// Application options typedef struct tool_config { /// Names of input and output map files @@ -45,6 +49,8 @@ typedef struct tool_config { enum image_format format_out; /// Locate strings of this minimum length within image int locate_strings; + /// Print out the total section image size in bytes + char show_size; /// Configuration flags for dumping symbol descriptions enum show_field show_fields; /// Configuration flags for dumping symbol content diff --git a/src/override.c b/src/override.c index 65dcbbd..56bd402 100644 --- a/src/override.c +++ b/src/override.c @@ -1,6 +1,6 @@ ///@file ///@brief Override symbol data from key-value string specification -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -38,9 +38,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -63,9 +62,7 @@ override_append(char *overrides, const char *append_fmt, ...) // Find length of appended override directive, plus NUL terminator add_length = vsnprintf(NULL, 0, append_fmt, args_copy) + sizeof(*new_string); -#ifdef DEBUG - printf("%s: %zu + %zu\t(%s)\n", __func__, old_length, add_length, append_fmt); -#endif + if (DEBUG) printf("%s: %zu + %zu\t(%s)\n", __func__, old_length, add_length, append_fmt); new_string = realloc(overrides, old_length + add_length); if (new_string) { @@ -77,9 +74,7 @@ override_append(char *overrides, const char *append_fmt, ...) fprintf(stderr, _("%s: Override directive truncated during append.\n"), __func__); } -#ifdef DEBUG - printf("%1$s: %2$p -> %3$p (%3$s)\n", __func__, overrides, new_string); -#endif + if (DEBUG) printf("%1$s: %2$p -> %3$p (%3$s)\n", __func__, overrides, new_string); overrides = new_string; } else { fprintf(stderr, _("Could not append override directive \"")); @@ -112,9 +107,7 @@ parse_hex_bytes( while (*start && parsed < max_length) { if (1 == sscanf(start, " %2hhx%n", &value, &converted)) { output[parsed++] = value; -#ifdef DEBUG - printf("%.*s=%02hhx,\t", converted, start, value); -#endif + if (DEBUG) printf("%.*s=%02hhx,\t", converted, start, value); start += converted; } else { fprintf(stderr, _("Failed after parsing %d hex bytes with \"%s\" remaining (%s)\n"), @@ -135,9 +128,7 @@ parse_overrides(char *overrides, const nvm_symbol *list, int size) int i, parsed = 0, length; if (! overrides || ! list) return -1; -#ifdef DEBUG - printf(_("%s: \"%s\"\n"), __func__, overrides); -#endif + if (DEBUG) printf(_("%s: \"%s\"\n"), __func__, overrides); // Mirror token list from known symbols for (i = 0; i < size; ++i) { @@ -155,9 +146,7 @@ parse_overrides(char *overrides, const nvm_symbol *list, int size) i = getsubopt(&subopt, (char**) symbols, &value); if (i >= 0 && i < size) { length = parse_hex_bytes(value, list[i].blob_address, list[i].size); -#ifdef DEBUG - printf(_("Parsed %d bytes for field %s\n"), length, symbols[i]); -#endif + if (DEBUG) printf(_("Parsed %d bytes for field %s\n"), length, symbols[i]); if (length > 0) { ++parsed; continue; diff --git a/src/print_symbols.c b/src/print_symbols.c index 8e1c0d1..27136ff 100644 --- a/src/print_symbols.c +++ b/src/print_symbols.c @@ -1,6 +1,6 @@ ///@file ///@brief Pretty-print a dump of symbols that were parsed -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -32,9 +32,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -62,9 +61,7 @@ print_symbol_description_iterator( (! symbol->field->print_func)) printf("%s:", symbol->field->symbol); else printf("%s:", symbol->field->description); if (*conf & showByteSize) printf(" %zu bytes", symbol->size); -#ifdef DEBUG - printf(" %p", symbol->blob_address); -#endif + if (DEBUG) printf(" %p", symbol->blob_address); return NULL; //continue iterating } diff --git a/src/symbol_list.c b/src/symbol_list.c index cae4c64..2bb029c 100644 --- a/src/symbol_list.c +++ b/src/symbol_list.c @@ -70,7 +70,7 @@ symbol_list_foreach_count(const nvm_symbol list[], const int size, const symbol_list_iterator_f func, const void *arg) { const nvm_symbol *sym; - int count; + int count = 0; if (! list || ! size) return 0; diff --git a/src/symbol_map.c b/src/symbol_map.c index 4dbaa3f..4db72c7 100644 --- a/src/symbol_map.c +++ b/src/symbol_map.c @@ -1,6 +1,6 @@ ///@file ///@brief Parsing of ELF files as symbol map sources -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -39,9 +39,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 /// Flags for open() system call #define OPEN_FLAGS (O_RDONLY | O_BINARY) @@ -99,10 +98,8 @@ find_symtab_and_section( while ((scn = elf_nextscn(elf, scn)) != NULL) { // Get the section header if (gelf_getshdr(scn, &shdr) != NULL) { -#ifdef DEBUG - fprintf(stderr, _("%s: [%zu] %s\n"), __func__, - elf_ndxscn(scn), elf_strptr(elf, shstrndx, shdr.sh_name)); -#endif + if (DEBUG) printf(_("%s: [%zu] %s\n"), __func__, + elf_ndxscn(scn), elf_strptr(elf, shstrndx, shdr.sh_name)); if (shdr.sh_type == SHT_SYMTAB) { *symtab = scn; *strings_index = shdr.sh_link; @@ -117,6 +114,9 @@ find_symtab_and_section( elf_ndxscn(scn), elf_errmsg(elf_errno())); } } + if (! *symtab) fprintf(stderr, _("No ELF symbol table found\n")); + if (! *section) fprintf(stderr, _("No ELF section named '%s' found\n"), + section_name); } @@ -289,6 +289,15 @@ symbol_map_blob_size(nvm_symbol_map_source *source) +void symbol_map_print_size(nvm_symbol_map_source *source, + int parseable) +{ + printf(parseable ? "total: %zu bytes\n" : _("Section image size: %zu bytes\n"), + symbol_map_blob_size(source)); +} + + + void symbol_map_close(nvm_symbol_map_source *source) { diff --git a/src/symbol_map.h b/src/symbol_map.h index 43ec211..d80321a 100644 --- a/src/symbol_map.h +++ b/src/symbol_map.h @@ -63,6 +63,12 @@ size_t symbol_map_blob_size( nvm_symbol_map_source *source ///< [in,out] Handle of the map source ); +///@brief Print out the size of the source's binary data +void symbol_map_print_size( + nvm_symbol_map_source *source, ///< [in] Handle of the map source + int parseable ///< [in] Avoid localized output + ); + ///@brief Close the symbol map source handle and free associated resources void symbol_map_close( nvm_symbol_map_source *source ///< [in,out] Handle of the map source diff --git a/src/transform.c b/src/transform.c index cb4be81..d57d8e1 100644 --- a/src/transform.c +++ b/src/transform.c @@ -1,6 +1,6 @@ ///@file ///@brief Copy symbol data between different lists -///@copyright Copyright (C) 2014 Andre Colomb +///@copyright Copyright (C) 2014, 2015 Andre Colomb /// /// This file is part of elf-mangle. /// @@ -32,9 +32,8 @@ #include #include -#ifdef DEBUG -#undef DEBUG -#endif +/// Compile diagnostic output messages? +#define DEBUG 0 @@ -62,18 +61,14 @@ transfer_field_iterator( symbol_src = symbol_list_find_field(conf->list_src, conf->num_src, symbol_dst->field); if (symbol_src) { -#ifdef DEBUG - printf(_("%s: Target `%s' (%p) matches source symbol %p\n"), __func__, - symbol_dst->field->symbol, symbol_dst, symbol_src); -#endif + if (DEBUG) printf(_("%s: Target `%s' (%p) matches source symbol %p\n"), __func__, + symbol_dst->field->symbol, symbol_dst, symbol_src); if (symbol_dst->field->copy_func) copy_func = symbol_dst->field->copy_func; copied = copy_func( symbol_dst->field, symbol_dst->blob_address, symbol_src->blob_address, symbol_dst->size); -#ifdef DEBUG - printf(_("%s: %zu of %zu bytes copied\n"), - symbol_dst->field->symbol, copied, symbol_dst->size); -#endif + if (DEBUG) printf(_("%s: %zu of %zu bytes copied\n"), + symbol_dst->field->symbol, copied, symbol_dst->size); } else { fprintf(stderr, "Target map field %s not found in source.", symbol_dst->field->symbol); } @@ -91,8 +86,6 @@ transfer_fields(const nvm_symbol *list_src, int num_src, .num_src = num_src, }; -#ifdef DEBUG - printf("%s: Copy %d symbols in to %d out\n", __func__, num_src, num_dst); -#endif + if (DEBUG) printf("%s: Copy %d symbols in to %d out\n", __func__, num_src, num_dst); symbol_list_foreach(list_dst, num_dst, transfer_field_iterator, &conf); }