From b5caf439b4c7ff9bbeddf87e7c19065f81ea730d Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 22 Jun 2009 23:08:54 +0000 Subject: Defs for new relocation types git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1927 42af7a65-404d-4744-a932-0658087f49c3 --- misc/buildroot/toolchain/nxflat/Makefile | 2 +- misc/buildroot/toolchain/nxflat/ldnxflat.c | 107 +++-- misc/buildroot/toolchain/nxflat/nxflat.h | 161 ++++--- misc/buildroot/toolchain/nxflat/readnxflat.c | 670 +++++++++++++++++++++++++++ misc/buildroot/toolchain/nxflat/readxflat.c | 669 -------------------------- 5 files changed, 823 insertions(+), 786 deletions(-) create mode 100644 misc/buildroot/toolchain/nxflat/readnxflat.c delete mode 100644 misc/buildroot/toolchain/nxflat/readxflat.c (limited to 'misc/buildroot/toolchain') diff --git a/misc/buildroot/toolchain/nxflat/Makefile b/misc/buildroot/toolchain/nxflat/Makefile index 287dda7d6..93a0fa288 100644 --- a/misc/buildroot/toolchain/nxflat/Makefile +++ b/misc/buildroot/toolchain/nxflat/Makefile @@ -39,7 +39,7 @@ LIBS = -lbfd -liberty -lz LDNXFLAT_OBJS = ldnxflat.o MKNXFLAT_OBJS = mknxflat.o -READNXFLAT_OBJS = readxflat.o +READNXFLAT_OBJS = readnxflat.o OBJS = $(LDNXFLAT_OBJS) $(MKNXFLAT_OBJS) $(READNXFLAT_OBJS) BIN = ldnxflat mknxflat readnxflat diff --git a/misc/buildroot/toolchain/nxflat/ldnxflat.c b/misc/buildroot/toolchain/nxflat/ldnxflat.c index 21ff59ad6..5a6505ed2 100644 --- a/misc/buildroot/toolchain/nxflat/ldnxflat.c +++ b/misc/buildroot/toolchain/nxflat/ldnxflat.c @@ -138,6 +138,12 @@ # define RAW_SIZE rawsize #endif +#define NXFLAT_RELOC_TARGET_TEXT 0 +#define NXFLAT_RELOC_TARGET_DATA 1 +#define NXFLAT_RELOC_TARGET_RODATA 2 +#define NXFLAT_RELOC_TARGET_BSS 3 +#define NXFLAT_RELOC_TARGET_UNKNOWN 4 + /*********************************************************************** * Private Types ***********************************************************************/ @@ -456,7 +462,7 @@ put_special_symbol(asymbol * begin_sym, asymbol * end_sym, begin_sect_vma = begin_sym->section->vma; - file_offset = NXFLAT_HDR_SIZE + /* Size of the xFLT header */ + file_offset = NXFLAT_HDR_SIZE + /* Size of the NXFLAT header */ begin_sect_vma + /* Virtual address of section */ begin_sym_value + /* Value of the symbol */ offset; /* Additional file offset */ @@ -591,7 +597,7 @@ static void put_entry_point(struct nxflat_hdr_s *hdr) } } - /* Put the entry point into the xFLT header. */ + /* Put the entry point into the NXFLAT header. */ put_xflat32(&hdr->h_entry, entry_point); } @@ -600,7 +606,7 @@ static void put_entry_point(struct nxflat_hdr_s *hdr) * get_reloc_type ***********************************************************************/ -static int get_reloc_type(asection * sym_section, segment_info ** sym_segment) +static int get_reloc_type(asection *sym_section, segment_info **sym_segment) { int i; @@ -623,7 +629,7 @@ static int get_reloc_type(asection * sym_section, segment_info ** sym_segment) { *sym_segment = &bss_info; } - return NXFLAT_RELOC_TYPE_BSS; + return NXFLAT_RELOC_TARGET_BSS; } } @@ -641,7 +647,7 @@ static int get_reloc_type(asection * sym_section, segment_info ** sym_segment) { *sym_segment = &text_info; } - return NXFLAT_RELOC_TYPE_TEXT; + return NXFLAT_RELOC_TARGET_TEXT; } } @@ -656,14 +662,17 @@ static int get_reloc_type(asection * sym_section, segment_info ** sym_segment) vdbg("Sym section %s is DATA\n", sym_section->name); if (sym_segment) - *sym_segment = &data_info; - return NXFLAT_RELOC_TYPE_DATA; + { + *sym_segment = &data_info; + } + return NXFLAT_RELOC_TARGET_DATA; } } err("Could not find region for sym_section \"%s\" (%p)\n", sym_section->name, sym_section); - return NXFLAT_RELOC_TYPE_NONE; + + return NXFLAT_RELOC_TARGET_UNKNOWN; } /*********************************************************************** @@ -682,7 +691,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, int i; int j; - nxflat_relocs = *relocs; + nxflat_relocs = *relocs; nxflat_reloc_count = *n_relocs; for (i = 0; i < inf->nsubsects; i++) @@ -924,7 +933,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, /* And tuck in the new relocation. */ - nxflat_relocs[nxflat_reloc_count].r_info = NXFLAT_RELOC(reltype, relpp[j]->address); + nxflat_relocs[nxflat_reloc_count].r_info = NXFLAT_RELOC(NXFLAT_RELOC_TYPE_ABS32, relpp[j]->address); nxflat_reloc_count++; } } @@ -1053,7 +1062,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, /* Locate the address referred to by the section type. */ reltype = get_reloc_type(rel_section, NULL); - if (reltype == NXFLAT_RELOC_TYPE_TEXT) + if (reltype == NXFLAT_RELOC_TARGET_TEXT) { err("Symbol in GOT32 relocation is in TEXT\n"); err(" At addr %08x to sym '%s' [%08x]\n", @@ -1087,7 +1096,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, /* Locate the address referred to by the section type. */ reltype = get_reloc_type(rel_section, NULL); - if (reltype != NXFLAT_RELOC_TYPE_DATA) + if (reltype != NXFLAT_RELOC_TARGET_DATA) { err("Symbol in GOT32 relocation is not .data\n"); err(" At addr %08x to sym '%s' [%08x]\n", @@ -1102,7 +1111,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, /* And tuck in the new relocation. */ - nxflat_relocs[nxflat_reloc_count].r_info = NXFLAT_RELOC(reltype, relpp[j]->address); + nxflat_relocs[nxflat_reloc_count].r_info = NXFLAT_RELOC(NXFLAT_RELOC_TYPE_REL32D, relpp[j]->address); nxflat_reloc_count++; #endif } @@ -1143,7 +1152,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, /* Locate the address referred to by section type. */ reltype = get_reloc_type(rel_section, NULL); - if (reltype != NXFLAT_RELOC_TYPE_TEXT) + if (reltype != NXFLAT_RELOC_TARGET_TEXT) { err("Symbol in GOTPC relocation is not .text\n"); err(" At addr %08x to sym '%s' [%08x]\n", @@ -1158,7 +1167,7 @@ resolve_segment_relocs(bfd * input_bfd, segment_info * inf, asymbol ** syms, /* And tuck in the new relocation. */ - nxflat_relocs[nxflat_reloc_count].r_info = NXFLAT_RELOC(reltype, relpp[j]->address); + nxflat_relocs[nxflat_reloc_count].r_info = NXFLAT_RELOC(NXFLAT_RELOC_TYPE_REL32I, relpp[j]->address); nxflat_reloc_count++; } } @@ -1480,10 +1489,10 @@ static struct nxflat_reloc_s *output_relocs(bfd * input_bfd, asymbol ** symbols, int rc; int i; - *n_relocs = 0; - nxflat_relocs = NULL; + *n_relocs = 0; + nxflat_relocs = NULL; nxflat_reloc_count = 0; - rc = 0; + rc = 0; vdbg("Before map high mark %08x cooked %08x raw %08x \n", (int)bss_info.high_mark, (int)bss_info.subsect[0]->COOKED_SIZE, @@ -1637,19 +1646,16 @@ static void show_usage(void) fprintf(stderr, "Where options are one or more of the following. Note\n"); fprintf(stderr, "that a space is always required between the option and\n"); fprintf(stderr, "any following arguments.\n\n"); - fprintf(stderr, " -d Use dynamic symbol table [symtab]\n"); + fprintf(stderr, " -d Use dynamic symbol table [Default: symtab]\n"); fprintf(stderr, " -e \n"); - fprintf(stderr, " Entry point to module [%s for executable]\n", + fprintf(stderr, " Entry point to module [Default: %s]\n", default_exe_entry_name); - fprintf(stderr, " NULL for shared library\n"); fprintf(stderr, " -o \n"); - fprintf(stderr, " Output to [.xflt]\n"); + fprintf(stderr, " Output to [Default: .nxf]\n"); fprintf(stderr, " -s \n"); - fprintf(stderr, " Set stack size to . Ignored if -l also\n"); - fprintf(stderr, " selected. [%d]\n", DEFAULT_STACK_SIZE); - fprintf(stderr, " -v Verbose output [no verbose output]\n"); - fprintf(stderr, " If -v is applied twice, additional debug output\n"); - fprintf(stderr, " be enabled.\n"); + fprintf(stderr, " Set stack size to [Default: %d]\n", DEFAULT_STACK_SIZE); + fprintf(stderr, " -v Verbose outpu.t If -v is applied twice, additional\n"); + fprintf(stderr, " debug output is enabled [Default: no verbose output].\n"); fprintf(stderr, "\n"); exit(2); } @@ -1683,7 +1689,6 @@ static void parse_args(int argc, char **argv) { switch (opt) { - case 'd': dsyms++; break; @@ -1801,29 +1806,29 @@ int main(int argc, char **argv, char **envp) dbg("Reading section %s\n", s->name); /* ignore blatantly useless sections */ - if (is_unwanted_section(s)) - continue; - if (s->flags == SEC_ALLOC) - { - vdbg(" Section %s is ALLOC only\n", s->name); - register_section(s, &bss_info); - continue; - } - if ((s->flags & SEC_CODE) && (s->flags & SEC_ALLOC)) - { - vdbg(" Section %s is CODE\n", s->name); - register_section(s, &text_info); - continue; - } - if ((s->flags & SEC_DATA) && (s->flags & SEC_ALLOC)) + if (!is_unwanted_section(s)) { - vdbg(" Section %s is DATA\n", s->name); - register_section(s, &data_info); - continue; + if (s->flags == SEC_ALLOC) + { + vdbg(" Section %s is ALLOC only\n", s->name); + register_section(s, &bss_info); + } + else if ((s->flags & SEC_CODE) != 0 && (s->flags & SEC_ALLOC) != 0) + { + vdbg(" Section %s is CODE\n", s->name); + register_section(s, &text_info); + } + else if ((s->flags & SEC_DATA) != 0 && (s->flags & SEC_ALLOC) != 0) + { + vdbg(" Section %s is DATA\n", s->name); + register_section(s, &data_info); + } + else + { + vdbg("WARNING: ignoring section %s\n", s->name); + } } - - vdbg("WARNING: ignoring section %s\n", s->name); } /* Fixup high and low water VMA address */ @@ -1925,9 +1930,9 @@ int main(int argc, char **argv, char **envp) reloc = (u_int32_t*)output_relocs(bf, symbol_table, number_of_symbols, &reloc_len); - /* Fill in the xFLT file header */ + /* Fill in the NXFLAT file header */ - memcpy(hdr.h_magic, "xFLT", 4); + memcpy(hdr.h_magic, NXFLAT_MAGIC, 4); put_xflat32(&hdr.h_datastart, NXFLAT_HDR_SIZE + text_info.size); put_xflat32(&hdr.h_dataend, NXFLAT_HDR_SIZE + text_info.size + data_info.size); @@ -1966,7 +1971,7 @@ int main(int argc, char **argv, char **envp) { out_filename = malloc(strlen(bfd_filename) + 5); /* 5 to add suffix */ strcpy(out_filename, bfd_filename); - strcat(out_filename, ".xflt"); + strcat(out_filename, ".nxf"); } fd = open(out_filename, O_WRONLY | O_PLATFORM | O_CREAT | O_TRUNC, 0744); diff --git a/misc/buildroot/toolchain/nxflat/nxflat.h b/misc/buildroot/toolchain/nxflat/nxflat.h index e8419426a..577d6a9e7 100644 --- a/misc/buildroot/toolchain/nxflat/nxflat.h +++ b/misc/buildroot/toolchain/nxflat/nxflat.h @@ -62,55 +62,73 @@ ****************************************************************************/ struct nxflat_hdr_s - { - /* The "magic number" identifying the file type. This field should contain - * "NxFT". NOTE that there is no other versioning information other than - * this magic number. */ - - char h_magic[4]; - - /* The following fields provide the memory map for the nxflat binary. - * h_entry - Offset to the the first executable insruction from the - * beginning of the file. h_datastart - Offset to the beginning of the data - * segment from the beginning of the file. This field can also interpreted - * as the size of the ISpace segment. h_dataend - Offset to the end of the - * data segment from the beginning of the file. h_bssend - Offset to the - * end of bss segment from the beginning of the file. The text segment can - * be considered to be the contiguous (unrelocated) address space range - * from address zero through (but not including) h_datastart. The size of - * the data/bss segment includes (as a minimum) the data and bss regions - * (bss_end - data_start) as well as the size of the stack. At run time, - * this region will also include program arguments and environement - * variables. The bss segment is data_end through bss_end. */ - - u_int32_t h_entry; - u_int32_t h_datastart; - u_int32_t h_dataend; - u_int32_t h_bssend; - - /* Size of stack, in bytes */ - - u_int32_t h_stacksize; - - /* Relocation entries h_relocstart - Offset to the beginning of an array of - * relocation records (struct nxflat_reloc). The offset is relative to the - * start of the file h_reloccount - The number of relocation records in the - * arry */ - - u_int32_t h_relocstart; /* Offset of relocation records */ - u_int32_t h_reloccount; /* Number of relocation records */ - - /* Imported symbol table (NOTE no symbols are exported) h_importsymbols - - * Offset to the beginning of an array of imported symbol structures - * (struct nxflat_import). The h_importsymbols offset is relative to the - * beginning of the file. Each entry of the array contains an u_int32_t - * offset (again from the beginning of the file) to the name of a symbol - * string. This string is null-terminated. h_importcount - The number of - * records in the h_exportsymbols array. */ - - u_int32_t h_importsymbols; /* Offset to list of imported symbols */ - u_int16_t h_importcount; /* Number of imported symbols */ - }; +{ + /* The "magic number" identifying the file type. This field should contain + * "NxFT". NOTE that there is no other versioning information other than + * this magic number. + */ + + char h_magic[4]; + + /* The following fields provide the memory map for the nxflat binary. + * + * h_entry - Offset to the the first executable insruction from + * the beginning of the file. + * h_datastart - Offset to the beginning of the data segment from + * the beginning of the file. This field can also + * interpreted as the size of the ISpace segment. + * h_dataend - Offset to the end of the data segment from the + * beginning of the file. + * h_bssend - Offset to the end of bss segment from the beginning + * of the file. + * + * The text segment can be considered to be the contiguous (unrelocated) + * address space range from address zero through (but not including) + * h_datastart. + * + * The size of the data/bss segment includes (as a minimum) the data + * and bss regions (bss_end - data_start) as well as the size of the + * stack. At run time, this region will also include program arguments + * and environement variables. + * + * The bss segment is data_end through bss_end. + */ + + u_int32_t h_entry; + u_int32_t h_datastart; + u_int32_t h_dataend; + u_int32_t h_bssend; + + /* Size of stack, in bytes */ + + u_int32_t h_stacksize; + + /* Relocation entries: + * + * h_relocstart - Offset to the beginning of an array of relocation + * records (struct nxflat_reloc). The offset is + * relative to the start of the file + * h_reloccount - The number of relocation records in the arry + */ + + u_int32_t h_relocstart; /* Offset of relocation records */ + u_int32_t h_reloccount; /* Number of relocation records */ + + /* Imported symbol table (NOTE no symbols are exported): + * + * h_importsymbols - Offset to the beginning of an array of imported + * symbol structures (struct nxflat_import). The + * h_importsymbols offset is relative to the + * beginning of the file. Each entry of the + * array contains an uint32 offset (again from + * the beginning of the file) to the name of + * a symbol string. This string is null-terminated. + * h_importcount - The number of records in the h_exportsymbols array. + */ + + u_int32_t h_importsymbols; /* Offset to list of imported symbols */ + u_int16_t h_importcount; /* Number of imported symbols */ +}; /**************************************************************************** * NXFLAT Relocation types. @@ -119,33 +137,46 @@ struct nxflat_hdr_s ****************************************************************************/ struct nxflat_reloc_s - { - u_int32_t r_info; /* Bit-encoded relocation info */ - }; +{ + u_int32_t r_info; /* Bit-encoded relocation info */ +}; /* Pack the type and the offset into one 32-bit value */ -#define NXFLAT_RELOC(t,o) (((u_int32_t)((t) & 3) << 28) | ((o) & 0x1fffffff)) +#define NXFLAT_RELOC(t,o) (((u_int32_t)((t) & 3) << 30) | ((o) & 0x1fffffff)) /* The top three bits of the relocation info is the relocation type (see the * NXFLAT_RELOC_TYPE_* definitions below. This is an unsigned value. */ -#define NXFLAT_RELOC_TYPE(r) ((u_int32_t)(r) >> 28) +#define NXFLAT_RELOC_TYPE(r) ((u_int32_t)(r) >> 30) /* The bottom 28 bits of the relocation info is the (non-negative) offset into * the D-Space that needs the fixup. */ -#define NXFLAT_RELOC_OFFSET(r) ((u_int32_t)(r) & 0x1fffffff) +#define NXFLAT_RELOC_OFFSET(r) ((u_int32_t)(r) & 0x3fffffff) -/* These are possible values for the relocation type */ +/* These are possible values for the relocation type: + * + * NXFLAT_RELOC_TYPE_REL32I Meaning: Object file contains a 32-bit offset + * into I-Space at the the offset. + * Fixup: Add mapped I-Space address to the offset. + * NXFLAT_RELOC_TYPE_REL32D Meaning: Object file contains a 32-bit offset + * into D-Space at the the offset. + * Fixup: Add allocated D-Space address to the + * offset. + * NXFLAT_RELOC_TYPE_ABS32 Meaning: Offset refers to a struct nxflat_import_s + * describing a function pointer to be + * imported. + * Fixup: Provide the absolute function address + * in the struct nxflat_import_s instance. + */ -#define NXFLAT_RELOC_TYPE_NONE 0 /* Invalid relocation type */ -#define NXFLAT_RELOC_TYPE_TEXT 1 /* Symbol lies in .text region */ -#define NXFLAT_RELOC_TYPE_DATA 2 /* Symbol lies in .data region */ -#define NXFLAT_RELOC_TYPE_BSS 3 /* Symbol lies in .bss region */ -#define NXFLAT_RELOC_TYPE_NUM 4 +#define NXFLAT_RELOC_TYPE_REL32I 0 +#define NXFLAT_RELOC_TYPE_REL32D 1 +#define NXFLAT_RELOC_TYPE_ABS32 2 +#define NXFLAT_RELOC_TYPE_NUM 3 /* Number of relocation types */ /**************************************************************************** * NXFLAT Imported symbol type @@ -155,10 +186,10 @@ struct nxflat_reloc_s ****************************************************************************/ struct nxflat_import_s - { - u_int32_t i_funcname; /* Offset to name of imported function */ - u_int32_t i_funcaddress; /* Resolved address of imported function */ - }; +{ + u_int32_t i_funcname; /* Offset to name of imported function */ + u_int32_t i_funcaddress; /* Resolved address of imported function */ +}; #endif /* __TOOLCHAIN_NXFLAT_NXFLAT_H */ diff --git a/misc/buildroot/toolchain/nxflat/readnxflat.c b/misc/buildroot/toolchain/nxflat/readnxflat.c new file mode 100644 index 000000000..783ffabb7 --- /dev/null +++ b/misc/buildroot/toolchain/nxflat/readnxflat.c @@ -0,0 +1,670 @@ +/*********************************************************************** + * toolchain/nxflat/readnxflat.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Modified from readxflat (see http://xflat.org): + * + * Copyright (c) 2002, 2006, Cadenux, LLC. All rights reserved. + * Copyright (c) 2002, 2006, Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ***********************************************************************/ + +/*********************************************************************** + * Compilation Flags + ***********************************************************************/ + +#define SWAP_BYTES 1 + +/*********************************************************************** + * Included Files + ***********************************************************************/ +#include +#include +#include +#include +#include +#include /* ntohl and friends */ +#include "nxflat.h" + +/*********************************************************************** + * Compilation Switches + ***********************************************************************/ + +/* #define RELOCS_IN_NETWORK_ORDER */ + +/*********************************************************************** + * Definitions + ***********************************************************************/ +#define NXFLAT_HDR_SIZE sizeof(struct nxflat_hdr_s) + +/*********************************************************************** + * Private Data + ***********************************************************************/ +static const char *program_name; +static const char *nxflat_filename; + +static int dump_header = 0; +static int dump_relocs = 0; +static int dump_imports = 0; +static int dump_text = 0; +static int dump_data = 0; +static int verbose = 0; + +static int num_errors = 0; + +#ifdef ARCH_BIG_ENDIAN +static int big_endian = 1; /* Assume big-endian */ +#else +static int big_endian = 0; /* Assume little-endian */ +#endif + +/*********************************************************************** + * Private Constant Data + ***********************************************************************/ + +static const char unknown[] = "UNKNOWN"; + +static const char hdr_reloc_rel32i[] = "RELOC_REL32I"; +static const char hdr_reloc_rel32d[] = "RELOC_REL32D"; +static const char hdr_reloc_abs32[] = "RELOC_ABS32"; + +static const char *reloc_type_string[] = { + hdr_reloc_rel32i, + hdr_reloc_rel32d, + hdr_reloc_abs32, + unknown +}; + +/*********************************************************************** + * Public Function Prototypes + ***********************************************************************/ + +extern void __attribute__ ((weak)) print_insn_arm(u_int32_t pc, + FILE * stream, + u_int32_t given); + +/*********************************************************************** + * Private Functions + ***********************************************************************/ + +/*********************************************************************** + * swap32 + ***********************************************************************/ + +static inline u_int32_t nxflat_swap32(u_int32_t little) +{ + u_int32_t big = + ((little >> 24) & 0xff) | + (((little >> 16) & 0xff) << 8) | + (((little >> 8) & 0xff) << 16) | ((little & 0xff) << 24); + return big; +} + +/*********************************************************************** + * get_nxflat32 + ***********************************************************************/ + +static inline u_int32_t get_nxflat32(u_int32_t * addr32) +{ + return ntohl(*addr32); +} + +/*********************************************************************** + * get_nxflat16 + ***********************************************************************/ + +static inline u_int16_t get_nxflat16(u_int16_t * addr16) +{ + return ntohs(*addr16); +} + +/*********************************************************************** + * dump_hex_data + ***********************************************************************/ + +static void dump_hex_data(FILE * in_stream, struct nxflat_hdr_s *header) +{ + u_int32_t data_start = get_nxflat32(&header->h_datastart); + u_int32_t data_end = get_nxflat32(&header->h_dataend); + int32_t words_left = (data_end - data_start) / sizeof(u_int32_t); + u_int32_t addr; + u_int32_t buffer[64]; + + printf("\nXFLAT DATA SEGMENT:\n\n"); + + /* Seek to the beginning of data in the file */ + + if (fseek(in_stream, data_start, SEEK_SET) != 0) + { + fprintf(stderr, + "ERROR: Failed to seek to data in file: offset: %08x\n", + data_start); + return; + } + + /* Now dump all of the data reading 64 words at a time */ + + addr = 0; + while (words_left > 0) + { + size_t nread = fread(buffer, sizeof(u_int32_t), 64, in_stream); + if (nread >= 0) + { + union + { + u_int32_t l[4]; + unsigned char b[16]; + } row; + int32_t i, j, k; + + for (i = 0; i < nread; i += 4) + { + for (j = 0; j < 4; j++) + { + row.l[j] = buffer[i + j]; + } + + printf("%08x: ", addr); + + for (j = 0; j < 4; j++) + { + printf("%08x ", row.l[j]); + } + + printf(" "); + + for (j = 0; j < 4 * sizeof(u_int32_t); j += sizeof(u_int32_t)) + { + for (k = 0; k < sizeof(u_int32_t); k++) + { + if (isprint(row.b[j + k])) + putchar(row.b[j + k]); + else + putchar('.'); + } + } + + putchar('\n'); + addr += 4 * sizeof(u_int32_t); + } + words_left -= nread; + } + else + break; + } + putchar('\n'); +} + +/*********************************************************************** + * disassemble_text + ***********************************************************************/ + +static void disassemble_text(FILE * in_stream, struct nxflat_hdr_s *header) +{ + if (print_insn_arm) + { + u_int32_t text_start = NXFLAT_HDR_SIZE; + u_int32_t text_end = get_nxflat32(&header->h_datastart); + int32_t insns_left = (text_end - text_start) / sizeof(u_int32_t); + u_int32_t addr; + u_int32_t buffer[64]; + + printf("\nXFLAT TEXT:\n\n"); + + /* Seek to the beginning of text in the file */ + if (fseek(in_stream, text_start, SEEK_SET) != 0) + { + fprintf(stderr, + "ERROR: Failed to seek to text in file: offset: %08x\n", + text_start); + return; + } + + /* Now dump all of the data reading 64 insns at a time */ + + addr = text_start; + while (insns_left > 0) + { + size_t nread = fread(buffer, sizeof(u_int32_t), 64, in_stream); + if (nread > 0) + { + int i; + for (i = 0; i < nread; i++) + { + u_int32_t insn = buffer[i]; + if (big_endian) + { + insn = nxflat_swap32(insn); + } + + printf("%08x %08x\t", addr, insn); + print_insn_arm(addr, stdout, insn); + putchar('\n'); + addr += sizeof(u_int32_t); + } + insns_left -= nread; + } + else + break; + putchar('\n'); + } + } +} + +/*********************************************************************** + * dump_imported_symbols + ***********************************************************************/ + +static void dump_imported_symbols(FILE *in_stream, struct nxflat_hdr_s *header) +{ + struct nxflat_import_s import; + u_int32_t import_offset; + u_int32_t data_start; + u_int32_t struct_offset; + u_int32_t name_offset; + char imported_symbol_name[NXFLAT_MAX_STRING_SIZE]; + int status; + int i; + + printf("\nIMPORTED SYMBOLS:\n"); + printf(" OFFSET ADDRESS SYMBOL NAME\n\n"); + + import_offset = get_nxflat32(&header->h_importsymbols); + data_start = get_nxflat32(&header->h_datastart); + + for (i = 0; i < get_nxflat16(&header->h_importcount); i++) + { + /* Seek to the next imported symbol */ + + struct_offset = i * sizeof(struct nxflat_import_s) + import_offset; + + if (fseek(in_stream, struct_offset, SEEK_SET) != 0) + { + fprintf(stderr, "ERROR: fseek to imported symbol %d struct failed\n", + i); + fprintf(stderr, " struct_offset: %d, errno: %d\n", struct_offset, + errno); + exit(1); + } + + /* Read the next import entry. */ + + status = fread((void *)&import, + sizeof(struct nxflat_import_s), 1, in_stream); + + if (status != 1) + { + fprintf(stderr, "ERROR: Read imported symbol %d struct failed, " + "errno: %d\n", i + 1, errno); + exit(1); + } + + if (big_endian) + { + import.i_funcname = nxflat_swap32(import.i_funcname); + import.i_funcaddress = nxflat_swap32(import.i_funcaddress); + } + + if (verbose) + { + /* Print the raw info */ + + printf("[%4d %08x %08x]\n", + i + 1, import.i_funcaddress, import.i_funcname); + } + + /* Seek to the function name in the file */ + + name_offset = import.i_funcname + NXFLAT_HDR_SIZE; + if (0 != fseek(in_stream, name_offset, SEEK_SET)) + { + fprintf(stderr, "ERROR: fseek to imported symbol %d name failed\n", + i); + fprintf(stderr, " name_offset: %d, errno: %d\n", + name_offset, errno); + exit(1); + } + + /* Then, read the imported symbol name (assuming it is less than + * NXFLAT_MAX_STRING_SIZE in length). */ + + status = fread((void *)imported_symbol_name, NXFLAT_MAX_STRING_SIZE, + 1, in_stream); + if (status != 1) + { + fprintf(stderr, "ERROR: Read imported symbol %d name failed, " + "errno: %d\n", i + 1, errno); + exit(1); + } + imported_symbol_name[NXFLAT_MAX_STRING_SIZE - 1] = '\0'; + + /* And print it */ + + printf("%5d %08x ", i + 1, (int)struct_offset - data_start); + + if (import.i_funcaddress) + { + printf("%08x ", import.i_funcaddress); + } + else + { + printf("UNKNOWN "); + } + + printf("%s\n", imported_symbol_name); + } +} + +/*********************************************************************** + * dump_relocation_entries + ***********************************************************************/ + +static void dump_relocation_entries(FILE * in_stream, struct nxflat_hdr_s *header) +{ + struct nxflat_reloc_s reloc; + int status; + int i; + + /* Seek to the beginning of the relocation records. */ + + if (0 != fseek(in_stream, get_nxflat32(&header->h_relocstart), SEEK_SET)) + { + fprintf(stderr, "ERROR: fseek to reloc records failed, errno: %d\n", + errno); + exit(1); + } + + printf("\nRELOCATION ENTRIES:\n"); + printf(" OFFSET RELOC TYPE\n\n"); + + for (i = 0; i < get_nxflat32(&header->h_reloccount); i++) + { + /* Read the next reloction entry. */ + + status = fread((void *)&reloc, sizeof(struct nxflat_reloc_s), 1, in_stream); + if (status != 1) + { + fprintf(stderr, "Error reading reloc record %d, errno: %d\n", + i + 1, errno); + exit(1); + } + +#ifdef RELOCS_IN_NETWORK_ORDER + { + u_int32_t *ptmp; + ptmp = (u_int32_t *) & reloc; + *ptmp = get_nxflat32(ptmp); + } +#endif + + if (NXFLAT_RELOC_TYPE(reloc.r_info) >= NXFLAT_RELOC_TYPE_NUM) + { + printf("%5d %08x UNKNOWN(%d)\n", i + 1, + NXFLAT_RELOC_OFFSET(reloc.r_info), NXFLAT_RELOC_TYPE(reloc.r_info)); + fprintf(stderr, "Error eloc type out of range(%d)\n", + NXFLAT_RELOC_TYPE(reloc.r_info)); + num_errors++; + } + else + { + printf("%5d %08x %-13s\n", + i + 1, NXFLAT_RELOC_OFFSET(reloc.r_info), + reloc_type_string[NXFLAT_RELOC_TYPE(reloc.r_info)]); + } + } +} + +/*********************************************************************** + * dump_hdr + ***********************************************************************/ + +static void dump_hdr(struct nxflat_hdr_s *header) +{ + /* Print the contents of the FLT header */ + + printf("\nXFLAT HEADER:\n"); + printf("\nMagic %c%c%c%c\n", + header->h_magic[0], header->h_magic[1], + header->h_magic[2], header->h_magic[3]); + + printf("\nMEMORY MAP:\n"); + printf(" Text start %08lx\n", NXFLAT_HDR_SIZE); + printf(" Entry point %08x\n", get_nxflat32(&header->h_entry)); + printf(" Data start %08x\n", get_nxflat32(&header->h_datastart)); + printf(" Data end %08x\n", get_nxflat32(&header->h_dataend) - 1); + printf(" Bss start %08x\n", get_nxflat32(&header->h_dataend)); + printf(" Bss end %08x\n", get_nxflat32(&header->h_bssend) - 1); + printf("TOTAL SIZE %08x\n\n", get_nxflat32(&header->h_bssend)); + printf("Stack size %08x\n", get_nxflat32(&header->h_stacksize)); + printf("\nRELOCATIONS:\n"); + printf(" Reloc start %08x\n", get_nxflat32(&header->h_relocstart)); + printf(" reloc count %d\n", get_nxflat32(&header->h_reloccount)); + printf("\nIMPORTED SYMBOLS:\n"); + printf(" Import start %08x\n", get_nxflat32(&header->h_importsymbols)); + printf(" Import count %d\n", get_nxflat16(&header->h_importcount)); +} + +/*********************************************************************** + * show_usage + ***********************************************************************/ + +static void show_usage(void) +{ + fprintf(stderr, "Usage: %s [options] \n\n", program_name); +#if 1 + fprintf(stderr, "Where options are one or more of the following:\n\n"); +#else + fprintf(stderr, "Where options are one or more of the following. Note\n"); + fprintf(stderr, "that a space is always required between the option and\n"); + fprintf(stderr, "any following arguments\n\n"); +#endif + fprintf(stderr, " -h Dump the XFLAT file header [not dumped]\n"); + fprintf(stderr, " -r Dump relocation entries [not dumped]\n"); + fprintf(stderr, " -i Dump the imported symbol table [not dumped]\n"); + fprintf(stderr, " -x Dump xFLT loader pathname [not dumped]\n"); + fprintf(stderr, " -c Disassemble the text section [not dumped]\n"); + fprintf(stderr, " -d Dump data section (hex) [not dumped]\n"); + fprintf(stderr, " -a Dump all of the above [not dumped]\n"); +#ifdef ARCH_BIG_ENDIAN + fprintf(stderr, " -b Assume little-endian byteorder [big endian]\n"); +#else + fprintf(stderr, " -b Assume big-endian byteorder [little endian]\n"); +#endif + fprintf(stderr, " -v Output verbose debug info [no output]\n"); + fprintf(stderr, "\n"); + exit(1); +} + +/*********************************************************************** + * parse_args + ***********************************************************************/ + +static void parse_args(int argc, char **argv) +{ + int opt; + + /* Save our name (for show_usage) */ + + program_name = argv[0]; + + /* At least three things must appear on the program line: the program name, + * the BFD filname, and at least one option. */ + + if (argc < 3) + { + fprintf(stderr, "ERROR: Missing required arguments\n\n"); + show_usage(); + } + + /* Get miscellaneous options from the command line. */ + + while ((opt = getopt(argc, argv, "hrieLlxcbdav")) != -1) + { + switch (opt) + { + + case 'h': /* Dump the flat file header */ + dump_header++; + break; + + case 'r': /* Dump the flat file header */ + dump_relocs++; + break; + + case 'i': /* Dump the imported symbol table */ + dump_imports++; + break; + + case 'c': /* Disassembly text */ + if (print_insn_arm) + { + dump_text++; + } + else + { + printf("-c ignored: No disassembler available\n"); + } + break; + + case 'b': /* other-endian */ +#ifdef ARCH_BIG_ENDIAN + big_endian = 0; +#else + big_endian++; +#endif + break; + + case 'd': /* Dump data */ + dump_data++; + break; + + case 'a': /* Dump everying */ + dump_header++; + dump_relocs++; + dump_imports++; + dump_text++; + dump_data++; + break; + + case 'v': /* Output verbose debug information */ + verbose++; + break; + + default: + fprintf(stderr, "%s Unknown option\n\n", argv[0]); + show_usage(); + break; + } + } + + /* Get the name of the input BFD file. */ + + nxflat_filename = argv[argc - 1]; +} + +/*********************************************************************** + * Public Functions + ***********************************************************************/ + +/*********************************************************************** + * main + ***********************************************************************/ + +int main(int argc, char **argv, char **envp) +{ + FILE *in_stream; + struct nxflat_hdr_s header; + + /* Get the input parameters */ + + parse_args(argc, argv); + + /* Open the FLT file */ + + in_stream = fopen(nxflat_filename, "rb"); + if (NULL == in_stream) + { + fprintf(stderr, "Cannot open file %s for reading\n", nxflat_filename); + exit(1); + } + + /* Read the FLT header */ + + if (1 != fread((void *)&header, sizeof(struct nxflat_hdr_s), 1, in_stream)) + { + fprintf(stderr, "Error reading flat header\n"); + exit(1); + } + + printf("Dumping Flat Binary File: %s\n", nxflat_filename); + + /* Dump the contents of the FLT header */ + + if (dump_header) + { + dump_hdr(&header); + } + + /* Dump the relocation entries */ + + if (dump_relocs) + { + dump_relocation_entries(in_stream, &header); + } + + /* Dump all imported symbols */ + + if (dump_imports) + { + dump_imported_symbols(in_stream, &header); + } + + if (dump_text) + { + disassemble_text(in_stream, &header); + } + + if (dump_data) + { + dump_hex_data(in_stream, &header); + } + + fclose(in_stream); + + if (num_errors > 0) + { + fprintf(stderr, "Finished with %d errors\n", num_errors); + } + + return 0; +} diff --git a/misc/buildroot/toolchain/nxflat/readxflat.c b/misc/buildroot/toolchain/nxflat/readxflat.c deleted file mode 100644 index d4131bc75..000000000 --- a/misc/buildroot/toolchain/nxflat/readxflat.c +++ /dev/null @@ -1,669 +0,0 @@ -/*********************************************************************** - * toolchain/nxflat/readnxflat.c - * - * Copyright (C) 2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Modified from readxflat (see http://xflat.org): - * - * Copyright (c) 2002, 2006, Cadenux, LLC. All rights reserved. - * Copyright (c) 2002, 2006, Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ***********************************************************************/ - -/*********************************************************************** - * Compilation Flags - ***********************************************************************/ - -#define SWAP_BYTES 1 - -/*********************************************************************** - * Included Files - ***********************************************************************/ -#include -#include -#include -#include -#include -#include /* ntohl and friends */ -#include "nxflat.h" - -/*********************************************************************** - * Compilation Switches - ***********************************************************************/ - -/* #define RELOCS_IN_NETWORK_ORDER */ - -/*********************************************************************** - * Definitions - ***********************************************************************/ -#define NXFLAT_HDR_SIZE sizeof(struct nxflat_hdr_s) - -/*********************************************************************** - * Private Data - ***********************************************************************/ -static const char *program_name; -static const char *nxflat_filename; - -static int dump_header = 0; -static int dump_relocs = 0; -static int dump_imports = 0; -static int dump_text = 0; -static int dump_data = 0; -static int verbose = 0; - -static int num_errors = 0; - -#ifdef ARCH_BIG_ENDIAN -static int big_endian = 1; /* Assume big-endian */ -#else -static int big_endian = 0; /* Assume little-endian */ -#endif - -/*********************************************************************** - * Private Constant Data - ***********************************************************************/ - -static const char unknown[] = "UNKNOWN"; - -static const char header_reloc_none[] = "RELOC_NONE"; -static const char header_reloc_text[] = "RELOC_TEXT"; -static const char header_reloc_data[] = "RELOC_DATA"; -static const char header_reloc_bss[] = "RELOC_BSS"; - -static const char *reloc_type_string[] = { - header_reloc_none, - header_reloc_text, - header_reloc_data, - header_reloc_bss, - unknown -}; - -/*********************************************************************** - * Public Function Prototypes - ***********************************************************************/ - -extern void __attribute__ ((weak)) print_insn_arm(u_int32_t pc, - FILE * stream, - u_int32_t given); - -/*********************************************************************** - * Private Functions - ***********************************************************************/ - -/*********************************************************************** - * swap32 - ***********************************************************************/ - -static inline u_int32_t nxflat_swap32(u_int32_t little) -{ - u_int32_t big = - ((little >> 24) & 0xff) | - (((little >> 16) & 0xff) << 8) | - (((little >> 8) & 0xff) << 16) | ((little & 0xff) << 24); - return big; -} - -/*********************************************************************** - * get_nxflat32 - ***********************************************************************/ - -static inline u_int32_t get_nxflat32(u_int32_t * addr32) -{ - return ntohl(*addr32); -} - -/*********************************************************************** - * get_nxflat16 - ***********************************************************************/ - -static inline u_int16_t get_nxflat16(u_int16_t * addr16) -{ - return ntohs(*addr16); -} - -/*********************************************************************** - * dump_hex_data - ***********************************************************************/ - -static void dump_hex_data(FILE * in_stream, struct nxflat_hdr_s *header) -{ - u_int32_t data_start = get_nxflat32(&header->h_datastart); - u_int32_t data_end = get_nxflat32(&header->h_dataend); - int32_t words_left = (data_end - data_start) / sizeof(u_int32_t); - u_int32_t addr; - u_int32_t buffer[64]; - - printf("\nXFLAT DATA SEGMENT:\n\n"); - - /* Seek to the beginning of data in the file */ - - if (fseek(in_stream, data_start, SEEK_SET) != 0) - { - fprintf(stderr, - "ERROR: Failed to seek to data in file: offset: %08x\n", - data_start); - return; - } - - /* Now dump all of the data reading 64 words at a time */ - - addr = 0; - while (words_left > 0) - { - size_t nread = fread(buffer, sizeof(u_int32_t), 64, in_stream); - if (nread >= 0) - { - union - { - u_int32_t l[4]; - unsigned char b[16]; - } row; - int32_t i, j, k; - - for (i = 0; i < nread; i += 4) - { - for (j = 0; j < 4; j++) - { - row.l[j] = buffer[i + j]; - } - - printf("%08x: ", addr); - - for (j = 0; j < 4; j++) - { - printf("%08x ", row.l[j]); - } - - printf(" "); - - for (j = 0; j < 4 * sizeof(u_int32_t); j += sizeof(u_int32_t)) - { - for (k = 0; k < sizeof(u_int32_t); k++) - { - if (isprint(row.b[j + k])) - putchar(row.b[j + k]); - else - putchar('.'); - } - } - - putchar('\n'); - addr += 4 * sizeof(u_int32_t); - } - words_left -= nread; - } - else - break; - } - putchar('\n'); -} - -/*********************************************************************** - * disassemble_text - ***********************************************************************/ - -static void disassemble_text(FILE * in_stream, struct nxflat_hdr_s *header) -{ - if (print_insn_arm) - { - u_int32_t text_start = NXFLAT_HDR_SIZE; - u_int32_t text_end = get_nxflat32(&header->h_datastart); - int32_t insns_left = (text_end - text_start) / sizeof(u_int32_t); - u_int32_t addr; - u_int32_t buffer[64]; - - printf("\nXFLAT TEXT:\n\n"); - - /* Seek to the beginning of text in the file */ - if (fseek(in_stream, text_start, SEEK_SET) != 0) - { - fprintf(stderr, - "ERROR: Failed to seek to text in file: offset: %08x\n", - text_start); - return; - } - - /* Now dump all of the data reading 64 insns at a time */ - - addr = text_start; - while (insns_left > 0) - { - size_t nread = fread(buffer, sizeof(u_int32_t), 64, in_stream); - if (nread > 0) - { - int i; - for (i = 0; i < nread; i++) - { - u_int32_t insn = buffer[i]; - if (big_endian) - { - insn = nxflat_swap32(insn); - } - - printf("%08x %08x\t", addr, insn); - print_insn_arm(addr, stdout, insn); - putchar('\n'); - addr += sizeof(u_int32_t); - } - insns_left -= nread; - } - else - break; - putchar('\n'); - } - } -} - -/*********************************************************************** - * dump_imported_symbols - ***********************************************************************/ - -static void dump_imported_symbols(FILE * in_stream, struct nxflat_hdr_s *header) -{ - struct nxflat_import_s import; - u_int32_t import_offset; - u_int32_t file_offset; - char imported_symbol_name[NXFLAT_MAX_STRING_SIZE]; - int status; - int i; - - printf("\nIMPORTED SYMBOLS:\n"); - printf(" ADDRESS DATA SEGM SYMBOL NAME\n\n"); - - import_offset = get_nxflat32(&header->h_importsymbols); - - for (i = 0; i < get_nxflat16(&header->h_importcount); i++) - { - /* Seek to the next imported symbol */ - - file_offset = i * sizeof(struct nxflat_import_s) + import_offset; - - if (fseek(in_stream, file_offset, SEEK_SET) != 0) - { - fprintf(stderr, "ERROR: fseek to imported symbol %d struct failed\n", - i); - fprintf(stderr, " file_offset: %d, errno: %d\n", file_offset, - errno); - exit(1); - } - - /* Read the next import entry. */ - - status = fread((void *)&import, - sizeof(struct nxflat_import_s), 1, in_stream); - - if (status != 1) - { - fprintf(stderr, "ERROR: Read imported symbol %d struct failed, " - "errno: %d\n", i + 1, errno); - exit(1); - } - - if (big_endian) - { - import.i_funcname = nxflat_swap32(import.i_funcname); - import.i_funcaddress = nxflat_swap32(import.i_funcaddress); - } - - if (verbose) - { - /* Print the raw info */ - - printf("[%4d %08x %08x]\n", - i + 1, import.i_funcaddress, import.i_funcname); - } - - /* Seek to the function name in the file */ - - file_offset = import.i_funcname + NXFLAT_HDR_SIZE; - if (0 != fseek(in_stream, file_offset, SEEK_SET)) - { - fprintf(stderr, "ERROR: fseek to imported symbol %d name failed\n", - i); - fprintf(stderr, " file_offset: %d, errno: %d\n", - file_offset, errno); - exit(1); - } - - /* Then, read the imported symbol name (assuming it is less than - * NXFLAT_MAX_STRING_SIZE in length). */ - - status = fread((void *)imported_symbol_name, NXFLAT_MAX_STRING_SIZE, - 1, in_stream); - if (status != 1) - { - fprintf(stderr, "ERROR: Read imported symbol %d name failed, " - "errno: %d\n", i + 1, errno); - exit(1); - } - imported_symbol_name[NXFLAT_MAX_STRING_SIZE - 1] = '\0'; - - /* And print it */ - - printf("%5d ", i + 1); - - if (import.i_funcaddress) - { - printf("%08x ", import.i_funcaddress); - } - else - { - printf("UNKNOWN "); - } - - printf("%s\n", imported_symbol_name); - } -} - -/*********************************************************************** - * dump_relocation_entries - ***********************************************************************/ - -static void dump_relocation_entries(FILE * in_stream, struct nxflat_hdr_s *header) -{ - struct nxflat_reloc_s reloc; - int status; - int i; - - /* Seek to the beginning of the relocation records. */ - - if (0 != fseek(in_stream, get_nxflat32(&header->h_relocstart), SEEK_SET)) - { - fprintf(stderr, "ERROR: fseek to reloc records failed, errno: %d\n", - errno); - exit(1); - } - - printf("\nRELOCATION ENTRIES:\n"); - printf(" DATA OFFS RELOC TYPE\n\n"); - - for (i = 0; i < get_nxflat32(&header->h_reloccount); i++) - { - /* Read the next reloction entry. */ - - status = fread((void *)&reloc, sizeof(struct nxflat_reloc_s), 1, in_stream); - if (status != 1) - { - fprintf(stderr, "Error reading reloc record %d, errno: %d\n", - i + 1, errno); - exit(1); - } - -#ifdef RELOCS_IN_NETWORK_ORDER - { - u_int32_t *ptmp; - ptmp = (u_int32_t *) & reloc; - *ptmp = get_nxflat32(ptmp); - } -#endif - - if (NXFLAT_RELOC_TYPE(reloc.r_info) >= NXFLAT_RELOC_TYPE_NUM) - { - printf("%5d %08x UNKNOWN(%d)\n", i + 1, - NXFLAT_RELOC_OFFSET(reloc.r_info), NXFLAT_RELOC_TYPE(reloc.r_info)); - fprintf(stderr, "Error eloc type out of range(%d)\n", - NXFLAT_RELOC_TYPE(reloc.r_info)); - num_errors++; - } - else - { - printf("%5d %08x %s\n", - i + 1, NXFLAT_RELOC_OFFSET(reloc.r_info), - reloc_type_string[NXFLAT_RELOC_TYPE(reloc.r_info)]); - } - } -} - -/*********************************************************************** - * dump_hdr - ***********************************************************************/ - -static void dump_hdr(struct nxflat_hdr_s *header) -{ - /* Print the contents of the FLT header */ - - printf("\nXFLAT HEADER:\n"); - printf("\nMagic %c%c%c%c\n", - header->h_magic[0], header->h_magic[1], - header->h_magic[2], header->h_magic[3]); - - printf("\nMEMORY MAP:\n"); - printf(" Text start %08lx\n", NXFLAT_HDR_SIZE); - printf(" Entry point %08x\n", get_nxflat32(&header->h_entry)); - printf(" Data start %08x\n", get_nxflat32(&header->h_datastart)); - printf(" Data end %08x\n", get_nxflat32(&header->h_dataend) - 1); - printf(" Bss start %08x\n", get_nxflat32(&header->h_dataend)); - printf(" Bss end %08x\n", get_nxflat32(&header->h_bssend) - 1); - printf("TOTAL SIZE %08x\n\n", get_nxflat32(&header->h_bssend)); - printf("Stack size %08x\n", get_nxflat32(&header->h_stacksize)); - printf("\nRELOCATIONS:\n"); - printf(" Reloc start %08x\n", get_nxflat32(&header->h_relocstart)); - printf(" reloc count %d\n", get_nxflat32(&header->h_reloccount)); - printf("\nIMPORTED SYMBOLS:\n"); - printf(" Import start %08x\n", get_nxflat32(&header->h_importsymbols)); - printf(" Import count %d\n\n", get_nxflat16(&header->h_importcount)); -} - -/*********************************************************************** - * show_usage - ***********************************************************************/ - -static void show_usage(void) -{ - fprintf(stderr, "Usage: %s [options] \n\n", program_name); -#if 1 - fprintf(stderr, "Where options are one or more of the following:\n\n"); -#else - fprintf(stderr, "Where options are one or more of the following. Note\n"); - fprintf(stderr, "that a space is always required between the option and\n"); - fprintf(stderr, "any following arguments\n\n"); -#endif - fprintf(stderr, " -h Dump the XFLAT file header [not dumped]\n"); - fprintf(stderr, " -r Dump relocation entries [not dumped]\n"); - fprintf(stderr, " -i Dump the imported symbol table [not dumped]\n"); - fprintf(stderr, " -x Dump xFLT loader pathname [not dumped]\n"); - fprintf(stderr, " -c Disassemble the text section [not dumped]\n"); - fprintf(stderr, " -d Dump data section (hex) [not dumped]\n"); - fprintf(stderr, " -a Dump all of the above [not dumped]\n"); -#ifdef ARCH_BIG_ENDIAN - fprintf(stderr, " -b Assume little-endian byteorder [big endian]\n"); -#else - fprintf(stderr, " -b Assume big-endian byteorder [little endian]\n"); -#endif - fprintf(stderr, " -v Output verbose debug info [no output]\n"); - fprintf(stderr, "\n"); - exit(1); -} - -/*********************************************************************** - * parse_args - ***********************************************************************/ - -static void parse_args(int argc, char **argv) -{ - int opt; - - /* Save our name (for show_usage) */ - - program_name = argv[0]; - - /* At least three things must appear on the program line: the program name, - * the BFD filname, and at least one option. */ - - if (argc < 3) - { - fprintf(stderr, "ERROR: Missing required arguments\n\n"); - show_usage(); - } - - /* Get miscellaneous options from the command line. */ - - while ((opt = getopt(argc, argv, "hrieLlxcbdav")) != -1) - { - switch (opt) - { - - case 'h': /* Dump the flat file header */ - dump_header++; - break; - - case 'r': /* Dump the flat file header */ - dump_relocs++; - break; - - case 'i': /* Dump the imported symbol table */ - dump_imports++; - break; - - case 'c': /* Disassembly text */ - if (print_insn_arm) - { - dump_text++; - } - else - { - printf("-c ignored: No disassembler available\n"); - } - break; - - case 'b': /* other-endian */ -#ifdef ARCH_BIG_ENDIAN - big_endian = 0; -#else - big_endian++; -#endif - break; - - case 'd': /* Dump data */ - dump_data++; - break; - - case 'a': /* Dump everying */ - dump_header++; - dump_relocs++; - dump_imports++; - dump_text++; - dump_data++; - break; - - case 'v': /* Output verbose debug information */ - verbose++; - break; - - default: - fprintf(stderr, "%s Unknown option\n\n", argv[0]); - show_usage(); - break; - } - } - - /* Get the name of the input BFD file. */ - - nxflat_filename = argv[argc - 1]; -} - -/*********************************************************************** - * Public Functions - ***********************************************************************/ - -/*********************************************************************** - * main - ***********************************************************************/ - -int main(int argc, char **argv, char **envp) -{ - FILE *in_stream; - struct nxflat_hdr_s header; - - /* Get the input parameters */ - - parse_args(argc, argv); - - /* Open the FLT file */ - - in_stream = fopen(nxflat_filename, "rb"); - if (NULL == in_stream) - { - fprintf(stderr, "Cannot open file %s for reading\n", nxflat_filename); - exit(1); - } - - /* Read the FLT header */ - - if (1 != fread((void *)&header, sizeof(struct nxflat_hdr_s), 1, in_stream)) - { - fprintf(stderr, "Error reading flat header\n"); - exit(1); - } - - printf("Dumping Flat Binary File: %s\n", nxflat_filename); - - /* Dump the contents of the FLT header */ - - if (dump_header) - { - dump_hdr(&header); - } - - /* Dump the relocation entries */ - - if (dump_relocs) - { - dump_relocation_entries(in_stream, &header); - } - - /* Dump all imported symbols */ - - if (dump_imports) - { - dump_imported_symbols(in_stream, &header); - } - - if (dump_text) - { - disassemble_text(in_stream, &header); - } - - if (dump_data) - { - dump_hex_data(in_stream, &header); - } - - fclose(in_stream); - - if (num_errors > 0) - { - fprintf(stderr, "Finished with %d errors\n", num_errors); - } - - return 0; -} -- cgit v1.2.3