scripts: Convert gen_offset_header to Python
By having this as a Python script rather than a host executable, this should simplify the build process on non-Unix platforms. With this change, pyelftools is now required to build Zephyr. Please consult the getting started documentation for your host platform for installation instructions. Jira: ZEP-2062 Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
parent
bc2454fa9e
commit
f5a8d498ea
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,7 +13,6 @@ outdir
|
|||
outdir-*
|
||||
scripts/basic/fixdep
|
||||
scripts/gen_idt/gen_idt
|
||||
scripts/gen_offset_header/gen_offset_header
|
||||
scripts/kconfig/conf
|
||||
scripts/kconfig/mconf
|
||||
scripts/kconfig/zconf.hash.c
|
||||
|
|
18
Kbuild
18
Kbuild
|
@ -51,15 +51,15 @@ arch/$(ARCH)/core/offsets/offsets.o: arch/$(ARCH)/core/offsets/offsets.c $(KCONF
|
|||
|
||||
|
||||
define offsetchk
|
||||
$(Q)set -e; \
|
||||
$(kecho) ' CHK $@'; \
|
||||
mkdir -p $(dir $@); \
|
||||
$(GENOFFSET_H) -i $(1) -o $@.tmp; \
|
||||
if [ -r $@ ] && cmp -s $@ $@.tmp; then \
|
||||
rm -f $@.tmp; \
|
||||
else \
|
||||
$(kecho) ' UPD $@'; \
|
||||
mv -f $@.tmp $@; \
|
||||
$(Q)set -e; \
|
||||
$(kecho) ' CHK $@'; \
|
||||
mkdir -p $(dir $@); \
|
||||
$(srctree)/scripts/gen_offset_header.py -i $(1) -o $@.tmp; \
|
||||
if [ -r $@ ] && cmp -s $@ $@.tmp; then \
|
||||
rm -f $@.tmp; \
|
||||
else \
|
||||
$(kecho) ' UPD $@'; \
|
||||
mv -f $@.tmp $@; \
|
||||
fi
|
||||
endef
|
||||
|
||||
|
|
8
Makefile
8
Makefile
|
@ -320,10 +320,8 @@ GDB = $(CROSS_COMPILE)gdb
|
|||
READELF = $(CROSS_COMPILE)readelf
|
||||
AWK = awk
|
||||
ifeq ($(PREBUILT_HOST_TOOLS),)
|
||||
GENOFFSET_H = scripts/gen_offset_header/gen_offset_header
|
||||
FIXDEP = scripts/basic/fixdep
|
||||
else
|
||||
GENOFFSET_H = $(PREBUILT_HOST_TOOLS)/gen_offset_header
|
||||
ifneq ($(filter host-tools, $(MAKECMDGOALS)),)
|
||||
FIXDEP = scripts/basic/fixdep
|
||||
else
|
||||
|
@ -416,7 +414,7 @@ exports += VERSION_MAJOR VERSION_MINOR PATCHLEVEL VERSION_RESERVED EXTRAVERSION
|
|||
exports += KERNELRELEASE KERNELVERSION
|
||||
exports += ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC CXX
|
||||
exports += CPP AR NM STRIP OBJCOPY OBJDUMP GDB
|
||||
exports += MAKE AWK INSTALLKERNEL PERL PYTHON GENOFFSET_H
|
||||
exports += MAKE AWK INSTALLKERNEL PERL PYTHON
|
||||
exports += HOSTCXX HOSTCXXFLAGS CHECK CHECKFLAGS
|
||||
|
||||
exports += KBUILD_CPPFLAGS NOSTDINC_FLAGS ZEPHYRINCLUDE OBJCOPYFLAGS LDFLAGS
|
||||
|
@ -456,7 +454,6 @@ PHONY += scripts_basic
|
|||
ifeq ($(PREBUILT_HOST_TOOLS),)
|
||||
scripts_basic:
|
||||
$(Q)$(MAKE) $(build)=scripts/basic
|
||||
$(Q)$(MAKE) $(build)=scripts/gen_offset_header
|
||||
else
|
||||
scripts_basic:
|
||||
endif
|
||||
|
@ -1278,10 +1275,9 @@ host-tools:
|
|||
$(Q)$(MAKE) $(build)=scripts/basic
|
||||
$(Q)$(MAKE) $(build)=scripts/kconfig standalone
|
||||
$(Q)$(MAKE) $(build)=scripts/gen_idt
|
||||
$(Q)$(MAKE) $(build)=scripts/gen_offset_header
|
||||
@mkdir -p ${ZEPHYR_BASE}/bin
|
||||
@cp scripts/basic/fixdep scripts/gen_idt/gen_idt scripts/kconfig/conf \
|
||||
scripts/gen_offset_header/gen_offset_header ${ZEPHYR_BASE}/bin
|
||||
${ZEPHYR_BASE}/bin
|
||||
|
||||
|
||||
# Documentation targets
|
||||
|
|
|
@ -63,7 +63,6 @@ environment for Windows. Follow the steps below to set it up:
|
|||
$ curl -O 'https://bootstrap.pypa.io/get-pip.py'
|
||||
$ ./get-pip.py
|
||||
$ rm get-pip.py
|
||||
|
||||
$ pip install -r scripts/requirements.txt
|
||||
|
||||
#. Build the Device Tree Compiler (DTC)
|
||||
|
|
63
scripts/gen_offset_header.py
Executable file
63
scripts/gen_offset_header.py
Executable file
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2017 Intel Corporation.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from elftools.elf.sections import SymbolTableSection
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
def get_symbol_table(obj):
|
||||
for section in obj.iter_sections():
|
||||
if isinstance(section, SymbolTableSection):
|
||||
return section
|
||||
|
||||
raise LookupError("Could not find symbol table")
|
||||
|
||||
def gen_offset_header(input_name, input_file, output_file):
|
||||
include_guard = "__INCLUDE_GUARD_%016x__" % abs(input_name.__hash__())
|
||||
output_file.write("""/* THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT.
|
||||
*
|
||||
* This header file provides macros for the offsets of various structure
|
||||
* members. These offset macros are primarily intended to be used in
|
||||
* assembly code.
|
||||
*/
|
||||
|
||||
#ifndef %s
|
||||
#define %s\n\n""" % (include_guard, include_guard))
|
||||
|
||||
obj = ELFFile(input_file)
|
||||
for sym in get_symbol_table(obj).iter_symbols():
|
||||
if isinstance(sym.name, bytes):
|
||||
sym.name = str(sym.name, 'ascii')
|
||||
|
||||
if not sym.name.endswith(('_OFFSET', '_SIZEOF')):
|
||||
continue
|
||||
if sym.entry['st_shndx'] != 'SHN_ABS':
|
||||
continue
|
||||
if sym.entry['st_info']['bind'] != 'STB_GLOBAL':
|
||||
continue
|
||||
|
||||
output_file.write("#define %s 0x%x\n" % (sym.name, sym.entry['st_value']))
|
||||
|
||||
output_file.write("\n#endif /* %s */\n" % include_guard)
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class = argparse.RawDescriptionHelpFormatter)
|
||||
|
||||
parser.add_argument("-i", "--input", required=True, help="Input object file")
|
||||
parser.add_argument("-o", "--output", required=True, help="Output header file")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
input_file = open(args.input, 'rb')
|
||||
output_file = open(args.output, 'w')
|
||||
|
||||
ret = gen_offset_header(args.input, input_file, output_file)
|
||||
sys.exit(ret)
|
|
@ -1,6 +0,0 @@
|
|||
HOSTCFLAGS_gen_offset_header.o += -DKERNEL_VERSION=0 -Wall -Werror -g
|
||||
HOSTCFLAGS_gen_idt.o += -Wno-unused-result
|
||||
|
||||
hostprogs-y += gen_offset_header
|
||||
gen_offset_header-objs := gen_offset_header.o
|
||||
always := $(hostprogs-y)
|
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 2014 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* @file
|
||||
* @brief Executable and Linking Format (ELF) definitions
|
||||
*
|
||||
* The definitions in this header conform to the "Tool Interface Standard (TIS)
|
||||
* Executable and Linking Format (ELF) Specification Version 1.2"
|
||||
*/
|
||||
|
||||
#ifndef _ELF_H
|
||||
#define _ELF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned int Elf32_Addr;
|
||||
typedef unsigned short Elf32_Half;
|
||||
typedef unsigned int Elf32_Off;
|
||||
typedef int Elf32_Sword;
|
||||
typedef unsigned int Elf32_Word;
|
||||
|
||||
|
||||
/*
|
||||
* Elf header
|
||||
*/
|
||||
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
#define EHDRSZ sizeof(Elf32_Ehdr)
|
||||
|
||||
/*
|
||||
* e_ident[] values
|
||||
*/
|
||||
#define EI_MAG0 0
|
||||
#define EI_MAG1 1
|
||||
#define EI_MAG2 2
|
||||
#define EI_MAG3 3
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define EI_VERSION 6
|
||||
#define EI_PAD 7
|
||||
|
||||
#define ELFMAG0 0x7f
|
||||
#define ELFMAG1 'E'
|
||||
#define ELFMAG2 'L'
|
||||
#define ELFMAG3 'F'
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
||||
/*
|
||||
* EI_CLASS
|
||||
*/
|
||||
#define ELFCLASSNONE 0
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
|
||||
/*
|
||||
* EI_DATA
|
||||
*/
|
||||
#define ELFDATANONE 0
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
/*
|
||||
* e_type
|
||||
*/
|
||||
#define ET_NONE 0
|
||||
#define ET_REL 1
|
||||
#define ET_EXEC 2
|
||||
#define ET_DYN 3
|
||||
#define ET_CORE 4
|
||||
#define ET_LOPROC 0xff00
|
||||
#define ET_HIPROC 0xffff
|
||||
|
||||
/*
|
||||
* e_machine
|
||||
*/
|
||||
#define EM_NONE 0 /* No machine */
|
||||
#define EM_M32 1 /* AT&T WE 32100 */
|
||||
#define EM_SPARC 2 /* SPARC */
|
||||
#define EM_386 3 /* Intel 80386 */
|
||||
#define EM_68K 4 /* Motorola 68000 */
|
||||
#define EM_88K 5 /* Motorola 88000 */
|
||||
#define EM_486 6 /* Intel 80486 */
|
||||
#define EM_860 7 /* Intel 80860 */
|
||||
#define EM_MIPS 8 /* MIPS RS3000 Big-Endian */
|
||||
#define EM_MIPS_RS4_BE 10 /* MIPS RS4000 Big-Endian */
|
||||
#define EM_PPC_OLD 17 /* PowerPC - old */
|
||||
#define EM_PPC 20 /* PowerPC */
|
||||
#define EM_RCE_OLD 25 /* RCE - old */
|
||||
#define EM_NEC_830 36 /* NEC 830 series */
|
||||
#define EM_RCE 39 /* RCE */
|
||||
#define EM_MCORE 39 /* MCORE */
|
||||
#define EM_ARM 40 /* ARM */
|
||||
#define EM_SH 42 /* SH */
|
||||
#define EM_COLDFIRE 52 /* Motorola ColdFire */
|
||||
#define EM_SC 58 /* SC */
|
||||
#define EM_M32R 36929 /* M32R */
|
||||
#define EM_NEC 36992 /* NEC 850 series */
|
||||
|
||||
/*
|
||||
* e_flags
|
||||
*/
|
||||
#define EF_PPC_EMB 0x80000000
|
||||
|
||||
#define EF_MIPS_NOREORDER 0x00000001
|
||||
#define EF_MIPS_PIC 0x00000002
|
||||
#define EF_MIPS_CPIC 0x00000004
|
||||
#define EF_MIPS_ARCH 0xf0000000
|
||||
#define EF_MIPS_ARCH_MIPS_2 0x10000000
|
||||
#define EF_MIPS_ARCH_MIPS_3 0x20000000
|
||||
|
||||
/*
|
||||
* e_version and EI_VERSION
|
||||
*/
|
||||
#define EV_NONE 0
|
||||
#define EV_CURRENT 1
|
||||
|
||||
/*
|
||||
* Special section indexes
|
||||
*/
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_LORESERVE 0xff00
|
||||
#define SHN_LOPROC 0xff00
|
||||
#define SHN_HIPROC 0xff1f
|
||||
#define SHN_ABS 0xfff1
|
||||
#define SHN_COMMON 0xfff2
|
||||
#define SHN_HIRESERVE 0xffff
|
||||
|
||||
#define SHN_GHCOMMON 0xff00
|
||||
/*
|
||||
* Section header
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type; /* SHT_... */
|
||||
Elf32_Word sh_flags; /* SHF_... */
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
#define SHDRSZ sizeof(Elf32_Shdr)
|
||||
|
||||
/*
|
||||
* sh_type
|
||||
*/
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_COMDAT 12
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
#define SHT_INIT_ARRAY 14
|
||||
#define SHT_FINI_ARRAY 15
|
||||
#define SHT_PREINIT_ARRAY 16
|
||||
#define SHT_GROUP 17
|
||||
#define SHT_SYMTAB_SHNDX 18
|
||||
#define SHT_NUM 19
|
||||
|
||||
/*
|
||||
* sh_flags
|
||||
*/
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
#define SHF_EXECINSTR 0x4
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
#define SHF_MERGE 0x10 /* not part of all ELF ABI docs */
|
||||
#define SHF_STRINGS 0x20 /* not part of all ELF ABI docs */
|
||||
#define SHF_INFO_LINK 0x40
|
||||
#define SHF_LINK_ORDER 0x80
|
||||
#define SHF_OS_NONCONFORMING 0x100
|
||||
#define SHF_GROUP 0x200
|
||||
#define SHF_TLS 0x400
|
||||
|
||||
/*
|
||||
* Symbol table
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
#define STN_UNDEF 0
|
||||
|
||||
#define STB_LOCAL 0
|
||||
#define STB_GLOBAL 1
|
||||
#define STB_WEAK 2
|
||||
#define STB_LOPROC 13
|
||||
#define STB_HIPROC 15
|
||||
|
||||
#define STT_NOTYPE 0
|
||||
#define STT_OBJECT 1
|
||||
#define STT_FUNC 2
|
||||
#define STT_SECTION 3
|
||||
#define STT_FILE 4
|
||||
#define STT_COMMON 5
|
||||
#define STT_TLS 6
|
||||
#define STT_LOOS 10
|
||||
#define STT_HIOS 12
|
||||
#define STT_LOPROC 13
|
||||
#define STT_HIPROC 15
|
||||
|
||||
#define ELF_ST_BIND(x) ((x) >> 4)
|
||||
#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
|
||||
#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
|
||||
#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
|
||||
|
||||
|
||||
/*
|
||||
* The STT_ARM_TFUNC type is used by the gnu compiler to mark Thumb
|
||||
* functions. The STT_ARM_16BIT type is the thumb equivalent of an
|
||||
* object. They are not part of the ARM ABI or EABI - they come from gnu.
|
||||
*/
|
||||
|
||||
#define STT_ARM_TFUNC STT_LOPROC /* GNU Thumb function */
|
||||
#define STT_ARM_16BIT STT_HIPROC /* GNU Thumb label */
|
||||
|
||||
|
||||
/*
|
||||
* Relocation
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
Elf32_Sword r_addend;
|
||||
} Elf32_Rela;
|
||||
|
||||
#define ELF32_R_SYM(info) ((info)>>8)
|
||||
#define ELF32_R_TYPE(info) ((unsigned char)(info))
|
||||
#define ELF32_R_INFO(sym,type) (((sym)<<8)+(unsigned char)(type))
|
||||
|
||||
/*
|
||||
* Program header
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
#define PHDRSZ sizeof(Elf32_Phdr)
|
||||
|
||||
/*
|
||||
* p_type
|
||||
*/
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
/*
|
||||
* p_flags
|
||||
*/
|
||||
#define PF_X 0x1
|
||||
#define PF_W 0x2
|
||||
#define PF_R 0x4
|
||||
#define PF_MASKPROC 0xf0000000
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag;
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
#define DT_NULL 0
|
||||
#define DT_NEEDED 1
|
||||
#define DT_PLTRELSZ 2
|
||||
#define DT_PLTGOT 3
|
||||
#define DT_HASH 4
|
||||
#define DT_STRTAB 5
|
||||
#define DT_SYMTAB 6
|
||||
#define DT_RELA 7
|
||||
#define DT_RELASZ 8
|
||||
#define DT_RELAENT 9
|
||||
#define DT_STRSZ 10
|
||||
#define DT_SYMENT 11
|
||||
#define DT_INIT 12
|
||||
#define DT_FINI 13
|
||||
#define DT_SONAME 14
|
||||
#define DT_RPATH 15
|
||||
#define DT_SYMBOLIC 16
|
||||
#define DT_REL 17
|
||||
#define DT_RELSZ 18
|
||||
#define DT_RELENT 19
|
||||
#define DT_PLTREL 20
|
||||
#define DT_DEBUG 21
|
||||
#define DT_TEXTREL 22
|
||||
#define DT_JMPREL 23
|
||||
#define DT_LOPROC 0x70000000
|
||||
#define DT_HIPROC 0x7fffffff
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ELF_H */
|
|
@ -1,670 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2014 Wind River Systems, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief generate offset definition header file
|
||||
*
|
||||
* genOffsetHeader -i <objectModule> -o <outputHeaderName>
|
||||
*
|
||||
* This Zephyr development host utility will process an ELF object module that
|
||||
* consists of a series of absolute symbols representing the byte offset of a
|
||||
* structure member and the size of the structure. Each absolute symbol will
|
||||
* be translated into a C preprocessor '#define' directive. For example,
|
||||
* assuming that the module offsets.o contains the following absolute symbols:
|
||||
*
|
||||
* $ nm offsets.o
|
||||
* 00000000 A ___kernel_t_nested_OFFSET
|
||||
* 00000004 A ___kernel_t_irq_stack_OFFSET
|
||||
* 00000008 A ___kernel_t_current_OFFSET
|
||||
* 0000000c A ___kernel_t_idle_OFFSET
|
||||
*
|
||||
* ... the following C preprocessor code will be generated:
|
||||
*
|
||||
* #define ___kernel_t_nested_OFFSET 0x0
|
||||
* #define ___kernel_t_irq_stack_OFFSET 0x4
|
||||
* #define ___kernel_t_current_OFFSET 0x8
|
||||
* #define ___kernel_t_idle_OFFSET 0xc
|
||||
*/
|
||||
|
||||
/* includes */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "elf.h"
|
||||
#include <stdlib.h> /* for malloc()/free()/exit() */
|
||||
#include <string.h> /* for strstr() */
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* defines */
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/* the symbol name suffix used to denote structure member offsets */
|
||||
|
||||
#define STRUCT_OFF_SUFFIX "_OFFSET"
|
||||
#define STRUCT_SIZ_SUFFIX "_SIZEOF"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG_PRINT(args...) printf(args)
|
||||
#else
|
||||
#define DBG_PRINT(args...)
|
||||
#endif
|
||||
|
||||
|
||||
/* byte swapping macros */
|
||||
|
||||
#define SWAB_Elf32_Half(x) ((x >> 8) | (x << 8))
|
||||
#define SWAB_Elf32_Word(x) (((x >> 24) & 0xff) | \
|
||||
((x << 8) & 0xff0000) | \
|
||||
((x >> 8) & 0xff00) | \
|
||||
((x << 24) & 0xff000000))
|
||||
|
||||
#define SWAB_Elf32_Addr SWAB_Elf32_Word
|
||||
#define SWAB_Elf32_Off SWAB_Elf32_Word
|
||||
#define SWAB_Elf32_Sword SWAB_Elf32_Word
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN32__) || defined(__WIN32__)
|
||||
#define OPEN_FLAGS (O_RDONLY|O_BINARY)
|
||||
#else
|
||||
#define OPEN_FLAGS (O_RDONLY)
|
||||
#endif
|
||||
|
||||
/* locals */
|
||||
|
||||
/* global indicating whether ELF structures need to be byte swapped */
|
||||
|
||||
static char swabRequired;
|
||||
|
||||
|
||||
/* usage information */
|
||||
|
||||
static char usage[] = "usage: %s -i <objectModule> -o <outputHeaderName>\n";
|
||||
|
||||
|
||||
/* output header file preamble */
|
||||
|
||||
static char preamble1[] = "\
|
||||
/* %s - structure member offsets definition header */\n\
|
||||
\n\
|
||||
/*\n\
|
||||
* Copyright (c) 2010-2014 Wind River Systems, Inc.\n\
|
||||
*\n\
|
||||
* Licensed under the Apache License, Version 2.0 (the \"License\");\n\
|
||||
* you may not use this file except in compliance with the License.\n\
|
||||
* You may obtain a copy of the License at\n\
|
||||
*\n\
|
||||
* http://www.apache.org/licenses/LICENSE-2.0\n\
|
||||
*\n\
|
||||
* Unless required by applicable law or agreed to in writing, software\n\
|
||||
* distributed under the License is distributed on an \"AS IS\" BASIS,\n\
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n\
|
||||
* See the License for the specific language governing permissions and\n\
|
||||
* limitations under the License.\n\
|
||||
* SPDX-License-Identifier: Apache-2.0\n\
|
||||
*/\n\
|
||||
\n\
|
||||
/* THIS FILE IS AUTO GENERATED. PLEASE DO NOT EDIT */\n\
|
||||
\n\
|
||||
/*\n\
|
||||
* This header file provides macros for the offsets of various structure\n\
|
||||
* members. These offset macros are primarily intended to be used in\n\
|
||||
* assembly code.\n\
|
||||
*/\n\n";
|
||||
|
||||
static char preamble2[] = "\
|
||||
/*\n\
|
||||
* Auto-generated header guard.\n\
|
||||
*/\n\
|
||||
#ifndef %s\n\
|
||||
#define %s\n\
|
||||
\n\
|
||||
#ifdef __cplusplus\n\
|
||||
extern \"C\" {\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
/* defines */\n\n";
|
||||
|
||||
|
||||
/* output header file postscript */
|
||||
|
||||
static char postscript[] = "\
|
||||
\n\
|
||||
#ifdef __cplusplus\n\
|
||||
}\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#endif /* _HGUARD_ */\n";
|
||||
|
||||
static Elf32_Ehdr ehdr; /* ELF header */
|
||||
static Elf32_Shdr * shdr; /* pointer to array ELF section headers */
|
||||
|
||||
/**
|
||||
* @brief byte swap the Elf32_Ehdr structure
|
||||
*
|
||||
* @returns N/A
|
||||
*/
|
||||
static void swabElfHdr(Elf32_Ehdr *pHdrToSwab)
|
||||
{
|
||||
if (swabRequired == 0)
|
||||
{
|
||||
return; /* do nothing */
|
||||
}
|
||||
|
||||
pHdrToSwab->e_type = SWAB_Elf32_Half(pHdrToSwab->e_type);
|
||||
pHdrToSwab->e_machine = SWAB_Elf32_Half(pHdrToSwab->e_machine);
|
||||
pHdrToSwab->e_version = SWAB_Elf32_Word(pHdrToSwab->e_version);
|
||||
pHdrToSwab->e_entry = SWAB_Elf32_Addr(pHdrToSwab->e_entry);
|
||||
pHdrToSwab->e_phoff = SWAB_Elf32_Off(pHdrToSwab->e_phoff);
|
||||
pHdrToSwab->e_shoff = SWAB_Elf32_Off(pHdrToSwab->e_shoff);
|
||||
pHdrToSwab->e_flags = SWAB_Elf32_Word(pHdrToSwab->e_flags);
|
||||
pHdrToSwab->e_ehsize = SWAB_Elf32_Half(pHdrToSwab->e_ehsize);
|
||||
pHdrToSwab->e_phentsize = SWAB_Elf32_Half(pHdrToSwab->e_phentsize);
|
||||
pHdrToSwab->e_phnum = SWAB_Elf32_Half(pHdrToSwab->e_phnum);
|
||||
pHdrToSwab->e_shentsize = SWAB_Elf32_Half(pHdrToSwab->e_shentsize);
|
||||
pHdrToSwab->e_shnum = SWAB_Elf32_Half(pHdrToSwab->e_shnum);
|
||||
pHdrToSwab->e_shstrndx = SWAB_Elf32_Half(pHdrToSwab->e_shstrndx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief byte swap the Elf32_Shdr structure
|
||||
*
|
||||
* @returns N/A
|
||||
*/
|
||||
static void swabElfSectionHdr(Elf32_Shdr *pHdrToSwab)
|
||||
{
|
||||
if (swabRequired == 0)
|
||||
{
|
||||
return; /* do nothing */
|
||||
}
|
||||
|
||||
pHdrToSwab->sh_name = SWAB_Elf32_Word(pHdrToSwab->sh_name);
|
||||
pHdrToSwab->sh_type = SWAB_Elf32_Word(pHdrToSwab->sh_type);
|
||||
pHdrToSwab->sh_flags = SWAB_Elf32_Word(pHdrToSwab->sh_flags);
|
||||
pHdrToSwab->sh_addr = SWAB_Elf32_Addr(pHdrToSwab->sh_addr);
|
||||
pHdrToSwab->sh_offset = SWAB_Elf32_Off(pHdrToSwab->sh_offset);
|
||||
pHdrToSwab->sh_size = SWAB_Elf32_Word(pHdrToSwab->sh_size);
|
||||
pHdrToSwab->sh_link = SWAB_Elf32_Word(pHdrToSwab->sh_link);
|
||||
pHdrToSwab->sh_info = SWAB_Elf32_Word(pHdrToSwab->sh_info);
|
||||
pHdrToSwab->sh_addralign = SWAB_Elf32_Word(pHdrToSwab->sh_addralign);
|
||||
pHdrToSwab->sh_addralign = SWAB_Elf32_Word(pHdrToSwab->sh_addralign);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief byte swap the Elf32_Sym structure
|
||||
*
|
||||
* @returns N/A
|
||||
*/
|
||||
static void swabElfSym(Elf32_Sym *pHdrToSwab)
|
||||
{
|
||||
if (swabRequired == 0)
|
||||
{
|
||||
return; /* do nothing */
|
||||
}
|
||||
|
||||
pHdrToSwab->st_name = SWAB_Elf32_Word(pHdrToSwab->st_name);
|
||||
pHdrToSwab->st_value = SWAB_Elf32_Addr(pHdrToSwab->st_value);
|
||||
pHdrToSwab->st_size = SWAB_Elf32_Word(pHdrToSwab->st_size);
|
||||
pHdrToSwab->st_shndx = SWAB_Elf32_Half(pHdrToSwab->st_shndx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the ELF header
|
||||
*
|
||||
* @param fd file descriptor of file from which to read
|
||||
* @returns 0 on success, -1 on failure
|
||||
*/
|
||||
static int ehdrLoad(int fd)
|
||||
{
|
||||
unsigned ix = 0x12345678; /* used to auto-detect endian-ness */
|
||||
size_t nBytes; /* number of bytes read from file */
|
||||
|
||||
if (lseek(fd, 0, SEEK_SET) == -1) {
|
||||
fprintf(stderr, "Unable to seek\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nBytes = read(fd, &ehdr, sizeof(ehdr));
|
||||
if (nBytes != sizeof(ehdr))
|
||||
{
|
||||
fprintf(stderr, "Failed to read ELF header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* perform some rudimentary ELF file validation */
|
||||
|
||||
if (strncmp((char *)ehdr.e_ident, ELFMAG, 4) != 0)
|
||||
{
|
||||
fprintf(stderr, "Input object module not ELF format\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 64-bit ELF module not supported (for now) */
|
||||
|
||||
if (ehdr.e_ident[EI_CLASS] != ELFCLASS32)
|
||||
{
|
||||
fprintf(stderr, "ELF64 class not supported\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dynamically determine the endianess of the host (in the absence of
|
||||
* a compile time macro ala _BYTE_ORDER). The ELF structures will require
|
||||
* byte swapping if the host and target have different byte ordering.
|
||||
*/
|
||||
|
||||
if (((*(char*)&ix == 0x78) && (ehdr.e_ident[EI_DATA] == ELFDATA2MSB)) ||
|
||||
((*(char*)&ix == 0x12) && (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)))
|
||||
{
|
||||
swabRequired = 1;
|
||||
DBG_PRINT("Swab required\n");
|
||||
}
|
||||
|
||||
swabElfHdr(&ehdr); /* swap bytes (if required) */
|
||||
|
||||
/* debugging: dump some important ELF header fields */
|
||||
|
||||
DBG_PRINT("Elf header Magic = %s\n", ehdr.e_ident);
|
||||
DBG_PRINT("Elf header e_type = %d\n", ehdr.e_type);
|
||||
DBG_PRINT("Elf header e_shstrndx = %d\n", ehdr.e_shstrndx);
|
||||
DBG_PRINT("Elf header e_shnum = %d\n", ehdr.e_shnum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the section headers
|
||||
* @param fd file descriptor of file from which to read
|
||||
*
|
||||
* @returns 0 on success, -1 on failure
|
||||
*/
|
||||
static int shdrsLoad(int fd)
|
||||
{
|
||||
size_t nBytes; /* number of bytes read from file */
|
||||
unsigned ix; /* loop index */
|
||||
|
||||
shdr = malloc(ehdr.e_shnum * sizeof(Elf32_Shdr));
|
||||
if (shdr == NULL)
|
||||
{
|
||||
fprintf(stderr, "No memory for section headers!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Seek to the start of the table of section headers */
|
||||
if (lseek(fd, ehdr.e_shoff, SEEK_SET) == -1) {
|
||||
fprintf(stderr, "Unable to seek\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ix = 0; ix < ehdr.e_shnum; ix++)
|
||||
{
|
||||
nBytes = read(fd, &shdr[ix], sizeof(Elf32_Shdr));
|
||||
if (nBytes != sizeof(Elf32_Shdr))
|
||||
{
|
||||
fprintf(stderr, "Unable to read entire section header (#%d)\n",
|
||||
ix);
|
||||
return -1;
|
||||
}
|
||||
|
||||
swabElfSectionHdr(&shdr[ix]); /* swap bytes (if required) */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* symTblFind - search the section headers for the symbol table
|
||||
*
|
||||
* This routine searches the section headers for the symbol table. There is
|
||||
* expected to be only one symbol table in the section headers.
|
||||
*
|
||||
* @param pSymTblOffset ptr to symbol table offset
|
||||
* @param pSymTblSize ptr to symbol table size
|
||||
* @returns 0 if found, -1 if not
|
||||
*/
|
||||
static int symTblFind(unsigned *pSymTblOffset, unsigned *pSymTblSize)
|
||||
{
|
||||
unsigned ix; /* loop index */
|
||||
|
||||
for (ix = 0; ix < ehdr.e_shnum; ++ix)
|
||||
{
|
||||
if (shdr[ix].sh_type == SHT_SYMTAB)
|
||||
{
|
||||
*pSymTblOffset = shdr[ix].sh_offset;
|
||||
*pSymTblSize = shdr[ix].sh_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Object module missing symbol table!\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief search the section headers for the string table
|
||||
*
|
||||
* This routine searches the section headers for the string table associated
|
||||
* with the symbol names.
|
||||
*
|
||||
* Typically, there are two string tables defined in the section headers. These
|
||||
* are ".shstrtbl" and ".strtbl" for section header names and symbol names
|
||||
* respectively. It has been observed with the DIAB compiler (but not with
|
||||
* either the GCC nor ICC compilers) that the two tables may be mashed together
|
||||
* into one. Consequently, the following algorithm is used to select the
|
||||
* appropriate string table.
|
||||
*
|
||||
* 1. Assume that the first found string table is valid.
|
||||
* 2. If another string table is found, use that only if its section header
|
||||
* index does not match the index for ".shstrtbl" stored in the ELF header.
|
||||
*
|
||||
* @param pStrTblIx ptr to string table's index
|
||||
* @returns 0 if found, -1 if not
|
||||
*/
|
||||
static int strTblFind(unsigned *pStrTblIx)
|
||||
{
|
||||
unsigned strTblIx = 0xffffffff;
|
||||
unsigned ix;
|
||||
|
||||
for (ix = 0; ix < ehdr.e_shnum; ++ix)
|
||||
{
|
||||
if (shdr[ix].sh_type == SHT_STRTAB)
|
||||
{
|
||||
if ((strTblIx == 0xffffffff) ||
|
||||
(ix != ehdr.e_shstrndx))
|
||||
{
|
||||
strTblIx = ix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strTblIx == 0xffffffff)
|
||||
{
|
||||
fprintf(stderr, "Object module missing string table!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*pStrTblIx = strTblIx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief load the string table
|
||||
*
|
||||
* @param fd file descriptor of file from which to read
|
||||
* @param strTblIx string table's index
|
||||
* @param ppStringTable ptr to ptr to string table
|
||||
* @returns 0 on success, -1 on failure
|
||||
*/
|
||||
static int strTblLoad(int fd, unsigned strTblIx, char **ppStringTable)
|
||||
{
|
||||
char * pTable;
|
||||
int nBytes;
|
||||
|
||||
DBG_PRINT("Allocating %d bytes for string table\n",
|
||||
shdr[strTblIx].sh_size);
|
||||
|
||||
pTable = malloc(shdr[strTblIx].sh_size);
|
||||
if (pTable == NULL)
|
||||
{
|
||||
fprintf(stderr, "No memory for string table!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lseek(fd, shdr[strTblIx].sh_offset, SEEK_SET) == -1) {
|
||||
free(pTable);
|
||||
fprintf(stderr, "Unable to seek\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nBytes = read(fd, pTable, shdr[strTblIx].sh_size);
|
||||
if (nBytes != shdr[strTblIx].sh_size)
|
||||
{
|
||||
free(pTable);
|
||||
fprintf(stderr, "Unable to read entire string table!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ppStringTable = pTable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief dump the header preamble to the header file
|
||||
*
|
||||
* @param fd file pointer to which to write
|
||||
* @parama filename name of the output file
|
||||
* @returns N/A
|
||||
*/
|
||||
static void headerPreambleDump(FILE *fp, char *filename)
|
||||
{
|
||||
unsigned hash = 5381; /* hash value */
|
||||
size_t ix; /* loop counter */
|
||||
char fileNameHash[20]; /* '_HGUARD_' + 8 character hash + '\0' */
|
||||
|
||||
/* dump header file preamble1[] */
|
||||
|
||||
fprintf(fp, preamble1, filename, filename, filename);
|
||||
|
||||
/*
|
||||
* Dump header file preamble2[]. Hash file name into something that
|
||||
* is small enough to be a C macro name and does not have invalid
|
||||
* characters for a macro name to use as a header guard. The result
|
||||
* of the hash should be unique enough for our purposes.
|
||||
*/
|
||||
|
||||
for (ix = 0; ix < sizeof(filename); ++ix)
|
||||
{
|
||||
hash = (hash * 33) + (unsigned int) filename[ix];
|
||||
}
|
||||
|
||||
sprintf(fileNameHash, "_HGUARD_%08x", hash);
|
||||
fprintf(fp, preamble2, fileNameHash, fileNameHash);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief dump the absolute symbols to the header file
|
||||
*
|
||||
* @param fd file descriptor of file from which to read
|
||||
* @param fp file pointer to which to write
|
||||
* @param symTblOffset symbol table offset
|
||||
* @param symTblSize size of the symbol table
|
||||
* @param pStringTable ptr to the string table
|
||||
* @returns N/A
|
||||
*/
|
||||
static void headerAbsoluteSymbolsDump(int fd, FILE *fp, Elf32_Off symTblOffset,
|
||||
Elf32_Word symTblSize, char *pStringTable)
|
||||
{
|
||||
Elf32_Sym aSym; /* absolute symbol */
|
||||
unsigned ix; /* loop counter */
|
||||
unsigned numSyms; /* number of symbols in the symbol table */
|
||||
size_t nBytes;
|
||||
|
||||
/* context the symbol table: pick out absolute syms */
|
||||
|
||||
numSyms = symTblSize / sizeof(Elf32_Sym);
|
||||
if (lseek(fd, symTblOffset, SEEK_SET) == -1) {
|
||||
fprintf(stderr, "Unable to seek\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (ix = 0; ix < numSyms; ++ix)
|
||||
{
|
||||
/* read in a single symbol structure */
|
||||
nBytes = read(fd, &aSym, sizeof(Elf32_Sym));
|
||||
|
||||
if (nBytes) {
|
||||
swabElfSym(&aSym); /* swap bytes (if required) */
|
||||
}
|
||||
|
||||
/*
|
||||
* Only generate definitions for global absolute symbols
|
||||
* of the form *_OFFSET
|
||||
*/
|
||||
|
||||
if ((aSym.st_shndx == SHN_ABS) &&
|
||||
(ELF_ST_BIND(aSym.st_info) == STB_GLOBAL))
|
||||
{
|
||||
if ((strstr(&pStringTable[aSym.st_name],
|
||||
STRUCT_OFF_SUFFIX) != NULL) ||
|
||||
(strstr(&pStringTable[aSym.st_name],
|
||||
STRUCT_SIZ_SUFFIX) != NULL))
|
||||
{
|
||||
fprintf(fp, "#define\t%s\t0x%X\n",
|
||||
&pStringTable[aSym.st_name], aSym.st_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief dump the header postscript to the header file
|
||||
* @param fp file pointer to which to write
|
||||
* @returns N/A
|
||||
*/
|
||||
static void headerPostscriptDump(FILE *fp)
|
||||
{
|
||||
fputs(postscript, fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief entry point for the genOffsetHeader utility
|
||||
*
|
||||
* usage: $ genOffsetHeader -i <objectModule> -o <outputHeaderName>
|
||||
*
|
||||
* @returns 0 on success, 1 on failure
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Elf32_Off symTblOffset = 0;
|
||||
Elf32_Word symTblSize; /* in bytes */
|
||||
char * pStringTable = NULL;
|
||||
char * inFileName = NULL;
|
||||
char * outFileName = NULL;
|
||||
int option;
|
||||
int inFd = -1;
|
||||
FILE * outFile = NULL;
|
||||
unsigned strTblIx;
|
||||
|
||||
/* argument parsing */
|
||||
|
||||
if (argc != 5)
|
||||
{
|
||||
fprintf(stderr, usage, argv[0]);
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
while ((option = getopt(argc, argv, "i:o:")) != -1)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case 'i':
|
||||
inFileName = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
outFileName = optarg;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, usage, argv[0]);
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
|
||||
/* open input object ELF module and output header file */
|
||||
|
||||
inFd = open(inFileName, OPEN_FLAGS);
|
||||
|
||||
if (inFd == -1)
|
||||
{
|
||||
fprintf(stderr, "Cannot open input object module");
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
outFile = fopen(outFileName, "w");
|
||||
|
||||
if (outFile == NULL)
|
||||
{
|
||||
fprintf(stderr, "Cannot open output header file");
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the following order, attempt to ...
|
||||
* 1. Load the ELF header
|
||||
* 2. Load the section headers
|
||||
* 3. Find the symbol table
|
||||
* 4. Find the string table
|
||||
* 5. Load the string table
|
||||
* Bail if any of those steps fail.
|
||||
*/
|
||||
|
||||
if ((ehdrLoad(inFd) != 0) ||
|
||||
(shdrsLoad(inFd) != 0) ||
|
||||
(symTblFind(&symTblOffset, &symTblSize) != 0) ||
|
||||
(strTblFind(&strTblIx) != 0) ||
|
||||
(strTblLoad(inFd, strTblIx, &pStringTable) != 0))
|
||||
{
|
||||
goto errorReturn;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Dump the following to the header file ...
|
||||
* 1. Header file preamble
|
||||
* 2. Absolute symbols
|
||||
* 3. Header file postscript
|
||||
*/
|
||||
|
||||
headerPreambleDump(outFile, outFileName);
|
||||
headerAbsoluteSymbolsDump(inFd, outFile,
|
||||
symTblOffset, symTblSize, pStringTable);
|
||||
headerPostscriptDump(outFile);
|
||||
|
||||
/* done: cleanup */
|
||||
|
||||
close(inFd);
|
||||
fclose(outFile);
|
||||
free(shdr);
|
||||
free(pStringTable);
|
||||
|
||||
return 0;
|
||||
|
||||
errorReturn:
|
||||
if (inFd != -1)
|
||||
{
|
||||
close(inFd);
|
||||
}
|
||||
|
||||
if (outFile != NULL)
|
||||
{
|
||||
fclose(outFile);
|
||||
}
|
||||
|
||||
if (shdr != NULL)
|
||||
{
|
||||
free(shdr);
|
||||
}
|
||||
|
||||
if (pStringTable != NULL)
|
||||
{
|
||||
free(pStringTable);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
Loading…
Reference in a new issue