Resync new repository with old repo r5166

git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo
2012-09-17 18:18:44 +00:00
commit 57623d42eb
5691 changed files with 1361853 additions and 0 deletions
@@ -0,0 +1,9 @@
comment "NuttX Binary Support"
config BR2_PACKAGE_NXFLAT
bool "Build NXFLAT tools"
default n
depends on BR2_arm
help
Build tools need to build NuttX NXFLAT load-able binary
+74
View File
@@ -0,0 +1,74 @@
############################################################################
# toolchain/nxflat/Makefile
#
# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must 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.
#
############################################################################
CFLAGS += -Wall -I. -I$(BINUTILS_DIR1)/bfd -I$(BINUTILS_DIR)/include
LDFLAGS += -L$(BINUTILS_DIR1)/bfd -L$(BINUTILS_DIR1)/libiberty
LIBS = -lbfd -liberty -lz -lc
LDNXFLAT_OBJS = ldnxflat.o
MKNXFLAT_OBJS = mknxflat.o
READNXFLAT_OBJS = readnxflat.o
OBJS = $(LDNXFLAT_OBJS) $(MKNXFLAT_OBJS) $(READNXFLAT_OBJS)
BIN = ldnxflat mknxflat readnxflat
GXX_VERSION = ${shell $(ARCHCXX) -dumpversion | cut -d. -f1}
all: $(BIN)
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
arch:
@ln -sf $(ARCH) arch
ldnxflat: arch $(LDNXFLAT_OBJS)
$(CC) $(LDFLAGS) $(LDNXFLAT_OBJS) -o $@ $(LIBS)
mknxflat: arch $(MKNXFLAT_OBJS)
$(CC) $(LDFLAGS) $(MKNXFLAT_OBJS) -o $@ $(LIBS)
arch/libarch.a:
$(MAKE) -C arch CC="$(CC)"
readnxflat: arch $(READNXFLAT_OBJS) arch/libarch.a
$(CC) $(LDFLAGS) -L arch -o $@ $(READNXFLAT_OBJS) $(LIBS) -larch
# Housekeeping
clean:
-$(MAKE) -C arch clean
rm -f *.o $(BIN) arch *.exe *~ .*.swp
@@ -0,0 +1,50 @@
############################################################################
# toolchain/nxflat/arm/Makefile
#
# Copyright (C) 2009 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must 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.
#
############################################################################
CFLAGS += -Wall
BIN = libarch.a
OBJS = disarm.o
all: $(BIN)
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
$(BIN): $(OBJS)
$(AR) rcs $@ $<
clean:
rm -f *.o *.a *~ .*.swp core
+303
View File
@@ -0,0 +1,303 @@
/***********************************************************************
* xflat/tools/arm/arch.h
* ARM thumb2 ELF support for BFD.
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Simply lifted with minimal change from the BFD, binutils 2.19.1:
*
* Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
* Free Software Foundation, Inc.
*
* This file is part of BFD, the Binary File Descriptor library.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*
***********************************************************************/
#ifndef _TOOLCHAIN_NXFLAT_ARM_ARCH_H
#define _TOOLCHAIN_NXFLAT_ARM_ARCH_H
#include "reloc-macros.h"
/* Inform ldnxflat that this is 32-bit ARM code */
#define NXFLAT_ARM 1
#undef NXFLAT_THUMB2
/* Processor specific flags for the ELF header e_flags field. */
#define EF_ARM_RELEXEC 0x01
#define EF_ARM_HASENTRY 0x02
#define EF_ARM_INTERWORK 0x04
#define EF_ARM_APCS_26 0x08
#define EF_ARM_APCS_FLOAT 0x10
#define EF_ARM_PIC 0x20
#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use. */
#define EF_ARM_NEW_ABI 0x80
#define EF_ARM_OLD_ABI 0x100
#define EF_ARM_SOFT_FLOAT 0x200
#define EF_ARM_VFP_FLOAT 0x400
#define EF_ARM_MAVERICK_FLOAT 0x800
/* Frame unwind information */
#define PT_ARM_EXIDX (PT_LOPROC + 1)
/* Other constants defined in the ARM ELF spec. version B-01. */
#define EF_ARM_SYMSARESORTED 0x04 /* NB conflicts with EF_INTERWORK */
#define EF_ARM_DYNSYMSUSESEGIDX 0x08 /* NB conflicts with EF_APCS26 */
#define EF_ARM_MAPSYMSFIRST 0x10 /* NB conflicts with EF_APCS_FLOAT */
#define EF_ARM_EABIMASK 0xFF000000
/* Constants defined in AAELF. */
#define EF_ARM_BE8 0x00800000
#define EF_ARM_LE8 0x00400000
#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
#define EF_ARM_EABI_UNKNOWN 0x00000000
#define EF_ARM_EABI_VER1 0x01000000
#define EF_ARM_EABI_VER2 0x02000000
#define EF_ARM_EABI_VER3 0x03000000
#define EF_ARM_EABI_VER4 0x04000000
#define EF_ARM_EABI_VER5 0x05000000
/* Local aliases for some flags to match names used by COFF port. */
#define F_INTERWORK EF_ARM_INTERWORK
#define F_APCS26 EF_ARM_APCS_26
#define F_APCS_FLOAT EF_ARM_APCS_FLOAT
#define F_PIC EF_ARM_PIC
#define F_SOFT_FLOAT EF_ARM_SOFT_FLOAT
#define F_VFP_FLOAT EF_ARM_VFP_FLOAT
/* Additional symbol types for Thumb. */
#define STT_ARM_TFUNC 13 /* A Thumb function. */
#define STT_ARM_16BIT 15 /* A Thumb label. */
/* Additional section types. */
#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */
#define SHT_ARM_PREEMPTMAP 0x70000002 /* Section pre-emption details. */
#define SHT_ARM_ATTRIBUTES 0x70000003 /* Section holds attributes. */
/* ARM-specific values for sh_flags. */
#define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point. */
#define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */
/* ARM-specific program header flags. */
#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base. */
#define PF_ARM_PI 0x20000000 /* Segment is position-independent. */
#define PF_ARM_ABS 0x40000000 /* Segment must be loaded at its base address. */
/* Values for the Tag_CPU_arch EABI attribute. */
#define TAG_CPU_ARCH_PRE_V4 0
#define TAG_CPU_ARCH_V4 1
#define TAG_CPU_ARCH_V4T 2
#define TAG_CPU_ARCH_V5T 3
#define TAG_CPU_ARCH_V5TE 4
#define TAG_CPU_ARCH_V5TEJ 5
#define TAG_CPU_ARCH_V6 6
#define TAG_CPU_ARCH_V6KZ 7
#define TAG_CPU_ARCH_V6T2 8
#define TAG_CPU_ARCH_V6K 9
#define TAG_CPU_ARCH_V7 10
/* Relocation types. */
START_RELOC_NUMBERS (elf_arm_reloc_type)
/* AAELF official names and numbers. */
RELOC_NUMBER (R_ARM_NONE, 0)
RELOC_NUMBER (R_ARM_PC24, 1) /* deprecated */
RELOC_NUMBER (R_ARM_ABS32, 2)
RELOC_NUMBER (R_ARM_REL32, 3)
RELOC_NUMBER (R_ARM_LDR_PC_G0, 4)
RELOC_NUMBER (R_ARM_ABS16, 5)
RELOC_NUMBER (R_ARM_ABS12, 6)
RELOC_NUMBER (R_ARM_THM_ABS5, 7)
RELOC_NUMBER (R_ARM_ABS8, 8)
RELOC_NUMBER (R_ARM_SBREL32, 9)
RELOC_NUMBER (R_ARM_THM_CALL, 10)
RELOC_NUMBER (R_ARM_THM_PC8, 11)
RELOC_NUMBER (R_ARM_BREL_ADJ, 12)
RELOC_NUMBER (R_ARM_SWI24, 13) /* obsolete */
RELOC_NUMBER (R_ARM_THM_SWI8, 14) /* obsolete */
RELOC_NUMBER (R_ARM_XPC25, 15) /* obsolete */
RELOC_NUMBER (R_ARM_THM_XPC22, 16) /* obsolete */
RELOC_NUMBER (R_ARM_TLS_DTPMOD32, 17)
RELOC_NUMBER (R_ARM_TLS_DTPOFF32, 18)
RELOC_NUMBER (R_ARM_TLS_TPOFF32, 19)
RELOC_NUMBER (R_ARM_COPY, 20) /* Copy symbol at runtime. */
RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* Create GOT entry. */
RELOC_NUMBER (R_ARM_JUMP_SLOT, 22) /* Create PLT entry. */
RELOC_NUMBER (R_ARM_RELATIVE, 23) /* Adjust by program base. */
RELOC_NUMBER (R_ARM_GOTOFF32, 24) /* 32 bit offset to GOT. */
RELOC_NUMBER (R_ARM_BASE_PREL, 25) /* 32 bit PC relative offset to GOT. */
RELOC_NUMBER (R_ARM_GOT_BREL, 26) /* 32 bit GOT entry. */
RELOC_NUMBER (R_ARM_PLT32, 27) /* deprecated - 32 bit PLT address. */
RELOC_NUMBER (R_ARM_CALL, 28)
RELOC_NUMBER (R_ARM_JUMP24, 29)
RELOC_NUMBER (R_ARM_THM_JUMP24, 30)
RELOC_NUMBER (R_ARM_BASE_ABS, 31)
RELOC_NUMBER (R_ARM_ALU_PCREL7_0, 32) /* obsolete */
RELOC_NUMBER (R_ARM_ALU_PCREL15_8, 33) /* obsolete */
RELOC_NUMBER (R_ARM_ALU_PCREL23_15, 34) /* obsolete */
RELOC_NUMBER (R_ARM_LDR_SBREL_11_0, 35) /* deprecated, should have _NC suffix */
RELOC_NUMBER (R_ARM_ALU_SBREL_19_12, 36) /* deprecated, should have _NC suffix */
RELOC_NUMBER (R_ARM_ALU_SBREL_27_20, 37) /* deprecated, should have _CK suffix */
RELOC_NUMBER (R_ARM_TARGET1, 38)
RELOC_NUMBER (R_ARM_SBREL31, 39) /* deprecated */
RELOC_NUMBER (R_ARM_V4BX, 40)
RELOC_NUMBER (R_ARM_TARGET2, 41)
RELOC_NUMBER (R_ARM_PREL31, 42)
RELOC_NUMBER (R_ARM_MOVW_ABS_NC, 43)
RELOC_NUMBER (R_ARM_MOVT_ABS, 44)
RELOC_NUMBER (R_ARM_MOVW_PREL_NC, 45)
RELOC_NUMBER (R_ARM_MOVT_PREL, 46)
RELOC_NUMBER (R_ARM_THM_MOVW_ABS_NC, 47)
RELOC_NUMBER (R_ARM_THM_MOVT_ABS, 48)
RELOC_NUMBER (R_ARM_THM_MOVW_PREL_NC, 49)
RELOC_NUMBER (R_ARM_THM_MOVT_PREL, 50)
RELOC_NUMBER (R_ARM_THM_JUMP19, 51)
RELOC_NUMBER (R_ARM_THM_JUMP6, 52)
RELOC_NUMBER (R_ARM_THM_ALU_PREL_11_0, 53)
RELOC_NUMBER (R_ARM_THM_PC12, 54)
RELOC_NUMBER (R_ARM_ABS32_NOI, 55)
RELOC_NUMBER (R_ARM_REL32_NOI, 56)
RELOC_NUMBER (R_ARM_ALU_PC_G0_NC, 57)
RELOC_NUMBER (R_ARM_ALU_PC_G0, 58)
RELOC_NUMBER (R_ARM_ALU_PC_G1_NC, 59)
RELOC_NUMBER (R_ARM_ALU_PC_G1, 60)
RELOC_NUMBER (R_ARM_ALU_PC_G2, 61)
RELOC_NUMBER (R_ARM_LDR_PC_G1, 62)
RELOC_NUMBER (R_ARM_LDR_PC_G2, 63)
RELOC_NUMBER (R_ARM_LDRS_PC_G0, 64)
RELOC_NUMBER (R_ARM_LDRS_PC_G1, 65)
RELOC_NUMBER (R_ARM_LDRS_PC_G2, 66)
RELOC_NUMBER (R_ARM_LDC_PC_G0, 67)
RELOC_NUMBER (R_ARM_LDC_PC_G1, 68)
RELOC_NUMBER (R_ARM_LDC_PC_G2, 69)
RELOC_NUMBER (R_ARM_ALU_SB_G0_NC, 70)
RELOC_NUMBER (R_ARM_ALU_SB_G0, 71)
RELOC_NUMBER (R_ARM_ALU_SB_G1_NC, 72)
RELOC_NUMBER (R_ARM_ALU_SB_G1, 73)
RELOC_NUMBER (R_ARM_ALU_SB_G2, 74)
RELOC_NUMBER (R_ARM_LDR_SB_G0, 75)
RELOC_NUMBER (R_ARM_LDR_SB_G1, 76)
RELOC_NUMBER (R_ARM_LDR_SB_G2, 77)
RELOC_NUMBER (R_ARM_LDRS_SB_G0, 78)
RELOC_NUMBER (R_ARM_LDRS_SB_G1, 79)
RELOC_NUMBER (R_ARM_LDRS_SB_G2, 80)
RELOC_NUMBER (R_ARM_LDC_SB_G0, 81)
RELOC_NUMBER (R_ARM_LDC_SB_G1, 82)
RELOC_NUMBER (R_ARM_LDC_SB_G2, 83)
RELOC_NUMBER (R_ARM_MOVW_BREL_NC, 84)
RELOC_NUMBER (R_ARM_MOVT_BREL, 85)
RELOC_NUMBER (R_ARM_MOVW_BREL, 86)
RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC, 87)
RELOC_NUMBER (R_ARM_THM_MOVT_BREL, 88)
RELOC_NUMBER (R_ARM_THM_MOVW_BREL, 89)
/* 90-93 unallocated */
RELOC_NUMBER (R_ARM_PLT32_ABS, 94)
RELOC_NUMBER (R_ARM_GOT_ABS, 95)
RELOC_NUMBER (R_ARM_GOT_PREL, 96)
RELOC_NUMBER (R_ARM_GOT_BREL12, 97)
RELOC_NUMBER (R_ARM_GOTOFF12, 98)
RELOC_NUMBER (R_ARM_GOTRELAX, 99)
RELOC_NUMBER (R_ARM_GNU_VTENTRY, 100) /* deprecated - old C++ abi */
RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101) /* deprecated - old C++ abi */
RELOC_NUMBER (R_ARM_THM_JUMP11, 102)
RELOC_NUMBER (R_ARM_THM_JUMP8, 103)
RELOC_NUMBER (R_ARM_TLS_GD32, 104)
RELOC_NUMBER (R_ARM_TLS_LDM32, 105)
RELOC_NUMBER (R_ARM_TLS_LDO32, 106)
RELOC_NUMBER (R_ARM_TLS_IE32, 107)
RELOC_NUMBER (R_ARM_TLS_LE32, 108)
RELOC_NUMBER (R_ARM_TLS_LDO12, 109)
RELOC_NUMBER (R_ARM_TLS_LE12, 110)
RELOC_NUMBER (R_ARM_TLS_IE12GP, 111)
/* 112 - 127 private range */
RELOC_NUMBER (R_ARM_ME_TOO, 128) /* obsolete */
/* Extensions? R=read-only? */
RELOC_NUMBER (R_ARM_RXPC25, 249)
RELOC_NUMBER (R_ARM_RSBREL32, 250)
RELOC_NUMBER (R_ARM_THM_RPC22, 251)
RELOC_NUMBER (R_ARM_RREL32, 252)
RELOC_NUMBER (R_ARM_RABS32, 253)
RELOC_NUMBER (R_ARM_RPC24, 254)
RELOC_NUMBER (R_ARM_RBASE, 255)
/* Unofficial names for some of the relocs. */
FAKE_RELOC (R_ARM_GOTOFF, R_ARM_GOTOFF32) /* 32 bit offset to GOT. */
FAKE_RELOC (R_ARM_THM_PC22, R_ARM_THM_CALL)
FAKE_RELOC (R_ARM_THM_PC11, R_ARM_THM_JUMP11)
FAKE_RELOC (R_ARM_THM_PC9, R_ARM_THM_JUMP8)
/* Relocs with both a different name, and (apparently) different meaning in
GNU usage. */
FAKE_RELOC (R_ARM_GOTPC, R_ARM_BASE_PREL) /* 32 bit PC relative offset to GOT. */
FAKE_RELOC (R_ARM_GOT32, R_ARM_GOT_BREL) /* 32 bit GOT entry. */
FAKE_RELOC (R_ARM_ROSEGREL32, R_ARM_SBREL31) /* ??? */
FAKE_RELOC (R_ARM_AMP_VCALL9, R_ARM_BREL_ADJ) /* Thumb-something. Not used. */
END_RELOC_NUMBERS (R_ARM_max = 256)
#ifdef BFD_ARCH_SIZE
/* EABI object attributes. */
enum
{
/* 0-3 are generic. */
Tag_CPU_raw_name = 4,
Tag_CPU_name,
Tag_CPU_arch,
Tag_CPU_arch_profile,
Tag_ARM_ISA_use,
Tag_THUMB_ISA_use,
Tag_VFP_arch,
Tag_WMMX_arch,
Tag_NEON_arch,
Tag_PCS_config,
Tag_ABI_PCS_R9_use,
Tag_ABI_PCS_RW_data,
Tag_ABI_PCS_RO_data,
Tag_ABI_PCS_GOT_use,
Tag_ABI_PCS_wchar_t,
Tag_ABI_FP_rounding,
Tag_ABI_FP_denormal,
Tag_ABI_FP_exceptions,
Tag_ABI_FP_user_exceptions,
Tag_ABI_FP_number_model,
Tag_ABI_align8_needed,
Tag_ABI_align8_preserved,
Tag_ABI_enum_size,
Tag_ABI_HardFP_use,
Tag_ABI_VFP_args,
Tag_ABI_WMMX_args,
Tag_ABI_optimization_goals,
Tag_ABI_FP_optimization_goals,
/* 32 is generic. */
};
#endif
/* The name of the note section used to identify arm variants. */
#define ARM_NOTE_SECTION ".note.gnu.arm.ident"
/* Special section names. */
#define ELF_STRING_ARM_unwind ".ARM.exidx"
#define ELF_STRING_ARM_unwind_info ".ARM.extab"
#define ELF_STRING_ARM_unwind_once ".gnu.linkonce.armexidx."
#define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab."
#endif /* _TOOLCHAIN_NXFLAT_ARM_ARCH_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,216 @@
/***********************************************************************
* toolchain/nxflat/arm/dyncall_skeleton.def
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must 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.
*
***********************************************************************/
/*******************************************************************
* File Prologue
*******************************************************************/
static const char file_prologue[] =
"/*******************************************************************\n"
" *\n"
" * This file contains the dynamic call logic that performs the thunk\n"
" * for outound calls from one module to another.\n"
" *\n"
" * ARM register quick reference:\n"
" *\n"
" * Name Number ARM Procedure Calling Standard Role\n"
" *\n"
" * a1 r0 argument 1/integer result/scratch register/argc\n"
" * a2 r1 argument 2/scratch register/argv\n"
" * a3 r2 argument 3/scratch register/envp\n"
" * a4 r3 argument 4/scratch register\n"
" * v1 r4 register variable\n"
" * v2 r5 register variable\n"
" * v3 r6 register variable\n"
" * v4 r7 register variable\n"
" * v5 r8 register variable\n"
" * sb/v6 r9 static base/register variable\n"
" * sl/v7 r10 stack limit/stack chunk handle/reg. variable\n"
" * fp r11 frame pointer\n"
" * ip r12 scratch register/new-sb in inter-link-unit calls\n"
" * sp r13 lower end of current stack frame\n"
" * lr r14 link address/scratch register\n"
" * pc r15 program counter\n"
" *******************************************************************/\n\n"
"/*******************************************************************\n"
" * Included Files\n"
" *******************************************************************/\n\n"
"/*******************************************************************\n"
" * Definitions\n"
" *******************************************************************/\n";
static const char import_prologue[] = "";
/*******************************************************************
* Import Function Name String Table
*******************************************************************/
static const char import_name_strtab_prologue[] =
"\n/*******************************************************************\n"
" * Import Function Names\n"
" *******************************************************************/\n\n"
"/* These are the names of all of the functions that are imported.\n"
" * Notice that all data associated with the library names is retained\n"
" * in the .text section."
" */\n\n"
"\t.text\n"
"\t.align\t0\n";
#define MKIMPSTRTABARG(fn,i) (i), (i), (i), (fn), (i), (i)
static const char import_name_strtab_format[] =
"\n\t.local\t__dynimport%04d\n"
"\t.type\t__dynimport%04d, object\n\n"
"__dynimport%04d:\n"
"\t.asciz\t\"%s\"\n"
"\t.size\t__dynimport%04d, .-__dynimport%04d\n";
/*******************************************************************
* Dyanamic Call Information
*******************************************************************/
static const char dynimport_decl_prologue[] =
"\n/*******************************************************************\n"
" * Imported Symbol Table (an array of type struct flat_import)\n"
" *******************************************************************/\n\n"
"/* Notice that, unlike most other arrays in this file, this array\n"
" * is declared to reside in .data. Because of this, there will be\n"
" * per-process instances of this table.\n"
" */\n\n"
"\t.data\n"
"\t.align\t2\n\n"
"\t.global\t__dynimport_begin\n"
"\t.type\t__dynimport_begin, object\n"
"\t.global\t__dynimport_end\n"
"\t.type\t__dynimport_end, object\n\n";
#define MKINFODECLARGS(fn, i) (i), (fn), (i)
static const char dynimport_decl_format[] =
"\t.local\t__dyninfo%04d\t/* Dynamic info for imported symbol %s */\n"
"\t.type\t__dyninfo%04d, object\n";
static const char dynimport_array_prologue[] =
"\n__dynimport_begin:\n";
#define MKINFOARGS(fn, i) (i), (fn), (i), (i), (i)
static const char dynimport_array_format[] =
"__dyninfo%04d:\t\t\t/* Dynamic info for imported symbol %s */\n"
"\t.word\t__dynimport%04d\t/* Offset to name of imported function */\n"
"\t.word\t0\t\t/* Resolved address of imported function */\n"
"\t.size\t__dyninfo%04d, .-__dyninfo%04d\n";
static const char dynimport_array_epilogue[] =
"__dynimport_end:\n"
"\t.size\t__dynimport_begin, __dynimport_end-__dynimport_begin\n";
static const char dyncall_decl_prologue[] =
"\n/*******************************************************************\n"
" * Dynamic Call Logic\n"
" *******************************************************************/\n\n"
"\t.text\n"
"\t.align\t2\n";
#define MKCALLARGS(fn, i) (fn), (fn), (fn), (fn), (i), (i), (i), (fn), (fn)
#ifndef __NO_GOT__
static const char dyncall_format[] =
"\n/* Dynamic call logic for imported symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d(GOTOFF)\n"
"\t.size\t%s, .-%s\n";
static const char nonreturning_dyncall_format[] =
"\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d(GOTOFF)\n"
"\t.size\t%s, .-%s\n";
#else
static const char dyncall_format[] =
"\n/* Dynamic call logic for imported symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d\n"
"\t.size\t%s, .-%s\n";
static const char nonreturning_dyncall_format[] =
"\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d\n"
"\t.size\t%s, .-%s\n";
#endif
/*******************************************************************
* File Epilogue
*******************************************************************/
static const char file_epilogue[] =
"\t.end\n";
File diff suppressed because it is too large Load Diff
+769
View File
@@ -0,0 +1,769 @@
/***********************************************************************
* xflat/tools/mknxflat.c
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Modified from ldelflib (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 <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must 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.
*
***********************************************************************/
/***********************************************************************
* Included Files
***********************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <bfd.h>
#include "nxflat.h"
#include "arch/arch.h"
/***********************************************************************
* Definitions
***********************************************************************/
#define dbg(format, arg...) \
if (verbose) printf(format, ## arg)
#define BSF_GLOBL_FUNC (BSF_GLOBAL|BSF_FUNCTION)
#define BSF_WEAK_FUNC (BSF_WEAK|BSF_FUNCTION)
#define BSF_DEFINED (BSF_LOCAL|BSF_GLOBAL)
#define IS_GLOBL_FUNC(x) ((((x)->flags)&(BSF_GLOBL_FUNC))==(BSF_GLOBL_FUNC))
#define IS_WEAK_FUNC(x) ((((x)->flags)&(BSF_WEAK_FUNC))==(BSF_WEAK_FUNC))
#define IS_DEFINED(x) ((((x)->flags)&(BSF_DEFINED))!=0)
#define IS_OBJECT(x) ((((x)->flags)&(BSF_OBJECT))!=0)
#define IS_WEAK(x) ((((x)->flags)&(BSF_WEAK))!=0)
#define MAX_EXPORT_NAMES 1024
/***********************************************************************
* Private Types
***********************************************************************/
typedef int (*symfunc_type) (asymbol * sym, void *arg);
typedef int (*namefunc_type) (const char *name, void *arg);
/***********************************************************************
* Private Variables
***********************************************************************/
/* Command line settings (counters but treated like booleans) */
static int verbose = 0;
static int weak_imports = 0;
static int dsyms = 0;
/* Characteristics of things */
static int calls_nonreturning_functions = 0;
/* Sizes of things */
static long number_of_symbols = 0;
static long number_undefined = 0;
/* Names of things */
static const char *program_name = NULL;
static const char *bfd_filename = NULL;
static const char *out_filename = NULL;
/* The symbol table. */
static asymbol **symbol_table = NULL;
/* handle to included file */
static FILE *include_stream = NULL;
static char token[1024];
static int counter;
/***********************************************************************
* Private constant data
***********************************************************************/
/* All of the strings defining the generated file are here: */
#include "arch/dyncall_skeleton.def"
static const char dyn_symbol_prefix[] = "__dyn";
#define DYN_SYMBOL_PREFIX_LEN 5
/* This is the list of names of libc and libpthread functions that
* do not return. These may require some special handling -- at a
* minimum, they must tie up resources that can only be released
* when the function returns.
*/
static const char *const nonreturners[] = {
"abort", /* Never returns */
"exit", /* Never returns */
"_exit", /* Never returns */
"longjmp", /* Never returns */
"_longjmp", /* Never returns */
"pthread_exit", /* Never returns */
"siglongjmp", /* Never returns */
NULL /* End of list */
};
/***********************************************************************
* Private Functions
***********************************************************************/
/***********************************************************************
* show_usage
***********************************************************************/
static void show_usage(void)
{
fprintf(stderr, "Usage: %s [options] <bfd-filename>\n\n", program_name);
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, " -f <cmd-filename>\n");
fprintf(stderr, " Take next commands from <cmd-filename> [cmd-line]\n");
fprintf(stderr, " -o <out-filename>\n");
fprintf(stderr, " Output to <out-filename> [stdout]\n");
fprintf(stderr, " -v Verbose output [no output]\n");
fprintf(stderr, " -w Import weakly declared functions, i.e., weakly\n");
fprintf(stderr, " declared functions are expected to be provided at\n");
fprintf(stderr, " load-time [not imported]\n");
fprintf(stderr, "\n");
exit(1);
}
/***********************************************************************
* get_symbols
***********************************************************************/
static asymbol **get_symbols(bfd * abfd, long *num)
{
long storage_needed;
asymbol **symbol_table;
long number_of_symbols;
if (dsyms)
storage_needed = bfd_get_dynamic_symtab_upper_bound(abfd);
else
storage_needed = bfd_get_symtab_upper_bound(abfd);
if (storage_needed < 0)
abort();
if (storage_needed == 0)
return NULL;
symbol_table = (asymbol **) malloc(storage_needed);
if (dsyms)
number_of_symbols = bfd_canonicalize_dynamic_symtab(abfd, symbol_table);
else
number_of_symbols = bfd_canonicalize_symtab(abfd, symbol_table);
if (number_of_symbols < 0)
abort();
*num = number_of_symbols;
return symbol_table;
}
/***********************************************************************
* traverse_undefined_functions
***********************************************************************/
static int traverse_undefined_functions(void *arg, symfunc_type fn)
{
int i;
for (i = 0; i < number_of_symbols; i++)
{
/* Check if it is undefined and not an object. I have found that symbol
* typing can be misleading: Imported functions are not marked as
* BSF_FUNCTION; weakly defined objects are listed as undefined objects.
* Conclusion: We will error if a object is truly undefined! */
if ((symbol_table[i]->value == 0) &&
(!IS_DEFINED(symbol_table[i])) && (!IS_OBJECT(symbol_table[i])))
{
/* Is is imported as a "weak" symbol? If so, we will process the
* symbol only if we were requested to do so from the command line. */
if ((!IS_WEAK(symbol_table[i])) || (weak_imports > 0))
{
/* Yes, process the symbol */
if (fn(symbol_table[i], arg) != 0)
{
/* If the function returns a non-zero value, then we
* terminate the traversal and return a non-zero value also. */
return 1;
}
}
}
}
/* Return 0 meaning that all undefined symbols were examined successfully. */
return 0;
}
/***********************************************************************
* put_string
***********************************************************************/
static void put_string(int fd, const char *string)
{
ssize_t bytes_available = strlen(string);
ssize_t bytes_written = write(fd, string, bytes_available);
if (bytes_written < 0)
{
fprintf(stderr,
"Failed to write %ld bytes of string to output, errno=%d\n",
(long)bytes_available, errno);
exit(5);
}
else if (bytes_written != bytes_available)
{
fprintf(stderr, "Only wrote %ld of %ld bytes of string to output\n",
(long)bytes_written, (long)bytes_available);
exit(6);
}
}
/***********************************************************************
* does_not_return_name/sym
***********************************************************************/
static int does_not_return_name(const char *func_name)
{
int i;
/* Check every name in the list of (usually) non-returning function */
for (i = 0; nonreturners[i] != NULL; i++)
{
/* Is this function name in the list */
if (strcmp(func_name, nonreturners[i]) == 0)
{
/* Yes, return true now. */
return 1;
}
}
/* Its not in the list, return false */
return 0;
}
static int does_not_return_sym(asymbol * sym, void *arg)
{
const char *func_name = sym->name;
if (func_name)
return does_not_return_name(func_name);
else
return 0;
}
/***********************************************************************
* check_for_nonreturning_functions
***********************************************************************/
static void check_for_nonreturning_functions(void)
{
calls_nonreturning_functions =
traverse_undefined_functions(NULL, does_not_return_sym);
}
/***********************************************************************
* count_undefined
***********************************************************************/
static int count_undefined(asymbol * sym, void *arg)
{
number_undefined++;
return 0;
}
/***********************************************************************
* put_dynimport_decl
***********************************************************************/
static int put_dynimport_decl(asymbol * sym, void *arg)
{
char dynimport_decl[1024];
const char *func_name = sym->name;
int fd = (int)arg;
/* Put the declaration for the dynamic info structure */
if (func_name)
{
sprintf(dynimport_decl, dynimport_decl_format,
MKINFODECLARGS(func_name, counter));
put_string(fd, dynimport_decl);
counter++;
}
return 0;
}
/***********************************************************************
* put_dynimport_array
***********************************************************************/
static int put_dynimport_array(asymbol * sym, void *arg)
{
char dynimport_array[1024];
const char *func_name = sym->name;
int fd = (int)arg;
/* Create the dynimport_array */
if (func_name)
{
sprintf(dynimport_array, dynimport_array_format,
MKINFOARGS(func_name, counter));
put_string(fd, dynimport_array);
counter++;
}
return 0;
}
/***********************************************************************
* put_nxflat_import
***********************************************************************/
static int put_nxflat_import(asymbol * sym, void *arg)
{
char thunk[4096];
const char *func_name = sym->name;
int fd = (int)arg;
if (func_name)
{
/* Create the thunk */
if (does_not_return_name(func_name) != 0)
{
/* The special case for functions that may not return */
sprintf(thunk, nonreturning_dyncall_format, MKCALLARGS(func_name, counter));
}
else
{
/* The normal case */
sprintf(thunk, dyncall_format, MKCALLARGS(func_name, counter));
}
put_string(fd, thunk);
counter++;
}
return 0;
}
/***********************************************************************
* put_all_nxflat_import
***********************************************************************/
static void put_all_nxflat_import(int fd)
{
if (number_undefined > 0)
{
/* Put all of the declarations for the dynimport structures together. */
put_string(fd, dynimport_decl_prologue);
counter = 0;
(void)traverse_undefined_functions((void *)fd, put_dynimport_decl);
/* Put all of the dynimport structures together as an array */
put_string(fd, dynimport_array_prologue);
counter = 0;
(void)traverse_undefined_functions((void *)fd, put_dynimport_array);
put_string(fd, dynimport_array_epilogue);
/* Put all of the dyncall logic together */
put_string(fd, dyncall_decl_prologue);
counter = 0;
(void)traverse_undefined_functions((void *)fd, put_nxflat_import);
}
}
/***********************************************************************
* put_import_name
***********************************************************************/
static int put_import_name(asymbol * sym, void *arg)
{
char import_name[512];
const char *func_name = sym->name;
int fd = (int)arg;
/* Create the import_name */
if (func_name)
{
sprintf(import_name, import_name_strtab_format,
MKIMPSTRTABARG(func_name, counter));
put_string(fd, import_name);
counter++;
}
return 0;
}
/***********************************************************************
* put_import_name_strtab
***********************************************************************/
static void inline put_import_name_strtab(int fd)
{
if (number_undefined > 0)
{
counter = 0;
put_string(fd, import_name_strtab_prologue);
(void)traverse_undefined_functions((void *)fd, put_import_name);
}
}
/***********************************************************************
* put_file_epilogue
***********************************************************************/
static void inline put_file_epilogue(int fd)
{
put_string(fd, file_epilogue);
}
/***********************************************************************
* put_file_prologue
***********************************************************************/
static void inline put_file_prologue(int fd)
{
put_string(fd, file_prologue);
if (number_undefined > 0)
{
put_string(fd, import_prologue);
}
}
/***********************************************************************
* get_file_token
***********************************************************************/
#define ISSPACE(c) \
((c==' ')||(c=='\f')||(c=='\n')||(c=='\r')||(c=='\t')||(c=='\v'))
#define ISTERMINATOR(c) (ISSPACE(c)||(c==EOF))
static int get_file_token(FILE * in_stream)
{
int i;
int c;
/* Skip over leading whitespace */
do
c = getc(in_stream);
while ISSPACE
(c);
if (c == EOF)
return EOF;
/* Add the token to the buffer. Copy characters until the buffer is full, or
* a terminator is encountered. */
for (i = 0; ((i < 1023) && !ISTERMINATOR(c)); i++, c = getc(in_stream))
{
token[i] = (char)c;
}
/* Handle the string truncation case. */
token[i] = '\0';
while (!ISTERMINATOR(c))
c = getc(in_stream);
/* Return success. On next entry, we will get the next character after the
* terminator. If the terminator was EOF, we should get EOF again. */
return 0;
}
/***********************************************************************
* get_token
***********************************************************************/
static char *get_token(int *argno, int argc, char **argv)
{
char *retval = NULL;
if (include_stream)
{
if (get_file_token(include_stream) == EOF)
{
fclose(include_stream);
include_stream = NULL;
retval = get_token(argno, argc, argv);
}
else
{
retval = strdup(token);
}
}
else if (*argno >= argc)
{
retval = NULL;
}
else
{
retval = argv[*argno];
(*argno)++;
}
return retval;
}
/***********************************************************************
* get_arg
***********************************************************************/
static char *get_arg(int *argno, int argc, char **argv)
{
char *retval;
/* Get the next argument */
retval = get_token(argno, argc, argv);
if ((retval == NULL) || (retval[0] == '-'))
{
fprintf(stderr, "Option requires an argument\n\n");
show_usage();
}
return retval;
}
/***********************************************************************
* get_opt
***********************************************************************/
static int get_opt(int *argno, int argc, char **argv)
{
char *opt;
int len;
int retval = -1;
/* Get the next argument */
opt = get_token(argno, argc, argv);
if (opt != NULL)
{
/* It must be of length 2 and start with a '-' */
len = strlen(opt);
if ((len == 2) && (opt[0] == '-'))
{
retval = (int)opt[1];
}
else
{
fprintf(stderr, "%s Unrecognized option\n\n", opt);
show_usage();
}
}
return retval;
}
/***********************************************************************
* parse_args
***********************************************************************/
static void parse_args(int argc, char **argv)
{
int argno = 1;
int opt;
/* Save our name (for show_usage) */
program_name = argv[0];
if (argc < 2)
{
fprintf(stderr, "ERROR: Missing required arguments\n\n");
show_usage();
}
/* Get the name of the input BFD file. This is always the last thing in the
* argument list. We decrement argc so that the parsing logic will not look
* at it. */
bfd_filename = argv[argc - 1];
argc--;
/* Get miscellaneous options from the command line. */
while ((opt = get_opt(&argno, argc, argv)) != -1)
{
switch (opt)
{
case 'd':
dsyms++;
break;
case 'f':
{
char *filename = get_arg(&argno, argc, argv);
if (include_stream)
{
fprintf(stderr, "Cannot use -f from within a cmd-file\n\n");
show_usage();
}
else
{
include_stream = fopen(filename, "r");
if (!include_stream)
{
fprintf(stderr, "Could not open cmd-file %s\n\n", filename);
show_usage();
}
}
}
break;
case 'o':
out_filename = get_arg(&argno, argc, argv);
break;
case 'v':
verbose++;
break;
case 'w':
weak_imports++;
break;
default:
fprintf(stderr, "%s Unknown option\n\n", argv[0]);
show_usage();
break;
}
}
}
/***********************************************************************
* Public Functions
***********************************************************************/
/***********************************************************************
* main
***********************************************************************/
int main(int argc, char **argv, char **envp)
{
bfd *bf;
int out_fd = 0;
/* Get the input arguments */
parse_args(argc, argv);
/* Make sure that we can option the BFD file */
dbg("Opening BFD file: %s\n", bfd_filename);
if (!(bf = bfd_openr(bfd_filename, 0)))
{
fprintf(stderr, "Failed to open BFD file: %s, errno=%d\n",
bfd_filename, errno);
exit(2);
}
dbg("Checking format\n");
if (bfd_check_format(bf, bfd_object) == 0)
{
fprintf(stderr, "BFD file %s is not an object file\n", bfd_filename);
exit(3);
}
dbg("Loading symbol table from BFD file %s\n", bfd_filename);
symbol_table = get_symbols(bf, &number_of_symbols);
/* Count the number of undefined function symbols */
(void)traverse_undefined_functions(NULL, count_undefined);
/* Check if the module calls any non-returning functions (like exit). These
* will require some additional setup. */
check_for_nonreturning_functions();
/* Make sure that we can open the output file if one is specified. If no
* out_filename is specified, we'll use stdout. */
if (out_filename)
{
out_fd = open(out_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (out_fd < 0)
{
fprintf(stderr, "Failed to open output file: %s, errno=%d\n",
out_filename, errno);
exit(4);
}
}
/* Output the thunk file in three pieces: 1. The constant file prologue 2.
* Library path information (if any) 3. Library file name information (if
* any) 4. Exported symbole information (if any) 5. Imported symbole
* information (if any) 6. The constant file epilogue. */
put_file_prologue(out_fd);
put_import_name_strtab(out_fd);
put_all_nxflat_import(out_fd);
put_file_epilogue(out_fd);
if (out_fd > 0)
close(out_fd);
exit(0);
}
+202
View File
@@ -0,0 +1,202 @@
/****************************************************************************
* toolchain/nxflat/nxflat.h
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must 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.
*
****************************************************************************/
#ifndef __TOOLCHAIN_NXFLAT_NXFLAT_H
#define __TOOLCHAIN_NXFLAT_NXFLAT_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/types.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define NXFLAT_MAX_STRING_SIZE 64 /* Largest size of string (w/zterminator) */
#define NXFLAT_MAGIC "NxFT" /* NXFLAT magic number */
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* The NXFLAT file header
*
* The elements within this structure are stored in network order (i.e.,
* ntohs() and ntohl() should be used to access fields within the
* header.
****************************************************************************/
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 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
*/
u_int32_t h_relocstart; /* Offset 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_s). 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.
*/
u_int32_t h_importsymbols; /* Offset to list of imported symbols */
/* 16-bit counts
*
* h_reloccount - The number of relocation records in the arry
* h_importcount - The number of records in the h_importsymbols array.
*/
u_int16_t h_reloccount; /* Number of relocation records */
u_int16_t h_importcount; /* Number of imported symbols */
};
/****************************************************************************
* NXFLAT Relocation types.
*
* The relocation records are an array of the following type.
****************************************************************************/
struct nxflat_reloc_s
{
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) << 30) | ((o) & 0x3fffffff))
/* 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) >> 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) & 0x3fffffff)
/* 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 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 offset.
* Fixup: Add allocated D-Space address to the
* offset.
* NXFLAT_RELOC_TYPE_REL32ID Meaning: Object file contains a 32-bit offset
* into I-Space at the offset that will
* unfortunately be references relative
* to the GOT
* Fixup: Add allocated the mapped I-Space
* address MINUS the allocated D-Space
* address to the offset.
*/
#define NXFLAT_RELOC_TYPE_REL32I 0
#define NXFLAT_RELOC_TYPE_REL32D 1
#undef NXFLAT_RELOC_TYPE_REL32ID /* May not need */
#define NXFLAT_RELOC_TYPE_NUM 2 /* Number of relocation types */
/****************************************************************************
* NXFLAT Imported symbol type
*
* The imported symbols are an array of the following type. The fields
* in each element are stored in native machine order.
****************************************************************************/
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 */
};
#endif /* __TOOLCHAIN_NXFLAT_NXFLAT_H */
+69
View File
@@ -0,0 +1,69 @@
############################################################################
# toolchain/nxflat/nxflat.mk
#
# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must 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.
#
############################################################################
NXFLAT_DIR = $(TOPDIR)/toolchain/nxflat
$(NXFLAT_DIR)/.compiled:
ifeq ($(strip $(BR2_GCC_TARGET_ARCH)),"armv7-m")
echo "NUTTX_DIR: $(NUTTX_DIR)"
$(MAKE) -C $(NXFLAT_DIR) BINUTILS_DIR="$(BINUTILS_DIR)" \
BINUTILS_DIR1="$(BINUTILS_DIR1)" ARCH=thumb2 CC="$(HOSTCC)"
else
echo "NUTTX_DIR: $(NUTTX_DIR)"
$(MAKE) -C $(NXFLAT_DIR) BINUTILS_DIR="$(BINUTILS_DIR)" \
BINUTILS_DIR1="$(BINUTILS_DIR1)" ARCH=$(BR2_ARCH) CC="$(HOSTCC)"
endif
touch $@
$(NXFLAT_DIR)/.installed: $(NXFLAT_DIR)/.compiled
install -m 755 $(NXFLAT_DIR)/mknxflat $(STAGING_DIR)/bin/mknxflat
install -m 755 $(NXFLAT_DIR)/ldnxflat $(STAGING_DIR)/bin/ldnxflat
install -m 755 $(NXFLAT_DIR)/readnxflat $(STAGING_DIR)/bin/readnxflat
touch $@
nxflat: binutils $(NXFLAT_DIR)/.installed
nxflat-clean:
$(MAKE) -C $(NXFLAT_DIR) clean
rm -f $(STAGING_DIR)/bin/mknxflat $(STAGING_DIR)/bin/ldnxflat $(STAGING_DIR)/bin/readnxflat
rm -f $(NXFLAT_DIR)/.compiled $(NXFLAT_DIR)/.installed
nxflat-dirclean: nxflat-clean
true
ifeq ($(strip $(BR2_PACKAGE_NXFLAT)),y)
TARGETS += nxflat
endif
@@ -0,0 +1,717 @@
/***********************************************************************
* toolchain/nxflat/readnxflat.c
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <netinet/in.h> /* 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";
#ifdef NXFLAT_RELOC_TYPE_REL32ID
static const char hdr_reloc_rel32id[] = "RELOC_REL32ID";
#endif
static const char *reloc_type_string[] = {
hdr_reloc_rel32i,
hdr_reloc_rel32d,
#ifdef NXFLAT_RELOC_TYPE_REL32ID
hdr_reloc_rel32id,
#else
unknown,
#endif
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: %s\n",
struct_offset, strerror(errno));
exit(1);
}
/* Read the next import entry. */
status = fread((void *)&import,
sizeof(struct nxflat_import_s), 1, in_stream);
if (status != 1)
{
if (ferror(in_stream))
{
fprintf(stderr, "ERROR: Read imported symbol %d struct failed: %s\n",
i + 1, strerror(errno));
}
else
{
fprintf(stderr, "ERROR: Read imported symbol %d struct: End-of-file after %d\n",
i + 1, struct_offset);
}
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("[Import: %4d Offset: %08x Name: %08x Address: %08x]\n",
i + 1, struct_offset, import.i_funcname, import.i_funcaddress);
}
/* Seek to the function name in the file */
name_offset = import.i_funcname + NXFLAT_HDR_SIZE;
if (fseek(in_stream, name_offset, SEEK_SET) != 0)
{
fprintf(stderr, "ERROR: fseek to imported symbol %d name failed\n",
i);
fprintf(stderr, " name_offset: %d %s\n",
name_offset, strerror(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)
{
if (ferror(in_stream))
{
fprintf(stderr, "ERROR: Read imported symbol %d name failed: %s\n",
i + 1, strerror(errno));
}
else
{
fprintf(stderr, "ERROR: Read imported symbol %d name: End-of-file after offset=%d\n",
i + 1, name_offset);
}
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: %s\n",
strerror(errno));
exit(1);
}
printf("\nRELOCATION ENTRIES:\n");
printf(" OFFSET RELOC TYPE\n\n");
for (i = 0; i < get_nxflat16(&header->h_reloccount); i++)
{
/* Read the next reloction entry. */
status = fread((void *)&reloc, sizeof(struct nxflat_reloc_s), 1, in_stream);
if (status != 1)
{
if (ferror(in_stream))
{
fprintf(stderr, "ERROR: Read reloc record %d: %s\n",
i + 1, strerror(errno));
}
else
{
fprintf(stderr, "ERROR: Read reloc record %d: End-of-file\n",
i + 1);
}
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", (long)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_nxflat16(&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] <flat-filename>\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;
int status;
/* 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 */
status = fread((void *)&header, sizeof(struct nxflat_hdr_s), 1, in_stream);
if (status != 1)
{
if (ferror(in_stream))
{
fprintf(stderr, "ERROR: Read flat header: %s\n", strerror(errno));
}
else
{
fprintf(stderr, "ERROR: Read flat header: End-of-file\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;
}
@@ -0,0 +1,140 @@
/***********************************************************************
* xflat/tools/arm/arch.h
* Generic relocation support for BFD.
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Simply lifted with minimal change from the BFD, binutils 2.19.1:
*
* Copyright 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
* Free Software Foundation, Inc.
*
* This file is part of BFD, the Binary File Descriptor library.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*
***********************************************************************/
/* These macros are used by the various *.h target specific header
files to either generate an enum containing all the known relocations
for that target, or if RELOC_MACROS_GEN_FUNC is defined, a recognition
function is generated instead. (This is used by binutils/readelf.c)
Given a header file like this:
START_RELOC_NUMBERS (foo)
RELOC_NUMBER (R_foo_NONE, 0)
RELOC_NUMBER (R_foo_32, 1)
EMPTY_RELOC (R_foo_good)
FAKE_RELOC (R_foo_illegal, 9)
END_RELOC_NUMBERS (R_foo_count)
Then the following will be produced by default (ie if
RELOC_MACROS_GEN_FUNC is *not* defined).
enum foo
{
R_foo_NONE = 0,
R_foo_32 = 1,
R_foo_good,
R_foo_illegal = 9,
R_foo_count
};
Note: The value of the symbol defined in the END_RELOC_NUMBERS
macro (R_foo_count in the case of the example above) will be
set to the value of the whichever *_RELOC macro preceeds it plus
one. Therefore if you intend to use the symbol as a sentinel for
the highest valid macro value you should make sure that the
preceeding *_RELOC macro is the highest valid number. ie a
declaration like this:
START_RELOC_NUMBERS (foo)
RELOC_NUMBER (R_foo_NONE, 0)
RELOC_NUMBER (R_foo_32, 1)
FAKE_RELOC (R_foo_illegal, 9)
FAKE_RELOC (R_foo_synonym, 0)
END_RELOC_NUMBERS (R_foo_count)
will result in R_foo_count having a value of 1 (R_foo_synonym + 1)
rather than 10 or 2 as might be expected.
Alternatively you can assign a value to END_RELOC_NUMBERS symbol
explicitly, like this:
START_RELOC_NUMBERS (foo)
RELOC_NUMBER (R_foo_NONE, 0)
RELOC_NUMBER (R_foo_32, 1)
FAKE_RELOC (R_foo_illegal, 9)
FAKE_RELOC (R_foo_synonym, 0)
END_RELOC_NUMBERS (R_foo_count = 2)
If RELOC_MACROS_GEN_FUNC *is* defined, then instead the
following function will be generated:
static const char *foo (unsigned long rtype);
static const char *
foo (unsigned long rtype)
{
switch (rtype)
{
case 0: return "R_foo_NONE";
case 1: return "R_foo_32";
default: return NULL;
}
}
*/
#ifndef __TOOLCHAIN_NXFLAT_RELOC_MACROS_H
#define __TOOLCHAIN_NXFLAT_RELOC_MACROS_H
#ifdef RELOC_MACROS_GEN_FUNC
/* This function takes the relocation number and returns the
string version name of the name of that relocation. If
the relocation is not recognised, NULL is returned. */
#define START_RELOC_NUMBERS(name) \
static const char *name (unsigned long rtype); \
static const char * \
name (unsigned long rtype) \
{ \
switch (rtype) \
{
#define RELOC_NUMBER(name, number) \
case number: return #name;
#define FAKE_RELOC(name, number)
#define EMPTY_RELOC(name)
#define END_RELOC_NUMBERS(name) \
default: return NULL; \
} \
}
#else /* Default to generating enum. */
#define START_RELOC_NUMBERS(name) enum name {
#define RELOC_NUMBER(name, number) name = number,
#define FAKE_RELOC(name, number) name = number,
#define EMPTY_RELOC(name) name,
#define END_RELOC_NUMBERS(name) name };
#endif
#endif /* __TOOLCHAIN_NXFLAT_RELOC_MACROS_H */
@@ -0,0 +1,50 @@
############################################################################
# toolchain/nxflat/thumb2/Makefile
#
# Copyright (C) 2009 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must 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.
#
############################################################################
CFLAGS += -Wall
BIN = libarch.a
OBJS = disthumb2.o
all: $(BIN)
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) -o $@ $<
$(BIN): $(OBJS)
$(AR) rcs $@ $<
clean:
rm -f *.o *.a *~ .*.swp core
@@ -0,0 +1,303 @@
/***********************************************************************
* xflat/tools/thumb2/arch.h
* ARM thumb2 ELF support for BFD.
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Simply lifted with minimal change from the BFD, binutils 2.19.1:
*
* Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
* Free Software Foundation, Inc.
*
* This file is part of BFD, the Binary File Descriptor library.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*
***********************************************************************/
#ifndef _TOOLCHAIN_NXFLAT_THUMB2_ARCH_H
#define _TOOLCHAIN_NXFLAT_THUMB2_ARCH_H
#include "reloc-macros.h"
/* Inform ldnxflat that this is 16-bit Thumb2 code */
#define NXFLAT_ARM 1
#define NXFLAT_THUMB2 1
/* Processor specific flags for the ELF header e_flags field. */
#define EF_ARM_RELEXEC 0x01
#define EF_ARM_HASENTRY 0x02
#define EF_ARM_INTERWORK 0x04
#define EF_ARM_APCS_26 0x08
#define EF_ARM_APCS_FLOAT 0x10
#define EF_ARM_PIC 0x20
#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use. */
#define EF_ARM_NEW_ABI 0x80
#define EF_ARM_OLD_ABI 0x100
#define EF_ARM_SOFT_FLOAT 0x200
#define EF_ARM_VFP_FLOAT 0x400
#define EF_ARM_MAVERICK_FLOAT 0x800
/* Frame unwind information */
#define PT_ARM_EXIDX (PT_LOPROC + 1)
/* Other constants defined in the ARM ELF spec. version B-01. */
#define EF_ARM_SYMSARESORTED 0x04 /* NB conflicts with EF_INTERWORK */
#define EF_ARM_DYNSYMSUSESEGIDX 0x08 /* NB conflicts with EF_APCS26 */
#define EF_ARM_MAPSYMSFIRST 0x10 /* NB conflicts with EF_APCS_FLOAT */
#define EF_ARM_EABIMASK 0xFF000000
/* Constants defined in AAELF. */
#define EF_ARM_BE8 0x00800000
#define EF_ARM_LE8 0x00400000
#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
#define EF_ARM_EABI_UNKNOWN 0x00000000
#define EF_ARM_EABI_VER1 0x01000000
#define EF_ARM_EABI_VER2 0x02000000
#define EF_ARM_EABI_VER3 0x03000000
#define EF_ARM_EABI_VER4 0x04000000
#define EF_ARM_EABI_VER5 0x05000000
/* Local aliases for some flags to match names used by COFF port. */
#define F_INTERWORK EF_ARM_INTERWORK
#define F_APCS26 EF_ARM_APCS_26
#define F_APCS_FLOAT EF_ARM_APCS_FLOAT
#define F_PIC EF_ARM_PIC
#define F_SOFT_FLOAT EF_ARM_SOFT_FLOAT
#define F_VFP_FLOAT EF_ARM_VFP_FLOAT
/* Additional symbol types for Thumb. */
#define STT_ARM_TFUNC 13 /* A Thumb function. */
#define STT_ARM_16BIT 15 /* A Thumb label. */
/* Additional section types. */
#define SHT_ARM_EXIDX 0x70000001 /* Section holds ARM unwind info. */
#define SHT_ARM_PREEMPTMAP 0x70000002 /* Section pre-emption details. */
#define SHT_ARM_ATTRIBUTES 0x70000003 /* Section holds attributes. */
/* ARM-specific values for sh_flags. */
#define SHF_ENTRYSECT 0x10000000 /* Section contains an entry point. */
#define SHF_COMDEF 0x80000000 /* Section may be multiply defined in the input to a link step. */
/* ARM-specific program header flags. */
#define PF_ARM_SB 0x10000000 /* Segment contains the location addressed by the static base. */
#define PF_ARM_PI 0x20000000 /* Segment is position-independent. */
#define PF_ARM_ABS 0x40000000 /* Segment must be loaded at its base address. */
/* Values for the Tag_CPU_arch EABI attribute. */
#define TAG_CPU_ARCH_PRE_V4 0
#define TAG_CPU_ARCH_V4 1
#define TAG_CPU_ARCH_V4T 2
#define TAG_CPU_ARCH_V5T 3
#define TAG_CPU_ARCH_V5TE 4
#define TAG_CPU_ARCH_V5TEJ 5
#define TAG_CPU_ARCH_V6 6
#define TAG_CPU_ARCH_V6KZ 7
#define TAG_CPU_ARCH_V6T2 8
#define TAG_CPU_ARCH_V6K 9
#define TAG_CPU_ARCH_V7 10
/* Relocation types. */
START_RELOC_NUMBERS (elf_arm_reloc_type)
/* AAELF official names and numbers. */
RELOC_NUMBER (R_ARM_NONE, 0)
RELOC_NUMBER (R_ARM_PC24, 1) /* deprecated */
RELOC_NUMBER (R_ARM_ABS32, 2)
RELOC_NUMBER (R_ARM_REL32, 3)
RELOC_NUMBER (R_ARM_LDR_PC_G0, 4)
RELOC_NUMBER (R_ARM_ABS16, 5)
RELOC_NUMBER (R_ARM_ABS12, 6)
RELOC_NUMBER (R_ARM_THM_ABS5, 7)
RELOC_NUMBER (R_ARM_ABS8, 8)
RELOC_NUMBER (R_ARM_SBREL32, 9)
RELOC_NUMBER (R_ARM_THM_CALL, 10)
RELOC_NUMBER (R_ARM_THM_PC8, 11)
RELOC_NUMBER (R_ARM_BREL_ADJ, 12)
RELOC_NUMBER (R_ARM_SWI24, 13) /* obsolete */
RELOC_NUMBER (R_ARM_THM_SWI8, 14) /* obsolete */
RELOC_NUMBER (R_ARM_XPC25, 15) /* obsolete */
RELOC_NUMBER (R_ARM_THM_XPC22, 16) /* obsolete */
RELOC_NUMBER (R_ARM_TLS_DTPMOD32, 17)
RELOC_NUMBER (R_ARM_TLS_DTPOFF32, 18)
RELOC_NUMBER (R_ARM_TLS_TPOFF32, 19)
RELOC_NUMBER (R_ARM_COPY, 20) /* Copy symbol at runtime. */
RELOC_NUMBER (R_ARM_GLOB_DAT, 21) /* Create GOT entry. */
RELOC_NUMBER (R_ARM_JUMP_SLOT, 22) /* Create PLT entry. */
RELOC_NUMBER (R_ARM_RELATIVE, 23) /* Adjust by program base. */
RELOC_NUMBER (R_ARM_GOTOFF32, 24) /* 32 bit offset to GOT. */
RELOC_NUMBER (R_ARM_BASE_PREL, 25) /* 32 bit PC relative offset to GOT. */
RELOC_NUMBER (R_ARM_GOT_BREL, 26) /* 32 bit GOT entry. */
RELOC_NUMBER (R_ARM_PLT32, 27) /* deprecated - 32 bit PLT address. */
RELOC_NUMBER (R_ARM_CALL, 28)
RELOC_NUMBER (R_ARM_JUMP24, 29)
RELOC_NUMBER (R_ARM_THM_JUMP24, 30)
RELOC_NUMBER (R_ARM_BASE_ABS, 31)
RELOC_NUMBER (R_ARM_ALU_PCREL7_0, 32) /* obsolete */
RELOC_NUMBER (R_ARM_ALU_PCREL15_8, 33) /* obsolete */
RELOC_NUMBER (R_ARM_ALU_PCREL23_15, 34) /* obsolete */
RELOC_NUMBER (R_ARM_LDR_SBREL_11_0, 35) /* deprecated, should have _NC suffix */
RELOC_NUMBER (R_ARM_ALU_SBREL_19_12, 36) /* deprecated, should have _NC suffix */
RELOC_NUMBER (R_ARM_ALU_SBREL_27_20, 37) /* deprecated, should have _CK suffix */
RELOC_NUMBER (R_ARM_TARGET1, 38)
RELOC_NUMBER (R_ARM_SBREL31, 39) /* deprecated */
RELOC_NUMBER (R_ARM_V4BX, 40)
RELOC_NUMBER (R_ARM_TARGET2, 41)
RELOC_NUMBER (R_ARM_PREL31, 42)
RELOC_NUMBER (R_ARM_MOVW_ABS_NC, 43)
RELOC_NUMBER (R_ARM_MOVT_ABS, 44)
RELOC_NUMBER (R_ARM_MOVW_PREL_NC, 45)
RELOC_NUMBER (R_ARM_MOVT_PREL, 46)
RELOC_NUMBER (R_ARM_THM_MOVW_ABS_NC, 47)
RELOC_NUMBER (R_ARM_THM_MOVT_ABS, 48)
RELOC_NUMBER (R_ARM_THM_MOVW_PREL_NC, 49)
RELOC_NUMBER (R_ARM_THM_MOVT_PREL, 50)
RELOC_NUMBER (R_ARM_THM_JUMP19, 51)
RELOC_NUMBER (R_ARM_THM_JUMP6, 52)
RELOC_NUMBER (R_ARM_THM_ALU_PREL_11_0, 53)
RELOC_NUMBER (R_ARM_THM_PC12, 54)
RELOC_NUMBER (R_ARM_ABS32_NOI, 55)
RELOC_NUMBER (R_ARM_REL32_NOI, 56)
RELOC_NUMBER (R_ARM_ALU_PC_G0_NC, 57)
RELOC_NUMBER (R_ARM_ALU_PC_G0, 58)
RELOC_NUMBER (R_ARM_ALU_PC_G1_NC, 59)
RELOC_NUMBER (R_ARM_ALU_PC_G1, 60)
RELOC_NUMBER (R_ARM_ALU_PC_G2, 61)
RELOC_NUMBER (R_ARM_LDR_PC_G1, 62)
RELOC_NUMBER (R_ARM_LDR_PC_G2, 63)
RELOC_NUMBER (R_ARM_LDRS_PC_G0, 64)
RELOC_NUMBER (R_ARM_LDRS_PC_G1, 65)
RELOC_NUMBER (R_ARM_LDRS_PC_G2, 66)
RELOC_NUMBER (R_ARM_LDC_PC_G0, 67)
RELOC_NUMBER (R_ARM_LDC_PC_G1, 68)
RELOC_NUMBER (R_ARM_LDC_PC_G2, 69)
RELOC_NUMBER (R_ARM_ALU_SB_G0_NC, 70)
RELOC_NUMBER (R_ARM_ALU_SB_G0, 71)
RELOC_NUMBER (R_ARM_ALU_SB_G1_NC, 72)
RELOC_NUMBER (R_ARM_ALU_SB_G1, 73)
RELOC_NUMBER (R_ARM_ALU_SB_G2, 74)
RELOC_NUMBER (R_ARM_LDR_SB_G0, 75)
RELOC_NUMBER (R_ARM_LDR_SB_G1, 76)
RELOC_NUMBER (R_ARM_LDR_SB_G2, 77)
RELOC_NUMBER (R_ARM_LDRS_SB_G0, 78)
RELOC_NUMBER (R_ARM_LDRS_SB_G1, 79)
RELOC_NUMBER (R_ARM_LDRS_SB_G2, 80)
RELOC_NUMBER (R_ARM_LDC_SB_G0, 81)
RELOC_NUMBER (R_ARM_LDC_SB_G1, 82)
RELOC_NUMBER (R_ARM_LDC_SB_G2, 83)
RELOC_NUMBER (R_ARM_MOVW_BREL_NC, 84)
RELOC_NUMBER (R_ARM_MOVT_BREL, 85)
RELOC_NUMBER (R_ARM_MOVW_BREL, 86)
RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC, 87)
RELOC_NUMBER (R_ARM_THM_MOVT_BREL, 88)
RELOC_NUMBER (R_ARM_THM_MOVW_BREL, 89)
/* 90-93 unallocated */
RELOC_NUMBER (R_ARM_PLT32_ABS, 94)
RELOC_NUMBER (R_ARM_GOT_ABS, 95)
RELOC_NUMBER (R_ARM_GOT_PREL, 96)
RELOC_NUMBER (R_ARM_GOT_BREL12, 97)
RELOC_NUMBER (R_ARM_GOTOFF12, 98)
RELOC_NUMBER (R_ARM_GOTRELAX, 99)
RELOC_NUMBER (R_ARM_GNU_VTENTRY, 100) /* deprecated - old C++ abi */
RELOC_NUMBER (R_ARM_GNU_VTINHERIT, 101) /* deprecated - old C++ abi */
RELOC_NUMBER (R_ARM_THM_JUMP11, 102)
RELOC_NUMBER (R_ARM_THM_JUMP8, 103)
RELOC_NUMBER (R_ARM_TLS_GD32, 104)
RELOC_NUMBER (R_ARM_TLS_LDM32, 105)
RELOC_NUMBER (R_ARM_TLS_LDO32, 106)
RELOC_NUMBER (R_ARM_TLS_IE32, 107)
RELOC_NUMBER (R_ARM_TLS_LE32, 108)
RELOC_NUMBER (R_ARM_TLS_LDO12, 109)
RELOC_NUMBER (R_ARM_TLS_LE12, 110)
RELOC_NUMBER (R_ARM_TLS_IE12GP, 111)
/* 112 - 127 private range */
RELOC_NUMBER (R_ARM_ME_TOO, 128) /* obsolete */
/* Extensions? R=read-only? */
RELOC_NUMBER (R_ARM_RXPC25, 249)
RELOC_NUMBER (R_ARM_RSBREL32, 250)
RELOC_NUMBER (R_ARM_THM_RPC22, 251)
RELOC_NUMBER (R_ARM_RREL32, 252)
RELOC_NUMBER (R_ARM_RABS32, 253)
RELOC_NUMBER (R_ARM_RPC24, 254)
RELOC_NUMBER (R_ARM_RBASE, 255)
/* Unofficial names for some of the relocs. */
FAKE_RELOC (R_ARM_GOTOFF, R_ARM_GOTOFF32) /* 32 bit offset to GOT. */
FAKE_RELOC (R_ARM_THM_PC22, R_ARM_THM_CALL)
FAKE_RELOC (R_ARM_THM_PC11, R_ARM_THM_JUMP11)
FAKE_RELOC (R_ARM_THM_PC9, R_ARM_THM_JUMP8)
/* Relocs with both a different name, and (apparently) different meaning in
GNU usage. */
FAKE_RELOC (R_ARM_GOTPC, R_ARM_BASE_PREL) /* 32 bit PC relative offset to GOT. */
FAKE_RELOC (R_ARM_GOT32, R_ARM_GOT_BREL) /* 32 bit GOT entry. */
FAKE_RELOC (R_ARM_ROSEGREL32, R_ARM_SBREL31) /* ??? */
FAKE_RELOC (R_ARM_AMP_VCALL9, R_ARM_BREL_ADJ) /* Thumb-something. Not used. */
END_RELOC_NUMBERS (R_ARM_max = 256)
#ifdef BFD_ARCH_SIZE
/* EABI object attributes. */
enum
{
/* 0-3 are generic. */
Tag_CPU_raw_name = 4,
Tag_CPU_name,
Tag_CPU_arch,
Tag_CPU_arch_profile,
Tag_ARM_ISA_use,
Tag_THUMB_ISA_use,
Tag_VFP_arch,
Tag_WMMX_arch,
Tag_NEON_arch,
Tag_PCS_config,
Tag_ABI_PCS_R9_use,
Tag_ABI_PCS_RW_data,
Tag_ABI_PCS_RO_data,
Tag_ABI_PCS_GOT_use,
Tag_ABI_PCS_wchar_t,
Tag_ABI_FP_rounding,
Tag_ABI_FP_denormal,
Tag_ABI_FP_exceptions,
Tag_ABI_FP_user_exceptions,
Tag_ABI_FP_number_model,
Tag_ABI_align8_needed,
Tag_ABI_align8_preserved,
Tag_ABI_enum_size,
Tag_ABI_HardFP_use,
Tag_ABI_VFP_args,
Tag_ABI_WMMX_args,
Tag_ABI_optimization_goals,
Tag_ABI_FP_optimization_goals,
/* 32 is generic. */
};
#endif
/* The name of the note section used to identify arm variants. */
#define ARM_NOTE_SECTION ".note.gnu.arm.ident"
/* Special section names. */
#define ELF_STRING_ARM_unwind ".ARM.exidx"
#define ELF_STRING_ARM_unwind_info ".ARM.extab"
#define ELF_STRING_ARM_unwind_once ".gnu.linkonce.armexidx."
#define ELF_STRING_ARM_unwind_info_once ".gnu.linkonce.armextab."
#endif /* _TOOLCHAIN_NXFLAT_THUMB2_ARCH_H */
@@ -0,0 +1,16 @@
/***********************************************************************
* toolchain/nxflat/thumb2/disasm.c
* ARM Thumb2 Disassembler
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
***********************************************************************/
#include <stdio.h>
#include <sys/types.h>
int print_insn_arm(u_int32_t pc, FILE *stream, u_int32_t given)
{
return -1;
}
@@ -0,0 +1,222 @@
/***********************************************************************
* toolchain/nxflat/thumb2/dyncall_skeleton.def
*
* Copyright (C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must 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.
*
***********************************************************************/
/*******************************************************************
* File Prologue
*******************************************************************/
static const char file_prologue[] =
"/*******************************************************************\n"
" *\n"
" * This file contains the dynamic call logic that performs the thunk\n"
" * for outound calls from one module to another.\n"
" *\n"
" * ARM register quick reference:\n"
" *\n"
" * Name Number ARM Procedure Calling Standard Role\n"
" *\n"
" * a1 r0 argument 1/integer result/scratch register/argc\n"
" * a2 r1 argument 2/scratch register/argv\n"
" * a3 r2 argument 3/scratch register/envp\n"
" * a4 r3 argument 4/scratch register\n"
" * v1 r4 register variable\n"
" * v2 r5 register variable\n"
" * v3 r6 register variable\n"
" * v4 r7 register variable\n"
" * v5 r8 register variable\n"
" * sb/v6 r9 static base/register variable\n"
" * sl/v7 r10 stack limit/stack chunk handle/reg. variable\n"
" * fp r11 frame pointer\n"
" * ip r12 scratch register/new-sb in inter-link-unit calls\n"
" * sp r13 lower end of current stack frame\n"
" * lr r14 link address/scratch register\n"
" * pc r15 program counter\n"
" *******************************************************************/\n\n"
"\t.syntax\tunified\n"
"\t.thumb\n\n"
"/*******************************************************************\n"
" * Included Files\n"
" *******************************************************************/\n\n"
"/*******************************************************************\n"
" * Definitions\n"
" *******************************************************************/\n";
static const char import_prologue[] = "";
/*******************************************************************
* Import Function Name String Table
*******************************************************************/
static const char import_name_strtab_prologue[] =
"\n/*******************************************************************\n"
" * Import Function Names\n"
" *******************************************************************/\n\n"
"/* These are the names of all of the functions that are imported.\n"
" * Notice that all data associated with the library names is retained\n"
" * in the .text section."
" */\n\n"
"\t.text\n"
"\t.align\t0\n";
#define MKIMPSTRTABARG(fn,i) (i), (i), (i), (fn), (i), (i)
static const char import_name_strtab_format[] =
"\n\t.local\t__dynimport%04d\n"
"\t.type\t__dynimport%04d, object\n\n"
"__dynimport%04d:\n"
"\t.asciz\t\"%s\"\n"
"\t.size\t__dynimport%04d, .-__dynimport%04d\n";
/*******************************************************************
* Dyanamic Call Information
*******************************************************************/
static const char dynimport_decl_prologue[] =
"\n/*******************************************************************\n"
" * Imported Symbol Table (an array of type struct flat_import)\n"
" *******************************************************************/\n\n"
"/* Notice that, unlike most other arrays in this file, this array\n"
" * is declared to reside in .data. Because of this, there will be\n"
" * per-process instances of this table.\n"
" */\n\n"
"\t.data\n"
"\t.align\t2\n\n"
"\t.global\t__dynimport_begin\n"
"\t.type\t__dynimport_begin, object\n"
"\t.global\t__dynimport_end\n"
"\t.type\t__dynimport_end, object\n\n";
#define MKINFODECLARGS(fn, i) (i), (fn), (i)
static const char dynimport_decl_format[] =
"\t.local\t__dyninfo%04d\t/* Dynamic info for imported symbol %s */\n"
"\t.type\t__dyninfo%04d, object\n";
static const char dynimport_array_prologue[] =
"\n__dynimport_begin:\n";
#define MKINFOARGS(fn, i) (i), (fn), (i), (i), (i)
static const char dynimport_array_format[] =
"__dyninfo%04d:\t\t\t/* Dynamic info for imported symbol %s */\n"
"\t.word\t__dynimport%04d\t/* Offset to name of imported function */\n"
"\t.word\t0\t\t/* Resolved address of imported function */\n"
"\t.size\t__dyninfo%04d, .-__dyninfo%04d\n";
static const char dynimport_array_epilogue[] =
"__dynimport_end:\n"
"\t.size\t__dynimport_begin, __dynimport_end-__dynimport_begin\n";
static const char dyncall_decl_prologue[] =
"\n/*******************************************************************\n"
" * Dynamic Call Logic\n"
" *******************************************************************/\n\n"
"\t.text\n"
"\t.align\t2\n";
#define MKCALLARGS(fn, i) (fn), (fn), (fn), (fn), (i), (i), (i), (fn), (fn)
#ifndef __NO_GOT__
static const char dyncall_format[] =
"\n/* Dynamic call logic for imported symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n"
"\t.thumb_func\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d(GOTOFF)\n"
"\t.size\t%s, .-%s\n";
static const char nonreturning_dyncall_format[] =
"\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n"
"\t.thumb_func\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d(GOTOFF)\n"
"\t.size\t%s, .-%s\n";
#else
static const char dyncall_format[] =
"\n/* Dynamic call logic for imported symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n"
"\t.thumb_func\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d\n"
"\t.size\t%s, .-%s\n";
static const char nonreturning_dyncall_format[] =
"\n/* Dynamic call logic for imported, non-returning symbol %s */\n\n"
"\t.global\t%s\n"
"\t.type\t%s, function\n"
"\t.thumb_func\n\n"
"%s:\n"
"\tldr\tip,.Ldyn%04d\n"
"\tadd\tip,ip,sl\n"
"\tldr\tip,[ip,#4]\n"
"\tbx\tip\n"
".Ldyn%04d:\n"
"\t.word\t__dyninfo%04d\n"
"\t.size\t%s, .-%s\n";
#endif
/*******************************************************************
* File Epilogue
*******************************************************************/
static const char file_epilogue[] =
"\t.end\n";