From 7ed4d2a409cb24e7beef850c6b90e47f0f6b71d2 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sat, 9 Apr 2016 12:48:08 +0200 Subject: add support for nds32 architecture Verified on a FPGA board sponsored by Andes Technology. Signed-off-by: Waldemar Brodkorb --- package/libthread_db/Makefile | 2 + target/config/Config.in.binutils | 3 + target/config/Config.in.compiler | 3 + target/config/Config.in.cpu | 4 +- target/config/Config.in.gdb | 5 + target/config/Config.in.kernelcfg | 1 + target/config/Config.in.kernelversion | 11 + target/config/Config.in.runtime | 1 + target/config/Config.in.target | 1 + target/linux/config/Config.in.ethernet | 10 + target/linux/config/Config.in.kernel | 4 + target/linux/config/Config.in.serial | 6 +- target/linux/patches/3.4.112/nds32.patch | 72132 ++++ target/nds32/Makefile | 3 + target/nds32/kernel/andes-ag101p | 5 + target/nds32/kernel/generic-nds32 | 2 + target/nds32/systems/andes-ag101p | 9 + target/nds32/uclibc-ng.config | 248 + toolchain/Makefile | 2 +- toolchain/binutils/Makefile | 2 +- toolchain/binutils/patches/2.24/binutils.nds32 | 409259 ++++++++++++++++++++++ toolchain/gcc/Makefile | 4 + toolchain/gcc/patches/4.9.3/gcc.nds32 | 383894 ++++++++++++++++++++ 23 files changed, 865607 insertions(+), 4 deletions(-) create mode 100644 target/linux/patches/3.4.112/nds32.patch create mode 100644 target/nds32/kernel/andes-ag101p create mode 100644 target/nds32/kernel/generic-nds32 create mode 100644 target/nds32/systems/andes-ag101p create mode 100644 target/nds32/uclibc-ng.config create mode 100644 toolchain/binutils/patches/2.24/binutils.nds32 create mode 100644 toolchain/gcc/patches/4.9.3/gcc.nds32 diff --git a/package/libthread_db/Makefile b/package/libthread_db/Makefile index 90ed2f28f..4b65bf1f2 100644 --- a/package/libthread_db/Makefile +++ b/package/libthread_db/Makefile @@ -32,10 +32,12 @@ INSTALL_STYLE:= manual do-install: ${INSTALL_DIR} ${IDIR_LIBTHREAD_DB}/lib +ifeq ($(ADK_TARGET_USE_STATIC_LIBS),) ifeq ($(ADK_TARGET_LIB_MUSL),) ifeq (${ADK_TARGET_UCLINUX},) ${CP} ${STAGING_TARGET_DIR}/lib/libthread_db*.so* ${IDIR_LIBTHREAD_DB}/lib endif endif +endif include ${ADK_TOPDIR}/mk/pkg-bottom.mk diff --git a/target/config/Config.in.binutils b/target/config/Config.in.binutils index 3d31a774b..494aa4469 100644 --- a/target/config/Config.in.binutils +++ b/target/config/Config.in.binutils @@ -17,11 +17,13 @@ config ADK_TOOLCHAIN_BINUTILS_GIT depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_CRIS + depends on !ADK_TARGET_ARCH_NDS32 config ADK_TOOLCHAIN_BINUTILS_2_26_1 bool "2.26.1" depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_AVR32 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_CPU_CRIS_CRISV10 config ADK_TOOLCHAIN_BINUTILS_2_25_1 @@ -31,6 +33,7 @@ config ADK_TOOLCHAIN_BINUTILS_2_25_1 depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_H8300 depends on !ADK_TARGET_ARCH_MOXIE + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_CPU_CRIS_CRISV10 config ADK_TOOLCHAIN_BINUTILS_2_24 diff --git a/target/config/Config.in.compiler b/target/config/Config.in.compiler index ba41d89fb..c9d950c1d 100644 --- a/target/config/Config.in.compiler +++ b/target/config/Config.in.compiler @@ -33,6 +33,7 @@ config ADK_TOOLCHAIN_GCC_GIT depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_METAG + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_OR1K select ADK_DISABLE_HONOUR_CFLAGS @@ -41,6 +42,7 @@ config ADK_TOOLCHAIN_GCC_6_1_0 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_METAG + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_OR1K select ADK_DISABLE_HONOUR_CFLAGS @@ -54,6 +56,7 @@ config ADK_TOOLCHAIN_GCC_5_4_0 depends on !ADK_TARGET_ARCH_H8300 depends on !ADK_TARGET_ARCH_M32R depends on !ADK_TARGET_ARCH_METAG + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_OR1K depends on !ADK_TARGET_SYSTEM_KINETIS_K70 depends on !(ADK_TARGET_LIB_GLIBC && ADK_TARGET_ARCH_SH) diff --git a/target/config/Config.in.cpu b/target/config/Config.in.cpu index 2b463ed33..d318a6440 100644 --- a/target/config/Config.in.cpu +++ b/target/config/Config.in.cpu @@ -720,7 +720,7 @@ config ADK_TARGET_CPU_MSP430 # nds32 config ADK_TARGET_CPU_NDS32 bool "nds32" - select ADK_TARGET_WITH_NPTL + select ADK_TARGET_WITH_LT select ADK_TARGET_WITH_MMU depends on ADK_TARGET_ARCH_NDS32 @@ -1437,6 +1437,7 @@ config ADK_TARGET_GCC_CPU default "cortex-m4" if ADK_TARGET_CPU_ARM_CORTEX_M4 default "leon" if ADK_TARGET_CPU_SPARC_LEON default "mpcore" if ADK_TARGET_CPU_ARM_ARM11MPCORE + default "n13" if ADK_TARGET_CPU_NDS32 default "powerpc" if ADK_TARGET_CPU_PPC default "powerpc64" if ADK_TARGET_CPU_PPC64_POWERPC64 default "power6" if ADK_TARGET_CPU_PPC64_POWER6 @@ -1623,6 +1624,7 @@ config ADK_TARGET_CPU_TYPE default "mips64r6" if ADK_TARGET_CPU_MIPS64_MIPS64R6 default "mips64" if ADK_TARGET_CPU_MIPS64_LOONGSON2F default "ppc64" if ADK_TARGET_ARCH_PPC64 + default "nds32" if ADK_TARGET_CPU_NDS32 default "v8" if ADK_TARGET_CPU_SPARC_V8 default "v9" if ADK_TARGET_CPU_SPARC64_V9 default "leon" if ADK_TARGET_CPU_SPARC_LEON diff --git a/target/config/Config.in.gdb b/target/config/Config.in.gdb index a9d279044..bbde9df6c 100644 --- a/target/config/Config.in.gdb +++ b/target/config/Config.in.gdb @@ -4,12 +4,14 @@ choice prompt "GNU debugger version" default ADK_TOOLCHAIN_GDB_H8300_GIT if ADK_TARGET_ARCH_H8300 +default ADK_TOOLCHAIN_GDB_NDS32 if ADK_TARGET_ARCH_NDS32 default ADK_TOOLCHAIN_GDB_7_11_1 config ADK_TOOLCHAIN_GDB_GIT bool "git" depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 config ADK_TOOLCHAIN_GDB_H8300_GIT bool "h8300-git" @@ -19,16 +21,19 @@ config ADK_TOOLCHAIN_GDB_7_11_1 bool "7.11.1" depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 config ADK_TOOLCHAIN_GDB_7_10_1 bool "7.10.1" depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 config ADK_TOOLCHAIN_GDB_7_9_1 bool "7.9.1" depends on !ADK_TARGET_ARCH_AVR32 depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 config ADK_TOOLCHAIN_GDB_7_8_2 bool "7.8.2" diff --git a/target/config/Config.in.kernelcfg b/target/config/Config.in.kernelcfg index c1e562f7b..27a6bbf1e 100644 --- a/target/config/Config.in.kernelcfg +++ b/target/config/Config.in.kernelcfg @@ -23,4 +23,5 @@ config ADK_TARGET_KERNEL_DEFCONFIG default "nsim_700_defconfig" if ADK_TARGET_SYSTEM_NSIM_ARCV1 default "nsim_hs_defconfig" if ADK_TARGET_SYSTEM_NSIM_ARCV2 default "10m50_defconfig" if ADK_TARGET_SYSTEM_QEMU_NIOS2 + default "orca_defconfig" if ADK_TARGET_SYSTEM_ANDES_AG101P diff --git a/target/config/Config.in.kernelversion b/target/config/Config.in.kernelversion index 4411d78aa..b6b35d52f 100644 --- a/target/config/Config.in.kernelversion +++ b/target/config/Config.in.kernelversion @@ -11,15 +11,18 @@ default ADK_TARGET_KERNEL_VERSION_4_4_14 config ADK_TARGET_KERNEL_VERSION_GIT bool "linux-git" + depends on !ADK_TARGET_ARCH_NDS32 config ADK_TARGET_KERNEL_VERSION_4_6_3 bool "4.6.3" + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_BOARD_BCM28XX depends on !ADK_TARGET_SYSTEM_SOLIDRUN_IMX6 select ADK_TARGET_KERNEL_VERSION_4_6 config ADK_TARGET_KERNEL_VERSION_4_5_7 bool "4.5.7" + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_BOARD_BCM28XX depends on !ADK_TARGET_SYSTEM_SOLIDRUN_IMX6 @@ -27,6 +30,7 @@ config ADK_TARGET_KERNEL_VERSION_4_5_7 config ADK_TARGET_KERNEL_VERSION_4_4_14 bool "4.4.14" + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_SYSTEM_SOLIDRUN_IMX6 select ADK_TARGET_KERNEL_VERSION_4_4 @@ -37,6 +41,7 @@ config ADK_TARGET_KERNEL_VERSION_4_1_26 depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 depends on !ADK_TARGET_ARCH_NIOS2 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_SYSTEM_KINETIS_K70 select ADK_TARGET_KERNEL_VERSION_4_1 @@ -46,6 +51,7 @@ config ADK_TARGET_KERNEL_VERSION_3_18_33 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_BOARD_ATH79 @@ -60,6 +66,7 @@ config ADK_TARGET_KERNEL_VERSION_3_14_72 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_BOARD_ATH79 @@ -72,6 +79,7 @@ config ADK_TARGET_KERNEL_VERSION_3_12_59 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_BOARD_ATH79 @@ -86,6 +94,7 @@ config ADK_TARGET_KERNEL_VERSION_3_10_101 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_BOARD_ATH79 @@ -115,6 +124,7 @@ config ADK_TARGET_KERNEL_VERSION_3_2_80 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_BOARD_ATH79 @@ -129,6 +139,7 @@ config ADK_TARGET_KERNEL_VERSION_2_6_32_70 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_SPARC depends on !ADK_TARGET_BOARD_ATH79 diff --git a/target/config/Config.in.runtime b/target/config/Config.in.runtime index 6ed3bc5b7..6657e044c 100644 --- a/target/config/Config.in.runtime +++ b/target/config/Config.in.runtime @@ -285,6 +285,7 @@ config ADK_RUNTIME_CONSOLE_SERIAL_SPEED default "9600" if ADK_TARGET_SYSTEM_FON_FON2100 default "9600" if ADK_TARGET_SYSTEM_NUMATO_MIMASV2 default "38400" if ADK_TARGET_SYSTEM_PCENGINES_WRAP + default "38400" if ADK_TARGET_SYSTEM_ANDES_AG101P default "115200" config ADK_RUNTIME_KBD_LAYOUT diff --git a/target/config/Config.in.target b/target/config/Config.in.target index ec72d1b44..5fef2270e 100644 --- a/target/config/Config.in.target +++ b/target/config/Config.in.target @@ -8,5 +8,6 @@ config ADK_TARGET_CMDLINE default "kinetis_platform=k70-som" if ADK_TARGET_SYSTEM_KINETIS_K70 default "metag_da.console_poll=1" if ADK_TARGET_SYSTEM_QEMU_METAG default "earlycon=uart8250,mmio32,0x9d050020,115200n8 console=ttyS0,115200n8" if ADK_TARGET_CPU_XTENSA_DE212 + default "earlyprintk=uart8250-32bit,0x99600000" if ADK_TARGET_SYSTEM_ANDES_AG101P default "" diff --git a/target/linux/config/Config.in.ethernet b/target/linux/config/Config.in.ethernet index 6ef03ee4b..cfb12e1db 100644 --- a/target/linux/config/Config.in.ethernet +++ b/target/linux/config/Config.in.ethernet @@ -23,6 +23,9 @@ config ADK_KERNEL_NET_VENDOR_IBM config ADK_KERNEL_NET_VENDOR_INTEL bool +config ADK_KERNEL_NET_VENDOR_FARADAY + bool + config ADK_KERNEL_NET_VENDOR_FREESCALE bool @@ -400,6 +403,13 @@ config ADK_KERNEL_ETHOC default y if ADK_TARGET_SYSTEM_QEMU_OR1K default n +config ADK_KERNEL_FTMAC100 + bool "Andes ethernet driver" + select ADK_KERNEL_NET_VENDOR_FARADAY + depends on ADK_TARGET_SYSTEM_ANDES_AG101P + default y if ADK_TARGET_SYSTEM_ANDES_AG101P + default n + config ADK_KERNEL_ATL1 tristate "Atheros/Attansic L1 Gigabit Ethernet support" select ADK_KERNEL_NET_VENDOR_ATHEROS diff --git a/target/linux/config/Config.in.kernel b/target/linux/config/Config.in.kernel index b52c621d1..924d0e6e6 100644 --- a/target/linux/config/Config.in.kernel +++ b/target/linux/config/Config.in.kernel @@ -58,11 +58,15 @@ config ADK_KERNEL_CPU_LITTLE_ENDIAN menu "Kernel options" +config ADK_KERNEL_HOTPLUG + bool + config ADK_KERNEL_DEVTMPFS bool config ADK_KERNEL_DEVTMPFS_MOUNT bool + select ADK_KERNEL_HOTPLUG config ADK_KERNEL_UEVENT_HELPER bool diff --git a/target/linux/config/Config.in.serial b/target/linux/config/Config.in.serial index 113599149..82d745271 100644 --- a/target/linux/config/Config.in.serial +++ b/target/linux/config/Config.in.serial @@ -2,7 +2,7 @@ # material, please see the LICENCE file in the top-level directory. menu "Serial devices support" -depends on ADK_TARGET_WITH_SERIAL || ADK_TARGET_QEMU || ADK_TARGET_VBOX || ADK_TARGET_SIM +depends on ADK_TARGET_WITH_SERIAL || ADK_TARGET_QEMU || ADK_TARGET_VBOX || ADK_TARGET_SIM || ADK_TARGET_GENERIC config ADK_KERNEL_SERIAL_8250_CONSOLE bool @@ -90,6 +90,7 @@ config ADK_KERNEL_SERIAL_8250 depends on ADK_TARGET_SYSTEM_XILINX_KINTEX7 \ || ADK_TARGET_SYSTEM_IMGTEC_CI20 \ || ADK_TARGET_SYSTEM_LINKSYS_NSLU2 \ + || ADK_TARGET_SYSTEM_ANDES_AG101P \ || ADK_TARGET_SYSTEM_PCENGINES_APU \ || ADK_TARGET_SYSTEM_PCENGINES_ALIX \ || ADK_TARGET_SYSTEM_QEMU_MICROBLAZE_ML605 \ @@ -102,6 +103,7 @@ config ADK_KERNEL_SERIAL_8250 || ADK_TARGET_SYSTEM_QEMU_XTENSA \ || ADK_TARGET_SYSTEM_OR1K_SIM \ || ADK_TARGET_SYSTEM_IBM_X40 \ + || ADK_TARGET_SYSTEM_GENERIC_NDS32 \ || ADK_TARGET_SYSTEM_GENERIC_X86 \ || ADK_TARGET_SYSTEM_GENERIC_X86_64 \ || ADK_TARGET_SYSTEM_MIKROTIK_RB532 \ @@ -109,6 +111,7 @@ config ADK_KERNEL_SERIAL_8250 default y if ADK_TARGET_SYSTEM_XILINX_KINTEX7 default y if ADK_TARGET_SYSTEM_IMGTEC_CI20 default y if ADK_TARGET_SYSTEM_LINKSYS_NSLU2 + default y if ADK_TARGET_SYSTEM_ANDES_AG101P default y if ADK_TARGET_SYSTEM_PCENGINES_APU default y if ADK_TARGET_SYSTEM_PCENGINES_ALIX default y if ADK_TARGET_SYSTEM_QEMU_MICROBLAZE_ML605 @@ -121,6 +124,7 @@ config ADK_KERNEL_SERIAL_8250 default y if ADK_TARGET_SYSTEM_QEMU_XTENSA default y if ADK_TARGET_SYSTEM_OR1K_SIM default y if ADK_TARGET_SYSTEM_IBM_X40 + default y if ADK_TARGET_SYSTEM_GENERIC_NDS32 default y if ADK_TARGET_SYSTEM_GENERIC_X86 default y if ADK_TARGET_SYSTEM_GENERIC_X86_64 default y if ADK_TARGET_SYSTEM_MIKROTIK_RB532 diff --git a/target/linux/patches/3.4.112/nds32.patch b/target/linux/patches/3.4.112/nds32.patch new file mode 100644 index 000000000..d0da6f7b3 --- /dev/null +++ b/target/linux/patches/3.4.112/nds32.patch @@ -0,0 +1,72132 @@ +diff -Nur linux-3.4.110.orig/arch/nds32/boot/install.sh linux-3.4.110/arch/nds32/boot/install.sh +--- linux-3.4.110.orig/arch/nds32/boot/install.sh 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/boot/install.sh 2016-04-07 10:20:50.862077930 +0200 +@@ -0,0 +1,47 @@ ++#!/bin/sh ++# ++# arch/nds32/boot/install.sh ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Copyright (C) 1995 by Linus Torvalds ++# Copyright (C) 2009 Andes Technology Corporation ++# ++# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin ++# Adapted from code in arch/i386/boot/install.sh by Russell King ++# ++# "make install" script for arm architecture ++# ++# Arguments: ++# $1 - kernel version ++# $2 - kernel image file ++# $3 - kernel map file ++# $4 - default install path (blank if root directory) ++# ++ ++# User may have a custom install script ++if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi ++if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi ++ ++# Normal install ++echo "Installing normal kernel" ++base=vmlinux ++ ++if [ -f $4/$base-$1 ]; then ++ mv $4/$base-$1 $4/$base-$1.old ++fi ++cat $2 > $4/$base-$1 ++ ++# Install system map file ++if [ -f $4/System.map-$1 ]; then ++ mv $4/System.map-$1 $4/System.map-$1.old ++fi ++cp $3 $4/System.map-$1 ++ ++if [ -x /sbin/loadmap ]; then ++ /sbin/loadmap ++else ++ echo "You have to install it yourself" ++fi +diff -Nur linux-3.4.110.orig/arch/nds32/boot/Makefile linux-3.4.110/arch/nds32/boot/Makefile +--- linux-3.4.110.orig/arch/nds32/boot/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/boot/Makefile 2016-04-07 10:20:50.862077930 +0200 +@@ -0,0 +1,22 @@ ++# ++# arch/nds32/boot/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Copyright (C) 1995-2002 Russell King ++# Copyright (C) 2009 Andes Technology Corporation ++# ++ ++targets := Image ++ ++$(obj)/Image: vmlinux FORCE ++ $(call if_changed,objcopy) ++ @echo ' Kernel: $@ is ready' ++ ++.PHONY: FORCE ++install: $(obj)/Image ++ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ ++ $(obj)/Image System.map "$(INSTALL_PATH)" ++ +diff -Nur linux-3.4.110.orig/arch/nds32/common/dmabounce.c linux-3.4.110/arch/nds32/common/dmabounce.c +--- linux-3.4.110.orig/arch/nds32/common/dmabounce.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/common/dmabounce.c 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,672 @@ ++/* ++ * arch/nds32/common/dmabounce.c ++ * ++ * Special dma_{map/unmap/dma_sync}_* routines for systems that have ++ * limited DMA windows. These functions utilize bounce buffers to ++ * copy data to/from buffers located outside the DMA region. This ++ * only works for systems in which DMA memory is at the bottom of ++ * RAM and the remainder of memory is at the top an the DMA memory ++ * can be marked as ZONE_DMA. Anything beyond that such as discontigous ++ * DMA windows will require custom implementations that reserve memory ++ * areas at early bootup. ++ * ++ * Original version by Brad Parker (brad@heeltoe.com) ++ * Re-written by Christopher Hoover ++ * Made generic by Deepak Saxena ++ * ++ * Copyright (C) 2002 Hewlett Packard Company. ++ * Copyright (C) 2004 MontaVista Software, Inc. ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#undef DEBUG ++ ++#undef STATS ++#ifdef STATS ++#define DO_STATS(X) do { X ; } while (0) ++#else ++#define DO_STATS(X) do { } while (0) ++#endif ++ ++/* ************************************************** */ ++ ++struct safe_buffer { ++ struct list_head node; ++ ++ /* original request */ ++ void *ptr; ++ size_t size; ++ int direction; ++ ++ /* safe buffer info */ ++ struct dma_pool *pool; ++ void *safe; ++ dma_addr_t safe_dma_addr; ++}; ++ ++struct dmabounce_device_info { ++ struct list_head node; ++ ++ struct device *dev; ++ struct dma_pool *small_buffer_pool; ++ struct dma_pool *large_buffer_pool; ++ struct list_head safe_buffers; ++ unsigned long small_buffer_size, large_buffer_size; ++#ifdef STATS ++ unsigned long sbp_allocs; ++ unsigned long lbp_allocs; ++ unsigned long total_allocs; ++ unsigned long map_op_count; ++ unsigned long bounce_count; ++#endif ++}; ++ ++static LIST_HEAD(dmabounce_devs); ++ ++#ifdef STATS ++static void print_alloc_stats(struct dmabounce_device_info *device_info) ++{ ++ printk(KERN_INFO ++ "%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n", ++ device_info->dev->bus_id, ++ device_info->sbp_allocs, device_info->lbp_allocs, ++ device_info->total_allocs - device_info->sbp_allocs - ++ device_info->lbp_allocs, device_info->total_allocs); ++} ++#endif ++ ++/* find the given device in the dmabounce device list */ ++static inline struct dmabounce_device_info *find_dmabounce_dev(struct device ++ *dev) ++{ ++ struct list_head *entry; ++ ++ list_for_each(entry, &dmabounce_devs) { ++ struct dmabounce_device_info *d = ++ list_entry(entry, struct dmabounce_device_info, node); ++ ++ if (d->dev == dev) ++ return d; ++ } ++ return NULL; ++} ++ ++/* allocate a 'safe' buffer and keep track of it */ ++static inline struct safe_buffer *alloc_safe_buffer(struct dmabounce_device_info ++ *device_info, void *ptr, ++ size_t size, ++ enum dma_data_direction dir) ++{ ++ struct safe_buffer *buf; ++ struct dma_pool *pool; ++ struct device *dev = device_info->dev; ++ void *safe; ++ dma_addr_t safe_dma_addr; ++ ++ dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n", __func__, ptr, size, dir); ++ ++ DO_STATS(device_info->total_allocs++); ++ ++ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); ++ if (buf == NULL) { ++ dev_warn(dev, "%s: kmalloc failed\n", __func__); ++ return NULL; ++ } ++ ++ if (size <= device_info->small_buffer_size) { ++ pool = device_info->small_buffer_pool; ++ safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); ++ ++ DO_STATS(device_info->sbp_allocs++); ++ } else if (size <= device_info->large_buffer_size) { ++ pool = device_info->large_buffer_pool; ++ safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); ++ ++ DO_STATS(device_info->lbp_allocs++); ++ } else { ++ pool = NULL; ++ safe = ++ dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC); ++ } ++ ++ if (safe == NULL) { ++ dev_warn(device_info->dev, ++ "%s: could not alloc dma memory (size=%d)\n", ++ __func__, size); ++ kfree(buf); ++ return NULL; ++ } ++#ifdef STATS ++ if (device_info->total_allocs % 1000 == 0) ++ print_alloc_stats(device_info); ++#endif ++ ++ buf->ptr = ptr; ++ buf->size = size; ++ buf->direction = dir; ++ buf->pool = pool; ++ buf->safe = safe; ++ buf->safe_dma_addr = safe_dma_addr; ++ ++ list_add(&buf->node, &device_info->safe_buffers); ++ ++ return buf; ++} ++ ++/* determine if a buffer is from our "safe" pool */ ++static inline struct safe_buffer *find_safe_buffer(struct dmabounce_device_info ++ *device_info, ++ dma_addr_t safe_dma_addr) ++{ ++ struct list_head *entry; ++ ++ list_for_each(entry, &device_info->safe_buffers) { ++ struct safe_buffer *b = ++ list_entry(entry, struct safe_buffer, node); ++ ++ if (b->safe_dma_addr == safe_dma_addr) ++ return b; ++ } ++ ++ return NULL; ++} ++ ++static inline void ++free_safe_buffer(struct dmabounce_device_info *device_info, ++ struct safe_buffer *buf) ++{ ++ dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf); ++ ++ list_del(&buf->node); ++ ++ if (buf->pool) ++ dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr); ++ else ++ dma_free_coherent(device_info->dev, buf->size, buf->safe, ++ buf->safe_dma_addr); ++ ++ kfree(buf); ++} ++ ++/* ************************************************** */ ++ ++#ifdef STATS ++ ++static void print_map_stats(struct dmabounce_device_info *device_info) ++{ ++ printk(KERN_INFO ++ "%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n", ++ device_info->dev->bus_id, ++ device_info->map_op_count, device_info->bounce_count); ++} ++#endif ++ ++static inline dma_addr_t ++map_single(struct device *dev, void *ptr, size_t size, ++ enum dma_data_direction dir) ++{ ++ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); ++ dma_addr_t dma_addr; ++ int needs_bounce = 0; ++ ++ if (device_info) ++ DO_STATS(device_info->map_op_count++); ++ ++ dma_addr = virt_to_dma(dev, ptr); ++ ++ if (dev->dma_mask) { ++ unsigned long mask = *dev->dma_mask; ++ unsigned long limit; ++ ++ limit = (mask + 1) & ~mask; ++ if (limit && size > limit) { ++ dev_err(dev, "DMA mapping too big (requested %#x " ++ "mask %#Lx)\n", size, *dev->dma_mask); ++ return ~0; ++ } ++ ++ /* ++ * Figure out if we need to bounce from the DMA mask. ++ */ ++ needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask; ++ } ++ ++ if (device_info ++ && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) { ++ struct safe_buffer *buf; ++ ++ buf = alloc_safe_buffer(device_info, ptr, size, dir); ++ if (buf == 0) { ++ dev_err(dev, "%s: unable to map unsafe buffer %p!\n", ++ __func__, ptr); ++ return 0; ++ } ++ ++ dev_dbg(dev, ++ "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", ++ __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr), ++ buf->safe, (void *)buf->safe_dma_addr); ++ ++ if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL)) { ++ dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n", ++ __func__, ptr, buf->safe, size); ++ memcpy(buf->safe, ptr, size); ++ } ++ consistent_sync(buf->safe, size, dir); ++ ++ dma_addr = buf->safe_dma_addr; ++ } else { ++ consistent_sync(ptr, size, dir); ++ } ++ ++ return dma_addr; ++} ++ ++static inline void ++unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); ++ struct safe_buffer *buf = NULL; ++ ++ /* ++ * Trying to unmap an invalid mapping ++ */ ++ if (dma_addr == ~0) { ++ dev_err(dev, "Trying to unmap invalid mapping\n"); ++ return; ++ } ++ ++ if (device_info) ++ buf = find_safe_buffer(device_info, dma_addr); ++ ++ if (buf) { ++ BUG_ON(buf->size != size); ++ ++ dev_dbg(dev, ++ "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", ++ __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr), ++ buf->safe, (void *)buf->safe_dma_addr); ++ ++ DO_STATS(device_info->bounce_count++); ++ ++ if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)) { ++ dev_dbg(dev, ++ "%s: copy back safe %p to unsafe %p size %d\n", ++ __func__, buf->safe, buf->ptr, size); ++ memcpy(buf->ptr, buf->safe, size); ++ } ++ free_safe_buffer(device_info, buf); ++ } ++} ++ ++static inline void ++sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); ++ struct safe_buffer *buf = NULL; ++ ++ if (device_info) ++ buf = find_safe_buffer(device_info, dma_addr); ++ ++ if (buf) { ++ /* ++ * Both of these checks from original code need to be ++ * commented out b/c some drivers rely on the following: ++ * ++ * 1) Drivers may map a large chunk of memory into DMA space ++ * but only sync a small portion of it. Good example is ++ * allocating a large buffer, mapping it, and then ++ * breaking it up into small descriptors. No point ++ * in syncing the whole buffer if you only have to ++ * touch one descriptor. ++ * ++ * 2) Buffers that are mapped as DMA_BIDIRECTIONAL are ++ * usually only synced in one dir at a time. ++ * ++ * See drivers/net/eepro100.c for examples of both cases. ++ * ++ * -ds ++ * ++ * BUG_ON(buf->size != size); ++ * BUG_ON(buf->direction != dir); ++ */ ++ ++ dev_dbg(dev, ++ "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", ++ __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr), ++ buf->safe, (void *)buf->safe_dma_addr); ++ ++ DO_STATS(device_info->bounce_count++); ++ ++ switch (dir) { ++ case DMA_FROM_DEVICE: ++ dev_dbg(dev, ++ "%s: copy back safe %p to unsafe %p size %d\n", ++ __func__, buf->safe, buf->ptr, size); ++ memcpy(buf->ptr, buf->safe, size); ++ break; ++ case DMA_TO_DEVICE: ++ dev_dbg(dev, ++ "%s: copy out unsafe %p to safe %p, size %d\n", ++ __func__, buf->ptr, buf->safe, size); ++ memcpy(buf->safe, buf->ptr, size); ++ break; ++ case DMA_BIDIRECTIONAL: ++ BUG(); /* is this allowed? what does it mean? */ ++ default: ++ BUG(); ++ } ++ consistent_sync(buf->safe, size, dir); ++ } else { ++ consistent_sync(dma_to_virt(dev, dma_addr), size, dir); ++ } ++} ++ ++/* ************************************************** */ ++ ++/* ++ * see if a buffer address is in an 'unsafe' range. if it is ++ * allocate a 'safe' buffer and copy the unsafe buffer into it. ++ * substitute the safe buffer for the unsafe one. ++ * (basically move the buffer from an unsafe area to a safe one) ++ */ ++dma_addr_t ++dma_map_single(struct device *dev, void *ptr, size_t size, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ dma_addr_t dma_addr; ++ ++ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, ptr, size, dir); ++ ++ BUG_ON(dir == DMA_NONE); ++ ++ local_irq_save(flags); ++ ++ dma_addr = map_single(dev, ptr, size, dir); ++ ++ local_irq_restore(flags); ++ ++ return dma_addr; ++} ++ ++/* ++ * see if a mapped address was really a "safe" buffer and if so, copy ++ * the data from the safe buffer back to the unsafe buffer and free up ++ * the safe buffer. (basically return things back to the way they ++ * should be) ++ */ ++ ++void ++dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ ++ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", ++ __func__, (void *)dma_addr, size, dir); ++ ++ BUG_ON(dir == DMA_NONE); ++ ++ local_irq_save(flags); ++ ++ unmap_single(dev, dma_addr, size, dir); ++ ++ local_irq_restore(flags); ++} ++ ++int ++dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ int i; ++ ++ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); ++ ++ BUG_ON(dir == DMA_NONE); ++ ++ local_irq_save(flags); ++ ++ for (i = 0; i < nents; i++, sg++) { ++ struct page *page = sg->page; ++ unsigned int offset = sg->offset; ++ unsigned int length = sg->length; ++ void *ptr = page_address(page) + offset; ++ ++ sg->dma_address = map_single(dev, ptr, length, dir); ++ } ++ ++ local_irq_restore(flags); ++ ++ return nents; ++} ++ ++void ++dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ int i; ++ ++ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); ++ ++ BUG_ON(dir == DMA_NONE); ++ ++ local_irq_save(flags); ++ ++ for (i = 0; i < nents; i++, sg++) { ++ dma_addr_t dma_addr = sg->dma_address; ++ unsigned int length = sg->length; ++ ++ unmap_single(dev, dma_addr, length, dir); ++ } ++ ++ local_irq_restore(flags); ++} ++ ++void ++dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ ++ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", ++ __func__, (void *)dma_addr, size, dir); ++ ++ local_irq_save(flags); ++ ++ sync_single(dev, dma_addr, size, dir); ++ ++ local_irq_restore(flags); ++} ++ ++void ++dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ ++ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", ++ __func__, (void *)dma_addr, size, dir); ++ ++ local_irq_save(flags); ++ ++ sync_single(dev, dma_addr, size, dir); ++ ++ local_irq_restore(flags); ++} ++ ++void ++dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ int i; ++ ++ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); ++ ++ BUG_ON(dir == DMA_NONE); ++ ++ local_irq_save(flags); ++ ++ for (i = 0; i < nents; i++, sg++) { ++ dma_addr_t dma_addr = sg->dma_address; ++ unsigned int length = sg->length; ++ ++ sync_single(dev, dma_addr, length, dir); ++ } ++ ++ local_irq_restore(flags); ++} ++ ++void ++dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ unsigned long flags; ++ int i; ++ ++ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); ++ ++ BUG_ON(dir == DMA_NONE); ++ ++ local_irq_save(flags); ++ ++ for (i = 0; i < nents; i++, sg++) { ++ dma_addr_t dma_addr = sg->dma_address; ++ unsigned int length = sg->length; ++ ++ sync_single(dev, dma_addr, length, dir); ++ } ++ ++ local_irq_restore(flags); ++} ++ ++int ++dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, ++ unsigned long large_buffer_size) ++{ ++ struct dmabounce_device_info *device_info; ++ ++ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); ++ if (!device_info) { ++ printk(KERN_ERR ++ "Could not allocated dmabounce_device_info for %s", ++ dev->bus_id); ++ return -ENOMEM; ++ } ++ ++ device_info->small_buffer_pool = ++ dma_pool_create("small_dmabounce_pool", ++ dev, small_buffer_size, 0 /* byte alignment */ , ++ 0 /* no page-crossing issues */ ); ++ if (!device_info->small_buffer_pool) { ++ printk(KERN_ERR ++ "dmabounce: could not allocate small DMA pool for %s\n", ++ dev->bus_id); ++ kfree(device_info); ++ return -ENOMEM; ++ } ++ ++ if (large_buffer_size) { ++ device_info->large_buffer_pool = ++ dma_pool_create("large_dmabounce_pool", ++ dev, ++ large_buffer_size, 0 /* byte alignment */ , ++ 0 /* no page-crossing issues */ ); ++ if (!device_info->large_buffer_pool) { ++ printk(KERN_ERR ++ "dmabounce: could not allocate large DMA pool for %s\n", ++ dev->bus_id); ++ dma_pool_destroy(device_info->small_buffer_pool); ++ ++ return -ENOMEM; ++ } ++ } ++ ++ device_info->dev = dev; ++ device_info->small_buffer_size = small_buffer_size; ++ device_info->large_buffer_size = large_buffer_size; ++ INIT_LIST_HEAD(&device_info->safe_buffers); ++ ++#ifdef STATS ++ device_info->sbp_allocs = 0; ++ device_info->lbp_allocs = 0; ++ device_info->total_allocs = 0; ++ device_info->map_op_count = 0; ++ device_info->bounce_count = 0; ++#endif ++ ++ list_add(&device_info->node, &dmabounce_devs); ++ ++ printk(KERN_INFO "dmabounce: registered device %s on %s bus\n", ++ dev->bus_id, dev->bus->name); ++ ++ return 0; ++} ++ ++void dmabounce_unregister_dev(struct device *dev) ++{ ++ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); ++ ++ if (!device_info) { ++ printk(KERN_WARNING ++ "%s: Never registered with dmabounce but attempting" ++ "to unregister!\n", dev->bus_id); ++ return; ++ } ++ ++ if (!list_empty(&device_info->safe_buffers)) { ++ printk(KERN_ERR ++ "%s: Removing from dmabounce with pending buffers!\n", ++ dev->bus_id); ++ BUG(); ++ } ++ ++ if (device_info->small_buffer_pool) ++ dma_pool_destroy(device_info->small_buffer_pool); ++ if (device_info->large_buffer_pool) ++ dma_pool_destroy(device_info->large_buffer_pool); ++ ++#ifdef STATS ++ print_alloc_stats(device_info); ++ print_map_stats(device_info); ++#endif ++ ++ list_del(&device_info->node); ++ ++ kfree(device_info); ++ ++ printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n", ++ dev->bus_id, dev->bus->name); ++} ++ ++EXPORT_SYMBOL(dma_map_single); ++EXPORT_SYMBOL(dma_unmap_single); ++EXPORT_SYMBOL(dma_map_sg); ++EXPORT_SYMBOL(dma_unmap_sg); ++EXPORT_SYMBOL(dma_sync_single); ++EXPORT_SYMBOL(dma_sync_sg); ++EXPORT_SYMBOL(dmabounce_register_dev); ++EXPORT_SYMBOL(dmabounce_unregister_dev); ++ ++MODULE_AUTHOR ++ ("Christopher Hoover , Deepak Saxena "); ++MODULE_DESCRIPTION ++ ("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-3.4.110.orig/arch/nds32/common/Makefile linux-3.4.110/arch/nds32/common/Makefile +--- linux-3.4.110.orig/arch/nds32/common/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/common/Makefile 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,6 @@ ++# ++# Makefile for the linux kernel. ++# ++ ++obj-y += rtctime.o ++obj-$(CONFIG_DMABOUNCE) += dmabounce.o +diff -Nur linux-3.4.110.orig/arch/nds32/common/rtctime.c linux-3.4.110/arch/nds32/common/rtctime.c +--- linux-3.4.110.orig/arch/nds32/common/rtctime.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/common/rtctime.c 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,441 @@ ++/* ++ * linux/arch/nds32/common/rtctime.c ++ * ++ * Copyright (C) 2003 Deep Blue Solutions Ltd. ++ * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre. ++ * Based on rtc.c by Paul Gortmaker ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); ++static struct fasync_struct *rtc_async_queue; ++ ++/* ++ * rtc_lock protects rtc_irq_data ++ */ ++static DEFINE_SPINLOCK(rtc_lock); ++static unsigned long rtc_irq_data; ++ ++/* ++ * rtc_sem protects rtc_inuse and rtc_ops ++ */ ++static DEFINE_MUTEX(rtc_mutex); ++static unsigned long rtc_inuse; ++static struct rtc_ops *rtc_ops; ++ ++#define rtc_epoch 1900UL ++ ++/* ++ * Calculate the next alarm time given the requested alarm time mask ++ * and the current time. ++ */ ++void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, ++ struct rtc_time *alrm) ++{ ++ unsigned long next_time; ++ unsigned long now_time; ++ ++ next->tm_year = now->tm_year; ++ next->tm_mon = now->tm_mon; ++ next->tm_mday = now->tm_mday; ++ next->tm_hour = alrm->tm_hour; ++ next->tm_min = alrm->tm_min; ++ next->tm_sec = alrm->tm_sec; ++ ++ rtc_tm_to_time(now, &now_time); ++ rtc_tm_to_time(next, &next_time); ++ ++ if (next_time < now_time) { ++ /* Advance one day */ ++ next_time += 60 * 60 * 24; ++ rtc_time_to_tm(next_time, next); ++ } ++} ++ ++static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) ++{ ++ memset(tm, 0, sizeof(struct rtc_time)); ++ return ops->read_time(tm); ++} ++ ++static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) ++{ ++ int ret; ++ ++ ret = rtc_valid_tm(tm); ++ if (ret == 0) ++ ret = ops->set_time(tm); ++ ++ return ret; ++} ++ ++static inline int rtc_arm_read_alarm(struct rtc_ops *ops, ++ struct rtc_wkalrm *alrm) ++{ ++ int ret = -EINVAL; ++ if (ops->read_alarm) { ++ memset(alrm, 0, sizeof(struct rtc_wkalrm)); ++ ret = ops->read_alarm(alrm); ++ } ++ return ret; ++} ++ ++static inline int rtc_arm_set_alarm(struct rtc_ops *ops, ++ struct rtc_wkalrm *alrm) ++{ ++ int ret = -EINVAL; ++ if (ops->set_alarm) ++ ret = ops->set_alarm(alrm); ++ return ret; ++} ++ ++void rtc_update(unsigned long num, unsigned long events) ++{ ++ spin_lock(&rtc_lock); ++ rtc_irq_data = (rtc_irq_data + (num << 8)) | events; ++ spin_unlock(&rtc_lock); ++ ++ wake_up_interruptible(&rtc_wait); ++ kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); ++} ++ ++EXPORT_SYMBOL(rtc_update); ++ ++static ssize_t ++rtc_read(struct file *file, char __user * buf, size_t count, loff_t * ppos) ++{ ++ DECLARE_WAITQUEUE(wait, current); ++ unsigned long data; ++ ssize_t ret; ++ ++ if (count < sizeof(unsigned long)) ++ return -EINVAL; ++ ++ add_wait_queue(&rtc_wait, &wait); ++ do { ++ __set_current_state(TASK_INTERRUPTIBLE); ++ ++ spin_lock_irq(&rtc_lock); ++ data = rtc_irq_data; ++ rtc_irq_data = 0; ++ spin_unlock_irq(&rtc_lock); ++ ++ if (data != 0) { ++ ret = 0; ++ break; ++ } ++ if (file->f_flags & O_NONBLOCK) { ++ ret = -EAGAIN; ++ break; ++ } ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ schedule(); ++ } while (1); ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&rtc_wait, &wait); ++ ++ if (ret == 0) { ++ ret = put_user(data, (unsigned long __user *)buf); ++ if (ret == 0) ++ ret = sizeof(unsigned long); ++ } ++ return ret; ++} ++ ++static unsigned int rtc_poll(struct file *file, poll_table * wait) ++{ ++ unsigned long data; ++ ++ poll_wait(file, &rtc_wait, wait); ++ ++ spin_lock_irq(&rtc_lock); ++ data = rtc_irq_data; ++ spin_unlock_irq(&rtc_lock); ++ ++ return data != 0 ? POLLIN | POLLRDNORM : 0; ++} ++ ++static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct rtc_ops *ops = file->private_data; ++ struct rtc_time tm; ++ struct rtc_wkalrm alrm; ++ void __user *uarg = (void __user *)arg; ++ int ret = -EINVAL; ++ ++ switch (cmd) { ++ case RTC_ALM_READ: ++ ret = rtc_arm_read_alarm(ops, &alrm); ++ if (ret) ++ break; ++ ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); ++ if (ret) ++ ret = -EFAULT; ++ break; ++ ++ case RTC_ALM_SET: ++ ret = copy_from_user(&alrm.time, uarg, sizeof(tm)); ++ if (ret) { ++ ret = -EFAULT; ++ break; ++ } ++ alrm.enabled = 0; ++ alrm.pending = 0; ++ alrm.time.tm_mday = -1; ++ alrm.time.tm_mon = -1; ++ alrm.time.tm_year = -1; ++ alrm.time.tm_wday = -1; ++ alrm.time.tm_yday = -1; ++ alrm.time.tm_isdst = -1; ++ ret = rtc_arm_set_alarm(ops, &alrm); ++ break; ++ ++ case RTC_RD_TIME: ++ ret = rtc_arm_read_time(ops, &tm); ++ if (ret) ++ break; ++ ret = copy_to_user(uarg, &tm, sizeof(tm)); ++ if (ret) ++ ret = -EFAULT; ++ break; ++ ++ case RTC_SET_TIME: ++ if (!capable(CAP_SYS_TIME)) { ++ ret = -EACCES; ++ break; ++ } ++ ret = copy_from_user(&tm, uarg, sizeof(tm)); ++ if (ret) { ++ ret = -EFAULT; ++ break; ++ } ++ ret = rtc_arm_set_time(ops, &tm); ++ break; ++ ++ case RTC_EPOCH_SET: ++#ifndef rtc_epoch ++ /* ++ * There were no RTC clocks before 1900. ++ */ ++ if (arg < 1900) { ++ ret = -EINVAL; ++ break; ++ } ++ if (!capable(CAP_SYS_TIME)) { ++ ret = -EACCES; ++ break; ++ } ++ rtc_epoch = arg; ++ ret = 0; ++#endif ++ break; ++ ++ case RTC_EPOCH_READ: ++ ret = put_user(rtc_epoch, (unsigned long __user *)uarg); ++ break; ++ ++ case RTC_WKALM_SET: ++ ret = copy_from_user(&alrm, uarg, sizeof(alrm)); ++ if (ret) { ++ ret = -EFAULT; ++ break; ++ } ++ ret = rtc_arm_set_alarm(ops, &alrm); ++ break; ++ ++ case RTC_WKALM_RD: ++ ret = rtc_arm_read_alarm(ops, &alrm); ++ if (ret) ++ break; ++ ret = copy_to_user(uarg, &alrm, sizeof(alrm)); ++ if (ret) ++ ret = -EFAULT; ++ break; ++ ++ default: ++ if (ops->ioctl) ++ ret = ops->ioctl(cmd, arg); ++ break; ++ } ++ return ret; ++} ++ ++static int rtc_open(struct inode *inode, struct file *file) ++{ ++ int ret; ++ ++ mutex_lock(&rtc_mutex); ++ ++ if (rtc_inuse) { ++ ret = -EBUSY; ++ } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) { ++ ret = -ENODEV; ++ } else { ++ file->private_data = rtc_ops; ++ ++ ret = rtc_ops->open ? rtc_ops->open() : 0; ++ if (ret == 0) { ++ spin_lock_irq(&rtc_lock); ++ rtc_irq_data = 0; ++ spin_unlock_irq(&rtc_lock); ++ ++ rtc_inuse = 1; ++ } ++ } ++ mutex_unlock(&rtc_mutex); ++ ++ return ret; ++} ++ ++static int rtc_release(struct inode *inode, struct file *file) ++{ ++ struct rtc_ops *ops = file->private_data; ++ ++ if (ops->release) ++ ops->release(); ++ ++ spin_lock_irq(&rtc_lock); ++ rtc_irq_data = 0; ++ spin_unlock_irq(&rtc_lock); ++ ++ module_put(rtc_ops->owner); ++ rtc_inuse = 0; ++ ++ return 0; ++} ++ ++static int rtc_fasync(int fd, struct file *file, int on) ++{ ++ return fasync_helper(fd, file, on, &rtc_async_queue); ++} ++ ++static struct file_operations rtc_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .read = rtc_read, ++ .poll = rtc_poll, ++ .ioctl = rtc_ioctl, ++ .open = rtc_open, ++ .release = rtc_release, ++ .fasync = rtc_fasync, ++}; ++ ++static struct miscdevice rtc_miscdev = { ++ .minor = RTC_MINOR, ++ .name = "rtc", ++ .fops = &rtc_fops, ++}; ++ ++static int rtc_read_proc(char *page, char **start, off_t off, int count, ++ int *eof, void *data) ++{ ++ struct rtc_ops *ops = data; ++ struct rtc_wkalrm alrm; ++ struct rtc_time tm; ++ char *p = page; ++ ++ if (rtc_arm_read_time(ops, &tm) == 0) { ++ p += sprintf(p, ++ "rtc_time\t: %02d:%02d:%02d\n" ++ "rtc_date\t: %04d-%02d-%02d\n" ++ "rtc_epoch\t: %04lu\n", ++ tm.tm_hour, tm.tm_min, tm.tm_sec, ++ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, ++ rtc_epoch); ++ } ++ ++ if (rtc_arm_read_alarm(ops, &alrm) == 0) { ++ p += sprintf(p, "alrm_time\t: "); ++ if ((unsigned int)alrm.time.tm_hour <= 24) ++ p += sprintf(p, "%02d:", alrm.time.tm_hour); ++ else ++ p += sprintf(p, "**:"); ++ if ((unsigned int)alrm.time.tm_min <= 59) ++ p += sprintf(p, "%02d:", alrm.time.tm_min); ++ else ++ p += sprintf(p, "**:"); ++ if ((unsigned int)alrm.time.tm_sec <= 59) ++ p += sprintf(p, "%02d\n", alrm.time.tm_sec); ++ else ++ p += sprintf(p, "**\n"); ++ ++ p += sprintf(p, "alrm_date\t: "); ++ if ((unsigned int)alrm.time.tm_year <= 200) ++ p += sprintf(p, "%04d-", alrm.time.tm_year + 1900); ++ else ++ p += sprintf(p, "****-"); ++ if ((unsigned int)alrm.time.tm_mon <= 11) ++ p += sprintf(p, "%02d-", alrm.time.tm_mon + 1); ++ else ++ p += sprintf(p, "**-"); ++ if ((unsigned int)alrm.time.tm_mday <= 31) ++ p += sprintf(p, "%02d\n", alrm.time.tm_mday); ++ else ++ p += sprintf(p, "**\n"); ++ p += sprintf(p, "alrm_wakeup\t: %s\n", ++ alrm.enabled ? "yes" : "no"); ++ p += sprintf(p, "alrm_pending\t: %s\n", ++ alrm.pending ? "yes" : "no"); ++ } ++ ++ if (ops->proc) ++ p += ops->proc(p); ++ ++ return p - page; ++} ++ ++int register_rtc(struct rtc_ops *ops) ++{ ++ int ret = -EBUSY; ++ ++ mutex_lock(&rtc_mutex); ++ if (rtc_ops == NULL) { ++ rtc_ops = ops; ++ ++ ret = misc_register(&rtc_miscdev); ++ if (ret == 0) ++ create_proc_read_entry("driver/rtc", 0, NULL, ++ rtc_read_proc, ops); ++ } ++ mutex_unlock(&rtc_mutex); ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL(register_rtc); ++ ++void unregister_rtc(struct rtc_ops *rtc) ++{ ++ mutex_lock(&rtc_mutex); ++ if (rtc == rtc_ops) { ++ remove_proc_entry("driver/rtc", NULL); ++ misc_deregister(&rtc_miscdev); ++ rtc_ops = NULL; ++ } ++ mutex_unlock(&rtc_mutex); ++} ++ ++EXPORT_SYMBOL(unregister_rtc); +diff -Nur linux-3.4.110.orig/arch/nds32/configs/orca_8k_defconfig linux-3.4.110/arch/nds32/configs/orca_8k_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/orca_8k_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/orca_8k_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,132 @@ ++CONFIG_EXPERIMENTAL=y ++CONFIG_CROSS_COMPILE="nds32le-linux-" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=14 ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_HOTPLUG is not set ++# CONFIG_SIGNALFD is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_PLATFORM_AHBDMA=y ++CONFIG_PLATFORM_APBDMA=y ++CONFIG_SYS_CLK=30000000 ++CONFIG_UART_CLK=14745600 ++CONFIG_SDRAM_SIZE=0x40000000 ++CONFIG_CPU_CACHE_NONALIASING=y ++CONFIG_ANDES_PAGE_SIZE_8KB=y ++CONFIG_HIGHMEM=y ++CONFIG_HZ_100=y ++CONFIG_CMDLINE="root=/dev/ram0 rw mem=1024M@0x0 initrd=0x1000000,8M earlyprintk=uart8250-32bit,0x99600000 console=ttyS0,38400n8 loglevel=7 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_BRIDGE=y ++CONFIG_MTD=y ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_COMPAT=y ++CONFIG_MTD_PHYSMAP_START=0x80400000 ++CONFIG_MTD_PHYSMAP_LEN=0x2000000 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=4 ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_NETDEVICES=y ++CONFIG_TUN=y ++CONFIG_FTMAC100=y ++# CONFIG_INPUT_MOUSEDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_CPE_TS=y ++# CONFIG_SERIO is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_HW_RANDOM is not set ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_FTGPIO010=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_FTWDT010_WATCHDOG=y ++CONFIG_FB=y ++CONFIG_FB_FTLCDC100=y ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_PCM_OSS=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++CONFIG_SND_FTSSP010=y ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++CONFIG_MMC=y ++CONFIG_MMC_FTSDC010=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_FTRTC010=y ++CONFIG_EXT2_FS=y ++CONFIG_FUSE_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_TMPFS=y ++CONFIG_JFFS2_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_SHIRQ=y ++CONFIG_SCHEDSTATS=y ++CONFIG_TIMER_STATS=y ++CONFIG_SLUB_DEBUG_ON=y ++CONFIG_DEBUG_RT_MUTEXES=y ++CONFIG_DEBUG_SPINLOCK=y ++CONFIG_DEBUG_MUTEXES=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_MEMORY_INIT=y ++CONFIG_DEBUG_LIST=y ++CONFIG_DEBUG_SG=y ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set +diff -Nur linux-3.4.110.orig/arch/nds32/configs/orca_defconfig linux-3.4.110/arch/nds32/configs/orca_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/orca_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/orca_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,125 @@ ++CONFIG_EXPERIMENTAL=y ++CONFIG_CROSS_COMPILE="nds32le-linux-" ++CONFIG_SYSVIPC=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=14 ++CONFIG_NAMESPACES=y ++CONFIG_SYSCTL_SYSCALL=y ++CONFIG_KALLSYMS_ALL=y ++# CONFIG_HOTPLUG is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_MEASURE_INTERRUPT_LATENCY=y ++CONFIG_PLATFORM_AHBDMA=y ++CONFIG_PLATFORM_APBDMA=y ++CONFIG_SYS_CLK=30000000 ++CONFIG_UART_CLK=14745600 ++CONFIG_SDRAM_SIZE=0x40000000 ++CONFIG_MEMORY_START=0x0 ++# CONFIG_HWZOL is not set ++CONFIG_IVIC=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_BRIDGE=y ++CONFIG_MTD=y ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_COMPAT=y ++CONFIG_MTD_PHYSMAP_START=0x80400000 ++CONFIG_MTD_PHYSMAP_LEN=0x2000000 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=4 ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_NETDEVICES=y ++CONFIG_TUN=y ++CONFIG_FTMAC100=y ++# CONFIG_INPUT_MOUSEDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_CPE_TS=m ++# CONFIG_SERIO is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_HW_RANDOM is not set ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_GPIO_FTGPIO010=m ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_FTWDT010_WATCHDOG=m ++CONFIG_FB=y ++CONFIG_FB_FTLCDC100=y ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_PCM_OSS=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++CONFIG_SND_FTSSP010=m ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++CONFIG_MMC=y ++CONFIG_MMC_FTSDC010=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_RTC_DRV_FTRTC010=y ++CONFIG_EXT2_FS=y ++CONFIG_FUSE_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_CONFIGFS_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_V4_1=y ++CONFIG_NFS_USE_LEGACY_DNS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_HEADERS_CHECK=y ++CONFIG_DEBUG_SECTION_MISMATCH=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_DEBUG_INFO=y ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set +diff -Nur linux-3.4.110.orig/arch/nds32/configs/qemu_defconfig linux-3.4.110/arch/nds32/configs/qemu_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/qemu_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/qemu_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,98 @@ ++CONFIG_EXPERIMENTAL=y ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_LOG_BUF_SHIFT=14 ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_HOTPLUG is not set ++# CONFIG_SIGNALFD is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_PLAT_QEMU=y ++CONFIG_SYS_CLK=40000000 ++CONFIG_UART_CLK=14745600 ++CONFIG_SDRAM_SIZE=0x10000000 ++CONFIG_HZ_100=y ++CONFIG_CMDLINE="root=/dev/ram0 rw mem=1024M@0x0 initrd=0x1000000,8M earlyprintk=uart8250-32bit,0x99600000 console=ttyS0,38400n8 loglevel=7 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_FTSDC010=y ++CONFIG_NETDEVICES=y ++CONFIG_FTMAC100=y ++# CONFIG_INPUT_MOUSEDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_SERIO is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_HW_RANDOM is not set ++# CONFIG_HWMON is not set ++CONFIG_FB=y ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++CONFIG_EXT2_FS=y ++CONFIG_EXT2_FS_XATTR=y ++CONFIG_EXT2_FS_POSIX_ACL=y ++CONFIG_EXT2_FS_SECURITY=y ++CONFIG_EXT2_FS_XIP=y ++CONFIG_EXT3_FS=y ++CONFIG_EXT3_FS_POSIX_ACL=y ++CONFIG_EXT3_FS_SECURITY=y ++CONFIG_EXT4_FS=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_EXT4_DEBUG=y ++CONFIG_FUSE_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_TMPFS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_SHIRQ=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_SCHEDSTATS=y ++CONFIG_TIMER_STATS=y ++CONFIG_SLUB_DEBUG_ON=y ++CONFIG_DEBUG_RT_MUTEXES=y ++CONFIG_DEBUG_MUTEXES=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_LIST=y ++CONFIG_DEBUG_SG=y ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set +diff -Nur linux-3.4.110.orig/arch/nds32/configs/vep-be_defconfig linux-3.4.110/arch/nds32/configs/vep-be_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/vep-be_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/vep-be_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,777 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.29 ++# Mon Jul 13 11:42:57 2009 ++# ++CONFIG_NDS32=y ++CONFIG_NO_IOPORT=y ++CONFIG_GENERIC_IOMAP=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_FIND_NEXT_BIT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_HAVE_LATENCYTOP_SUPPORT=y ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# General setup ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++# CONFIG_TASKSTATS is not set ++# CONFIG_AUDIT is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_GROUP_SCHED is not set ++# CONFIG_CGROUPS is not set ++# CONFIG_SYSFS_DEPRECATED_V2 is not set ++# CONFIG_RELAY is not set ++# CONFIG_NAMESPACES is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_EMBEDDED=y ++CONFIG_UID16=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_KALLSYMS is not set ++# CONFIG_HOTPLUG is not set ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++# CONFIG_ELF_CORE is not set ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++# CONFIG_SIGNALFD is not set ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLOB is not set ++CONFIG_PROFILING=y ++CONFIG_TRACEPOINTS=y ++# CONFIG_MARKERS is not set ++CONFIG_OPROFILE=y ++CONFIG_HAVE_OPROFILE=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_BLOCK=y ++# CONFIG_LBD is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++# CONFIG_IOSCHED_AS is not set ++# CONFIG_IOSCHED_DEADLINE is not set ++# CONFIG_IOSCHED_CFQ is not set ++# CONFIG_DEFAULT_AS is not set ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++CONFIG_DEFAULT_NOOP=y ++CONFIG_DEFAULT_IOSCHED="noop" ++# CONFIG_FREEZER is not set ++ ++# ++# System Type ++# ++# CONFIG_PLAT_FARADAY is not set ++CONFIG_PLAT_VEP=y ++# CONFIG_PLAT_AG101 is not set ++# CONFIG_PLAT_AG102 is not set ++# CONFIG_PLAT_AG101P is not set ++# CONFIG_PLAT_QEMU is not set ++CONFIG_PLATFORM_INTC=y ++ ++# ++# VEP Platform Options ++# ++# CONFIG_CACHE_L2 is not set ++ ++# ++# Common Platform Options ++# ++# CONFIG_PLATFORM_AHBDMA is not set ++# CONFIG_PLATFORM_APBDMA is not set ++CONFIG_SYS_CLK=67737600 ++CONFIG_UART_CLK=36864000 ++CONFIG_SDRAM_SIZE=0x10000000 ++ ++# ++# Processor Features ++# ++CONFIG_CPU_CUSTOM=y ++# CONFIG_FPU is not set ++# CONFIG_AUDIO is not set ++# CONFIG_EVIC is not set ++CONFIG_CPU_CONTEXT_ID=y ++CONFIG_ANDES_PAGE_SIZE_4KB=y ++# CONFIG_ANDES_PAGE_SIZE_8KB is not set ++# CONFIG_KERNEL_SPACE_LARGE_PAGE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set ++# CONFIG_ALIGNMENT_TRAP is not set ++CONFIG_MMU=y ++ ++# ++# Kernel Features ++# ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_PAGEFLAGS_EXTENDED=y ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=0 ++CONFIG_VIRT_TO_BUS=y ++CONFIG_UNEVICTABLE_LRU=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_HZ_100=y ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++CONFIG_CMDLINE="root=/dev/ram0 rw mem=64M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" ++ ++# ++# Power management options ++# ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++# CONFIG_PM is not set ++ ++# ++# Bus options ++# ++# CONFIG_PCI is not set ++# CONFIG_ARCH_SUPPORTS_MSI is not set ++ ++# ++# Executable file formats ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_COMPAT_NET_DEV_OPS=y ++CONFIG_PACKET=y ++# CONFIG_PACKET_MMAP is not set ++CONFIG_UNIX=y ++CONFIG_XFRM=y ++# CONFIG_XFRM_USER is not set ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_FIB_HASH=y ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_IP_MROUTE is not set ++# CONFIG_ARPD is not set ++# CONFIG_SYN_COOKIES is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_NET_DSA is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_PHONET is not set ++CONFIG_WIRELESS=y ++# CONFIG_CFG80211 is not set ++CONFIG_WIRELESS_OLD_REGULATORY=y ++# CONFIG_WIRELESS_EXT is not set ++# CONFIG_LIB80211 is not set ++# CONFIG_MAC80211 is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_CONNECTOR is not set ++# CONFIG_MTD is not set ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++# CONFIG_BLK_DEV_XIP is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_FTSDC010 is not set ++# CONFIG_FTCFC010 is not set ++# CONFIG_BLK_DEV_HD is not set ++# CONFIG_MISC_DEVICES is not set ++CONFIG_HAVE_IDE=y ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++CONFIG_NETDEVICES=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++# CONFIG_VETH is not set ++# CONFIG_PHYLIB is not set ++CONFIG_NET_ETHERNET=y ++# CONFIG_MII is not set ++# CONFIG_SMC91X is not set ++# CONFIG_DNET is not set ++# CONFIG_IBM_NEW_EMAC_ZMII is not set ++# CONFIG_IBM_NEW_EMAC_RGMII is not set ++# CONFIG_IBM_NEW_EMAC_TAH is not set ++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set ++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set ++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set ++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_B44 is not set ++CONFIG_FTMAC100=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++ ++# ++# Wireless LAN ++# ++# CONFIG_WLAN_PRE80211 is not set ++# CONFIG_WLAN_80211 is not set ++# CONFIG_IWLWIFI_LEDS is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_ISDN is not set ++# CONFIG_PHONE is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_DEVKMEM=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_SERIAL_8250_EXTENDED is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=256 ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_GPIO_FTGPIO010 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_I2C is not set ++# CONFIG_SPI is not set ++# CONFIG_W1 is not set ++# CONFIG_POWER_SUPPLY is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_THERMAL_HWMON is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_REGULATOR is not set ++ ++# ++# Multimedia devices ++# ++ ++# ++# Multimedia core support ++# ++# CONFIG_VIDEO_DEV is not set ++# CONFIG_DVB_CORE is not set ++# CONFIG_VIDEO_MEDIA is not set ++ ++# ++# Multimedia drivers ++# ++# CONFIG_DAB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_VGASTATE is not set ++# CONFIG_VIDEO_OUTPUT_CONTROL is not set ++# CONFIG_FB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++ ++# ++# Display device support ++# ++# CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Console display driver support ++# ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_SOUND is not set ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_CLASS is not set ++# CONFIG_DMADEVICES is not set ++# CONFIG_UIO is not set ++# CONFIG_STAGING is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++# CONFIG_EXT2_FS_XATTR is not set ++# CONFIG_EXT2_FS_XIP is not set ++# CONFIG_EXT3_FS is not set ++# CONFIG_EXT4_FS is not set ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_FS_POSIX_ACL is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_XFS_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++CONFIG_FUSE_FS=y ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++# CONFIG_MSDOS_FS is not set ++# CONFIG_VFAT_FS is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++# CONFIG_PROC_KCORE is not set ++CONFIG_PROC_SYSCTL=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_HUGETLB_PAGE is not set ++# CONFIG_CONFIGFS_FS is not set ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++# CONFIG_NFS_V4 is not set ++# CONFIG_NFSD is not set ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_RPCSEC_GSS_KRB5 is not set ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++# CONFIG_SMB_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++CONFIG_NLS_ISO8859_1=y ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_ENABLE_MUST_CHECK=y ++CONFIG_FRAME_WARN=1024 ++# CONFIG_MAGIC_SYSRQ is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++CONFIG_DEBUG_FS=y ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_KERNEL is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_MEMORY_INIT is not set ++CONFIG_FRAME_POINTER=y ++# CONFIG_RCU_CPU_STALL_DETECTOR is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_NOP_TRACER=y ++CONFIG_RING_BUFFER=y ++CONFIG_TRACING=y ++ ++# ++# Tracers ++# ++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++CONFIG_DEBUG_USER=y ++# CONFIG_CCTL is not set ++CONFIG_ELFCHK_DEFAULT_ENABLE=y ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++# CONFIG_SECURITY_FILE_CAPABILITIES is not set ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++# CONFIG_CRYPTO_FIPS is not set ++# CONFIG_CRYPTO_MANAGER is not set ++# CONFIG_CRYPTO_MANAGER2 is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_SEQIV is not set ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_XCBC is not set ++ ++# ++# Digest ++# ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_MD4 is not set ++# CONFIG_CRYPTO_MD5 is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++# CONFIG_CRYPTO_AES is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_LZO is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++ ++# ++# Library routines ++# ++CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++# CONFIG_CRC32 is not set ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++CONFIG_PLIST=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_DMA=y +diff -Nur linux-3.4.110.orig/arch/nds32/configs/vep-le_defconfig linux-3.4.110/arch/nds32/configs/vep-le_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/vep-le_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/vep-le_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,777 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.29 ++# Mon Jul 13 11:41:30 2009 ++# ++CONFIG_NDS32=y ++CONFIG_NO_IOPORT=y ++CONFIG_GENERIC_IOMAP=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_FIND_NEXT_BIT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_HAVE_LATENCYTOP_SUPPORT=y ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# General setup ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++# CONFIG_TASKSTATS is not set ++# CONFIG_AUDIT is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_GROUP_SCHED is not set ++# CONFIG_CGROUPS is not set ++# CONFIG_SYSFS_DEPRECATED_V2 is not set ++# CONFIG_RELAY is not set ++# CONFIG_NAMESPACES is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_EMBEDDED=y ++CONFIG_UID16=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_KALLSYMS is not set ++# CONFIG_HOTPLUG is not set ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++# CONFIG_ELF_CORE is not set ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++# CONFIG_SIGNALFD is not set ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLOB is not set ++CONFIG_PROFILING=y ++CONFIG_TRACEPOINTS=y ++# CONFIG_MARKERS is not set ++CONFIG_OPROFILE=y ++CONFIG_HAVE_OPROFILE=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_BLOCK=y ++# CONFIG_LBD is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++# CONFIG_IOSCHED_AS is not set ++# CONFIG_IOSCHED_DEADLINE is not set ++# CONFIG_IOSCHED_CFQ is not set ++# CONFIG_DEFAULT_AS is not set ++# CONFIG_DEFAULT_DEADLINE is not set ++# CONFIG_DEFAULT_CFQ is not set ++CONFIG_DEFAULT_NOOP=y ++CONFIG_DEFAULT_IOSCHED="noop" ++# CONFIG_FREEZER is not set ++ ++# ++# System Type ++# ++# CONFIG_PLAT_FARADAY is not set ++CONFIG_PLAT_VEP=y ++# CONFIG_PLAT_AG101 is not set ++# CONFIG_PLAT_AG102 is not set ++# CONFIG_PLAT_AG101P is not set ++# CONFIG_PLAT_QEMU is not set ++CONFIG_PLATFORM_INTC=y ++ ++# ++# VEP Platform Options ++# ++# CONFIG_CACHE_L2 is not set ++ ++# ++# Common Platform Options ++# ++# CONFIG_PLATFORM_AHBDMA is not set ++# CONFIG_PLATFORM_APBDMA is not set ++CONFIG_SYS_CLK=67737600 ++CONFIG_UART_CLK=36864000 ++CONFIG_SDRAM_SIZE=0x10000000 ++ ++# ++# Processor Features ++# ++CONFIG_CPU_CUSTOM=y ++# CONFIG_FPU is not set ++# CONFIG_AUDIO is not set ++# CONFIG_EVIC is not set ++CONFIG_CPU_CONTEXT_ID=y ++CONFIG_ANDES_PAGE_SIZE_4KB=y ++# CONFIG_ANDES_PAGE_SIZE_8KB is not set ++# CONFIG_KERNEL_SPACE_LARGE_PAGE is not set ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set ++# CONFIG_ALIGNMENT_TRAP is not set ++CONFIG_MMU=y ++ ++# ++# Kernel Features ++# ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_PAGEFLAGS_EXTENDED=y ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=0 ++CONFIG_VIRT_TO_BUS=y ++CONFIG_UNEVICTABLE_LRU=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_HZ_100=y ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++CONFIG_CMDLINE="root=/dev/ram0 rw mem=64M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" ++ ++# ++# Power management options ++# ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++# CONFIG_PM is not set ++ ++# ++# Bus options ++# ++# CONFIG_PCI is not set ++# CONFIG_ARCH_SUPPORTS_MSI is not set ++ ++# ++# Executable file formats ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_COMPAT_NET_DEV_OPS=y ++CONFIG_PACKET=y ++# CONFIG_PACKET_MMAP is not set ++CONFIG_UNIX=y ++CONFIG_XFRM=y ++# CONFIG_XFRM_USER is not set ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_FIB_HASH=y ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_IP_MROUTE is not set ++# CONFIG_ARPD is not set ++# CONFIG_SYN_COOKIES is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_NET_DSA is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_PHONET is not set ++CONFIG_WIRELESS=y ++# CONFIG_CFG80211 is not set ++CONFIG_WIRELESS_OLD_REGULATORY=y ++# CONFIG_WIRELESS_EXT is not set ++# CONFIG_LIB80211 is not set ++# CONFIG_MAC80211 is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_CONNECTOR is not set ++# CONFIG_MTD is not set ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++# CONFIG_BLK_DEV_XIP is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++# CONFIG_FTSDC010 is not set ++# CONFIG_FTCFC010 is not set ++# CONFIG_BLK_DEV_HD is not set ++# CONFIG_MISC_DEVICES is not set ++CONFIG_HAVE_IDE=y ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++CONFIG_NETDEVICES=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++# CONFIG_VETH is not set ++# CONFIG_PHYLIB is not set ++CONFIG_NET_ETHERNET=y ++# CONFIG_MII is not set ++# CONFIG_SMC91X is not set ++# CONFIG_DNET is not set ++# CONFIG_IBM_NEW_EMAC_ZMII is not set ++# CONFIG_IBM_NEW_EMAC_RGMII is not set ++# CONFIG_IBM_NEW_EMAC_TAH is not set ++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set ++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set ++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set ++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_B44 is not set ++CONFIG_FTMAC100=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++ ++# ++# Wireless LAN ++# ++# CONFIG_WLAN_PRE80211 is not set ++# CONFIG_WLAN_80211 is not set ++# CONFIG_IWLWIFI_LEDS is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_ISDN is not set ++# CONFIG_PHONE is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++# CONFIG_INPUT_EVDEV is not set ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++# CONFIG_INPUT_TOUCHSCREEN is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_DEVKMEM=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_SERIAL_8250_EXTENDED is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=256 ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_GPIO_FTGPIO010 is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_I2C is not set ++# CONFIG_SPI is not set ++# CONFIG_W1 is not set ++# CONFIG_POWER_SUPPLY is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_THERMAL_HWMON is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_REGULATOR is not set ++ ++# ++# Multimedia devices ++# ++ ++# ++# Multimedia core support ++# ++# CONFIG_VIDEO_DEV is not set ++# CONFIG_DVB_CORE is not set ++# CONFIG_VIDEO_MEDIA is not set ++ ++# ++# Multimedia drivers ++# ++# CONFIG_DAB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_VGASTATE is not set ++# CONFIG_VIDEO_OUTPUT_CONTROL is not set ++# CONFIG_FB is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++ ++# ++# Display device support ++# ++# CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Console display driver support ++# ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_DUMMY_CONSOLE=y ++# CONFIG_SOUND is not set ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_RTC_LIB=y ++# CONFIG_RTC_CLASS is not set ++# CONFIG_DMADEVICES is not set ++# CONFIG_UIO is not set ++# CONFIG_STAGING is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++# CONFIG_EXT2_FS_XATTR is not set ++# CONFIG_EXT2_FS_XIP is not set ++# CONFIG_EXT3_FS is not set ++# CONFIG_EXT4_FS is not set ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_FS_POSIX_ACL is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_XFS_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++CONFIG_FUSE_FS=y ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++# CONFIG_MSDOS_FS is not set ++# CONFIG_VFAT_FS is not set ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++# CONFIG_PROC_KCORE is not set ++CONFIG_PROC_SYSCTL=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_HUGETLB_PAGE is not set ++# CONFIG_CONFIGFS_FS is not set ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++# CONFIG_NFS_V4 is not set ++# CONFIG_NFSD is not set ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_RPCSEC_GSS_KRB5 is not set ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++# CONFIG_SMB_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++CONFIG_NLS_ISO8859_1=y ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_ENABLE_MUST_CHECK=y ++CONFIG_FRAME_WARN=1024 ++# CONFIG_MAGIC_SYSRQ is not set ++# CONFIG_UNUSED_SYMBOLS is not set ++CONFIG_DEBUG_FS=y ++# CONFIG_HEADERS_CHECK is not set ++# CONFIG_DEBUG_KERNEL is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_MEMORY_INIT is not set ++CONFIG_FRAME_POINTER=y ++# CONFIG_RCU_CPU_STALL_DETECTOR is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_NOP_TRACER=y ++CONFIG_RING_BUFFER=y ++CONFIG_TRACING=y ++ ++# ++# Tracers ++# ++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++CONFIG_DEBUG_USER=y ++# CONFIG_CCTL is not set ++CONFIG_ELFCHK_DEFAULT_ENABLE=y ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++# CONFIG_SECURITY_FILE_CAPABILITIES is not set ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++# CONFIG_CRYPTO_FIPS is not set ++# CONFIG_CRYPTO_MANAGER is not set ++# CONFIG_CRYPTO_MANAGER2 is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_SEQIV is not set ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_XCBC is not set ++ ++# ++# Digest ++# ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_MD4 is not set ++# CONFIG_CRYPTO_MD5 is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++# CONFIG_CRYPTO_AES is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_LZO is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++ ++# ++# Library routines ++# ++CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++# CONFIG_CRC32 is not set ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++CONFIG_PLIST=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_DMA=y +diff -Nur linux-3.4.110.orig/arch/nds32/configs/xc5_8k_defconfig linux-3.4.110/arch/nds32/configs/xc5_8k_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/xc5_8k_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/xc5_8k_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,1051 @@ ++# ++# Automatically generated make config: don't edit ++# Linux kernel version: 2.6.29 ++# Fri Oct 2 14:21:05 2009 ++# ++CONFIG_NDS32=y ++# CONFIG_GENERIC_GPIO is not set ++CONFIG_NO_IOPORT=y ++CONFIG_GENERIC_IOMAP=y ++CONFIG_RWSEM_GENERIC_SPINLOCK=y ++CONFIG_GENERIC_HWEIGHT=y ++CONFIG_GENERIC_FIND_NEXT_BIT=y ++CONFIG_GENERIC_CALIBRATE_DELAY=y ++CONFIG_GENERIC_HARDIRQS=y ++CONFIG_LOCKDEP_SUPPORT=y ++CONFIG_STACKTRACE_SUPPORT=y ++CONFIG_HAVE_LATENCYTOP_SUPPORT=y ++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" ++ ++# ++# General setup ++# ++CONFIG_EXPERIMENTAL=y ++CONFIG_BROKEN_ON_SMP=y ++CONFIG_INIT_ENV_ARG_LIMIT=32 ++CONFIG_LOCALVERSION="" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SWAP=y ++CONFIG_SYSVIPC=y ++CONFIG_SYSVIPC_SYSCTL=y ++# CONFIG_POSIX_MQUEUE is not set ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++# CONFIG_TASKSTATS is not set ++# CONFIG_AUDIT is not set ++ ++# ++# RCU Subsystem ++# ++CONFIG_CLASSIC_RCU=y ++# CONFIG_TREE_RCU is not set ++# CONFIG_PREEMPT_RCU is not set ++# CONFIG_TREE_RCU_TRACE is not set ++# CONFIG_PREEMPT_RCU_TRACE is not set ++# CONFIG_IKCONFIG is not set ++CONFIG_LOG_BUF_SHIFT=14 ++# CONFIG_GROUP_SCHED is not set ++# CONFIG_CGROUPS is not set ++# CONFIG_SYSFS_DEPRECATED_V2 is not set ++# CONFIG_RELAY is not set ++# CONFIG_NAMESPACES is not set ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="" ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL=y ++CONFIG_ANON_INODES=y ++CONFIG_EMBEDDED=y ++CONFIG_UID16=y ++CONFIG_SYSCTL_SYSCALL=y ++CONFIG_KALLSYMS=y ++# CONFIG_KALLSYMS_ALL is not set ++CONFIG_KALLSYMS_EXTRA_PASS=y ++# CONFIG_HOTPLUG is not set ++CONFIG_PRINTK=y ++CONFIG_BUG=y ++CONFIG_ELF_CORE=y ++CONFIG_BASE_FULL=y ++CONFIG_FUTEX=y ++CONFIG_EPOLL=y ++# CONFIG_SIGNALFD is not set ++CONFIG_TIMERFD=y ++CONFIG_EVENTFD=y ++CONFIG_SHMEM=y ++CONFIG_AIO=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_SLUB_DEBUG=y ++CONFIG_COMPAT_BRK=y ++# CONFIG_SLAB is not set ++CONFIG_SLUB=y ++# CONFIG_SLOB is not set ++CONFIG_PROFILING=y ++CONFIG_TRACEPOINTS=y ++# CONFIG_MARKERS is not set ++CONFIG_OPROFILE=y ++CONFIG_HAVE_OPROFILE=y ++# CONFIG_KPROBES is not set ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set ++CONFIG_SLABINFO=y ++CONFIG_RT_MUTEXES=y ++CONFIG_BASE_SMALL=0 ++CONFIG_MODULES=y ++# CONFIG_MODULE_FORCE_LOAD is not set ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_MODULE_FORCE_UNLOAD is not set ++# CONFIG_MODVERSIONS is not set ++# CONFIG_MODULE_SRCVERSION_ALL is not set ++CONFIG_BLOCK=y ++# CONFIG_LBD is not set ++# CONFIG_BLK_DEV_IO_TRACE is not set ++# CONFIG_BLK_DEV_BSG is not set ++# CONFIG_BLK_DEV_INTEGRITY is not set ++ ++# ++# IO Schedulers ++# ++CONFIG_IOSCHED_NOOP=y ++CONFIG_IOSCHED_AS=y ++CONFIG_IOSCHED_DEADLINE=y ++CONFIG_IOSCHED_CFQ=y ++# CONFIG_DEFAULT_AS is not set ++# CONFIG_DEFAULT_DEADLINE is not set ++CONFIG_DEFAULT_CFQ=y ++# CONFIG_DEFAULT_NOOP is not set ++CONFIG_DEFAULT_IOSCHED="cfq" ++# CONFIG_FREEZER is not set ++ ++# ++# System Type ++# ++# CONFIG_PLAT_VEP is not set ++# CONFIG_PLAT_AG101 is not set ++# CONFIG_PLAT_AG102 is not set ++CONFIG_PLAT_AG101P=y ++# CONFIG_PLAT_QEMU is not set ++CONFIG_PLATFORM_INTC=y ++CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y ++ ++# ++# AG101P Platform Options ++# ++ ++# ++# Common Platform Options ++# ++CONFIG_PLATFORM_AHBDMA=y ++CONFIG_PLATFORM_APBDMA=y ++CONFIG_SYS_CLK=40000000 ++CONFIG_UART_CLK=14745600 ++CONFIG_SDRAM_SIZE=0x10000000 ++ ++# ++# Processor Features ++# ++CONFIG_CPU_CUSTOM=y ++# CONFIG_FPU is not set ++# CONFIG_AUDIO is not set ++# CONFIG_EVIC is not set ++CONFIG_CPU_CONTEXT_ID=y ++# CONFIG_CPU_CACHE_NONALIASING is not set ++# CONFIG_ANDES_PAGE_SIZE_4KB is not set ++CONFIG_ANDES_PAGE_SIZE_8KB=y ++CONFIG_KERNEL_SPACE_LARGE_PAGE=y ++# CONFIG_CPU_ICACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_DISABLE is not set ++# CONFIG_CPU_DCACHE_WRITETHROUGH is not set ++# CONFIG_ABI1 is not set ++CONFIG_ALIGNMENT_TRAP=y ++CONFIG_GENERIC_TIME=y ++CONFIG_GENERIC_CLOCKEVENTS=y ++CONFIG_MMU=y ++ ++# ++# Kernel Features ++# ++# CONFIG_NO_HZ is not set ++# CONFIG_HIGH_RES_TIMERS is not set ++CONFIG_GENERIC_CLOCKEVENTS_BUILD=y ++CONFIG_PREEMPT_NONE=y ++# CONFIG_PREEMPT_VOLUNTARY is not set ++# CONFIG_PREEMPT is not set ++CONFIG_SELECT_MEMORY_MODEL=y ++CONFIG_FLATMEM_MANUAL=y ++# CONFIG_DISCONTIGMEM_MANUAL is not set ++# CONFIG_SPARSEMEM_MANUAL is not set ++CONFIG_FLATMEM=y ++CONFIG_FLAT_NODE_MEM_MAP=y ++CONFIG_PAGEFLAGS_EXTENDED=y ++CONFIG_SPLIT_PTLOCK_CPUS=4 ++# CONFIG_PHYS_ADDR_T_64BIT is not set ++CONFIG_ZONE_DMA_FLAG=0 ++CONFIG_VIRT_TO_BUS=y ++CONFIG_UNEVICTABLE_LRU=y ++CONFIG_FORCE_MAX_ZONEORDER=11 ++CONFIG_HZ_100=y ++# CONFIG_HZ_250 is not set ++# CONFIG_HZ_300 is not set ++# CONFIG_HZ_1000 is not set ++CONFIG_HZ=100 ++# CONFIG_SCHED_HRTICK is not set ++CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" ++ ++# ++# Power management options ++# ++CONFIG_SYS_SUPPORTS_APM_EMULATION=y ++CONFIG_ARCH_SUSPEND_POSSIBLE=y ++# CONFIG_PM is not set ++ ++# ++# Bus options ++# ++# CONFIG_PCI is not set ++# CONFIG_ARCH_SUPPORTS_MSI is not set ++ ++# ++# Executable file formats ++# ++CONFIG_BINFMT_ELF=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++# CONFIG_HAVE_AOUT is not set ++# CONFIG_BINFMT_MISC is not set ++CONFIG_NET=y ++ ++# ++# Networking options ++# ++CONFIG_COMPAT_NET_DEV_OPS=y ++CONFIG_PACKET=y ++# CONFIG_PACKET_MMAP is not set ++CONFIG_UNIX=y ++CONFIG_XFRM=y ++# CONFIG_XFRM_USER is not set ++# CONFIG_XFRM_SUB_POLICY is not set ++# CONFIG_XFRM_MIGRATE is not set ++# CONFIG_XFRM_STATISTICS is not set ++CONFIG_NET_KEY=y ++# CONFIG_NET_KEY_MIGRATE is not set ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_IP_ADVANCED_ROUTER is not set ++CONFIG_IP_FIB_HASH=y ++# CONFIG_IP_PNP is not set ++# CONFIG_NET_IPIP is not set ++# CONFIG_NET_IPGRE is not set ++# CONFIG_IP_MROUTE is not set ++# CONFIG_ARPD is not set ++# CONFIG_SYN_COOKIES is not set ++# CONFIG_INET_AH is not set ++# CONFIG_INET_ESP is not set ++# CONFIG_INET_IPCOMP is not set ++# CONFIG_INET_XFRM_TUNNEL is not set ++# CONFIG_INET_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_TCP_CONG_ADVANCED is not set ++CONFIG_TCP_CONG_CUBIC=y ++CONFIG_DEFAULT_TCP_CONG="cubic" ++# CONFIG_TCP_MD5SIG is not set ++# CONFIG_IPV6 is not set ++# CONFIG_NETWORK_SECMARK is not set ++# CONFIG_NETFILTER is not set ++# CONFIG_IP_DCCP is not set ++# CONFIG_IP_SCTP is not set ++# CONFIG_TIPC is not set ++# CONFIG_ATM is not set ++# CONFIG_BRIDGE is not set ++# CONFIG_NET_DSA is not set ++# CONFIG_VLAN_8021Q is not set ++# CONFIG_DECNET is not set ++# CONFIG_LLC2 is not set ++# CONFIG_IPX is not set ++# CONFIG_ATALK is not set ++# CONFIG_X25 is not set ++# CONFIG_LAPB is not set ++# CONFIG_ECONET is not set ++# CONFIG_WAN_ROUTER is not set ++# CONFIG_NET_SCHED is not set ++# CONFIG_DCB is not set ++ ++# ++# Network testing ++# ++# CONFIG_NET_PKTGEN is not set ++# CONFIG_HAMRADIO is not set ++# CONFIG_CAN is not set ++# CONFIG_IRDA is not set ++# CONFIG_BT is not set ++# CONFIG_AF_RXRPC is not set ++# CONFIG_PHONET is not set ++CONFIG_WIRELESS=y ++# CONFIG_CFG80211 is not set ++CONFIG_WIRELESS_OLD_REGULATORY=y ++# CONFIG_WIRELESS_EXT is not set ++# CONFIG_LIB80211 is not set ++# CONFIG_MAC80211 is not set ++# CONFIG_WIMAX is not set ++# CONFIG_RFKILL is not set ++# CONFIG_NET_9P is not set ++ ++# ++# Device Drivers ++# ++ ++# ++# Generic Driver Options ++# ++CONFIG_STANDALONE=y ++CONFIG_PREVENT_FIRMWARE_BUILD=y ++# CONFIG_DEBUG_DRIVER is not set ++# CONFIG_DEBUG_DEVRES is not set ++# CONFIG_SYS_HYPERVISOR is not set ++# CONFIG_CONNECTOR is not set ++CONFIG_MTD=y ++# CONFIG_MTD_DEBUG is not set ++# CONFIG_MTD_CONCAT is not set ++CONFIG_MTD_PARTITIONS=y ++# CONFIG_MTD_TESTS is not set ++# CONFIG_MTD_REDBOOT_PARTS is not set ++CONFIG_MTD_CMDLINE_PARTS=y ++# CONFIG_MTD_AR7_PARTS is not set ++ ++# ++# User Modules And Translation Layers ++# ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLKDEVS=y ++CONFIG_MTD_BLOCK=y ++# CONFIG_FTL is not set ++# CONFIG_NFTL is not set ++# CONFIG_INFTL is not set ++# CONFIG_RFD_FTL is not set ++# CONFIG_SSFDC is not set ++# CONFIG_MTD_OOPS is not set ++ ++# ++# RAM/ROM/Flash chip drivers ++# ++CONFIG_MTD_CFI=y ++# CONFIG_MTD_JEDECPROBE is not set ++CONFIG_MTD_GEN_PROBE=y ++# CONFIG_MTD_CFI_ADV_OPTIONS is not set ++CONFIG_MTD_MAP_BANK_WIDTH_1=y ++CONFIG_MTD_MAP_BANK_WIDTH_2=y ++CONFIG_MTD_MAP_BANK_WIDTH_4=y ++# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set ++# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set ++CONFIG_MTD_CFI_I1=y ++CONFIG_MTD_CFI_I2=y ++# CONFIG_MTD_CFI_I4 is not set ++# CONFIG_MTD_CFI_I8 is not set ++CONFIG_MTD_CFI_INTELEXT=y ++# CONFIG_MTD_CFI_AMDSTD is not set ++# CONFIG_MTD_CFI_STAA is not set ++CONFIG_MTD_CFI_UTIL=y ++# CONFIG_MTD_RAM is not set ++# CONFIG_MTD_ROM is not set ++# CONFIG_MTD_ABSENT is not set ++ ++# ++# Mapping drivers for chip access ++# ++# CONFIG_MTD_COMPLEX_MAPPINGS is not set ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_COMPAT=y ++CONFIG_MTD_PHYSMAP_START=0x80400000 ++CONFIG_MTD_PHYSMAP_LEN=0x2000000 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=4 ++# CONFIG_MTD_PLATRAM is not set ++ ++# ++# Self-contained MTD device drivers ++# ++# CONFIG_MTD_SLRAM is not set ++# CONFIG_MTD_PHRAM is not set ++# CONFIG_MTD_MTDRAM is not set ++# CONFIG_MTD_BLOCK2MTD is not set ++ ++# ++# Disk-On-Chip Device Drivers ++# ++# CONFIG_MTD_DOC2000 is not set ++# CONFIG_MTD_DOC2001 is not set ++# CONFIG_MTD_DOC2001PLUS is not set ++# CONFIG_MTD_NAND is not set ++# CONFIG_MTD_ONENAND is not set ++ ++# ++# LPDDR flash memory drivers ++# ++# CONFIG_MTD_LPDDR is not set ++ ++# ++# UBI - Unsorted block images ++# ++# CONFIG_MTD_UBI is not set ++# CONFIG_PARPORT is not set ++CONFIG_BLK_DEV=y ++# CONFIG_BLK_DEV_COW_COMMON is not set ++CONFIG_BLK_DEV_LOOP=y ++# CONFIG_BLK_DEV_CRYPTOLOOP is not set ++# CONFIG_BLK_DEV_NBD is not set ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=16 ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++# CONFIG_BLK_DEV_XIP is not set ++# CONFIG_CDROM_PKTCDVD is not set ++# CONFIG_ATA_OVER_ETH is not set ++CONFIG_FTSDC010=y ++# CONFIG_FTCFC010 is not set ++# CONFIG_BLK_DEV_HD is not set ++# CONFIG_MISC_DEVICES is not set ++CONFIG_HAVE_IDE=y ++# CONFIG_IDE is not set ++ ++# ++# SCSI device support ++# ++# CONFIG_RAID_ATTRS is not set ++# CONFIG_SCSI is not set ++# CONFIG_SCSI_DMA is not set ++# CONFIG_SCSI_NETLINK is not set ++# CONFIG_ATA is not set ++# CONFIG_MD is not set ++CONFIG_NETDEVICES=y ++# CONFIG_DUMMY is not set ++# CONFIG_BONDING is not set ++# CONFIG_MACVLAN is not set ++# CONFIG_EQUALIZER is not set ++# CONFIG_TUN is not set ++# CONFIG_VETH is not set ++# CONFIG_PHYLIB is not set ++CONFIG_NET_ETHERNET=y ++# CONFIG_MII is not set ++# CONFIG_SMC91X is not set ++# CONFIG_DNET is not set ++# CONFIG_IBM_NEW_EMAC_ZMII is not set ++# CONFIG_IBM_NEW_EMAC_RGMII is not set ++# CONFIG_IBM_NEW_EMAC_TAH is not set ++# CONFIG_IBM_NEW_EMAC_EMAC4 is not set ++# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set ++# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set ++# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set ++# CONFIG_B44 is not set ++CONFIG_FTMAC100=y ++# CONFIG_NETDEV_1000 is not set ++# CONFIG_NETDEV_10000 is not set ++ ++# ++# Wireless LAN ++# ++# CONFIG_WLAN_PRE80211 is not set ++# CONFIG_WLAN_80211 is not set ++# CONFIG_IWLWIFI_LEDS is not set ++ ++# ++# Enable WiMAX (Networking options) to see the WiMAX drivers ++# ++# CONFIG_WAN is not set ++# CONFIG_PPP is not set ++# CONFIG_SLIP is not set ++# CONFIG_NETCONSOLE is not set ++# CONFIG_NETPOLL is not set ++# CONFIG_NET_POLL_CONTROLLER is not set ++# CONFIG_ISDN is not set ++# CONFIG_PHONE is not set ++ ++# ++# Input device support ++# ++CONFIG_INPUT=y ++# CONFIG_INPUT_FF_MEMLESS is not set ++# CONFIG_INPUT_POLLDEV is not set ++ ++# ++# Userland interfaces ++# ++# CONFIG_INPUT_MOUSEDEV is not set ++# CONFIG_INPUT_JOYDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_EVBUG is not set ++ ++# ++# Input Device Drivers ++# ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_INPUT_JOYSTICK is not set ++# CONFIG_INPUT_TABLET is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++CONFIG_TOUCHSCREEN_CPE_TS=y ++CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER=y ++# CONFIG_TOUCHSCREEN_FUJITSU is not set ++# CONFIG_TOUCHSCREEN_GUNZE is not set ++# CONFIG_TOUCHSCREEN_ELO is not set ++# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set ++# CONFIG_TOUCHSCREEN_MTOUCH is not set ++# CONFIG_TOUCHSCREEN_INEXIO is not set ++# CONFIG_TOUCHSCREEN_MK712 is not set ++# CONFIG_TOUCHSCREEN_PENMOUNT is not set ++# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set ++# CONFIG_TOUCHSCREEN_TOUCHWIN is not set ++# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set ++# CONFIG_INPUT_MISC is not set ++ ++# ++# Hardware I/O ports ++# ++# CONFIG_SERIO is not set ++# CONFIG_GAMEPORT is not set ++ ++# ++# Character devices ++# ++CONFIG_VT=y ++CONFIG_CONSOLE_TRANSLATIONS=y ++CONFIG_VT_CONSOLE=y ++CONFIG_HW_CONSOLE=y ++# CONFIG_VT_HW_CONSOLE_BINDING is not set ++CONFIG_DEVKMEM=y ++# CONFIG_SERIAL_NONSTANDARD is not set ++ ++# ++# Serial drivers ++# ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_SERIAL_8250_EXTENDED is not set ++ ++# ++# Non-8250 serial port support ++# ++CONFIG_SERIAL_CORE=y ++CONFIG_SERIAL_CORE_CONSOLE=y ++CONFIG_UNIX98_PTYS=y ++# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set ++CONFIG_LEGACY_PTYS=y ++CONFIG_LEGACY_PTY_COUNT=256 ++# CONFIG_IPMI_HANDLER is not set ++# CONFIG_HW_RANDOM is not set ++# CONFIG_R3964 is not set ++# CONFIG_GPIO_FTGPIO010_OLD is not set ++# CONFIG_RAW_DRIVER is not set ++# CONFIG_TCG_TPM is not set ++# CONFIG_I2C is not set ++# CONFIG_SPI is not set ++# CONFIG_GPIOLIB is not set ++# CONFIG_W1 is not set ++# CONFIG_POWER_SUPPLY is not set ++# CONFIG_HWMON is not set ++# CONFIG_THERMAL is not set ++# CONFIG_THERMAL_HWMON is not set ++# CONFIG_WATCHDOG is not set ++CONFIG_SSB_POSSIBLE=y ++ ++# ++# Sonics Silicon Backplane ++# ++# CONFIG_SSB is not set ++ ++# ++# Multifunction device drivers ++# ++# CONFIG_MFD_CORE is not set ++# CONFIG_MFD_SM501 is not set ++# CONFIG_HTC_PASIC3 is not set ++# CONFIG_MFD_TMIO is not set ++# CONFIG_REGULATOR is not set ++ ++# ++# Multimedia devices ++# ++ ++# ++# Multimedia core support ++# ++# CONFIG_VIDEO_DEV is not set ++# CONFIG_DVB_CORE is not set ++# CONFIG_VIDEO_MEDIA is not set ++ ++# ++# Multimedia drivers ++# ++# CONFIG_DAB is not set ++ ++# ++# Graphics support ++# ++# CONFIG_VGASTATE is not set ++# CONFIG_VIDEO_OUTPUT_CONTROL is not set ++CONFIG_FB=y ++# CONFIG_FIRMWARE_EDID is not set ++# CONFIG_FB_DDC is not set ++# CONFIG_FB_BOOT_VESA_SUPPORT is not set ++CONFIG_FB_CFB_FILLRECT=y ++CONFIG_FB_CFB_COPYAREA=y ++CONFIG_FB_CFB_IMAGEBLIT=y ++# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set ++# CONFIG_FB_SYS_FILLRECT is not set ++# CONFIG_FB_SYS_COPYAREA is not set ++# CONFIG_FB_SYS_IMAGEBLIT is not set ++# CONFIG_FB_FOREIGN_ENDIAN is not set ++# CONFIG_FB_SYS_FOPS is not set ++# CONFIG_FB_SVGALIB is not set ++# CONFIG_FB_MACMODES is not set ++# CONFIG_FB_BACKLIGHT is not set ++# CONFIG_FB_MODE_HELPERS is not set ++# CONFIG_FB_TILEBLITTING is not set ++ ++# ++# Frame buffer hardware drivers ++# ++# CONFIG_FB_S1D13XXX is not set ++CONFIG_FB_FTLCDC100=y ++CONFIG_PANEL_AUA036QN01=y ++# CONFIG_PANEL_CH7013A is not set ++# CONFIG_PANEL_AUA070VW04 is not set ++# CONFIG_PANEL_LW500AC9601 is not set ++CONFIG_FFB_MODE_RGB=y ++# CONFIG_FFB_MODE_YUV422 is not set ++# CONFIG_FFB_MODE_YUV420 is not set ++# CONFIG_FFB_MODE_8BPP is not set ++CONFIG_FFB_MODE_16BPP=y ++# CONFIG_FFB_MODE_24BPP is not set ++# CONFIG_FB_VIRTUAL is not set ++# CONFIG_FB_METRONOME is not set ++# CONFIG_FB_MB862XX is not set ++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set ++ ++# ++# Display device support ++# ++# CONFIG_DISPLAY_SUPPORT is not set ++ ++# ++# Console display driver support ++# ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_DUMMY_CONSOLE=y ++CONFIG_FRAMEBUFFER_CONSOLE=y ++# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set ++# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set ++# CONFIG_FONTS is not set ++CONFIG_FONT_8x8=y ++CONFIG_FONT_8x16=y ++CONFIG_LOGO=y ++CONFIG_LOGO_LINUX_MONO=y ++CONFIG_LOGO_LINUX_VGA16=y ++CONFIG_LOGO_LINUX_CLUT224=y ++CONFIG_SOUND=y ++CONFIG_SOUND_OSS_CORE=y ++CONFIG_SND=y ++CONFIG_SND_TIMER=y ++CONFIG_SND_PCM=y ++# CONFIG_SND_SEQUENCER is not set ++CONFIG_SND_OSSEMUL=y ++# CONFIG_SND_MIXER_OSS is not set ++CONFIG_SND_PCM_OSS=y ++CONFIG_SND_PCM_OSS_PLUGINS=y ++# CONFIG_SND_DYNAMIC_MINORS is not set ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_SND_VERBOSE_PRINTK is not set ++# CONFIG_SND_DEBUG is not set ++CONFIG_SND_DRIVERS=y ++# CONFIG_SND_DUMMY is not set ++# CONFIG_SND_MTPAV is not set ++# CONFIG_SND_SERIAL_U16550 is not set ++# CONFIG_SND_MPU401 is not set ++ ++# ++# ALSA NDS32 devices ++# ++CONFIG_SND_FTSSP010=y ++CONFIG_SND_FTSSP010_AC97=y ++# CONFIG_SND_FTSSP010_I2S is not set ++# CONFIG_SND_SOC is not set ++# CONFIG_SOUND_PRIME is not set ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++# CONFIG_MMC is not set ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++# CONFIG_RTC_DEBUG is not set ++ ++# ++# RTC interfaces ++# ++CONFIG_RTC_INTF_SYSFS=y ++CONFIG_RTC_INTF_PROC=y ++CONFIG_RTC_INTF_DEV=y ++# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set ++# CONFIG_RTC_DRV_TEST is not set ++ ++# ++# SPI RTC drivers ++# ++ ++# ++# Platform RTC drivers ++# ++# CONFIG_RTC_DRV_DS1286 is not set ++# CONFIG_RTC_DRV_DS1511 is not set ++# CONFIG_RTC_DRV_DS1553 is not set ++# CONFIG_RTC_DRV_DS1742 is not set ++# CONFIG_RTC_DRV_STK17TA8 is not set ++# CONFIG_RTC_DRV_M48T86 is not set ++# CONFIG_RTC_DRV_M48T35 is not set ++# CONFIG_RTC_DRV_M48T59 is not set ++# CONFIG_RTC_DRV_BQ4802 is not set ++# CONFIG_RTC_DRV_V3020 is not set ++ ++# ++# on-CPU RTC drivers ++# ++CONFIG_RTC_DRV_FTRTC010=y ++# CONFIG_DMADEVICES is not set ++# CONFIG_UIO is not set ++# CONFIG_STAGING is not set ++ ++# ++# File systems ++# ++CONFIG_EXT2_FS=y ++# CONFIG_EXT2_FS_XATTR is not set ++# CONFIG_EXT2_FS_XIP is not set ++# CONFIG_EXT3_FS is not set ++# CONFIG_EXT4_FS is not set ++# CONFIG_REISERFS_FS is not set ++# CONFIG_JFS_FS is not set ++# CONFIG_FS_POSIX_ACL is not set ++CONFIG_FILE_LOCKING=y ++# CONFIG_XFS_FS is not set ++# CONFIG_OCFS2_FS is not set ++# CONFIG_BTRFS_FS is not set ++CONFIG_DNOTIFY=y ++CONFIG_INOTIFY=y ++CONFIG_INOTIFY_USER=y ++# CONFIG_QUOTA is not set ++# CONFIG_AUTOFS_FS is not set ++# CONFIG_AUTOFS4_FS is not set ++CONFIG_FUSE_FS=y ++ ++# ++# CD-ROM/DVD Filesystems ++# ++# CONFIG_ISO9660_FS is not set ++# CONFIG_UDF_FS is not set ++ ++# ++# DOS/FAT/NT Filesystems ++# ++CONFIG_FAT_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_FAT_DEFAULT_CODEPAGE=437 ++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" ++# CONFIG_NTFS_FS is not set ++ ++# ++# Pseudo filesystems ++# ++CONFIG_PROC_FS=y ++# CONFIG_PROC_KCORE is not set ++CONFIG_PROC_SYSCTL=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_SYSFS=y ++CONFIG_TMPFS=y ++# CONFIG_TMPFS_POSIX_ACL is not set ++# CONFIG_HUGETLB_PAGE is not set ++# CONFIG_CONFIGFS_FS is not set ++CONFIG_MISC_FILESYSTEMS=y ++# CONFIG_ADFS_FS is not set ++# CONFIG_AFFS_FS is not set ++# CONFIG_HFS_FS is not set ++# CONFIG_HFSPLUS_FS is not set ++# CONFIG_BEFS_FS is not set ++# CONFIG_BFS_FS is not set ++# CONFIG_EFS_FS is not set ++CONFIG_JFFS2_FS=y ++CONFIG_JFFS2_FS_DEBUG=0 ++CONFIG_JFFS2_FS_WRITEBUFFER=y ++# CONFIG_JFFS2_FS_WBUF_VERIFY is not set ++# CONFIG_JFFS2_SUMMARY is not set ++# CONFIG_JFFS2_FS_XATTR is not set ++# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set ++CONFIG_JFFS2_ZLIB=y ++# CONFIG_JFFS2_LZO is not set ++CONFIG_JFFS2_RTIME=y ++# CONFIG_JFFS2_RUBIN is not set ++# CONFIG_CRAMFS is not set ++# CONFIG_SQUASHFS is not set ++# CONFIG_VXFS_FS is not set ++# CONFIG_MINIX_FS is not set ++# CONFIG_OMFS_FS is not set ++# CONFIG_HPFS_FS is not set ++# CONFIG_QNX4FS_FS is not set ++# CONFIG_ROMFS_FS is not set ++# CONFIG_SYSV_FS is not set ++# CONFIG_UFS_FS is not set ++CONFIG_NETWORK_FILESYSTEMS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++# CONFIG_NFS_V3_ACL is not set ++# CONFIG_NFS_V4 is not set ++# CONFIG_NFSD is not set ++CONFIG_LOCKD=y ++CONFIG_LOCKD_V4=y ++CONFIG_NFS_COMMON=y ++CONFIG_SUNRPC=y ++# CONFIG_SUNRPC_REGISTER_V4 is not set ++# CONFIG_RPCSEC_GSS_KRB5 is not set ++# CONFIG_RPCSEC_GSS_SPKM3 is not set ++# CONFIG_SMB_FS is not set ++# CONFIG_CIFS is not set ++# CONFIG_NCP_FS is not set ++# CONFIG_CODA_FS is not set ++# CONFIG_AFS_FS is not set ++ ++# ++# Partition Types ++# ++# CONFIG_PARTITION_ADVANCED is not set ++CONFIG_MSDOS_PARTITION=y ++CONFIG_NLS=y ++CONFIG_NLS_DEFAULT="iso8859-1" ++CONFIG_NLS_CODEPAGE_437=y ++# CONFIG_NLS_CODEPAGE_737 is not set ++# CONFIG_NLS_CODEPAGE_775 is not set ++# CONFIG_NLS_CODEPAGE_850 is not set ++# CONFIG_NLS_CODEPAGE_852 is not set ++# CONFIG_NLS_CODEPAGE_855 is not set ++# CONFIG_NLS_CODEPAGE_857 is not set ++# CONFIG_NLS_CODEPAGE_860 is not set ++# CONFIG_NLS_CODEPAGE_861 is not set ++# CONFIG_NLS_CODEPAGE_862 is not set ++# CONFIG_NLS_CODEPAGE_863 is not set ++# CONFIG_NLS_CODEPAGE_864 is not set ++# CONFIG_NLS_CODEPAGE_865 is not set ++# CONFIG_NLS_CODEPAGE_866 is not set ++# CONFIG_NLS_CODEPAGE_869 is not set ++# CONFIG_NLS_CODEPAGE_936 is not set ++# CONFIG_NLS_CODEPAGE_950 is not set ++# CONFIG_NLS_CODEPAGE_932 is not set ++# CONFIG_NLS_CODEPAGE_949 is not set ++# CONFIG_NLS_CODEPAGE_874 is not set ++# CONFIG_NLS_ISO8859_8 is not set ++# CONFIG_NLS_CODEPAGE_1250 is not set ++# CONFIG_NLS_CODEPAGE_1251 is not set ++# CONFIG_NLS_ASCII is not set ++CONFIG_NLS_ISO8859_1=y ++# CONFIG_NLS_ISO8859_2 is not set ++# CONFIG_NLS_ISO8859_3 is not set ++# CONFIG_NLS_ISO8859_4 is not set ++# CONFIG_NLS_ISO8859_5 is not set ++# CONFIG_NLS_ISO8859_6 is not set ++# CONFIG_NLS_ISO8859_7 is not set ++# CONFIG_NLS_ISO8859_9 is not set ++# CONFIG_NLS_ISO8859_13 is not set ++# CONFIG_NLS_ISO8859_14 is not set ++# CONFIG_NLS_ISO8859_15 is not set ++# CONFIG_NLS_KOI8_R is not set ++# CONFIG_NLS_KOI8_U is not set ++# CONFIG_NLS_UTF8 is not set ++# CONFIG_DLM is not set ++ ++# ++# Kernel hacking ++# ++CONFIG_TRACE_IRQFLAGS_SUPPORT=y ++# CONFIG_PRINTK_TIME is not set ++CONFIG_ENABLE_WARN_DEPRECATED=y ++CONFIG_ENABLE_MUST_CHECK=y ++CONFIG_FRAME_WARN=1024 ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_UNUSED_SYMBOLS is not set ++CONFIG_DEBUG_FS=y ++# CONFIG_HEADERS_CHECK is not set ++CONFIG_DEBUG_KERNEL=y ++CONFIG_DEBUG_SHIRQ=y ++CONFIG_DETECT_SOFTLOCKUP=y ++# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 ++CONFIG_SCHED_DEBUG=y ++CONFIG_SCHEDSTATS=y ++CONFIG_TIMER_STATS=y ++# CONFIG_DEBUG_OBJECTS is not set ++# CONFIG_SLUB_DEBUG_ON is not set ++# CONFIG_SLUB_STATS is not set ++CONFIG_DEBUG_RT_MUTEXES=y ++CONFIG_DEBUG_PI_LIST=y ++# CONFIG_RT_MUTEX_TESTER is not set ++CONFIG_DEBUG_SPINLOCK=y ++CONFIG_DEBUG_MUTEXES=y ++# CONFIG_DEBUG_LOCK_ALLOC is not set ++# CONFIG_PROVE_LOCKING is not set ++# CONFIG_LOCK_STAT is not set ++CONFIG_DEBUG_SPINLOCK_SLEEP=y ++# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set ++CONFIG_STACKTRACE=y ++# CONFIG_DEBUG_KOBJECT is not set ++CONFIG_DEBUG_INFO=y ++# CONFIG_DEBUG_VM is not set ++# CONFIG_DEBUG_WRITECOUNT is not set ++# CONFIG_DEBUG_MEMORY_INIT is not set ++CONFIG_DEBUG_LIST=y ++CONFIG_DEBUG_SG=y ++# CONFIG_DEBUG_NOTIFIERS is not set ++CONFIG_FRAME_POINTER=y ++# CONFIG_BOOT_PRINTK_DELAY is not set ++# CONFIG_RCU_TORTURE_TEST is not set ++# CONFIG_RCU_CPU_STALL_DETECTOR is not set ++# CONFIG_BACKTRACE_SELF_TEST is not set ++# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set ++# CONFIG_FAULT_INJECTION is not set ++# CONFIG_LATENCYTOP is not set ++CONFIG_SYSCTL_SYSCALL_CHECK=y ++CONFIG_NOP_TRACER=y ++CONFIG_RING_BUFFER=y ++CONFIG_TRACING=y ++ ++# ++# Tracers ++# ++# CONFIG_IRQSOFF_TRACER is not set ++# CONFIG_SCHED_TRACER is not set ++# CONFIG_CONTEXT_SWITCH_TRACER is not set ++# CONFIG_BOOT_TRACER is not set ++# CONFIG_TRACE_BRANCH_PROFILING is not set ++# CONFIG_FTRACE_STARTUP_TEST is not set ++# CONFIG_DYNAMIC_PRINTK_DEBUG is not set ++# CONFIG_SAMPLES is not set ++CONFIG_HAVE_ARCH_KGDB=y ++# CONFIG_KGDB is not set ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_DEBUG_LL is not set ++# CONFIG_CCTL is not set ++# CONFIG_ELFCHK_DEFAULT_ENABLE is not set ++ ++# ++# Security options ++# ++# CONFIG_KEYS is not set ++# CONFIG_SECURITY is not set ++# CONFIG_SECURITYFS is not set ++# CONFIG_SECURITY_FILE_CAPABILITIES is not set ++CONFIG_CRYPTO=y ++ ++# ++# Crypto core or helper ++# ++# CONFIG_CRYPTO_FIPS is not set ++# CONFIG_CRYPTO_MANAGER is not set ++# CONFIG_CRYPTO_MANAGER2 is not set ++# CONFIG_CRYPTO_GF128MUL is not set ++# CONFIG_CRYPTO_NULL is not set ++# CONFIG_CRYPTO_CRYPTD is not set ++# CONFIG_CRYPTO_AUTHENC is not set ++# CONFIG_CRYPTO_TEST is not set ++ ++# ++# Authenticated Encryption with Associated Data ++# ++# CONFIG_CRYPTO_CCM is not set ++# CONFIG_CRYPTO_GCM is not set ++# CONFIG_CRYPTO_SEQIV is not set ++ ++# ++# Block modes ++# ++# CONFIG_CRYPTO_CBC is not set ++# CONFIG_CRYPTO_CTR is not set ++# CONFIG_CRYPTO_CTS is not set ++# CONFIG_CRYPTO_ECB is not set ++# CONFIG_CRYPTO_LRW is not set ++# CONFIG_CRYPTO_PCBC is not set ++# CONFIG_CRYPTO_XTS is not set ++ ++# ++# Hash modes ++# ++# CONFIG_CRYPTO_HMAC is not set ++# CONFIG_CRYPTO_XCBC is not set ++ ++# ++# Digest ++# ++# CONFIG_CRYPTO_CRC32C is not set ++# CONFIG_CRYPTO_MD4 is not set ++# CONFIG_CRYPTO_MD5 is not set ++# CONFIG_CRYPTO_MICHAEL_MIC is not set ++# CONFIG_CRYPTO_RMD128 is not set ++# CONFIG_CRYPTO_RMD160 is not set ++# CONFIG_CRYPTO_RMD256 is not set ++# CONFIG_CRYPTO_RMD320 is not set ++# CONFIG_CRYPTO_SHA1 is not set ++# CONFIG_CRYPTO_SHA256 is not set ++# CONFIG_CRYPTO_SHA512 is not set ++# CONFIG_CRYPTO_TGR192 is not set ++# CONFIG_CRYPTO_WP512 is not set ++ ++# ++# Ciphers ++# ++# CONFIG_CRYPTO_AES is not set ++# CONFIG_CRYPTO_ANUBIS is not set ++# CONFIG_CRYPTO_ARC4 is not set ++# CONFIG_CRYPTO_BLOWFISH is not set ++# CONFIG_CRYPTO_CAMELLIA is not set ++# CONFIG_CRYPTO_CAST5 is not set ++# CONFIG_CRYPTO_CAST6 is not set ++# CONFIG_CRYPTO_DES is not set ++# CONFIG_CRYPTO_FCRYPT is not set ++# CONFIG_CRYPTO_KHAZAD is not set ++# CONFIG_CRYPTO_SALSA20 is not set ++# CONFIG_CRYPTO_SEED is not set ++# CONFIG_CRYPTO_SERPENT is not set ++# CONFIG_CRYPTO_TEA is not set ++# CONFIG_CRYPTO_TWOFISH is not set ++ ++# ++# Compression ++# ++# CONFIG_CRYPTO_DEFLATE is not set ++# CONFIG_CRYPTO_LZO is not set ++ ++# ++# Random Number Generation ++# ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set ++ ++# ++# Library routines ++# ++CONFIG_BITREVERSE=y ++CONFIG_GENERIC_FIND_LAST_BIT=y ++# CONFIG_CRC_CCITT is not set ++# CONFIG_CRC16 is not set ++# CONFIG_CRC_T10DIF is not set ++# CONFIG_CRC_ITU_T is not set ++CONFIG_CRC32=y ++# CONFIG_CRC7 is not set ++# CONFIG_LIBCRC32C is not set ++CONFIG_ZLIB_INFLATE=y ++CONFIG_ZLIB_DEFLATE=y ++CONFIG_PLIST=y ++CONFIG_HAS_IOMEM=y ++CONFIG_HAS_DMA=y +diff -Nur linux-3.4.110.orig/arch/nds32/configs/xc5_defconfig linux-3.4.110/arch/nds32/configs/xc5_defconfig +--- linux-3.4.110.orig/arch/nds32/configs/xc5_defconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/configs/xc5_defconfig 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,117 @@ ++CONFIG_EXPERIMENTAL=y ++CONFIG_CROSS_COMPILE="nds32le-linux-" ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_BSD_PROCESS_ACCT=y ++CONFIG_BSD_PROCESS_ACCT_V3=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=14 ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="/home/users/greentime/os/ramdisk/disk-nds32le-linux-glibc-v3 /home/users/greentime/os/ramdisk/disk-nds32le-linux-glibc-v3/dev/initramfs.devnodes" ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_HOTPLUG is not set ++# CONFIG_SIGNALFD is not set ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_PROFILING=y ++CONFIG_OPROFILE=y ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_PLATFORM_AHBDMA=y ++CONFIG_PLATFORM_APBDMA=y ++CONFIG_SYS_CLK=30000000 ++CONFIG_UART_CLK=14745600 ++CONFIG_SDRAM_SIZE=0x8000000 ++CONFIG_HZ_100=y ++CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0x99600000 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_NET_KEY=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET_XFRM_MODE_BEET is not set ++# CONFIG_INET_LRO is not set ++# CONFIG_INET_DIAG is not set ++# CONFIG_IPV6 is not set ++CONFIG_BRIDGE=y ++CONFIG_MTD=y ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_CHAR=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_PHYSMAP=y ++CONFIG_MTD_PHYSMAP_COMPAT=y ++CONFIG_MTD_PHYSMAP_START=0x80400000 ++CONFIG_MTD_PHYSMAP_LEN=0x2000000 ++CONFIG_MTD_PHYSMAP_BANKWIDTH=4 ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_NETDEVICES=y ++CONFIG_TUN=y ++CONFIG_FTMAC100=y ++# CONFIG_INPUT_MOUSEDEV is not set ++CONFIG_INPUT_EVDEV=y ++# CONFIG_INPUT_KEYBOARD is not set ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_INPUT_TOUCHSCREEN=y ++# CONFIG_SERIO is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=3 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=3 ++# CONFIG_HW_RANDOM is not set ++# CONFIG_HWMON is not set ++CONFIG_FB=y ++# CONFIG_VGA_CONSOLE is not set ++CONFIG_FRAMEBUFFER_CONSOLE=y ++CONFIG_LOGO=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_PCM_OSS=y ++# CONFIG_SND_SUPPORT_OLD_API is not set ++# CONFIG_SND_VERBOSE_PROCFS is not set ++# CONFIG_HID_SUPPORT is not set ++# CONFIG_USB_SUPPORT is not set ++CONFIG_MMC=y ++CONFIG_MMC_FTSDC010=y ++# CONFIG_MEMSTICK is not set ++# CONFIG_NEW_LEDS is not set ++# CONFIG_ACCESSIBILITY is not set ++CONFIG_RTC_LIB=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_HCTOSYS is not set ++CONFIG_EXT2_FS=y ++CONFIG_FUSE_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_TMPFS=y ++CONFIG_JFFS2_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_DEBUG_FS=y ++CONFIG_DEBUG_SHIRQ=y ++CONFIG_SCHEDSTATS=y ++CONFIG_TIMER_STATS=y ++CONFIG_DEBUG_RT_MUTEXES=y ++CONFIG_DEBUG_SPINLOCK=y ++CONFIG_DEBUG_MUTEXES=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_LIST=y ++CONFIG_DEBUG_SG=y ++CONFIG_DEBUG_USER=y ++CONFIG_DEBUG_ERRORS=y ++# CONFIG_CRYPTO_ANSI_CPRNG is not set ++# CONFIG_CRYPTO_HW is not set +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/amic.h linux-3.4.110/arch/nds32/include/asm/amic.h +--- linux-3.4.110.orig/arch/nds32/include/asm/amic.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/amic.h 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,60 @@ ++/* ++ * linux/arch/nds32/include/asm/amic.h ++ * ++ * Andes Multi-core Interrupt Controller Device Driver Interface ++ * ++ * Copyright (C) 2010 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Shawn Lin 09/02/2010 Created for Andes AG102 platform code. ++ */ ++ ++#ifndef __NDS32_AMIC_HEADER__ ++#define __NDS32_AMIC_HEADER__ ++ ++#define IRQ_BASE 0x0 ++#define IRQ_TOTAL 0x20 ++#define DEFAULT_MODE 0x000ecc00 ++#define DEFAULT_LEVEL 0xffffffff ++#define AMIC_BASE AMIC_VA_BASE ++#define CONFIG 0x00 ++#define CPUDC 0x04 ++#define CPUID0 0x08 ++#define CPUID1 0x0c ++#define INTTRG 0x20 ++#define INTLVL 0x24 ++#define INTSRC 0x28 ++#define IPITRG 0x40 ++#define IPISTA 0x44 ++#define IPIPTR 0x48 ++#define IPIGST 0x4c ++#define IPIGPT 0x50 ++#define INTEN 0x80 ++#define INTSTA 0x84 ++#define HW0STA 0x88 ++#define HW1STA 0x8c ++#define HW2STA 0x90 ++#define HW3STA 0x94 ++#define HW4STA 0x98 ++#define HW5STA 0x9c ++#define PRITY0 0xa0 ++#define PRITY1 0xa4 ++#define PRITY2 0xa8 ++#define PRITY3 0xac ++ ++#endif /* __NDS32_AMIC_HEADER__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/asm-offsets.h linux-3.4.110/arch/nds32/include/asm/asm-offsets.h +--- linux-3.4.110.orig/arch/nds32/include/asm/asm-offsets.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/asm-offsets.h 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1 @@ ++#include +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/assembler.h linux-3.4.110/arch/nds32/include/asm/assembler.h +--- linux-3.4.110.orig/arch/nds32/include/asm/assembler.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/assembler.h 2016-04-07 10:20:50.882078703 +0200 +@@ -0,0 +1,141 @@ ++/* ++ * linux/arch/nds32/include/asm/assembler.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_ASSEMBLER_H__ ++#define __NDS32_ASSEMBLER_H__ ++ ++/* ++ * Stack format ++ */ ++ ++#define S_PAD 0xac /* Padding for stack pointer 8-byte alignment. */ ++#define S_FUCOP_CTL 0xa8 ++#define S_LP 0xa4 ++#define S_GP 0xa0 ++#define S_FP 0x9c ++#define S_R25 0x98 ++#define S_R24 0x94 ++#define S_R23 0x90 ++#define S_R22 0x8c ++#define S_R21 0x88 ++#define S_R20 0x84 ++#define S_R19 0x80 ++#define S_R18 0x7c ++#define S_R17 0x78 ++#define S_R16 0x74 ++#define S_R15 0x70 ++#define S_R14 0x6c ++#define S_R13 0x68 ++#define S_R12 0x64 ++#define S_R11 0x60 ++#define S_R10 0x5c ++#define S_R9 0x58 ++#define S_R8 0x54 ++#define S_R7 0x50 ++#define S_R6 0x4c ++#define S_R5 0x48 ++#define S_R4 0x44 ++#define S_R3 0x40 ++#define S_R2 0x3c ++#define S_R1 0x38 ++#define S_R0 0x34 ++#define S_D1LO 0x30 ++#define S_D1HI 0x2c ++#define S_D0LO 0x28 ++#define S_D0HI 0x24 ++#define S_PP1 0x20 ++#define S_PP0 0x1c ++#define S_PIPC 0x18 ++#define S_PIPSW 0x14 ++#define S_ORIG_R0 0x10 ++#define S_SP 0xc ++#define S_IPC 0x8 ++#define S_IPSW 0x4 ++#define S_IR0 0x0 ++ ++#if !defined(CONFIG_ABI1) ++#define S_OFF 0 ++#else ++#define S_OFF 24 ++#endif ++ ++#ifdef __ASSEMBLY__ ++.macro get_thread_info, rd ++ srli \rd, $sp, #13 ++ slli \rd, \rd, #13 ++.endm ++ ++.macro gie_disable ++ setgie.d ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ isb ++#else ++ dsb ++#endif ++.endm ++ ++.macro gie_enable ++ setgie.e ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ isb ++#else ++ dsb ++#endif ++.endm ++ ++.macro gie_save oldpsw ++ mfsr \oldpsw, $ir0 ++ setgie.d ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ isb ++#else ++ dsb ++#endif ++.endm ++ ++.macro gie_restore oldpsw ++ andi \oldpsw, \oldpsw, #0x1 ++ beqz \oldpsw, 7001f ++ setgie.e ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ isb ++#else ++ dsb ++#endif ++7001: ++.endm ++ ++ ++#define USER(insn, reg, addr, opr) \ ++9999: insn reg, addr, opr; \ ++ .section __ex_table,"a"; \ ++ .align 3; \ ++ .long 9999b, 9001f; \ ++ .previous ++ ++#else /* __ASSEMBLY__ */ ++ ++__asm__ (".macro gie_disable\n\t" ++ "setgie.d\n\t" ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ "isb\n\t" ++#else ++ "dsb\n\t" ++#endif ++ ".endm\n\t" ++ ); ++ ++__asm__ (".macro gie_enable\n\t" ++ "setgie.e\n\t" ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ "isb\n\t" ++#else ++ "dsb\n\t" ++#endif ++ ".endm\n\t" ++ ); ++ ++#endif /* !__ASSEMBLY__ */ ++#endif /* __NDS32_ASSEMBLER_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/atomic.h linux-3.4.110/arch/nds32/include/asm/atomic.h +--- linux-3.4.110.orig/arch/nds32/include/asm/atomic.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/atomic.h 2016-04-07 10:20:50.890079013 +0200 +@@ -0,0 +1,267 @@ ++/* ++ * linux/arch/nds32/include/asm/atomic.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_ATOMIC_H__ ++#define __NDS32_ATOMIC_H__ ++ ++#include ++#include ++#include ++ ++#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) ++ ++#define ATOMIC_INIT(i) { (i) } ++#define atomic_set(v,i) (((v)->counter) = (i)) ++#define atomic_read(v) (*(volatile int *)&(v)->counter) ++ ++static inline void atomic_add(int i, atomic_t *v) ++{ ++ int temp; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tadd\t%0, %0, %2\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (temp) : "r" (&v->counter), "r" (i)); ++} ++ ++static inline void atomic_sub(int i, atomic_t *v) ++{ ++ int temp; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tsub\t%0, %0, %2\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (temp) : "r" (&v->counter), "r" (i)); ++} ++ ++#define atomic_inc(v) atomic_add(1, v) ++#define atomic_dec(v) atomic_sub(1, v) ++ ++static inline int atomic_inc_return(atomic_t *v) ++{ ++ int temp1, temp2; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\taddi\t%1, %1, #1\n" ++ "\tori\t%0, %1, #0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter)); ++ return temp2; ++} ++ ++static inline int atomic_dec_return(atomic_t *v) ++{ ++ int temp1, temp2; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\taddi\t%1, %1, #-1\n" ++ "\tori\t%0, %1, #0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter)); ++ return temp2; ++} ++ ++static inline int atomic_add_return(int i, atomic_t *v) ++{ ++ int temp1, temp2; ++ ++ smp_mb(); ++ ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\tadd\t%1, %1, %3\n" ++ "\tori\t%0, %1, #0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter), "r" (i)); ++ ++ smp_mb(); ++ ++ return temp2; ++} ++ ++static inline int atomic_sub_return(int i, atomic_t *v) ++{ ++ int temp1, temp2; ++ ++ smp_mb(); ++ ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\tsub\t%1, %1, %3\n" ++ "\tori\t%0, %1, #0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter), "r" (i)); ++ ++ smp_mb(); ++ ++ return temp2; ++} ++ ++/* ++ * atomic_dec_if_positive - conditionally subtract one from atomic variable ++ * @v: pointer of type atomic_t ++ * ++ * Atomically test @v and subtract one if @v is greater or equal than one. ++ * The function returns the old value of @v minus one. ++ */ ++static inline int atomic_dec_if_positive(atomic_t * v) ++{ ++ int temp1, temp2, temp3; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%2, [%3+$r15]\n" ++ "\taddi\t%0, %2, #-1\n" ++ "\tslts\t%1, $r15, %2\n" ++ "\tsub\t%2, %2, %1\n" ++ "\tscw\t%2, [%3+$r15]\n" ++ "\tbeqz\t%2, 1b\n" ++ : "=&r" (temp3), "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter)); ++ return temp3; ++} ++ ++ ++#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) ++#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) ++#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) ++#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0) ++ ++ ++static inline int atomic_cmpxchg(atomic_t *v, int old, int new) ++{ ++ int temp1, temp2, temp3; ++ ++ smp_mb(); ++ ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%0, [%3+$r15]\n" ++ "\tsub\t%2, %0, %5\n" ++ "\tcmovz\t%1, %4, %2\n" ++ "\tcmovn\t%1, %0, %2\n" ++ "\tscw\t%1, [%3+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp3), "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter), "r" (new), "r" (old)); ++ ++ smp_mb(); ++ ++ return temp3; ++} ++ ++static inline int atomic_xchg(atomic_t *v, int new) ++{ ++ int temp1, temp2; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%0, [%2+$r15]\n" ++ "\tori\t%1, %3, #0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter), "r" (new)); ++ return temp2; ++} ++ ++static inline int __atomic_add_unless(atomic_t *v, int a, int u) ++{ ++ int c, old; ++ ++ c = atomic_read(v); ++ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) ++ c = old; ++ return c; ++} ++ ++static inline int atomic_inc_not_zero(atomic_t *v) ++{ ++ int temp1, temp2; ++ __asm__ __volatile__( ++ "movi\t$r15, #0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\tslt\t%0, $r15, %1\n" ++ "\tadd\t%1, %1, %0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (temp2), "=&r" (temp1) ++ : "r" (&v->counter)); ++ return temp2; ++} ++ ++#define smp_mb__before_atomic_dec() barrier() ++#define smp_mb__after_atomic_dec() barrier() ++#define smp_mb__before_atomic_inc() barrier() ++#define smp_mb__after_atomic_inc() barrier() ++ ++//#include ++#else /* CONFIG_SMP*/ ++ ++ ++ ++#define ATOMIC_INIT(i) { (i) } ++ ++#ifdef __KERNEL__ ++ ++#include ++ ++static inline int atomic_dec_if_positive(atomic_t * v) ++{ ++ unsigned long flags; ++ int result; ++ ++ local_irq_save(flags); ++ result = v->counter; ++ result -= 1; ++ if (result >= 0) ++ v->counter = result; ++ local_irq_restore(flags); ++ return result; ++} ++ ++/* Atomic operations are already serializing on ARM */ ++#define smp_mb__before_atomic_dec() barrier() ++#define smp_mb__after_atomic_dec() barrier() ++#define smp_mb__before_atomic_inc() barrier() ++#define smp_mb__after_atomic_inc() barrier() ++ ++#endif ++ ++#endif /* CONFIG_SMP */ ++ ++#ifndef CONFIG_GENERIC_ATOMIC64 ++typedef struct { ++ u64 __aligned(8) counter; ++} atomic64_t; ++#define ATOMIC64_INIT(i) { (i) } ++static inline u64 atomic64_add_return(u64 i, atomic64_t *v){ return 0; } ++#endif /* CONFIG_GENERIC_ATOMIC64 */ ++ ++#endif /* __NDS32_ATOMIC_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/audio.h linux-3.4.110/arch/nds32/include/asm/audio.h +--- linux-3.4.110.orig/arch/nds32/include/asm/audio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/audio.h 2016-04-07 10:20:50.890079013 +0200 +@@ -0,0 +1,65 @@ ++/* ++ * linux/arch/nds32/include/asm/audio.h ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_AUDIO_H ++#define __ASM_NDS32_AUDIO_H ++ ++#ifndef __ASSEMBLY__ ++#include ++#include ++ ++extern void save_audio(struct task_struct *tsk); ++extern void audioload(struct audio_struct *audioregs); ++extern void save_audio(struct task_struct *__tsk); ++extern void do_audio_context_switch(unsigned long error_code, struct pt_regs *regs); ++ ++#ifdef CONFIG_AUDIO ++ ++#define test_tsk_audio(regs) (regs->NDS32_FUCOP_CTL & FUCOP_CTL_mskAUEN) ++ ++struct task_struct; ++ ++static inline void enable_audio(void) ++{ ++ SET_FUCOP_CTL(GET_FUCOP_CTL() | FUCOP_CTL_mskAUEN); ++} ++ ++static inline void disable_audio(void) ++{ ++ SET_FUCOP_CTL(GET_FUCOP_CTL() & ~FUCOP_CTL_mskAUEN); ++} ++ ++static inline void release_audio(struct pt_regs *regs) ++{ ++ regs->NDS32_FUCOP_CTL &= ~FUCOP_CTL_mskAUEN; ++ regs->NDS32_ipsw &= ~PSW_mskAEN; ++} ++ ++static inline void grab_audio(struct pt_regs *regs) ++{ ++ regs->NDS32_FUCOP_CTL |= FUCOP_CTL_mskAUEN; ++ regs->NDS32_ipsw |= PSW_mskAEN; ++} ++#ifdef CONFIG_UNLAZY_AUDIO ++static inline void unlazy_audio(struct task_struct *tsk) ++{ ++ preempt_disable(); ++ if (test_tsk_audio(task_pt_regs(tsk))) ++ save_audio(tsk); ++ preempt_enable(); ++} ++#endif ++static inline void clear_audio(struct pt_regs *regs) ++{ ++ preempt_disable(); ++ if (test_tsk_audio(regs)) { ++ release_audio(regs); ++ } ++ preempt_enable(); ++} ++#endif /* CONFIG_AUDIO */ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* __ASM_NDS32_AUDIO_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/auxvec.h linux-3.4.110/arch/nds32/include/asm/auxvec.h +--- linux-3.4.110.orig/arch/nds32/include/asm/auxvec.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/auxvec.h 2016-04-07 10:20:50.890079013 +0200 +@@ -0,0 +1,9 @@ ++/* ++ * linux/arch/nds32/include/asm/auxvec.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_AUXVEC_H__ ++#define __NDS32_AUXVEC_H__ ++ ++#endif /*__NDS32_AUXVEC_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/barrier.h linux-3.4.110/arch/nds32/include/asm/barrier.h +--- linux-3.4.110.orig/arch/nds32/include/asm/barrier.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/barrier.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,85 @@ ++/* ============================================================================ ++ * ++ * linux/arch/nds32/include/asm/system.h ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for NDS32 architecture. ++ * ++ * Revision History: ++ * ++ * Nov.26.2007 Initial ported by Tom, Shawn, and Steven, ++ * patched for KGDB and refined code by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#ifndef __ASM_NDS32_BARRIER_H ++#define __ASM_NDS32_BARRIER_H ++ ++#ifdef __KERNEL__ ++ ++/* ++ * This is used to ensure the compiler did actually allocate the register we ++ * asked it for some inline assembly sequences. Apparently we can't trust ++ * the compiler from one version to another so a bit of paranoia won't hurt. ++ * This string is meant to be concatenated with the inline asm string and ++ * will cause compilation to stop on mismatch. ++ * (for details, see gcc PR 15089) ++ */ ++#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" ++ ++#ifndef __ASSEMBLY__ ++ ++#include ++#include ++ ++struct thread_info; ++struct task_struct; ++ ++struct pt_regs; ++ ++void die(const char *msg, struct pt_regs *regs, int err) ++ __attribute__((noreturn)); ++ ++void die_if_kernel(const char *str, struct pt_regs *regs, int err); ++ ++#include ++ ++#define UDBG_UNDEFINED (1 << 0) ++#define UDBG_SYSCALL (1 << 1) ++#define UDBG_BADABORT (1 << 2) ++#define UDBG_SEGV (1 << 3) ++#define UDBG_BUS (1 << 4) ++ ++extern unsigned int user_debug; ++ ++#define mb() __asm__ __volatile__ ("" : : : "memory") ++#define rmb() mb() ++#define wmb() mb() ++#define read_barrier_depends() do { } while(0) ++#define set_mb(var, value) do { var = value; mb(); } while (0) ++#define set_wmb(var, value) do { var = value; wmb(); } while (0) ++ ++#ifdef CONFIG_SMP ++#define smp_mb() mb() ++#define smp_rmb() rmb() ++#define smp_wmb() wmb() ++#define smp_read_barrier_depends() read_barrier_depends() ++#else ++#define smp_mb() barrier() ++#define smp_rmb() barrier() ++#define smp_wmb() barrier() ++#define smp_read_barrier_depends() do { } while(0) ++#endif ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* __KERNEL__ */ ++ ++#endif //__ASM_NDS32_SYSTEM_H +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bitfield.h linux-3.4.110/arch/nds32/include/asm/bitfield.h +--- linux-3.4.110.orig/arch/nds32/include/asm/bitfield.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/bitfield.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,895 @@ ++/* ++ * linux/arch/nds32/include/asm/bitfield.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_BITFIELD_H__ ++#define __NDS32_BITFIELD_H__ ++/****************************************************************************** ++ * cr0: CPU_VER (CPU Version Register) ++ *****************************************************************************/ ++#define CPU_VER_offCFGID 0 /* Minor configuration */ ++#define CPU_VER_offREV 16 /* Revision of the CPU version */ ++#define CPU_VER_offCPUID 24 /* Major CPU versions */ ++ ++#define CPU_VER_mskCFGID ( 0xFFFF << CPU_VER_offCFGID ) ++#define CPU_VER_mskREV ( 0xFF << CPU_VER_offREV ) ++#define CPU_VER_mskCPUID ( 0xFF << CPU_VER_offCPUID ) ++ ++/****************************************************************************** ++ * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register) ++ *****************************************************************************/ ++#define ICM_CFG_offISET 0 /* I-cache sets (# of cache lines) per way */ ++#define ICM_CFG_offIWAY 3 /* I-cache ways */ ++#define ICM_CFG_offISZ 6 /* I-cache line size */ ++#define ICM_CFG_offILCK 9 /* I-cache locking support */ ++#define ICM_CFG_offILMB 10 /* On-chip ILM banks */ ++#define ICM_CFG_offBSAV 13 /* ILM base register alignment version */ ++/* bit 15:31 reserved */ ++ ++#define ICM_CFG_mskISET ( 0x7 << ICM_CFG_offISET ) ++#define ICM_CFG_mskIWAY ( 0x7 << ICM_CFG_offIWAY ) ++#define ICM_CFG_mskISZ ( 0x7 << ICM_CFG_offISZ ) ++#define ICM_CFG_mskILCK ( 0x1 << ICM_CFG_offILCK ) ++#define ICM_CFG_mskILMB ( 0x7 << ICM_CFG_offILMB ) ++#define ICM_CFG_mskBSAV ( 0x3 << ICM_CFG_offBSAV ) ++ ++/****************************************************************************** ++ * cr2: DCM_CFG (Data Cache/Memory Configuration Register) ++ *****************************************************************************/ ++#define DCM_CFG_offDSET 0 /* D-cache sets (# of cache lines) per way */ ++#define DCM_CFG_offDWAY 3 /* D-cache ways */ ++#define DCM_CFG_offDSZ 6 /* D-cache line size */ ++#define DCM_CFG_offDLCK 9 /* D-cache locking support */ ++#define DCM_CFG_offDLMB 10 /* On-chip DLM banks */ ++#define DCM_CFG_offBSAV 13 /* DLM base register alignment version */ ++/* bit 15:31 reserved */ ++ ++#define DCM_CFG_mskDSET ( 0x7 << DCM_CFG_offDSET ) ++#define DCM_CFG_mskDWAY ( 0x7 << DCM_CFG_offDWAY ) ++#define DCM_CFG_mskDSZ ( 0x7 << DCM_CFG_offDSZ ) ++#define DCM_CFG_mskDLCK ( 0x1 << DCM_CFG_offDLCK ) ++#define DCM_CFG_mskDLMB ( 0x7 << DCM_CFG_offDLMB ) ++#define DCM_CFG_mskBSAV ( 0x3 << DCM_CFG_offBSAV ) ++ ++/****************************************************************************** ++ * cr3: MMU_CFG (MMU Configuration Register) ++ *****************************************************************************/ ++#define MMU_CFG_offMMPS 0 /* Memory management protection scheme */ ++#define MMU_CFG_offMMPV 2 /* Memory management protection version number */ ++#define MMU_CFG_offFATB 7 /* Fully-associative or non-fully-associative TLB */ ++ ++#ifdef CONFIG_FULL_ASSOC ++#define MMU_CFG_offFATBSZ 8 /* TLB entries while using full-associative TLB */ ++#else ++#define MMU_CFG_offTBW 8 /* TLB ways(non-associative) TBS */ ++#define MMU_CFG_offTBS 11 /* TLB sets per way(non-associative) TBS */ ++/* bit 14:14 reserved */ ++#endif ++ ++#define MMU_CFG_offEP8MIN4 15 /* 8KB page supported while minimum page is 4KB */ ++#define MMU_CFG_offfEPSZ 16 /* Extra page size supported */ ++#define MMU_CFG_offTLBLCK 24 /* TLB locking support */ ++#define MMU_CFG_offHPTWK 25 /* Hardware Page Table Walker implemented */ ++#define MMU_CFG_offDE 26 /* Default endian */ ++#define MMU_CFG_offNTPT 27 /* Partitions for non-translated attributes */ ++#define MMU_CFG_offIVTB 28 /* Invisible TLB */ ++#define MMU_CFG_offVLPT 29 /* VLPT for fast TLB fill handling implemented */ ++#define MMU_CFG_offNTME 30 /* Non-translated VA to PA mapping */ ++/* bit 31 reserved */ ++ ++#define MMU_CFG_mskMMPS ( 0x3 << MMU_CFG_offMMPS ) ++#define MMU_CFG_mskMMPV ( 0x1F << MMU_CFG_offMMPV ) ++#define MMU_CFG_mskFATB ( 0x1 << MMU_CFG_offFATB ) ++#ifdef CONFIG_FULL_ASSOC ++#define MMU_CFG_mskFATBSZ ( 0x7f << MMU_CFG_offFATBSZ ) ++#else ++#define MMU_CFG_mskTBW ( 0x7 << MMU_CFG_offTBW ) ++#define MMU_CFG_mskTBS ( 0x7 << MMU_CFG_offTBS ) ++#endif ++#define MMU_CFG_mskEP8MIN4 ( 0x1 << MMU_CFG_offEP8MIN4 ) ++#define MMU_CFG_mskfEPSZ ( 0xFF << MMU_CFG_offfEPSZ ) ++#define MMU_CFG_mskTLBLCK ( 0x1 << MMU_CFG_offTLBLCK ) ++#define MMU_CFG_mskHPTWK ( 0x1 << MMU_CFG_offHPTWK ) ++#define MMU_CFG_mskDE ( 0x1 << MMU_CFG_offDE ) ++#define MMU_CFG_mskNTPT ( 0x1 << MMU_CFG_offNTPT ) ++#define MMU_CFG_mskIVTB ( 0x1 << MMU_CFG_offIVTB ) ++#define MMU_CFG_mskVLPT ( 0x1 << MMU_CFG_offVLPT ) ++#define MMU_CFG_mskNTME ( 0x1 << MMU_CFG_offNTME ) ++ ++/****************************************************************************** ++ * cr4: MSC_CFG (Misc Configuration Register) ++ *****************************************************************************/ ++#define MSC_CFG_offEDM 0 ++#define MSC_CFG_offLMDMA 1 ++#define MSC_CFG_offPFM 2 ++#define MSC_CFG_offHSMP 3 ++#define MSC_CFG_offTRACE 4 ++#define MSC_CFG_offDIV 5 ++#define MSC_CFG_offMAC 6 ++#define MSC_CFG_offAUDIO 7 ++#define MSC_CFG_offL2C 9 ++#define MSC_CFG_offRDREG 10 ++#define MSC_CFG_offADR24 11 ++#define MSC_CFG_offINTLC 12 ++#define MSC_CFG_offBASEV 13 ++#define MSC_CFG_offNOD 16 ++/* bit 13:31 reserved */ ++ ++#define MSC_CFG_mskEDM ( 0x1 << MSC_CFG_offEDM ) ++#define MSC_CFG_mskLMDMA ( 0x1 << MSC_CFG_offLMDMA ) ++#define MSC_CFG_mskPFM ( 0x1 << MSC_CFG_offPFM ) ++#define MSC_CFG_mskHSMP ( 0x1 << MSC_CFG_offHSMP ) ++#define MSC_CFG_mskTRACE ( 0x1 << MSC_CFG_offTRACE ) ++#define MSC_CFG_mskDIV ( 0x1 << MSC_CFG_offDIV ) ++#define MSC_CFG_mskMAC ( 0x1 << MSC_CFG_offMAC ) ++#define MSC_CFG_mskAUDIO ( 0x3 << MSC_CFG_offAUDIO ) ++#define MSC_CFG_mskL2C ( 0x1 << MSC_CFG_offL2C ) ++#define MSC_CFG_mskRDREG ( 0x1 << MSC_CFG_offRDREG ) ++#define MSC_CFG_mskADR24 ( 0x1 << MSC_CFG_offADR24 ) ++#define MSC_CFG_mskINTLC ( 0x1 << MSC_CFG_offINTLC ) ++#define MSC_CFG_mskBASEV ( 0x7 << MSC_CFG_offBASEV ) ++#define MSC_CFG_mskNOD ( 0x1 << MSC_CFG_offNOD ) ++ ++/****************************************************************************** ++ * cr5: CORE_CFG (Core Identification Register) ++ *****************************************************************************/ ++#define CORE_ID_offCOREID 0 ++/* bit 4:31 reserved */ ++ ++#define CORE_ID_mskCOREID ( 0xF << CORE_ID_offCOREID ) ++ ++/****************************************************************************** ++ * cr6: FUCOP_EXIST (FPU and Coprocessor Existence Configuration Register) ++ *****************************************************************************/ ++#define FUCOP_EXIST_offCP0EX 0 ++#define FUCOP_EXIST_offCP1EX 1 ++#define FUCOP_EXIST_offCP2EX 2 ++#define FUCOP_EXIST_offCP3EX 3 ++#define FUCOP_EXIST_offCP0ISFPU 31 ++ ++#define FUCOP_EXIST_mskCP0EX ( 0x1 << FUCOP_EXIST_offCP0EX ) ++#define FUCOP_EXIST_mskCP1EX ( 0x1 << FUCOP_EXIST_offCP1EX ) ++#define FUCOP_EXIST_mskCP2EX ( 0x1 << FUCOP_EXIST_offCP2EX ) ++#define FUCOP_EXIST_mskCP3EX ( 0x1 << FUCOP_EXIST_offCP3EX ) ++#define FUCOP_EXIST_mskCP0ISFPU ( 0x1 << FUCOP_EXIST_offCP0ISFPU ) ++ ++/****************************************************************************** ++ * ir0: PSW (Processor Status Word Register) ++ * ir1: IPSW (Interruption PSW Register) ++ * ir2: P_IPSW (Previous IPSW Register) ++ *****************************************************************************/ ++#define PSW_offGIE 0 /* Global Interrupt Enable */ ++#define PSW_offINTL 1 /* Interruption Stack Level */ ++#define PSW_offPOM 3 /* Processor Operation Mode, User/Superuser */ ++#define PSW_offBE 5 /* Endianness for data memory access, 1:MSB, 0:LSB */ ++#define PSW_offIT 6 /* Enable instruction address translation */ ++#define PSW_offDT 7 /* Enable data address translation */ ++#define PSW_offIME 8 /* Instruction Machine Error flag */ ++#define PSW_offDME 9 /* Data Machine Error flag */ ++#define PSW_offDEX 10 /* Debug Exception */ ++#define PSW_offHSS 11 /* Hardware Single Stepping */ ++#define PSW_offDRBE 12 /* Device Register Endian Mode */ ++#define PSW_offAEN 13 /* Audio ISA special feature */ ++#define PSW_offWBNA 14 /* Write Back Non-Allocate */ ++#define PSW_offIFCON 15 /* IFC On */ ++#define PSW_offCPL 16 /* Current Priority Level */ ++/* bit 19:31 reserved */ ++ ++#define PSW_mskGIE ( 0x1 << PSW_offGIE ) ++#define PSW_mskINTL ( 0x3 << PSW_offINTL ) ++#define PSW_mskPOM ( 0x3 << PSW_offPOM ) ++#define PSW_mskBE ( 0x1 << PSW_offBE ) ++#define PSW_mskIT ( 0x1 << PSW_offIT ) ++#define PSW_mskDT ( 0x1 << PSW_offDT ) ++#define PSW_mskIME ( 0x1 << PSW_offIME ) ++#define PSW_mskDME ( 0x1 << PSW_offDME ) ++#define PSW_mskDEX ( 0x1 << PSW_offDEX ) ++#define PSW_mskHSS ( 0x1 << PSW_offHSS ) ++#define PSW_mskDRBE ( 0x1 << PSW_offDRBE ) ++#define PSW_mskAEN ( 0x1 << PSW_offAEN ) ++#define PSW_mskWBNA ( 0x1 << PSW_offWBNA ) ++#define PSW_mskIFCON ( 0x1 << PSW_offIFCON ) ++#define PSW_mskCPL ( 0x7 << PSW_offCPL ) ++ ++#define PSW_SYSTEM ( 1 << PSW_offPOM ) ++#define PSW_INTL_1 ( 1 << PSW_offINTL ) ++#define PSW_CPL_NO ( 0 << PSW_offCPL ) ++#define PSW_CPL_ANY ( 7 << PSW_offCPL ) ++/****************************************************************************** ++ * ir3: IVB (Interruption Vector Base Register) ++ *****************************************************************************/ ++/* bit 0:12 reserved */ ++#define IVB_offNIVIC 1 /* Number of input for IVIC Controller */ ++#define IVB_offIVIC_VER 11 /* IVIC Version */ ++#define IVB_offEVIC 13 /* External Vector Interrupt Controller mode */ ++#define IVB_offESZ 14 /* Size of each vector entry */ ++#define IVB_offIVBASE 16 /* BasePA of interrupt vector table */ ++ ++#define IVB_mskNIVIC ( 0x7 << IVB_offNIVIC ) ++#define IVB_mskIVIC_VER ( 0x3 << IVB_offIVIC_VER ) ++#define IVB_mskEVIC ( 0x1 << IVB_offEVIC ) ++#define IVB_mskESZ ( 0x3 << IVB_offESZ ) ++#define IVB_mskIVBASE ( 0xFFFF << IVB_offIVBASE ) ++ ++/****************************************************************************** ++ * ir4: EVA (Exception Virtual Address Register) ++ * ir5: P_EVA (Previous EVA Register) ++ *****************************************************************************/ ++ ++ /* This register contains the VA that causes the exception */ ++ ++/****************************************************************************** ++ * ir6: ITYPE (Interruption Type Register) ++ * ir7: P_ITYPE (Previous ITYPE Register) ++ *****************************************************************************/ ++#define ITYPE_offETYPE 0 /* Exception Type */ ++#define ITYPE_offINST 4 /* Exception caused by insn fetch or data access */ ++/* bit 5:15 reserved */ ++#define ITYPE_offSWID 16 /* SWID of debugging exception */ ++/* bit 31:31 reserved */ ++ ++#define ITYPE_mskETYPE ( 0xF << ITYPE_offETYPE ) ++#define ITYPE_mskINST ( 0x1 << ITYPE_offINST ) ++#define ITYPE_mskSWID ( 0x7FFF << ITYPE_offSWID ) ++ ++/* Additional definitions for ITYPE register */ ++#define ITYPE_offSTYPE 16 /* Arithmetic Sub Type */ ++#define ITYPE_offCPID 20 /* Co-Processor ID which generate the exception */ ++ ++#define ITYPE_mskSTYPE ( 0xF << ITYPE_offSTYPE ) ++#define ITYPE_mskCPID ( 0x3 << ITYPE_offCPID ) ++ ++/****************************************************************************** ++ * ir8: MERR (Machine Error Log Register) ++ *****************************************************************************/ ++/* bit 0:30 reserved */ ++#define MERR_offBUSERR 31 /* Bus error caused by a load insn */ ++ ++#define MERR_mskBUSERR ( 0x1 << MERR_offBUSERR ) ++ ++/****************************************************************************** ++ * ir9: IPC (Interruption Program Counter Register) ++ * ir10: P_IPC (Previous IPC Register) ++ * ir11: OIPC (Overflow Interruption Program Counter Register) ++ *****************************************************************************/ ++ ++ /* This is the shadow stack register of the Program Counter */ ++ ++/****************************************************************************** ++ * ir12: P_P0 (Previous P0 Register) ++ * ir13: P_P1 (Previous P1 Register) ++ *****************************************************************************/ ++ ++ /* These are shadow registers of $p0 and $p1 */ ++ ++/****************************************************************************** ++ * ir14: INT_MASK (Interruption Masking Register) ++ *****************************************************************************/ ++#define INT_MASK_offH0IM 0 /* Hardware Interrupt 0 Mask bit */ ++#define INT_MASK_offH1IM 1 /* Hardware Interrupt 1 Mask bit */ ++#define INT_MASK_offH2IM 2 /* Hardware Interrupt 2 Mask bit */ ++#define INT_MASK_offH3IM 3 /* Hardware Interrupt 3 Mask bit */ ++#define INT_MASK_offH4IM 4 /* Hardware Interrupt 4 Mask bit */ ++#define INT_MASK_offH5IM 5 /* Hardware Interrupt 5 Mask bit */ ++/* bit 6:15 reserved */ ++#define INT_MASK_offSIM 16 /* Software Interrupt Mask bit */ ++/* bit 17:29 reserved */ ++#define INT_MASK_offIDIVZE 30 /* Enable detection for Divide-By-Zero */ ++#define INT_MASK_offDSSIM 31 /* Default Single Stepping Interruption Mask */ ++ ++#define INT_MASK_mskH0IM ( 0x1 << INT_MASK_offH0IM ) ++#define INT_MASK_mskH1IM ( 0x1 << INT_MASK_offH1IM ) ++#define INT_MASK_mskH2IM ( 0x1 << INT_MASK_offH2IM ) ++#define INT_MASK_mskH3IM ( 0x1 << INT_MASK_offH3IM ) ++#define INT_MASK_mskH4IM ( 0x1 << INT_MASK_offH4IM ) ++#define INT_MASK_mskH5IM ( 0x1 << INT_MASK_offH5IM ) ++#define INT_MASK_mskSIM ( 0x1 << INT_MASK_offSIM ) ++#define INT_MASK_mskIDIVZE ( 0x1 << INT_MASK_offIDIVZE ) ++#define INT_MASK_mskDSSIM ( 0x1 << INT_MASK_offDSSIM ) ++ ++/****************************************************************************** ++ * ir15: INT_PEND (Interrupt Pending Register) ++ *****************************************************************************/ ++#define INT_PEND_offH0I 0 /* Hardware Interrupt 0 pending bit */ ++#define INT_PEND_offH1I 1 /* Hardware Interrupt 1 pending bit */ ++#define INT_PEND_offH2I 2 /* Hardware Interrupt 2 pending bit */ ++#define INT_PEND_offH3I 3 /* Hardware Interrupt 3 pending bit */ ++#define INT_PEND_offH4I 4 /* Hardware Interrupt 4 pending bit */ ++#define INT_PEND_offH5I 5 /* Hardware Interrupt 5 pending bit */ ++ ++#define INT_PEND_offCIPL 0 /* Current Interrupt Priority Level */ ++ ++/* bit 6:15 reserved */ ++#define INT_PEND_offSWI 16 /* Software Interrupt pending bit */ ++/* bit 17:31 reserved */ ++ ++#define INT_PEND_mskH0I ( 0x1 << INT_PEND_offH0I ) ++#define INT_PEND_mskH1I ( 0x1 << INT_PEND_offH1I ) ++#define INT_PEND_mskH2I ( 0x1 << INT_PEND_offH2I ) ++#define INT_PEND_mskH3I ( 0x1 << INT_PEND_offH3I ) ++#define INT_PEND_mskH4I ( 0x1 << INT_PEND_offH4I ) ++#define INT_PEND_mskH5I ( 0x1 << INT_PEND_offH5I ) ++#define INT_PEND_mskCIPL ( 0x1 << INT_PEND_offCIPL ) ++#define INT_PEND_mskSWI ( 0x1 << INT_PEND_offSWI ) ++ ++/****************************************************************************** ++ * mr0: MMU_CTL (MMU Control Register) ++ *****************************************************************************/ ++#define MMU_CTL_offD 0 /* Default minimum page size */ ++#define MMU_CTL_offNTC0 1 /* Non-Translated Cachebility of partition 0 */ ++#define MMU_CTL_offNTC1 3 /* Non-Translated Cachebility of partition 1 */ ++#define MMU_CTL_offNTC2 5 /* Non-Translated Cachebility of partition 2 */ ++#define MMU_CTL_offNTC3 7 /* Non-Translated Cachebility of partition 3 */ ++#define MMU_CTL_offTBALCK 9 /* TLB all-lock resolution scheme */ ++#define MMU_CTL_offMPZIU 10 /* Multiple Page Size In Use bit */ ++#define MMU_CTL_offNTM0 11 /* Non-Translated VA to PA of partition 0 */ ++#define MMU_CTL_offNTM1 13 /* Non-Translated VA to PA of partition 1 */ ++#define MMU_CTL_offNTM2 15 /* Non-Translated VA to PA of partition 2 */ ++#define MMU_CTL_offNTM3 17 /* Non-Translated VA to PA of partition 3 */ ++/* bit 19:31 reserved */ ++ ++#define MMU_CTL_mskD ( 0x1 << MMU_CTL_offD ) ++#define MMU_CTL_mskNTC0 ( 0x3 << MMU_CTL_offNTC0 ) ++#define MMU_CTL_mskNTC1 ( 0x3 << MMU_CTL_offNTC1 ) ++#define MMU_CTL_mskNTC2 ( 0x3 << MMU_CTL_offNTC2 ) ++#define MMU_CTL_mskNTC3 ( 0x3 << MMU_CTL_offNTC3 ) ++#define MMU_CTL_mskTBALCK ( 0x1 << MMU_CTL_offTBALCK ) ++#define MMU_CTL_mskMPZIU ( 0x1 << MMU_CTL_offMPZIU ) ++#define MMU_CTL_mskNTM0 ( 0x3 << MMU_CTL_offNTM0 ) ++#define MMU_CTL_mskNTM1 ( 0x3 << MMU_CTL_offNTM1 ) ++#define MMU_CTL_mskNTM2 ( 0x3 << MMU_CTL_offNTM2 ) ++#define MMU_CTL_mskNTM3 ( 0x3 << MMU_CTL_offNTM3 ) ++ ++/****************************************************************************** ++ * mr1: L1_PPTB (L1 Physical Page Table Base Register) ++ *****************************************************************************/ ++#define L1_PPTB_offNV 0 /* Enable Hardware Page Table Walker (HPTWK) */ ++/* bit 1:11 reserved */ ++#define L1_PPTB_offBASE 12 /* First level physical page table base address */ ++ ++#define L1_PPTB_mskNV ( 0x1 << L1_PPTB_offNV ) ++#define L1_PPTB_mskBASE ( 0xFFFFF << L1_PPTB_offBASE ) ++ ++/****************************************************************************** ++ * mr2: TLB_VPN (TLB Access VPN Register) ++ *****************************************************************************/ ++/* bit 0:11 reserved */ ++#define TLB_VPN_offVPN 12 /* Virtual Page Number */ ++ ++#define TLB_VPN_mskVPN ( 0xFFFFF << TLB_VPN_offVPN ) ++ ++/****************************************************************************** ++ * mr3: TLB_DATA (TLB Access Data Register) ++ *****************************************************************************/ ++#define TLB_DATA_offV 0 /* PTE is valid and present */ ++#define TLB_DATA_offM 1 /* Page read/write access privilege */ ++#define TLB_DATA_offD 4 /* Dirty bit */ ++#define TLB_DATA_offX 5 /* Executable bit */ ++#define TLB_DATA_offA 6 /* Access bit */ ++#define TLB_DATA_offG 7 /* Global page (shared across contexts) */ ++#define TLB_DATA_offC 8 /* Cacheability atribute */ ++/* bit 11:11 reserved */ ++#define TLB_DATA_offPPN 12 /* Phisical Page Number */ ++ ++#define TLB_DATA_mskV ( 0x1 << TLB_DATA_offV ) ++#define TLB_DATA_mskM ( 0x7 << TLB_DATA_offM ) ++#define TLB_DATA_mskD ( 0x1 << TLB_DATA_offD ) ++#define TLB_DATA_mskX ( 0x1 << TLB_DATA_offX ) ++#define TLB_DATA_mskA ( 0x1 << TLB_DATA_offA ) ++#define TLB_DATA_mskG ( 0x1 << TLB_DATA_offG ) ++#define TLB_DATA_mskC ( 0x7 << TLB_DATA_offC ) ++#define TLB_DATA_mskPPN ( 0xFFFFF << TLB_DATA_offPPN ) ++ ++/****************************************************************************** ++ * mr4: TLB_MISC (TLB Access Misc Register) ++ *****************************************************************************/ ++#define TLB_MISC_offACC_PSZ 0 /* Page size of a PTE entry */ ++#define TLB_MISC_offCID 4 /* Context id */ ++/* bit 13:31 reserved */ ++ ++#define TLB_MISC_mskACC_PSZ ( 0xF << TLB_MISC_offACC_PSZ ) ++#define TLB_MISC_mskCID ( 0x1FF << TLB_MISC_offCID ) ++ ++/****************************************************************************** ++ * mr5: VLPT_IDX (Virtual Linear Page Table Index Register) ++ *****************************************************************************/ ++#define VLPT_IDX_offZERO 0 /* Always 0 */ ++#define VLPT_IDX_offEVPN 2 /* Exception Virtual Page Number */ ++#define VLPT_IDX_offVLPTB 22 /* Base VA of VLPT */ ++ ++#define VLPT_IDX_mskZERO ( 0x3 << VLPT_IDX_offZERO ) ++#define VLPT_IDX_mskEVPN ( 0xFFFFF << VLPT_IDX_offEVPN ) ++#define VLPT_IDX_mskVLPTB ( 0x3FF << VLPT_IDX_offVLPTB ) ++ ++/****************************************************************************** ++ * mr6: ILMB (Instruction Local Memory Base Register) ++ *****************************************************************************/ ++#define ILMB_offIEN 0 /* Enable ILM */ ++#define ILMB_offILMSZ 1 /* Size of ILM */ ++/* bit 5:19 reserved */ ++#define ILMB_offIBPA 20 /* Base PA of ILM */ ++ ++#define ILMB_mskIEN ( 0x1 << ILMB_offIEN ) ++#define ILMB_mskILMSZ ( 0xF << ILMB_offILMSZ ) ++#define ILMB_mskIBPA ( 0xFFF << ILMB_offIBPA ) ++ ++/****************************************************************************** ++ * mr7: DLMB (Data Local Memory Base Register) ++ *****************************************************************************/ ++#define DLMB_offDEN 0 /* Enable DLM */ ++#define DLMB_offDLMSZ 1 /* Size of DLM */ ++#define DLMB_offDBM 5 /* Enable Double-Buffer Mode for DLM */ ++#define DLMB_offDBB 6 /* Double-buffer bank which can be accessed by the processor */ ++/* bit 7:19 reserved */ ++#define DLMB_offDBPA 20 /* Base PA of DLM */ ++ ++#define DLMB_mskDEN ( 0x1 << DLMB_offDEN ) ++#define DLMB_mskDLMSZ ( 0xF << DLMB_offDLMSZ ) ++#define DLMB_mskDBM ( 0x1 << DLMB_offDBM ) ++#define DLMB_mskDBB ( 0x1 << DLMB_offDBB ) ++#define DLMB_mskDBPA ( 0xFFF << DLMB_offDBPA ) ++ ++/****************************************************************************** ++ * mr8: CACHE_CTL (Cache Control Register) ++ *****************************************************************************/ ++#define CACHE_CTL_offIC_EN 0 /* Enable I-cache */ ++#define CACHE_CTL_offDC_EN 1 /* Enable D-cache */ ++#define CACHE_CTL_offICALCK 2 /* I-cache all-lock resolution scheme */ ++#define CACHE_CTL_offDCALCK 3 /* D-cache all-lock resolution scheme */ ++#define CACHE_CTL_offDCCWF 4 /* Enable D-cache Critical Word Forwarding */ ++#define CACHE_CTL_offDCPMW 5 /* Enable D-cache concurrent miss and write-back processing */ ++/* bit 6:31 reserved */ ++ ++#define CACHE_CTL_mskIC_EN ( 0x1 << CACHE_CTL_offIC_EN ) ++#define CACHE_CTL_mskDC_EN ( 0x1 << CACHE_CTL_offDC_EN ) ++#define CACHE_CTL_mskICALCK ( 0x1 << CACHE_CTL_offICALCK ) ++#define CACHE_CTL_mskDCALCK ( 0x1 << CACHE_CTL_offDCALCK ) ++#define CACHE_CTL_mskDCCWF ( 0x1 << CACHE_CTL_offDCCWF ) ++#define CACHE_CTL_mskDCPMW ( 0x1 << CACHE_CTL_offDCPMW ) ++ ++/****************************************************************************** ++ * mr9: HSMP_SADDR (High Speed Memory Port Starting Address) ++ *****************************************************************************/ ++#define HSMP_SADDR_offEN 0 /* Enable control bit for the High Speed Memory port */ ++/* bit 1:19 reserved */ ++ ++#define HSMP_SADDR_offRANGE 1 /* Denote the address range (only defined in HSMP v2 ) */ ++#define HSMP_SADDR_offSADDR 20 /* Starting base PA of the High Speed Memory Port region */ ++ ++#define HSMP_SADDR_mskEN ( 0x1 << HSMP_SADDR_offEN ) ++#define HSMP_SADDR_mskRANGE ( 0xFFF << HSMP_SADDR_offRANGE ) ++#define HSMP_SADDR_mskSADDR ( 0xFFF << HSMP_SADDR_offSADDR ) ++ ++/****************************************************************************** ++ * mr10: HSMP_EADDR (High Speed Memory Port Ending Address) ++ *****************************************************************************/ ++/* bit 0:19 reserved */ ++#define HSMP_EADDR_offEADDR 20 ++ ++#define HSMP_EADDR_mskEADDR ( 0xFFF << HSMP_EADDR_offEADDR ) ++ ++/****************************************************************************** ++ * dr0+(n*5): BPCn (n=0-7) (Breakpoint Control Register) ++ *****************************************************************************/ ++#define BPC_offWP 0 /* Configuration of BPAn */ ++#define BPC_offEL 1 /* Enable BPAn */ ++#define BPC_offS 2 /* Data address comparison for a store instruction */ ++#define BPC_offP 3 /* Compared data address is PA */ ++#define BPC_offC 4 /* CID value is compared with the BPCIDn register */ ++#define BPC_offBE0 5 /* Enable byte mask for the comparison with register */ ++#define BPC_offBE1 6 /* Enable byte mask for the comparison with register */ ++#define BPC_offBE2 7 /* Enable byte mask for the comparison with register */ ++#define BPC_offBE3 8 /* Enable byte mask for the comparison with register */ ++#define BPC_offT 9 /* Enable breakpoint Embedded Tracer triggering operation */ ++ ++#define BPC_mskWP ( 0x1 << BPC_offWP ) ++#define BPC_mskEL ( 0x1 << BPC_offEL ) ++#define BPC_mskS ( 0x1 << BPC_offS ) ++#define BPC_mskP ( 0x1 << BPC_offP ) ++#define BPC_mskC ( 0x1 << BPC_offC ) ++#define BPC_mskBE0 ( 0x1 << BPC_offBE0 ) ++#define BPC_mskBE1 ( 0x1 << BPC_offBE1 ) ++#define BPC_mskBE2 ( 0x1 << BPC_offBE2 ) ++#define BPC_mskBE3 ( 0x1 << BPC_offBE3 ) ++#define BPC_mskT ( 0x1 << BPC_offT ) ++ ++/****************************************************************************** ++ * dr1+(n*5): BPAn (n=0-7) (Breakpoint Address Register) ++ *****************************************************************************/ ++ ++ /* These registers contain break point address */ ++ ++/****************************************************************************** ++ * dr2+(n*5): BPAMn (n=0-7) (Breakpoint Address Mask Register) ++ *****************************************************************************/ ++ ++ /* These registerd contain the address comparison mask for the BPAn register */ ++ ++/****************************************************************************** ++ * dr3+(n*5): BPVn (n=0-7) Breakpoint Data Value Register ++ *****************************************************************************/ ++ ++ /* The BPVn register contains the data value that will be compared with the ++ * incoming load/store data value */ ++ ++/****************************************************************************** ++ * dr4+(n*5): BPCIDn (n=0-7) (Breakpoint Context ID Register) ++ *****************************************************************************/ ++#define BPCID_offCID 0 /* CID that will be compared with a process's CID */ ++/* bit 9:31 reserved */ ++ ++#define BPCID_mskCID ( 0x1FF << BPCID_offCID ) ++ ++/****************************************************************************** ++ * dr40: EDM_CFG (EDM Configuration Register) ++ *****************************************************************************/ ++#define EDM_CFG_offBC 0 /* Number of hardware breakpoint sets implemented */ ++#define EDM_CFG_offDIMU 3 /* Debug Instruction Memory Unit exists */ ++/* bit 4:15 reserved */ ++#define EDM_CFG_offVER 16 /* EDM version */ ++ ++#define EDM_CFG_mskBC ( 0x7 << EDM_CFG_offBC ) ++#define EDM_CFG_mskDIMU ( 0x1 << EDM_CFG_offDIMU ) ++#define EDM_CFG_mskVER ( 0xFFFF << EDM_CFG_offVER ) ++ ++/****************************************************************************** ++ * dr41: EDMSW (EDM Status Word) ++ *****************************************************************************/ ++#define EDMSW_offWV 0 /* Write Valid */ ++#define EDMSW_offRV 1 /* Read Valid */ ++#define EDMSW_offDE 2 /* Debug exception has occurred for this core */ ++/* bit 3:31 reserved */ ++ ++#define EDMSW_mskWV ( 0x1 << EDMSW_offWV ) ++#define EDMSW_mskRV ( 0x1 << EDMSW_offRV ) ++#define EDMSW_mskDE ( 0x1 << EDMSW_offDE ) ++ ++/****************************************************************************** ++ * dr42: EDM_CTL (EDM Control Register) ++ *****************************************************************************/ ++/* bit 0:30 reserved */ ++#define EDM_CTL_offV3_EDM_MODE 6 /* EDM compatibility control bit */ ++#define EDM_CTL_offDEH_SEL 31 /* Controls where debug exception is directed to */ ++ ++#define EDM_CTL_mskV3_EDM_MODE ( 0x1 << EDM_CTL_offV3_EDM_MODE ) ++#define EDM_CTL_mskDEH_SEL ( 0x1 << EDM_CTL_offDEH_SEL ) ++ ++/****************************************************************************** ++ * dr43: EDM_DTR (EDM Data Transfer Register) ++ *****************************************************************************/ ++ ++ /* This is used to exchange data between the embedded EDM logic ++ * and the processor core */ ++ ++/****************************************************************************** ++ * dr44: BPMTC (Breakpoint Match Trigger Counter Register) ++ *****************************************************************************/ ++#define BPMTC_offBPMTC 0 /* Breakpoint match trigger counter value */ ++/* bit 16:31 reserved */ ++ ++#define BPMTC_mskBPMTC ( 0xFFFF << BPMTC_offBPMTC ) ++ ++/****************************************************************************** ++ * dr45: DIMBR (Debug Instruction Memory Base Register) ++ *****************************************************************************/ ++/* bit 0:11 reserved */ ++#define DIMBR_offDIMB 12 /* Base address of the Debug Instruction Memory (DIM) */ ++#define DIMBR_mskDIMB ( 0xFFFFF << DIMBR_offDIMB ) ++ ++/****************************************************************************** ++ * dr46: TECR0(Trigger Event Control register 0) ++ * dr47: TECR1 (Trigger Event Control register 1) ++ *****************************************************************************/ ++#define TECR_offBP 0 /* Controld which BP is used as a trigger source */ ++#define TECR_offNMI 8 /* Use NMI as a trigger source */ ++#define TECR_offHWINT 9 /* Corresponding interrupt is used as a trigger source */ ++#define TECR_offEVIC 15 /* Enable HWINT as a trigger source in EVIC mode */ ++#define TECR_offSYS 16 /* Enable SYSCALL instruction as a trigger source */ ++#define TECR_offDBG 17 /* Enable debug exception as a trigger source */ ++#define TECR_offMRE 18 /* Enable MMU related exception as a trigger source */ ++#define TECR_offE 19 /* An exception is used as a trigger source */ ++/* bit 20:30 reserved */ ++#define TECR_offL 31 /* Link/Cascade TECR0 trigger event to TECR1 trigger event */ ++ ++#define TECR_mskBP ( 0xFF << TECR_offBP ) ++#define TECR_mskNMI ( 0x1 << TECR_offBNMI ) ++#define TECR_mskHWINT ( 0x3F << TECR_offBHWINT ) ++#define TECR_mskEVIC ( 0x1 << TECR_offBEVIC ) ++#define TECR_mskSYS ( 0x1 << TECR_offBSYS ) ++#define TECR_mskDBG ( 0x1 << TECR_offBDBG ) ++#define TECR_mskMRE ( 0x1 << TECR_offBMRE ) ++#define TECR_mskE ( 0x1 << TECR_offE ) ++#define TECR_mskL ( 0x1 << TECR_offL ) ++ ++/****************************************************************************** ++ * pfr0-2: PFMC0-2 (Performance Counter Register 0-2) ++ *****************************************************************************/ ++ ++ /* These registers contains performance event count */ ++ ++/****************************************************************************** ++ * pfr3: PFM_CTL (Performance Counter Control Register) ++ *****************************************************************************/ ++#define PFM_CTL_offEN0 0 /* Enable PFMC0 */ ++#define PFM_CTL_offEN1 1 /* Enable PFMC1 */ ++#define PFM_CTL_offEN2 2 /* Enable PFMC2 */ ++#define PFM_CTL_offIE0 3 /* Enable interrupt for PFMC0 */ ++#define PFM_CTL_offIE1 4 /* Enable interrupt for PFMC1 */ ++#define PFM_CTL_offIE2 5 /* Enable interrupt for PFMC2 */ ++#define PFM_CTL_offOVF0 6 /* Overflow bit of PFMC0 */ ++#define PFM_CTL_offOVF1 7 /* Overflow bit of PFMC1 */ ++#define PFM_CTL_offOVF2 8 /* Overflow bit of PFMC2 */ ++#define PFM_CTL_offKS0 9 /* Enable superuser mode event counting for PFMC0 */ ++#define PFM_CTL_offKS1 10 /* Enable superuser mode event counting for PFMC1 */ ++#define PFM_CTL_offKS2 11 /* Enable superuser mode event counting for PFMC2 */ ++#define PFM_CTL_offKU0 12 /* Enable user mode event counting for PFMC0 */ ++#define PFM_CTL_offKU1 13 /* Enable user mode event counting for PFMC1 */ ++#define PFM_CTL_offKU2 14 /* Enable user mode event counting for PFMC2 */ ++#define PFM_CTL_offSEL0 15 /* The event selection for PFMC0 */ ++#define PFM_CTL_offSEL1 21 /* The event selection for PFMC1 */ ++#define PFM_CTL_offSEL2 27 /* The event selection for PFMC2 */ ++/* bit 28:31 reserved */ ++ ++#define PFM_CTL_mskEN0 ( 0x01 << PFM_CTL_offEN0 ) ++#define PFM_CTL_mskEN1 ( 0x01 << PFM_CTL_offEN1 ) ++#define PFM_CTL_mskEN2 ( 0x01 << PFM_CTL_offEN2 ) ++#define PFM_CTL_mskIE0 ( 0x01 << PFM_CTL_offIE0 ) ++#define PFM_CTL_mskIE1 ( 0x01 << PFM_CTL_offIE1 ) ++#define PFM_CTL_mskIE2 ( 0x01 << PFM_CTL_offIE2 ) ++#define PFM_CTL_mskOVF0 ( 0x01 << PFM_CTL_offOVF0 ) ++#define PFM_CTL_mskOVF1 ( 0x01 << PFM_CTL_offOVF1 ) ++#define PFM_CTL_mskOVF2 ( 0x01 << PFM_CTL_offOVF2 ) ++#define PFM_CTL_mskKS0 ( 0x01 << PFM_CTL_offKS0 ) ++#define PFM_CTL_mskKS1 ( 0x01 << PFM_CTL_offKS1 ) ++#define PFM_CTL_mskKS2 ( 0x01 << PFM_CTL_offKS2 ) ++#define PFM_CTL_mskKU0 ( 0x01 << PFM_CTL_offKU0 ) ++#define PFM_CTL_mskKU1 ( 0x01 << PFM_CTL_offKU1 ) ++#define PFM_CTL_mskKU2 ( 0x01 << PFM_CTL_offKU2 ) ++#define PFM_CTL_mskSEL0 ( 0x01 << PFM_CTL_offSEL0 ) ++#define PFM_CTL_mskSEL1 ( 0x3F << PFM_CTL_offSEL1 ) ++#define PFM_CTL_mskSEL2 ( 0x3F << PFM_CTL_offSEL2 ) ++ ++/****************************************************************************** ++ * SDZ_CTL (Structure Downsizing Control Register) ++ *****************************************************************************/ ++#define SDZ_CTL_offICDZ 0 /* I-cache downsizing control */ ++#define SDZ_CTL_offDCDZ 3 /* D-cache downsizing control */ ++#define SDZ_CTL_offMTBDZ 6 /* MTLB downsizing control */ ++#define SDZ_CTL_offBTBDZ 9 /* Branch Target Table downsizing control */ ++/* bit 12:31 reserved */ ++#define SDZ_CTL_mskICDZ ( 0x07 << SDZ_CTL_offICDZ ) ++#define SDZ_CTL_mskDCDZ ( 0x07 << SDZ_CTL_offDCDZ ) ++#define SDZ_CTL_mskMTBDZ ( 0x07 << SDZ_CTL_offMTBDZ ) ++#define SDZ_CTL_mskBTBDZ ( 0x07 << SDZ_CTL_offBTBDZ ) ++ ++/****************************************************************************** ++ * N12MISC_CTL (N12 Miscellaneous Control Register) ++ *****************************************************************************/ ++#define N12MISC_CTL_offBTB 0 /* Disable Branch Target Buffer */ ++#define N12MISC_CTL_offRTP 1 /* Disable Return Target Predictor */ ++#define N12MISC_CTL_offPTEPF 2 /* Disable HPTWK L2 PTE pefetch */ ++/* bit 3:31 reserved */ ++ ++#define N12MISC_CTL_makBTB ( 0x1 << N12MISC_CTL_offBTB ) ++#define N12MISC_CTL_makRTP ( 0x1 << N12MISC_CTL_offRTP ) ++#define N12MISC_CTL_makPTEPF ( 0x1 << N12MISC_CTL_offPTEPF ) ++ ++/****************************************************************************** ++ * PRUSR_ACC_CTL (Privileged Resource User Access Control Registers) ++ *****************************************************************************/ ++#define PRUSR_ACC_CTL_offDMA_EN 0 /* Allow user mode access of DMA registers */ ++#define PRUSR_ACC_CTL_offPFM_EN 1 /* Allow user mode access of PFM registers */ ++ ++#define PRUSR_ACC_CTL_mskDMA_EN ( 0x1 << PRUSR_ACC_CTL_offDMA_EN ) ++#define PRUSR_ACC_CTL_mskPFM_EN ( 0x1 << PRUSR_ACC_CTL_offPFM_EN ) ++ ++/****************************************************************************** ++ * dmar0: DMA_CFG (DMA Configuration Register) ++ *****************************************************************************/ ++#define DMA_CFG_offNCHN 0 /* The number of DMA channels implemented */ ++#define DMA_CFG_offUNEA 2 /* Un-aligned External Address transfer feature */ ++#define DMA_CFG_off2DET 3 /* 2-D Element Transfer feature */ ++/* bit 4:15 reserved */ ++#define DMA_CFG_offVER 16 /* DMA architecture and implementation version */ ++ ++#define DMA_CFG_mskNCHN ( 0x3 << DMA_CFG_offNCHN ) ++#define DMA_CFG_mskUNEA ( 0x1 << DMA_CFG_offUNEA ) ++#define DMA_CFG_msk2DET ( 0x1 << DMA_CFG_off2DET ) ++#define DMA_CFG_mskVER ( 0xFFFF << DMA_CFG_offVER ) ++ ++/****************************************************************************** ++ * dmar1: DMA_GCSW (DMA Global Control and Status Word Register) ++ *****************************************************************************/ ++#define DMA_GCSW_offC0STAT 0 /* DMA channel 0 state */ ++#define DMA_GCSW_offC1STAT 3 /* DMA channel 1 state */ ++/* bit 6:11 reserved */ ++#define DMA_GCSW_offC0INT 12 /* DMA channel 0 generate interrupt */ ++#define DMA_GCSW_offC1INT 13 /* DMA channel 1 generate interrupt */ ++/* bit 14:30 reserved */ ++#define DMA_GCSW_offEN 31 /* Enable DMA engine */ ++ ++#define DMA_GCSW_mskC0STAT ( 0x7 << DMA_GCSW_offC0STAT ) ++#define DMA_GCSW_mskC1STAT ( 0x7 << DMA_GCSW_offC1STAT ) ++#define DMA_GCSW_mskC0INT ( 0x1 << DMA_GCSW_offC0INT ) ++#define DMA_GCSW_mskC1INT ( 0x1 << DMA_GCSW_offC1INT ) ++#define DMA_GCSW_mskEN ( 0x1 << DMA_GCSW_offEN ) ++ ++/****************************************************************************** ++ * dmar2: DMA_CHNSEL (DMA Channel Selection Register) ++ *****************************************************************************/ ++#define DMA_CHNSEL_offCHAN 0 /* Selected channel number */ ++/* bit 2:31 reserved */ ++ ++#define DMA_CHNSEL_mskCHAN ( 0x3 << DMA_CHNSEL_offCHAN ) ++ ++/****************************************************************************** ++ * dmar3: DMA_ACT (DMA Action Register) ++ *****************************************************************************/ ++#define DMA_ACT_offACMD 0 /* DMA Action Command */ ++/* bit 2:31 reserved */ ++#define DMA_ACT_mskACMD ( 0x3 << DMA_ACT_offACMD ) ++ ++/****************************************************************************** ++ * dmar4: DMA_SETUP (DMA Setup Register) ++ *****************************************************************************/ ++#define DMA_SETUP_offLM 0 /* Local Memory Selection */ ++#define DMA_SETUP_offTDIR 1 /* Transfer Direction */ ++#define DMA_SETUP_offTES 2 /* Transfer Element Size */ ++#define DMA_SETUP_offESTR 4 /* External memory transfer Stride */ ++#define DMA_SETUP_offCIE 16 /* Interrupt Enable on Completion */ ++#define DMA_SETUP_offSIE 17 /* Interrupt Enable on explicit Stop */ ++#define DMA_SETUP_offEIE 18 /* Interrupt Enable on Error */ ++#define DMA_SETUP_offUE 19 /* Enable the Un-aligned External Address */ ++#define DMA_SETUP_off2DE 20 /* Enable the 2-D External Transfer */ ++#define DMA_SETUP_offCOA 21 /* Transfer Coalescable */ ++/* bit 22:31 reserved */ ++ ++#define DMA_SETUP_mskLM ( 0x1 << DMA_SETUP_offLM ) ++#define DMA_SETUP_mskTDIR ( 0x1 << DMA_SETUP_offTDIR ) ++#define DMA_SETUP_mskTES ( 0x3 << DMA_SETUP_offTES ) ++#define DMA_SETUP_mskESTR ( 0xFFF << DMA_SETUP_offESTR ) ++#define DMA_SETUP_mskCIE ( 0x1 << DMA_SETUP_offCIE ) ++#define DMA_SETUP_mskSIE ( 0x1 << DMA_SETUP_offSIE ) ++#define DMA_SETUP_mskEIE ( 0x1 << DMA_SETUP_offEIE ) ++#define DMA_SETUP_mskUE ( 0x1 << DMA_SETUP_offUE ) ++#define DMA_SETUP_msk2DE ( 0x1 << DMA_SETUP_off2DE ) ++#define DMA_SETUP_mskCOA ( 0x1 << DMA_SETUP_offCOA ) ++ ++/****************************************************************************** ++ * dmar5: DMA_ISADDR (DMA Internal Start Address Register) ++ *****************************************************************************/ ++#define DMA_ISADDR_offISADDR 0 /* Internal Start Address */ ++/* bit 20:31 reserved */ ++#define DMA_ISADDR_mskISADDR ( 0xFFFFF << DMA_ISADDR_offISADDR ) ++ ++/****************************************************************************** ++ * dmar6: DMA_ESADDR (DMA External Start Address Register) ++ *****************************************************************************/ ++/* This register holds External Start Address */ ++ ++/****************************************************************************** ++ * dmar7: DMA_TCNT (DMA Transfer Element Count Register) ++ *****************************************************************************/ ++#define DMA_TCNT_offTCNT 0 /* DMA transfer element count */ ++/* bit 18:31 reserved */ ++#define DMA_TCNT_mskTCNT ( 0x3FFFF << DMA_TCNT_offTCNT ) ++ ++/****************************************************************************** ++ * dmar8: DMA_STATUS (DMA Status Register) ++ *****************************************************************************/ ++#define DMA_STATUS_offSTAT 0 /* DMA channel state */ ++#define DMA_STATUS_offSTUNA 3 /* Un-aligned error on External Stride value */ ++#define DMA_STATUS_offDERR 4 /* DMA Transfer Disruption Error */ ++#define DMA_STATUS_offEUNA 5 /* Un-aligned error on the External address */ ++#define DMA_STATUS_offIUNA 6 /* Un-aligned error on the Internal address */ ++#define DMA_STATUS_offIOOR 7 /* Out-Of-Range error on the Internal address */ ++#define DMA_STATUS_offEBUS 8 /* Bus Error on an External DMA transfer */ ++#define DMA_STATUS_offESUP 9 /* DMA setup error */ ++/* bit 10:31 reserved */ ++ ++#define DMA_STATUS_mskSTAT ( 0x7 << DMA_STATUS_offSTAT ) ++#define DMA_STATUS_mskSTUNA ( 0x1 << DMDMA_STATUS_offSTUNA ) ++#define DMA_STATUS_mskDERR ( 0x1 << DMDMA_STATUS_offDERR ) ++#define DMA_STATUS_mskEUNA ( 0x1 << DMDMA_STATUS_offEUNA ) ++#define DMA_STATUS_mskIUNA ( 0x1 << DMDMA_STATUS_offIUNA ) ++#define DMA_STATUS_mskIOOR ( 0x1 << DMDMA_STATUS_offIOOR ) ++#define DMA_STATUS_mskEBUS ( 0x1 << DMDMA_STATUS_offEBUS ) ++#define DMA_STATUS_mskESUP ( 0x1 << DMDMA_STATUS_offESUP ) ++ ++/****************************************************************************** ++ * dmar9: DMA_2DSET (DMA 2D Setup Register) ++ *****************************************************************************/ ++#define DMA_2DSET_offWECNT 0 /* The Width Element Count for a 2-D region */ ++#define DMA_2DSET_offHTSTR 16 /* The Height Stride for a 2-D region */ ++ ++#define DMA_2DSET_mskHTSTR ( 0xFFFF << DMA_2DSET_offHTSTR ) ++#define DMA_2DSET_mskWECNT ( 0xFFFF << DMA_2DSET_offWECNT ) ++ ++/****************************************************************************** ++ * dmar10: DMA_2DSCTL (DMA 2D Startup Control Register) ++ *****************************************************************************/ ++#define DMA_2DSCTL_offSTWECNT 0 /* Startup Width Element Count for a 2-D region */ ++/* bit 16:31 reserved */ ++ ++#define DMA_2DSCTL_mskSTWECNT ( 0xFFFF << DMA_2DSCTL_offSTWECNT ) ++ ++/****************************************************************************** ++ * fpcsr: FPCSR (Floating-Point Control Status Register) ++ *****************************************************************************/ ++#define FPCSR_offRM 0 ++#define FPCSR_offIVO 2 ++#define FPCSR_offDBZ 3 ++#define FPCSR_offOVF 4 ++#define FPCSR_offUDF 5 ++#define FPCSR_offIEX 6 ++#define FPCSR_offIVOE 7 ++#define FPCSR_offDBZE 8 ++#define FPCSR_offOVFE 9 ++#define FPCSR_offUDFE 10 ++#define FPCSR_offIEXE 11 ++#define FPCSR_offDNZ 12 ++#define FPCSR_offIVOT 13 ++#define FPCSR_offDBZT 14 ++#define FPCSR_offOVFT 15 ++#define FPCSR_offUDFT 16 ++#define FPCSR_offIEXT 17 ++#define FPCSR_offDNIT 18 ++#define FPCSR_offRIT 19 ++ ++#define FPCSR_mskRM ( 0x3 << FPCSR_offRM ) ++#define FPCSR_mskIVO ( 0x1 << FPCSR_offIVO ) ++#define FPCSR_mskDBZ ( 0x1 << FPCSR_offDBZ ) ++#define FPCSR_mskOVF ( 0x1 << FPCSR_offOVF ) ++#define FPCSR_mskUDF ( 0x1 << FPCSR_offUDF ) ++#define FPCSR_mskIEX ( 0x1 << FPCSR_offIEX ) ++#define FPCSR_mskIVOE ( 0x1 << FPCSR_offIVOE ) ++#define FPCSR_mskDBZE ( 0x1 << FPCSR_offDBZE ) ++#define FPCSR_mskOVFE ( 0x1 << FPCSR_offOVFE ) ++#define FPCSR_mskUDFE ( 0x1 << FPCSR_offUDFE ) ++#define FPCSR_mskIEXE ( 0x1 << FPCSR_offIEXE ) ++#define FPCSR_mskDNZ ( 0x1 << FPCSR_offDNZ ) ++#define FPCSR_mskIVOT ( 0x1 << FPCSR_offIVOT ) ++#define FPCSR_mskDBZT ( 0x1 << FPCSR_offDBZT ) ++#define FPCSR_mskOVFT ( 0x1 << FPCSR_offOVFT ) ++#define FPCSR_mskUDFT ( 0x1 << FPCSR_offUDFT ) ++#define FPCSR_mskIEXT ( 0x1 << FPCSR_offIEXT ) ++#define FPCSR_mskDNIT ( 0x1 << FPCSR_offDNIT ) ++#define FPCSR_mskRIT ( 0x1 << FPCSR_offRIT ) ++#define FPCSR_mskALL (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX) ++#define FPCSR_mskALLE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE) ++#define FPCSR_mskALLT (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT) ++ ++/****************************************************************************** ++ * fpcfg: FPCFG (Floating-Point Configuration Register) ++ *****************************************************************************/ ++#define FPCFG_offSP 0 ++#define FPCFG_offDP 1 ++#define FPCFG_offFREG 2 ++#define FPCFG_offFMA 4 ++#define FPCFG_offIMVER 22 ++#define FPCFG_offAVER 27 ++ ++#define FPCFG_mskSP ( 0x1 << FPCFG_offSP ) ++#define FPCFG_mskDP ( 0x1 << FPCFG_offDP ) ++#define FPCFG_mskFREG ( 0x3 << FPCFG_offFREG ) ++#define FPCFG_mskFMA ( 0x1 << FPCFG_offFMA ) ++#define FPCFG_mskIMVER ( 0x1F << FPCFG_offIMVER ) ++#define FPCFG_mskAVER ( 0x1F << FPCFG_offAVER ) ++ ++/****************************************************************************** ++ * fucpr: FUCOP_CTL (FPU and Coprocessor Enable Control Register) ++ *****************************************************************************/ ++#define FUCOP_CTL_offCP0EN 0 ++#define FUCOP_CTL_offCP1EN 1 ++#define FUCOP_CTL_offCP2EN 2 ++#define FUCOP_CTL_offCP3EN 3 ++#define FUCOP_CTL_offAUEN 31 ++ ++#define FUCOP_CTL_mskCP0EN ( 0x1 << FUCOP_CTL_offCP0EN ) ++#define FUCOP_CTL_mskCP1EN ( 0x1 << FUCOP_CTL_offCP1EN ) ++#define FUCOP_CTL_mskCP2EN ( 0x1 << FUCOP_CTL_offCP2EN ) ++#define FUCOP_CTL_mskCP3EN ( 0x1 << FUCOP_CTL_offCP3EN ) ++#define FUCOP_CTL_mskAUEN ( 0x1 << FUCOP_CTL_offAUEN ) ++ ++#endif /* __NDS32_BITFIELD_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bitops.h linux-3.4.110/arch/nds32/include/asm/bitops.h +--- linux-3.4.110.orig/arch/nds32/include/asm/bitops.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/bitops.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,256 @@ ++/* ++ * linux/arch/nds32/include/asm/bitops.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_BITOPS_H__ ++#define __NDS32_BITOPS_H__ ++ ++#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) ++ ++/* ++#include ++ ++static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p) ++{ ++ unsigned long flags; ++ unsigned long mask = 1UL << (bit & 31); ++ ++ p += bit >> 5; ++ ++ raw_local_irq_save(flags); ++ *p |= mask; ++ raw_local_irq_restore(flags); ++} ++ ++static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p) ++{ ++ unsigned long flags; ++ unsigned long mask = 1UL << (bit & 31); ++ ++ p += bit >> 5; ++ ++ raw_local_irq_save(flags); ++ *p &= ~mask; ++ raw_local_irq_restore(flags); ++} ++ ++static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p) ++{ ++ unsigned long flags; ++ unsigned long mask = 1UL << (bit & 31); ++ ++ p += bit >> 5; ++ ++ raw_local_irq_save(flags); ++ *p ^= mask; ++ raw_local_irq_restore(flags); ++} ++ ++static inline int ++____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p) ++{ ++ unsigned long flags; ++ unsigned int res; ++ unsigned long mask = 1UL << (bit & 31); ++ ++ p += bit >> 5; ++ ++ raw_local_irq_save(flags); ++ res = *p; ++ *p = res | mask; ++ raw_local_irq_restore(flags); ++ ++ return (res & mask) != 0; ++} ++static inline int ++____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p) ++{ ++ unsigned long flags; ++ unsigned int res; ++ unsigned long mask = 1UL << (bit & 31); ++ ++ p += bit >> 5; ++ ++ raw_local_irq_save(flags); ++ res = *p; ++ *p = res & ~mask; ++ raw_local_irq_restore(flags); ++ ++ return (res & mask) != 0; ++} ++ ++static inline int ++____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p) ++{ ++ unsigned long flags; ++ unsigned int res; ++ unsigned long mask = 1UL << (bit & 31); ++ ++ p += bit >> 5; ++ ++ raw_local_irq_save(flags); ++ res = *p; ++ *p = res ^ mask; ++ raw_local_irq_restore(flags); ++ ++ return (res & mask) != 0; ++} ++ ++#include ++#ifndef CONFIG_SMP ++#define ATOMIC_BITOP(name,nr,p) \ ++ (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p)) ++#else ++#define ATOMIC_BITOP(name,nr,p) _##name(nr,p) ++#endif ++ ++#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p) ++*/ ++ ++static inline void set_bit(int nr,volatile unsigned long *addr) ++{ ++ unsigned long mask = BIT_MASK(nr); ++ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); ++ unsigned long tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tor\t%0, %0, %2\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (p), "r" (mask) ++ : "memory"); ++} ++ ++static inline void clear_bit(int nr, volatile unsigned long *addr) ++{ ++ unsigned long mask = BIT_MASK(nr); ++ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); ++ unsigned long tmp; ++ ++ mask = ~mask; ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tand\t%0, %0, %2\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (p), "r" (mask) ++ : "memory"); ++} ++ ++static inline void change_bit(int nr, volatile unsigned long *addr) ++{ ++ unsigned long mask = BIT_MASK(nr); ++ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); ++ unsigned long tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\txor\t%0, %0, %2\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (p), "r" (mask) ++ : "memory"); ++} ++ ++static inline int test_and_set_bit(int nr, volatile unsigned long *addr) ++{ ++ unsigned long mask = BIT_MASK(nr); ++ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); ++ unsigned long tmp ,ret; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%2+$r15]\n" ++ "\tor\t%1, %0, %3\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (ret), "=&r" (tmp) ++ : "r" (p), "r" (mask) ++ : "memory"); ++ return (ret & mask) != 0; ++} ++ ++static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) ++{ ++ unsigned long mask = BIT_MASK(nr); ++ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); ++ unsigned long tmp, ret; ++ unsigned long mask2 = ~mask; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%2+$r15]\n" ++ "\tand\t%1, %0, %3\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (ret), "=&r" (tmp) ++ : "r" (p), "r" (mask2) ++ : "memory"); ++ return (ret & mask) != 0; ++} ++ ++static inline int test_and_change_bit(int nr, volatile unsigned long *addr) ++{ ++ unsigned long mask = BIT_MASK(nr); ++ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); ++ unsigned long tmp, ret; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%2+$r15]\n" ++ "\txor\t%1, %0, %3\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (ret), "=&r" (tmp) ++ : "r" (p), "r" (mask) ++ : "memory"); ++ return (ret & mask) != 0; ++} ++#else ++#include ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* ++ * Ext2 is defined to use little-endian byte ordering. ++ */ ++#include ++ ++#endif /* __KERNEL__ */ ++ ++#define smp_mb__before_clear_bit() barrier() ++#define smp_mb__after_clear_bit() barrier() ++ ++#endif /* __NDS32_BITOPS_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bitsperlong.h linux-3.4.110/arch/nds32/include/asm/bitsperlong.h +--- linux-3.4.110.orig/arch/nds32/include/asm/bitsperlong.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/bitsperlong.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1 @@ ++#include +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bug.h linux-3.4.110/arch/nds32/include/asm/bug.h +--- linux-3.4.110.orig/arch/nds32/include/asm/bug.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/bug.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * linux/arch/nds32/include/asm/bug.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_BUG_H__ ++#define __NDS32_BUG_H__ ++ ++#define HAVE_ARCH_BUG ++#include ++ ++#define BUG() do { \ ++ dump_stack(); \ ++ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ ++ panic("BUG!"); \ ++} while (0) ++ ++#endif /* __NDS32_BUG_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/bugs.h linux-3.4.110/arch/nds32/include/asm/bugs.h +--- linux-3.4.110.orig/arch/nds32/include/asm/bugs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/bugs.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/bugs.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_BUGS_H__ ++#define __NDS32_BUGS_H__ ++ ++static inline void check_bugs(void) {} ++ ++#endif /* __NDS32_BUGS_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/byteorder.h linux-3.4.110/arch/nds32/include/asm/byteorder.h +--- linux-3.4.110.orig/arch/nds32/include/asm/byteorder.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/byteorder.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,15 @@ ++/* ++ * linux/arch/nds32/include/asm/byteorder.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_BYTEORDER_H__ ++#define __NDS32_BYTEORDER_H__ ++ ++#ifdef __NDS32_EB__ ++#include ++#else ++#include ++#endif ++ ++#endif /* __NDS32_BYTEORDER_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cacheflush.h linux-3.4.110/arch/nds32/include/asm/cacheflush.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cacheflush.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cacheflush.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * linux/arch/nds32/include/asm/cacheflush.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_CACHEFLUSH_H__ ++#define __NDS32_CACHEFLUSH_H__ ++ ++#include ++ ++#define PG_dcache_dirty PG_arch_1 ++ ++void flush_cache_mm(struct mm_struct *mm); ++ ++void flush_cache_dup_mm(struct mm_struct *mm); ++ ++void flush_cache_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end); ++ ++void flush_cache_page(struct vm_area_struct *vma, ++ unsigned long addr, unsigned long pfn); ++ ++void flush_cache_kmaps(void); ++ ++void flush_cache_vmap(unsigned long start, unsigned long end); ++ ++void flush_cache_vunmap(unsigned long start, unsigned long end); ++ ++ ++void flush_dcache_page(struct page *page); ++ ++void copy_to_user_page(struct vm_area_struct *vma, struct page *page, ++ unsigned long vaddr, void *dst, void *src, int len); ++ ++void copy_from_user_page(struct vm_area_struct *vma, struct page *page, ++ unsigned long vaddr, void *dst, void *src, int len); ++ ++#ifndef CONFIG_CPU_CACHE_NONALIASING ++#define ARCH_HAS_FLUSH_ANON_PAGE ++void flush_anon_page(struct vm_area_struct *vma, ++ struct page *page, unsigned long vaddr); ++ ++#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE ++void flush_kernel_dcache_page(struct page *page); ++#endif ++ ++void flush_icache_range(unsigned long start, unsigned long end); ++ ++void flush_icache_page(struct vm_area_struct *vma, struct page *page); ++ ++#define flush_dcache_mmap_lock(mapping) spin_lock_irq(&(mapping)->tree_lock) ++#define flush_dcache_mmap_unlock(mapping) spin_unlock_irq(&(mapping)->tree_lock) ++ ++#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 ++#endif /* __NDS32_CACHEFLUSH_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cache.h linux-3.4.110/arch/nds32/include/asm/cache.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cache.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cache.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * linux/arch/nds32/include/asm/cache.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_CACHE_H__ ++#define __NDS32_CACHE_H__ ++ ++#define L1_CACHE_BYTES 32 ++#define L1_CACHE_SHIFT 5 ++ ++/* ++ * * Memory returned by kmalloc() may be used for DMA, so we must make ++ * * sure that all such allocations are cache aligned. Otherwise, ++ * * unrelated code may cause parts of the buffer to be read into the ++ * * cache before the transfer is done, causing old data to be seen by ++ * * the CPU. ++ * */ ++#define ARCH_DMA_MINALIGN L1_CACHE_BYTES ++ ++ ++#endif /* __NDS32_CACHE_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cache_info.h linux-3.4.110/arch/nds32/include/asm/cache_info.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cache_info.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cache_info.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * linux/arch/nds32/include/asm/cache.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++struct cache_info { ++ unsigned char cache_type; ++ unsigned char ways; ++ unsigned char way_bits; ++ unsigned char line_bits; ++ unsigned char line_size; ++ unsigned char set_bits; ++ unsigned short sets; ++ unsigned short size; ++ unsigned short aliasing_num; ++ unsigned int aliasing_mask; ++ unsigned int not_aliasing_mask; ++}; +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/checksum.h linux-3.4.110/arch/nds32/include/asm/checksum.h +--- linux-3.4.110.orig/arch/nds32/include/asm/checksum.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/checksum.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,173 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1995, 96, 97, 98, 99, 2001 by Ralf Baechle ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * Copyright (C) 2001 Thiemo Seufer. ++ * Copyright (C) 2002 Maciej W. Rozycki ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++#ifndef _ASM_CHECKSUM_H ++#define _ASM_CHECKSUM_H ++ ++#include ++ ++#include ++ ++/* ++ * computes the checksum of a memory block at buff, length len, ++ * and adds in "sum" (32-bit) ++ * ++ * returns a 32-bit number suitable for feeding into itself ++ * or csum_tcpudp_magic ++ * ++ * this function must be called with even lengths, except ++ * for the last fragment, which may be odd ++ * ++ * it's best to have buff aligned on a 32-bit boundary ++ */ ++unsigned int csum_partial(const void *buff, int len, unsigned int sum); ++ ++/* ++ * this is a new version of the above that records errors it finds in *errp, ++ * but continues and zeros the rest of the buffer. ++ */ ++unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len, ++ unsigned int sum, int *errp); ++ ++/* ++ * Copy and checksum to user ++ */ ++#define HAVE_CSUM_COPY_USER ++static inline unsigned int csum_and_copy_to_user (const unsigned char *src, ++ unsigned char __user *dst, ++ int len, int sum, ++ int *err_ptr) ++{ ++ sum = csum_partial(src, len, sum); ++ ++ if (copy_to_user(dst, src, len)) { ++ *err_ptr = -EFAULT; ++ return -1; ++ } ++ ++ return sum; ++} ++ ++/* ++ * the same as csum_partial, but copies from user space (but on MIPS ++ * we have just one address space, so this is identical to the above) ++ */ ++unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, ++ int len, unsigned int sum); ++ ++/* ++ * Fold a partial checksum without adding pseudo headers ++ */ ++static inline unsigned short int csum_fold(unsigned int sum) ++{ ++ __asm__( ++ "slli\t$p1,%0,16\n\t" ++ "add\t%0,%0,$p1\n\t" ++ "slt\t$p1,%0,$p1\n\t" ++ "srli\t%0,%0,16\n\t" ++ "add\t%0,%0,$p1\n\t" ++ "movi\t$p1,0xffff\n\t" ++ "xor\t%0,%0,$p1" ++ : "=r" (sum) ++ : "0" (sum)); ++ ++ return sum; ++} ++ ++/* ++ * This is a version of ip_compute_csum() optimized for IP headers, ++ * which always checksum on 4 octet boundaries. ++ * ++ * By Jorge Cwik , adapted for linux by ++ * Arnt Gulbrandsen. ++ */ ++static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) ++{ ++ unsigned int *word = (unsigned int *) iph; ++ unsigned int *stop = word + ihl; ++ unsigned int csum; ++ int carry; ++ ++ csum = word[0]; ++ csum += word[1]; ++ carry = (csum < word[1]); ++ csum += carry; ++ ++ csum += word[2]; ++ carry = (csum < word[2]); ++ csum += carry; ++ ++ csum += word[3]; ++ carry = (csum < word[3]); ++ csum += carry; ++ ++ word += 4; ++ do { ++ csum += *word; ++ carry = (csum < *word); ++ csum += carry; ++ word++; ++ } while (word != stop); ++ ++ return csum_fold(csum); ++} ++ ++static inline unsigned int csum_tcpudp_nofold(unsigned long saddr, ++ unsigned long daddr, unsigned short len, unsigned short proto, ++ unsigned int sum) ++{ ++ __asm__( ++ "add\t%0, %0, %2\n\t" ++ "slt\t$p1, %0, %2\n\t" ++ "add\t%0, %0, $p1\n\t" ++ ++ "add\t%0, %0, %3\n\t" ++ "slt\t$p1, %0, %3\n\t" ++ "add\t%0, %0, $p1\n\t" ++ ++ "add\t%0, %0, %4\n\t" ++ "slt\t$p1, %0, %4\n\t" ++ "add\t%0, %0, $p1" ++ : "=r" (sum) ++ : "0" (daddr), "r"(saddr), ++#ifdef __NDS32_EL__ ++ "r" (((unsigned long)htons(len)<<16) + proto*256), ++#else ++ "r" (((unsigned long)(proto)<<16) + len), ++#endif ++ "r" ((__force unsigned long)sum)); ++ ++ return sum; ++} ++ ++/* ++ * computes the checksum of the TCP/UDP pseudo-header ++ * returns a 16-bit checksum, already complemented ++ */ ++static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, ++ unsigned long daddr, ++ unsigned short len, ++ unsigned short proto, ++ unsigned int sum) ++{ ++ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); ++} ++ ++/* ++ * this routine is used for miscellaneous IP-like checksums, mainly ++ * in icmp.c ++ */ ++static inline unsigned short ip_compute_csum(const void * buff, int len) ++{ ++ return csum_fold(csum_partial(buff, len, 0)); ++} ++ ++#endif /* _ASM_CHECKSUM_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cmpxchg.h linux-3.4.110/arch/nds32/include/asm/cmpxchg.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cmpxchg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cmpxchg.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,88 @@ ++#ifndef __ASM_NDS32_CMPXCHG_H ++#define __ASM_NDS32_CMPXCHG_H ++ ++#include ++ ++#define xchg(ptr,x) \ ++ ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) ++ ++static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) ++{ ++ extern void __bad_xchg(volatile void *, int); ++ unsigned long ret; ++ unsigned long flags; ++ ++ switch (size) { ++ case 4: ++#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%2+$r15]\n" ++ "\tori\t%1, %3, #0x0\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (ret), "=&r" (flags) ++ : "r" (ptr), "r" (x) ++ : "memory"); ++#else ++ raw_local_irq_save(flags); ++ ret = *(volatile unsigned long *)ptr; ++ *(volatile unsigned long *)ptr = x; ++ raw_local_irq_restore(flags); ++#endif ++ break; ++ default: ++ __bad_xchg(ptr, size); ++ ret = 0; ++ } ++ return ret; ++} ++ ++ ++#define __HAVE_ARCH_CMPXCHG 1 ++ ++static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, ++ unsigned long new, int size) ++{ ++ extern void __cmpxchg_called_with_bad_pointer(void); /*nonexistence */ ++ unsigned long retval, tmp; ++ unsigned long flags; ++ switch (size) { ++ case 4: ++#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%3+$r15]\n" ++ "\tsub\t%2, %0, %5\n" ++ "\tcmovz\t%1, %4, %2\n" ++ "\tcmovn\t%1, %0, %2\n" ++ "\tscw\t%1, [%3+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (retval), "=&r" (flags), "=&r" (tmp) ++ : "r" (ptr), "r" (new), "r" (old)); ++#else ++ raw_local_irq_save(flags); ++ retval = *(volatile unsigned long *)ptr; ++ if (retval == old) ++ *(volatile unsigned long *)ptr = new; ++ raw_local_irq_restore(flags); ++#endif ++ break; ++ default: ++ __cmpxchg_called_with_bad_pointer(); ++ tmp = 0; ++ } ++ return retval; ++} ++ ++#define cmpxchg(ptr,o,n) \ ++ ({ \ ++ __typeof__(*(ptr)) _o_ = (o); \ ++ __typeof__(*(ptr)) _n_ = (n); \ ++ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ ++ (unsigned long)_n_, sizeof(*(ptr))); \ ++ }) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cpu.h linux-3.4.110/arch/nds32/include/asm/cpu.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cpu.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * linux/arch/nds32/include/asm/cpu.h ++ * ++ * Copyright (C) 2004-2005 ARM Ltd. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_NDS32_CPU_H ++#define __ASM_NDS32_CPU_H ++ ++#include ++ ++struct cpuinfo_nds32 { ++ struct cpu cpu; ++#ifdef CONFIG_SMP ++ unsigned int loops_per_jiffy; ++#endif ++}; ++ ++DECLARE_PER_CPU(struct cpuinfo_nds32, cpu_data); ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cputime.h linux-3.4.110/arch/nds32/include/asm/cputime.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cputime.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cputime.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/cputime.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_CPUTIME_H__ ++#define __NDS32_CPUTIME_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/cpuver.h linux-3.4.110/arch/nds32/include/asm/cpuver.h +--- linux-3.4.110.orig/arch/nds32/include/asm/cpuver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/cpuver.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,34 @@ ++/* ++ * linux/arch/nds32/include/asm/cpuver.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_CPUVER_H__ ++#define __NDS32_CPUVER_H__ ++ ++#include ++#include ++ ++#define GET_CPU_ID()\ ++ (( GET_CPU_VER() & CPU_VER_mskCPUID) >> CPU_VER_offCPUID) ++ ++#define GET_CPU_REV()\ ++ (( GET_CPU_VER() & CPU_VER_mskREV) >> CPU_VER_offREV) ++ ++#define GET_CPU_CFGID()\ ++ (( GET_CPU_VER() & CPU_VER_mskCFGID) >> CPU_VER_offCFGID) ++ ++#define CPU_IS_N1213_43U1HA0()\ ++ (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0c000000) &&\ ++ ((GET_CPU_VER() & CPU_VER_mskREV) == 0x00010000)) ++ ++#define CPU_IS_N1213_43U1HB0()\ ++ (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0c000000) &&\ ++ ((GET_CPU_VER() & CPU_VER_mskREV) == 0x00020000)) ++ ++#define CPU_IS_N1033_S()\ ++ (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0a000000) &&\ ++ ((GET_CPU_VER() & CPU_VER_mskREV) == 0x000c0000)) ++ ++#endif ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/current.h linux-3.4.110/arch/nds32/include/asm/current.h +--- linux-3.4.110.orig/arch/nds32/include/asm/current.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/current.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * linux/arch/nds32/include/asm/current.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_CURRENT_H__ ++#define __NDS32_CURRENT_H__ ++ ++#include ++ ++static inline struct task_struct *get_current(void) ++{ ++ return current_thread_info()->task; ++} ++ ++#define current get_current() ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/delay.h linux-3.4.110/arch/nds32/include/asm/delay.h +--- linux-3.4.110.orig/arch/nds32/include/asm/delay.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/delay.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,39 @@ ++/* ++ * linux/arch/nds32/include/asm/delay.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_DELAY_H__ ++#define __NDS32_DELAY_H__ ++ ++#include ++ ++static inline void __delay(unsigned long loops) ++{ ++ __asm__ __volatile__ ( ++ "1:\n" ++ "\taddi\t%0, %0, -1\n" ++ "\tbgtz\t%0, 1b\n" ++ : "=r" (loops) : "0" (loops)); ++} ++ ++static inline void __udelay(unsigned long usecs, unsigned long lpj) ++{ ++ usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + ++ 0x80000000ULL) >> 32); ++ usecs=(unsigned long)(((unsigned long long)usecs*lpj)>>32); ++ __delay(usecs); ++} ++ ++#define udelay(usecs) __udelay((usecs), loops_per_jiffy) ++ ++/* make sure "usecs *= ..." in udelay do not overflow. */ ++#if HZ >= 1000 ++#define MAX_UDELAY_MS 1 ++#elif HZ <= 200 ++#define MAX_UDELAY_MS 5 ++#else ++#define MAX_UDELAY_MS (1000 / HZ) ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/device.h linux-3.4.110/arch/nds32/include/asm/device.h +--- linux-3.4.110.orig/arch/nds32/include/asm/device.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/device.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/device.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_DEVICE_H__ ++#define __NDS32_DEVICE_H__ ++ ++#include ++ ++#endif /* __NDS32_DEVICE_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/div64.h linux-3.4.110/arch/nds32/include/asm/div64.h +--- linux-3.4.110.orig/arch/nds32/include/asm/div64.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/div64.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/div64.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_DIV64_H__ ++#define __NDS32_DIV64_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/dmad.h linux-3.4.110/arch/nds32/include/asm/dmad.h +--- linux-3.4.110.orig/arch/nds32/include/asm/dmad.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/dmad.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,1071 @@ ++/* ++ * Copyright Andes Technology Corporation 2007-2008 ++ * All Rights Reserved. ++ * ++ * Revision History: ++ * ++ * Aug.21.2007 Created. ++ * ++ * DESCRIPTION ++ * ++ * DMA controller driver internal supplement library. ++ * ++ */ ++ ++#ifndef __NDS_DMAD_INC__ ++#define __NDS_DMAD_INC__ ++ ++#include ++ ++/***************************************************************************** ++ * Configuration section ++*****************************************************************************/ ++ ++/* Debug trace enable switch */ ++#define DMAD_ERROR_TRACE 1 /* message for fatal errors */ ++//MOD by river 2010.10.19 ++#define DMAD_DEBUG_TRACE 0 /* message for debug trace */ ++//End MOD by river 2010.10.19 ++ ++//#ifndef addr_t ++typedef u32 addr_t; ++//#endif ++/* for amerald */ ++#define AMERALD_PRODUCT_ID 0x41471000 ++#define AMERALD_MASK 0xFFFFF000 ++ ++/***************************************************************************** ++ * DMAC - AG101 AHB ++*****************************************************************************/ ++/* Device base address */ ++#define DMAC_BASE DMAC_FTDMAC020_0_VA_BASE ++ ++/* DMA controller registers (8-bit width) */ ++#define DMAC_INT (DMAC_BASE + 0x00) ++#define DMAC_INT_TC (DMAC_BASE + 0x04) ++#define DMAC_INT_TC_CLR (DMAC_BASE + 0x08) ++#define DMAC_INT_ERRABT (DMAC_BASE + 0x0c) ++#define DMAC_INT_ERRABT_CLR (DMAC_BASE + 0x10) ++#define DMAC_TC (DMAC_BASE + 0x14) ++#define DMAC_ERRABT (DMAC_BASE + 0x18) ++#define DMAC_CH_EN (DMAC_BASE + 0x1c) ++#define DMAC_CH_BUSY (DMAC_BASE + 0x20) ++#define DMAC_CSR (DMAC_BASE + 0x24) ++#define DMAC_SYNC (DMAC_BASE + 0x28) ++ ++/* DMA channel registers base address */ ++#define DMAC_C0_OFFSET 0x100 ++#define DMAC_C1_OFFSET 0x120 ++#define DMAC_C2_OFFSET 0x140 ++#define DMAC_C3_OFFSET 0x160 ++#define DMAC_C4_OFFSET 0x180 ++#define DMAC_C5_OFFSET 0x1a0 ++#define DMAC_C6_OFFSET 0x1c0 ++#define DMAC_C7_OFFSET 0x1e0 ++ ++#define DMAC_C0_BASE (DMAC_BASE + DMAC_C0_OFFSET) ++#define DMAC_C1_BASE (DMAC_BASE + DMAC_C1_OFFSET) ++#define DMAC_C2_BASE (DMAC_BASE + DMAC_C2_OFFSET) ++#define DMAC_C3_BASE (DMAC_BASE + DMAC_C3_OFFSET) ++#define DMAC_C4_BASE (DMAC_BASE + DMAC_C4_OFFSET) ++#define DMAC_C5_BASE (DMAC_BASE + DMAC_C5_OFFSET) ++#define DMAC_C6_BASE (DMAC_BASE + DMAC_C6_OFFSET) ++#define DMAC_C7_BASE (DMAC_BASE + DMAC_C7_OFFSET) ++ ++#define DMAC_MAX_CHANNELS 8 ++#define DMAC_BASE_CH(n) (DMAC_C0_BASE + \ ++ (DMAC_C1_OFFSET - DMAC_C0_OFFSET) * \ ++ (addr_t)(n)) /* n = 0 ~ 3 */ ++ ++#define DMAC_CSR_OFFSET 0x00 ++#define DMAC_CFG_OFFSET 0x04 ++#define DMAC_SRC_ADDR_OFFSET 0x08 ++#define DMAC_DST_ADDR_OFFSET 0x0c ++#define DMAC_LLP_OFFSET 0x10 ++#define DMAC_SIZE_OFFSET 0x14 ++ ++/* DMA channel 0 registers (32-bit width) */ ++#define DMAC_C0_CSR (DMAC_C0_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C0_CFG (DMAC_C0_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C0_SRC_ADDR (DMAC_C0_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C0_DST_ADDR (DMAC_C0_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C0_LLP (DMAC_C0_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C0_SIZE (DMAC_C0_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 1 registers (32-bit width) */ ++#define DMAC_C1_CSR (DMAC_C1_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C1_CFG (DMAC_C1_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C1_SRC_ADDR (DMAC_C1_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C1_DST_ADDR (DMAC_C1_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C1_LLP (DMAC_C1_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C1_SIZE (DMAC_C1_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 2 registers (32-bit width) */ ++#define DMAC_C2_CSR (DMAC_C2_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C2_CFG (DMAC_C2_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C2_SRC_ADDR (DMAC_C2_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C2_DST_ADDR (DMAC_C2_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C2_LLP (DMAC_C2_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C2_SIZE (DMAC_C2_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 3 registers (32-bit width) */ ++#define DMAC_C3_CSR (DMAC_C3_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C3_CFG (DMAC_C3_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C3_SRC_ADDR (DMAC_C3_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C3_DST_ADDR (DMAC_C3_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C3_LLP (DMAC_C3_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C3_SIZE (DMAC_C3_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 4 registers (32-bit width) */ ++#define DMAC_C4_CSR (DMAC_C4_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C4_CFG (DMAC_C4_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C4_SRC_ADDR (DMAC_C4_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C4_DST_ADDR (DMAC_C4_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C4_LLP (DMAC_C4_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C4_SIZE (DMAC_C4_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 5 registers (32-bit width) */ ++#define DMAC_C5_CSR (DMAC_C5_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C5_CFG (DMAC_C5_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C5_SRC_ADDR (DMAC_C5_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C5_DST_ADDR (DMAC_C5_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C5_LLP (DMAC_C5_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C5_SIZE (DMAC_C5_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 6 registers (32-bit width) */ ++#define DMAC_C6_CSR (DMAC_C6_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C6_CFG (DMAC_C6_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C6_SRC_ADDR (DMAC_C6_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C6_DST_ADDR (DMAC_C6_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C6_LLP (DMAC_C6_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C6_SIZE (DMAC_C6_BASE + DMAC_SIZE_OFFSET) ++ ++/* DMA channel 7 registers (32-bit width) */ ++#define DMAC_C7_CSR (DMAC_C7_BASE + DMAC_CSR_OFFSET) ++#define DMAC_C7_CFG (DMAC_C7_BASE + DMAC_CFG_OFFSET) ++#define DMAC_C7_SRC_ADDR (DMAC_C7_BASE + DMAC_SRC_ADDR_OFFSET) ++#define DMAC_C7_DST_ADDR (DMAC_C7_BASE + DMAC_DST_ADDR_OFFSET) ++#define DMAC_C7_LLP (DMAC_C7_BASE + DMAC_LLP_OFFSET) ++#define DMAC_C7_SIZE (DMAC_C7_BASE + DMAC_SIZE_OFFSET) ++ ++/***************************************************************************** ++ * DMAC defs - AG101 AHB ++*****************************************************************************/ ++ ++/* Interrupt status register (+00) */ ++#define DMAC_INT0_MASK 0x01 ++#define DMAC_INT0_BIT 0 ++#define DMAC_INT1_MASK 0x02 ++#define DMAC_INT1_BIT 1 ++#define DMAC_INT2_MASK 0x04 ++#define DMAC_INT2_BIT 2 ++#define DMAC_INT3_MASK 0x08 ++#define DMAC_INT3_BIT 3 ++ ++/* Interrupt for terminal count status register (+0x04) */ ++#define DMAC_INT_TC0_MASK 0x01 ++#define DMAC_INT_TC0_BIT 0 ++#define DMAC_INT_TC1_MASK 0x02 ++#define DMAC_INT_TC1_BIT 1 ++#define DMAC_INT_TC2_MASK 0x04 ++#define DMAC_INT_TC2_BIT 2 ++#define DMAC_INT_TC3_MASK 0x08 ++#define DMAC_INT_TC3_BIT 3 ++#define DMAC_INT_TC4_MASK 0x01 ++#define DMAC_INT_TC4_BIT 0 ++#define DMAC_INT_TC5_MASK 0x02 ++#define DMAC_INT_TC5_BIT 1 ++#define DMAC_INT_TC6_MASK 0x04 ++#define DMAC_INT_TC6_BIT 2 ++#define DMAC_INT_TC7_MASK 0x08 ++#define DMAC_INT_TC7_BIT 3 ++ ++#define DMAC_INT_TC_MASK 0xff ++#define DMAC_INT_TC_SHIFT 0 ++ ++/* Interrupt for terminal count clear register (+0x08) */ ++#define DMAC_INT_TC0_CLR_MASK 0x01 ++#define DMAC_INT_TC0_CLR_BIT 0 ++#define DMAC_INT_TC1_CLR_MASK 0x02 ++#define DMAC_INT_TC1_CLR_BIT 1 ++#define DMAC_INT_TC2_CLR_MASK 0x04 ++#define DMAC_INT_TC2_CLR_BIT 2 ++#define DMAC_INT_TC3_CLR_MASK 0x08 ++#define DMAC_INT_TC3_CLR_BIT 3 ++ ++#define DMAC_INT_TC_CLR_MASK 0x0f ++#define DMAC_INT_TC_CLR_SHIFT 0 ++ ++/* Interrupt for error/abort status register (+0x0c, 32-bits width) */ ++#define DMAC_INT_ERR0_MASK 0x00000001 ++#define DMAC_INT_ERR0_BIT 0 ++#define DMAC_INT_ERR1_MASK 0x00000002 ++#define DMAC_INT_ERR1_BIT 1 ++#define DMAC_INT_ERR2_MASK 0x00000004 ++#define DMAC_INT_ERR2_BIT 2 ++#define DMAC_INT_ERR3_MASK 0x00000008 ++#define DMAC_INT_ERR3_BIT 3 ++ ++#define DMAC_INT_ERR_MASK 0x0000000f ++#define DMAC_INT_ERR_SHIFT 0 ++ ++#define DMAC_INT_ABT0_MASK 0x00010000 ++#define DMAC_INT_ABT0_BIT 16 ++#define DMAC_INT_ABT1_MASK 0x00020000 ++#define DMAC_INT_ABT1_BIT 17 ++#define DMAC_INT_ABT2_MASK 0x00040000 ++#define DMAC_INT_ABT2_BIT 18 ++#define DMAC_INT_ABT3_MASK 0x00080000 ++#define DMAC_INT_ABT3_BIT 19 ++ ++#define DMAC_INT_ABT_MASK 0x000f0000 ++#define DMAC_INT_ABT_SHIFT 16 ++ ++/* Interrupt for error/abort status clear register (+0x10, 32-bits width) */ ++#define DMAC_INT_ERR0_CLR_MASK 0x00000001 ++#define DMAC_INT_ERR0_CLR_BIT 0 ++#define DMAC_INT_ERR1_CLR_MASK 0x00000002 ++#define DMAC_INT_ERR1_CLR_BIT 1 ++#define DMAC_INT_ERR2_CLR_MASK 0x00000004 ++#define DMAC_INT_ERR2_CLR_BIT 2 ++#define DMAC_INT_ERR3_CLR_MASK 0x00000008 ++#define DMAC_INT_ERR3_CLR_BIT 3 ++ ++#define DMAC_INT_ERR_CLR_MASK 0x0000000f ++#define DMAC_INT_ERR_CLR_SHIFT 0 ++ ++#define DMAC_INT_ABT0_CLR_MASK 0x00010000 ++#define DMAC_INT_ABT0_CLR_BIT 16 ++#define DMAC_INT_ABT1_CLR_MASK 0x00020000 ++#define DMAC_INT_ABT1_CLR_BIT 17 ++#define DMAC_INT_ABT2_CLR_MASK 0x00040000 ++#define DMAC_INT_ABT2_CLR_BIT 18 ++#define DMAC_INT_ABT3_CLR_MASK 0x00080000 ++#define DMAC_INT_ABT3_CLR_BIT 19 ++ ++#define DMAC_INT_ABT_CLR_MASK 0x000f0000 ++#define DMAC_INT_ABT_CLR_SHIFT 16 ++ ++/* Terminal count status register (+0x14) */ ++#define DMAC_TC0_MASK 0x01 ++#define DMAC_TC0_BIT 0 ++#define DMAC_TC1_MASK 0x02 ++#define DMAC_TC1_BIT 1 ++#define DMAC_TC2_MASK 0x04 ++#define DMAC_TC2_BIT 2 ++#define DMAC_TC3_MASK 0x08 ++#define DMAC_TC3_BIT 3 ++ ++/* Error/abort status register (+0x18, 32-bits width) */ ++#define DMAC_ERR0_MASK 0x00000001 ++#define DMAC_ERR0_BIT 0 ++#define DMAC_ERR1_MASK 0x00000002 ++#define DMAC_ERR1_BIT 1 ++#define DMAC_ERR2_MASK 0x00000004 ++#define DMAC_ERR2_BIT 2 ++#define DMAC_ERR3_MASK 0x00000008 ++#define DMAC_ERR3_BIT 3 ++ ++#define DMAC_ABT0_MASK 0x00010000 ++#define DMAC_ABT0_BIT 16 ++#define DMAC_ABT1_MASK 0x00020000 ++#define DMAC_ABT1_BIT 17 ++#define DMAC_ABT2_MASK 0x00040000 ++#define DMAC_ABT2_BIT 18 ++#define DMAC_ABT3_MASK 0x00080000 ++#define DMAC_ABT3_BIT 19 ++ ++/* Channel enable status register (+0x1c) */ ++#define DMAC_CH0_EN_MASK 0x01 ++#define DMAC_CH0_EN_BIT 0 ++#define DMAC_CH1_EN_MASK 0x02 ++#define DMAC_CH1_EN_BIT 1 ++#define DMAC_CH2_EN_MASK 0x04 ++#define DMAC_CH2_EN_BIT 2 ++#define DMAC_CH3_EN_MASK 0x08 ++#define DMAC_CH3_EN_BIT 3 ++ ++/* Channel busy status register (+0x20) */ ++#define DMAC_CH0_BUSY_MASK 0x01 ++#define DMAC_CH0_BUSY_BIT 0 ++#define DMAC_CH1_BUSY_MASK 0x02 ++#define DMAC_CH1_BUSY_BIT 1 ++#define DMAC_CH2_BUSY_MASK 0x04 ++#define DMAC_CH2_BUSY_BIT 2 ++#define DMAC_CH3_BUSY_MASK 0x08 ++#define DMAC_CH3_BUSY_BIT 3 ++ ++/* Main configuration status register (+0x24) */ ++#define DMAC_DMACEN_MASK 0x01 ++#define DMAC_DMACEN_BIT 0 ++#define DMAC_M0ENDIAN_MASK 0x02 ++#define DMAC_M0ENDIAN_BIT 1 ++#define DMAC_M1ENDIAN_MASK 0x04 ++#define DMAC_M1ENDIAN_BIT 2 ++ ++ #define DMAC_ENDIAN_LITTLE 0 ++ #define DMAC_ENDIAN_BIG 1 ++ ++/* Sync register (+0x28) */ ++#define DMAC_SYNC0_MASK 0x01 ++#define DMAC_SYNC0_BIT 0 ++#define DMAC_SYNC1_MASK 0x02 ++#define DMAC_SYNC1_BIT 1 ++#define DMAC_SYNC2_MASK 0x04 ++#define DMAC_SYNC2_BIT 2 ++#define DMAC_SYNC3_MASK 0x08 ++#define DMAC_SYNC3_BIT 3 ++ ++/* DMA channel 0~n Control Registers (CH[n]_BASE + 0x00) */ ++#define DMAC_CSR_CH_EN_MASK 0x00000001 ++#define DMAC_CSR_CH_EN_BIT 0 ++ ++#define DMAC_CSR_DST_SEL_MASK 0x00000002 ++#define DMAC_CSR_DST_SEL_BIT 1 ++#define DMAC_CSR_SRC_SEL_MASK 0x00000004 ++#define DMAC_CSR_SRC_SEL_BIT 2 ++ #define DMAC_CSR_SEL_MASTER0 0x00 ++ #define DMAC_CSR_SEL_MASTER1 0x01 ++ ++#define DMAC_CSR_DSTAD_CTL_MASK 0x00000018 ++#define DMAC_CSR_DSTAD_CTL_SHIFT 3 ++#define DMAC_CSR_SRCAD_CTL_MASK 0x00000060 ++#define DMAC_CSR_SRCAD_CTL_SHIFT 5 ++ #define DMAC_CSR_AD_INC 0x00 ++ #define DMAC_CSR_AD_DEC 0x01 ++ #define DMAC_CSR_AD_FIX 0x02 ++ ++#define DMAC_CSR_MODE_MASK 0x00000080 ++#define DMAC_CSR_MODE_BIT 7 ++ #define DMAC_CSR_MODE_NORMAL 0x00 ++ #define DMAC_CSR_MODE_HSHK 0x01 ++ ++#define DMAC_CSR_DST_WIDTH_MASK 0x00000700 ++#define DMAC_CSR_DST_WIDTH_SHIFT 8 ++#define DMAC_CSR_SRC_WIDTH_MASK 0x00003800 ++#define DMAC_CSR_SRC_WIDTH_SHIFT 11 ++ #define DMAC_CSR_WIDTH_8 0x00 ++ #define DMAC_CSR_WIDTH_16 0x01 ++ #define DMAC_CSR_WIDTH_32 0x02 ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++#define DMAC_CYCLE_TO_BYTES(cycle, width) ((cycle) << (width)) ++#define DMAC_BYTES_TO_CYCLE(bytes, width) ((bytes) >> (width)) ++#else ++#define DMAC_CYCLE_TO_BYTES(cycle, width) 0 ++#define DMAC_BYTES_TO_CYCLE(bytes, width) 0 ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++#define DMAC_CSR_ABT 0x00008000 ++#define DMAC_CSR_ABT_BIT 15 ++ ++#define DMAC_CSR_SRC_SIZE_MASK 0x00070000 ++#define DMAC_CSR_SRC_SIZE_SHIFT 16 ++ #define DMAC_CSR_SIZE_1 0x00 ++ #define DMAC_CSR_SIZE_4 0x01 ++ #define DMAC_CSR_SIZE_8 0x02 ++ #define DMAC_CSR_SIZE_16 0x03 ++ #define DMAC_CSR_SIZE_32 0x04 ++ #define DMAC_CSR_SIZE_64 0x05 ++ #define DMAC_CSR_SIZE_128 0x06 ++ #define DMAC_CSR_SIZE_256 0x07 ++ ++#define DMAC_CSR_PROT1 0x00080000 ++#define DMAC_CSR_PROT1_BIT 19 ++#define DMAC_CSR_PROT2 0x00100000 ++#define DMAC_CSR_PROT2_BIT 20 ++#define DMAC_CSR_PROT3 0x00200000 ++#define DMAC_CSR_PROT3_BIT 21 ++ ++#define DMAC_CSR_CHPRI_MASK 0x00c00000 ++#define DMAC_CSR_CHPRI_SHIFT 22 ++ #define DMAC_CSR_CHPRI_0 0x00 ++ #define DMAC_CSR_CHPRI_1 0x01 ++ #define DMAC_CSR_CHPRI_2 0x02 ++ #define DMAC_CSR_CHPRI_3 0x03 ++ ++#define DMAC_CSR_FF_TH_MASK 0x07000000 ++#define DMAC_CSR_FF_TH_SHIFT 24 ++ #define DMAC_CSR_FF_TH_1 0x00 ++ #define DMAC_CSR_FF_TH_2 0x01 ++ #define DMAC_CSR_FF_TH_4 0x02 ++ #define DMAC_CSR_FF_TH_8 0x03 ++ #define DMAC_CSR_FF_TH_16 0x04 ++ ++#define DMAC_CSR_TC_MSK_MSK 0x80000000 ++#define DMAC_CSR_TC_MSK_BIT 31 ++ ++/* DMA channel 0~n Configuration Registers (CH[n]_BASE + 0x04) */ ++#define DMAC_CFG_INT_TC_MSK 0x00000001 ++#define DMAC_CFG_INT_TC_MSK_BIT 0 ++#define DMAC_CFG_INT_ERR_MSK 0x00000002 ++#define DMAC_CFG_INT_ERR_MSK_BIT 1 ++#define DMAC_CFG_INT_ABT_MSK 0x00000004 ++#define DMAC_CFG_INT_ABT_MSK_BIT 2 ++ ++#define DMAC_CFG_INT_SRC_RS_MASK 0x00000078 ++#define DMAC_CFG_INT_SRC_RS_SHIFT 3 ++#define DMAC_CFG_INT_SRC_HE_MASK 0x00000080 ++#define DMAC_CFG_INT_SRC_HE_BIT 7 ++ ++#define DMAC_CFG_BUSY_MASK 0x00000100 ++#define DMAC_CFG_BUSY_BIT 8 ++ ++#define DMAC_CFG_INT_DST_RS_MASK 0x00001e00 ++#define DMAC_CFG_INT_DST_RS_SHIFT 9 ++#define DMAC_CFG_INT_DST_HE_MASK 0x00002000 ++#define DMAC_CFG_INT_DST_HE_BIT 13 ++ ++#ifdef CONFIG_PLAT_AG102 ++ #define DMAC_REQN_IDERX 0 ++ #define DMAC_REQN_IDETX 1 ++ #define DMAC_REQN_I2SAC97RX 2 ++ #define DMAC_REQN_I2SAC97TX 3 ++ #define DMAC_REQN_UART2RX 4 ++ #define DMAC_REQN_UART2TX 5 ++ #define DMAC_REQN_UART1RX 6 ++ #define DMAC_REQN_UART1TX 7 ++ #define DMAC_REQN_SDC 8 ++ #define DMAC_REQN_CFC 9 ++ #define DMAC_REQN_LPCREQ0 10 ++ #define DMAC_REQN_LPCREQ1 11 ++ #define DMAC_REQN_LPCREQ2 12 ++ #define DMAC_REQN_LPCREQ3 13 ++ #define DMAC_REQN_NONE 14 ++ #define DMAC_REQN_LPCREQ5 15 ++ #define DMAC_REQN_MAX 15 ++#else ++ #define DMAC_REQN_NONE PMU_REQN_NONE ++ #define DMAC_REQN_CFC PMU_REQN_CFC ++ #define DMAC_REQN_SSP PMU_REQN_SSP ++ #define DMAC_REQN_UART1TX PMU_REQN_UART1TX ++ #define DMAC_REQN_UART1RX PMU_REQN_UART1RX ++ #define DMAC_REQN_UART2TX PMU_REQN_UART2TX ++ #define DMAC_REQN_UART2RX PMU_REQN_UART2RX ++ #define DMAC_REQN_SDC PMU_REQN_SDC ++ #define DMAC_REQN_I2SAC97TX PMU_REQN_I2SAC97TX ++ #define DMAC_REQN_I2SAC97RX PMU_REQN_I2SAC97RX ++/* for amerald ac97 ssp2 */ ++ #define DMAC_REQN_I2SAC97TX_AMERALD PMU_REQN_I2SAC97TX_AMERALD ++ #define DMAC_REQN_I2SAC97RX_AMERALD PMU_REQN_I2SAC97RX_AMERALD ++ #define DMAC_REQN_USB PMU_REQN_USB ++ #define DMAC_REQN_EXT0 PMU_REQN_EXT0 ++ #define DMAC_REQN_EXT1 PMU_REQN_EXT1 ++ #define DMAC_REQN_MAX PMU_REQN_MAX ++#endif ++#define DMAC_CFG_INT_LLPCNT_MASK 0x000f0000 ++#define DMAC_CFG_INT_LLPCNT_SHIFT 16 ++ ++/* DMA channel 0~n Linked List Descriptor Registers (CH[n]_BASE + 0x10) */ ++#define DMAC_LLP_ADDR_MASK 0xfffffffc ++#define DMAC_LLP_ADDR_SHIFT 2 ++#define DMAC_LLP_MASTER_MASK 0x00000001 ++#define DMAC_LLP_MASTER_BIT 0 ++ #define DMAC_LLP_MASTER_0 0 ++ #define DMAC_LLP_MASTER_1 1 ++ ++/* DMA channel 0~3 Transfer Size Registers (CH[n]_BASE + 0x14) */ ++#define DMAC_TOT_SIZE_MASK 0x003fffff ++#define DMAC_TOT_SIZE_SHIFT 0 ++ ++ ++/***************************************************************************** ++ * APBBR - AG101 AHB to APB Bridge ++*****************************************************************************/ ++/* Device base address */ ++#ifdef CONFIG_PLAT_AG102 ++#define APBBR_BASE APBBR_VA_BASE ++#else ++#define APBBR_BASE APBBRG_FTAPBBRG020S_0_VA_BASE ++#endif ++ ++/* DMA channel A registers (32-bit width) */ ++#define APBBR_DMAA_BASE (APBBR_BASE + 0x80) ++#define APBBR_DMAB_BASE (APBBR_BASE + 0x90) ++#define APBBR_DMAC_BASE (APBBR_BASE + 0xa0) ++#define APBBR_DMAD_BASE (APBBR_BASE + 0xb0) ++ ++#define APBBR_DMA_MAX_CHANNELS APBBRG_FTAPBBRG020S_IRQ_COUNT ++/* n = 0 ~ APBBRG_FTAPBBRG020S_IRQ_COUNT */ ++#define APBBR_DMA_BASE_CH(n) (APBBR_DMAA_BASE + \ ++ (APBBR_DMAB_BASE - APBBR_DMAA_BASE) * \ ++ (addr_t)(n)) ++ ++#define APBBR_DMA_SAD_OFFSET 0x00 ++#define APBBR_DMA_DAD_OFFSET 0x04 ++#define APBBR_DMA_CYC_OFFSET 0x08 ++#define APBBR_DMA_CMD_OFFSET 0x0c ++ ++ ++/***************************************************************************** ++ * APBBR defs - AG101 AHB to APB Bridge ++*****************************************************************************/ ++ ++/* APBBR slave#n (n = 1~6, 8, 11, 16~23) base/size register */ ++#define APBBR_SLAVE_SIZE_MASK 0x000f0000 /* Size of address space */ ++#define APBBR_SLAVE_SIZE_SHIFT 16 ++ #define APBBR_SIZE_1M 0 ++ #define APBBR_SIZE_2M 1 ++ #define APBBR_SIZE_4M 2 ++ #define APBBR_SIZE_8M 3 ++ #define APBBR_SIZE_16M 4 ++ #define APBBR_SIZE_32M 5 ++ #define APBBR_SIZE_64M 6 ++ #define APBBR_SIZE_128M 7 ++ #define APBBR_SIZE_256M 8 ++ ++#define APBBR_SLAVE_BASE_MASK 0x3ff00000 ++#define APBBR_SLAVE_BASE_SHIFT 20 ++ ++/* APBBR DMA channel transfer cycles register ++ * DMA cycles (data size), 1 or 4 bus data transfer cycles per DMA cycle ++ * => transfer size = cycles * data_width * burst(1 or 4) ++ * so, max = 16M*4*4 = 256M ++ */ ++#define APBBR_DMA_CYC_MASK 0x00ffffff ++#define APBBR_DMA_CYC_SHIFT 0 ++ ++/* APBBR DMA channel command register */ ++#define APBBR_DMA_CHEN_MASK 0x00000001 ++#define APBBR_DMA_CHEN_BIT 0 ++ ++#define APBBR_DMA_FINTST_MASK 0x00000002 ++#define APBBR_DMA_FINTST_BIT 1 ++#define APBBR_DMA_FINTEN_MASK 0x00000004 ++#define APBBR_DMA_FINTEN_BIT 2 ++ ++#define APBBR_DMA_BURST_MASK 0x00000008 ++#define APBBR_DMA_BURST_BIT 3 ++ ++#define APBBR_DMA_ERRINTST_MASK 0x00000010 ++#define APBBR_DMA_ERRINTST_BIT 4 ++#define APBBR_DMA_ERRINTEN_MASK 0x00000020 ++#define APBBR_DMA_ERRINTEN_BIT 5 ++ ++#define APBBR_DMA_SRCADDRSEL_MASK 0x00000040 ++#define APBBR_DMA_SRCADDRSEL_BIT 6 ++#define APBBR_DMA_DSTADDRSEL_MASK 0x00000080 ++#define APBBR_DMA_DSTADDRSEL_BIT 7 ++ #define APBBR_ADDRSEL_APB 0 ++ #define APBBR_ADDRSEL_AHB 1 ++ ++#define APBBR_DMA_SRCADDRINC_MASK 0x00000700 ++#define APBBR_DMA_SRCADDRINC_SHIFT 8 ++#define APBBR_DMA_DSTADDRINC_MASK 0x00007000 ++#define APBBR_DMA_DSTADDRINC_SHIFT 12 ++ #define APBBR_ADDRINC_FIXED 0 /* no increment */ ++ #define APBBR_ADDRINC_I1X 1 /* +1, +4 (burst) */ ++ #define APBBR_ADDRINC_I2X 2 /* +2, +8 (burst) */ ++ #define APBBR_ADDRINC_I4X 3 /* +4, +16 (burst) */ ++ #define APBBR_ADDRINC_D1 5 /* -1 */ ++ #define APBBR_ADDRINC_D2 6 /* -2 */ ++ #define APBBR_ADDRINC_D4 7 /* -4 */ ++ ++#define APBBR_DMA_DREQSEL_MASK 0x000f0000 ++#define APBBR_DMA_DREQSEL_SHIFT 16 ++#define APBBR_DMA_SREQSEL_MASK 0x0f000000 ++#define APBBR_DMA_SREQSEL_SHIFT 24 ++ ++#ifdef CONFIG_PLAT_AG102 ++ #define APBBR_REQN_NONE 0 ++ #define APBBR_REQN_CFC 1 ++ #define APBBR_REQN_SSP 2 ++ #define APBBR_REQN_SDC 8 ++ #define APBBR_REQN_I2SAC97TX 6 ++ #define APBBR_REQN_SSP2 8 ++ #define APBBR_REQN_STUART 9 ++ #define APBBR_REQN_BTUART 10 ++ #define APBBR_REQN_IRDA 11 ++ #define APBBR_REQN_SMMC 12 ++// #define APBBR_REQN_USB 0 ++ #define APBBR_REQN_I2SAC97RX 13 ++ #define APBBR_REQN_FUSB220 14 ++ #define APBBR_REQN_MMSC 15 ++ #define APBBR_REQN_MAX 15 ++#else ++ #define APBBR_REQN_NONE 0 ++ #define APBBR_REQN_CFC 1 ++ #define APBBR_REQN_SSP 2 ++ #define APBBR_REQN_SDC 5 ++/* for amerald sd */ ++ #define APBBR_REQN_SDC_AMERALD 7 ++/* for amerald ac97 ssp2 */ ++ #define APBBR_REQN_I2SAC97TX_AMERALD 8 ++ #define APBBR_REQN_I2SAC97RX_AMERALD 9 ++ ++ #define APBBR_REQN_I2SAC97TX 6 ++ #define APBBR_REQN_SSP2 8 ++ #define APBBR_REQN_STUART 9 /* UART1 ? */ ++ #define APBBR_REQN_BTUART 10 /* UART2 ? */ ++ #define APBBR_REQN_IRDA 11 ++ #define APBBR_REQN_SMMC 12 ++ //#define APBBR_REQN_USB 13 ++ #define APBBR_REQN_I2SAC97RX 13 ++ #define APBBR_REQN_FUSB220 14 ++ #define APBBR_REQN_MMSC 15 ++ #define APBBR_REQN_MAX 15 ++#endif ++ ++#define APBBR_DMA_DATAWIDTH_MASK 0x00300000 /* Data width of transfer */ ++#define APBBR_DMA_DATAWIDTH_SHIFT 20 ++ #define APBBR_DATAWIDTH_4 0 /* word */ ++ #define APBBR_DATAWIDTH_2 1 /* half-word */ ++ #define APBBR_DATAWIDTH_1 2 /* byte */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++#define APBBR_DMA_CYCLE_TO_BYTES(cycle, width) ((cycle) << (2-(width))) ++#define APBBR_DMA_BYTES_TO_CYCLE(bytes, width) ((bytes) >> (2-(width))) ++#else ++#define APBBR_DMA_CYCLE_TO_BYTES(cycle, width) 0 ++#define APBBR_DMA_BYTES_TO_CYCLE(bytes, width) 0 ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++ ++#ifdef CONFIG_PLAT_AG102 ++ ++/***************************************************************************** ++ * PCU - AG102 Core APB ++*****************************************************************************/ ++/* Device base address */ ++#define PCU_BASE PCU_VA_BASE ++/* PMU registers (32-bit width) */ ++/* Add by Dennis on 2011.03.09 */ ++#define PCU_DMA_SEL (PCU_BASE+ 0x38) ++ ++#else /* CONFIG_PLAT_AG102 */ ++ ++/***************************************************************************** ++ * PMU - AG101 Core APB ++*****************************************************************************/ ++/* Device base address */ ++#define PMU_BASE PMU_FTPMU010_0_VA_BASE ++ ++/* PMU registers (32-bit width) */ ++#define PMU_AHBDMA_REQACK (PMU_BASE + 0x90) ++ ++#define PMU_CFC_REQACK_CFG (PMU_BASE + 0xa0) ++#define PMU_SSP1_REQACK_CFG (PMU_BASE + 0xa4) ++#define PMU_UART1TX_REQACK_CFG (PMU_BASE + 0xa8) ++#define PMU_UART1RX_REQACK_CFG (PMU_BASE + 0xac) ++#define PMU_UART2TX_REQACK_CFG (PMU_BASE + 0xb0) ++#define PMU_UART2RX_REQACK_CFG (PMU_BASE + 0xb4) ++#define PMU_SDC_REQACK_CFG (PMU_BASE + 0xb8) ++#define PMU_I2SAC97TX_REQACK_CFG (PMU_BASE + 0xbc) ++#define PMU_I2SAC97RX_REQACK_CFG (PMU_BASE + 0xc4) ++#define PMU_UART3TX_REQACK_CFG (PMU_BASE + 0xc0) ++#define PMU_UART3RX_REQACK_CFG (PMU_BASE + 0xcc) ++#define PMU_USB_REQACK_CFG (PMU_BASE + 0xc8) ++#define PMU_IRDA_REQACK_CFG (PMU_BASE + 0xd0) ++#define PMU_EXT0_REQACK_CFG (PMU_BASE + 0xd4) ++#define PMU_EXT1_REQACK_CFG (PMU_BASE + 0xd8) ++ ++ ++/***************************************************************************** ++ * PMU - AG101 Core APB ++*****************************************************************************/ ++ ++/* Driving capability and slew rate control register 2 (+0x48) */ ++#define PMU_STUART_DCSR_MASK 0x0000000f ++#define PMU_STUART_DCSR_SHIFT 0 ++#define PMU_BTUART_DCSR_MASK 0x00000f00 ++#define PMU_BTUART_DCSR_SHIFT 8 ++/*#define PMU_FFUART_DCSR_MASK 0x0000f000*/ ++/*#define PMU_FFUART_DCSR_SHIFT 12 */ ++#define PMU_PMU_DCSR_MASK 0x000f0000 ++#define PMU_PMU_DCSR_SHIFT 16 ++#define PMU_I2SAC97_DCSR_MASK 0x00f00000 ++#define PMU_I2SAC97_DCSR_SHIFT 20 ++#define PMU_SSP_DCSR_MASK 0x0f000000 ++#define PMU_SSP_DCSR_SHIFT 24 ++#define PMU_SD_DCSR_MASK 0xf0000000 ++#define PMU_SD_DCSR_SHIFT 28 ++ ++/* AHB DMA REQ/ACK connection configuration status register (+0x90) */ ++#define PMU_CH0_REQACK_MASK 0x0000000f ++#define PMU_CH0_REQACK_SHIFT 0 ++#define PMU_CH1_REQACK_MASK 0x000000f0 ++#define PMU_CH1_REQACK_SHIFT 4 ++#define PMU_CH2_REQACK_MASK 0x00000f00 ++#define PMU_CH2_REQACK_SHIFT 8 ++#define PMU_CH3_REQACK_MASK 0x0000f000 ++#define PMU_CH3_REQACK_SHIFT 12 ++#define PMU_CH4_REQACK_MASK 0x000f0000 ++#define PMU_CH4_REQACK_SHIFT 16 ++#define PMU_CH5_REQACK_MASK 0x00f00000 ++#define PMU_CH5_REQACK_SHIFT 20 ++#define PMU_CH6_REQACK_MASK 0x0f000000 ++#define PMU_CH6_REQACK_SHIFT 24 ++#define PMU_CH7_REQACK_MASK 0xf0000000 ++#define PMU_CH7_REQACK_SHIFT 28 ++ ++ #define PMU_REQN_NONE 0 ++ #define PMU_REQN_CFC 1 ++ #define PMU_REQN_SSP 2 ++ #define PMU_REQN_UART1TX 3 ++ #define PMU_REQN_UART1RX 4 ++ #define PMU_REQN_UART2TX 5 ++ #define PMU_REQN_UART2RX 6 ++ #define PMU_REQN_SDC 7 ++ #define PMU_REQN_I2SAC97TX 8 ++ #define PMU_REQN_I2SAC97RX 10 ++/* for amerald ac97 ssp2 */ ++ #define PMU_REQN_I2SAC97TX_AMERALD 8 ++ #define PMU_REQN_I2SAC97RX_AMERALD 9 ++ #define PMU_REQN_USB 11 ++ #define PMU_REQN_EXT0 14 ++ #define PMU_REQN_EXT1 15 ++ #define PMU_REQN_MAX 15 ++ ++/* CFC ..., etc, REQ/ACK connection configuration registers (0xa0 ~ 0xd8) */ ++#define PMU_CHANNEL_MASK 0x00000007 ++#define PMU_CHANNEL_SHIFT 0 ++#define PMU_DMACUSED_MASK 0x00000008 ++#define PMU_DMACUSED_BIT 3 ++ ++#endif /* CONFIG_PLAT_AG102 */ ++ ++ ++/***************************************************************************** ++ * DMAD globals section ++ */ ++ ++enum DMAD_DMAC_CORE { ++ DMAD_DMAC_AHB_CORE, ++ DMAD_DMAC_APB_CORE ++}; ++ ++enum DMAD_CHREG_FLAGS { ++ DMAD_FLAGS_NON_BLOCK = 0x00000000, ++ DMAD_FLAGS_SLEEP_BLOCK = 0x00000001, ++ DMAD_FLAGS_SPIN_BLOCK = 0x00000002, ++ DMAD_FLAGS_RING_MODE = 0x00000008, /* ring submission mode */ ++ DMAD_FLAGS_BIDIRECTION = 0x00000010, /* indicates both tx and rx */ ++}; ++ ++enum DMAD_CHDIR ++{ ++ DMAD_DIR_A0_TO_A1 = 0, ++ DMAD_DIR_A1_TO_A0 = 1, ++}; ++ ++/* AHB Channel Request ++ * ++ * Notes for developers: ++ * These should be channel-only properties. Controller-specific properties ++ * should be separated as other driver structure or driver buildin-hardcode. ++ * If controller properties are embeded in this union, request for a channel ++ * may unexpectedly override the controller setting of the request of other ++ * channels. ++ */ ++typedef struct dmad_ahb_chreq ++{ ++ /* channel property */ ++ u32 sync; /* (in) different clock domain */ ++ u32 priority; /* (in) DMAC_CSR_CHPRI_xxx */ ++ u32 hw_handshake; /* (in) hardware handshaking on/off */ ++ u32 burst_size; /* (in) DMAC_CSR_SIZE_xxx */ ++ ++ /* source property */ ++ union { ++ u32 src_width; /* (in) DMAC_CSR_WIDTH_xxx */ ++ u32 addr0_width; /* (in) bi-direction mode alias */ ++ u32 ring_width; /* (in) ring-mode alias */ ++ }; ++ union { ++ u32 src_ctrl; /* (in) DMAC_CSR_AD_xxx */ ++ u32 addr0_ctrl; /* (in) bi-direction mode alias */ ++ u32 ring_ctrl; /* (in) ring-mode alias */ ++ }; ++ union { ++ u32 src_reqn; /* (in) DMAC_REQN_xxx */ ++ u32 addr0_reqn; /* (in) bi-direction mode alias */ ++ u32 ring_reqn; /* (in) ring-mode alias */ ++ }; ++ ++ /* destination property */ ++ union { ++ u32 dst_width; /* (in) DMAC_CSR_WIDTH_xxx */ ++ u32 addr1_width; /* (in) bi-direction mode alias */ ++ u32 dev_width; /* (in) ring-mode alias */ ++ }; ++ union { ++ u32 dst_ctrl; /* (in) DMAC_CSR_AD_xxx */ ++ u32 addr1_ctrl; /* (in) bi-direction mode alias */ ++ u32 dev_ctrl; /* (in) ring-mode alias */ ++ }; ++ union { ++ u32 dst_reqn; /* (in) DMAC_REQN_xxx */ ++ u32 addr1_reqn; /* (in) bi-direction mode alias */ ++ u32 dev_reqn; /* (in) ring-mode alias */ ++ }; ++ ++ /* (in) transfer direction, valid only if following flags were set ... ++ * DMAD_FLAGS_BIDIRECTION or ++ * DMAD_FLAGS_RING_MODE ++ * value: ++ * 0 (addr0 -> addr1, or ring-buff to device) ++ * 1 (addr0 <- addr1, or device to ring-buff) ++ */ ++ u32 tx_dir; ++ ++} dmad_ahb_chreq; ++ ++/* APB Channel Request ++ * ++ * Notes for developers: ++ * These should be channel-only properties. Controller-specific properties ++ * should be separated as other driver structure or driver buildin-hardcode. ++ * If controller properties are embeded in this union, request for a channel ++ * may unexpectedly override the controller setting of the request of other ++ * channels. ++ */ ++typedef struct dmad_apb_chreq ++{ ++ /* controller property (removed! should not exist in this struct) */ ++ ++ /* channel property */ ++ u32 burst_mode; /* (in) Burst mode (0/1) */ ++ u32 data_width; /* (in) APBBR_DATAWIDTH_xxx */ ++ ++ /* source property */ ++ union { ++ u32 src_ctrl; /* (in) APBBR_ADDRINC_xxx */ ++ u32 addr0_ctrl; /* (in) bi-direction mode alias */ ++ u32 ring_ctrl; /* (in) ring-mode alias */ ++ }; ++ union { ++ u32 src_reqn; /* (in) APBBR_REQN_xxx */ ++ u32 addr0_reqn; /* (in) bi-direction mode alias */ ++ u32 ring_reqn; /* (in) ring-mode alias */ ++ }; ++ ++ /* destination property */ ++ union { ++ u32 dst_ctrl; /* (in) APBBR_ADDRINC_xxx */ ++ u32 addr1_ctrl; /* (in) bi-direction mode alias */ ++ u32 dev_ctrl; /* (in) ring-mode alias */ ++ }; ++ union { ++ u32 dst_reqn; /* (in) APBBR_REQN_xxx */ ++ u32 addr1_reqn; /* (in) bi-direction mode alias */ ++ u32 dev_reqn; /* (in) ring-mode alias */ ++ }; ++ ++ /* (in) transfer direction, valid only if following flags were set ... ++ * DMAD_FLAGS_BIDIRECTION or ++ * DMAD_FLAGS_RING_MODE ++ * value: ++ * 0 (addr0 -> addr1, or ring-buff to device) ++ * 1 (addr0 <- addr1, or device to ring-buff) ++ */ ++ u32 tx_dir; ++ ++} dmad_apb_chreq; ++ ++/* Channel Request Descriptor */ ++typedef struct dmad_chreq ++{ ++ /* common fields */ ++ u32 controller; /* (in) enum DMAD_DMAC_CORE */ ++ u32 flags; /* (in) enum DMAD_CHREQ_FLAGS */ ++ ++ /********************************************************************** ++ * ring mode specific fields (valid only for DMAD_FLAGS_RING_MODE) ++ * note: ++ * - size fields are in unit of data width ++ * * for AHB, ring size is limited to 4K * data_width of data if ++ * hw-LLP is not used ++ * * for AHB, ring size is limited to 4K * data_width * LLP-count ++ * hw-if LLP is used ++ * * for APB, ring size is limited to 16M * data_width of data ++ * - currently sw ring mode dma supports only fixed or incremental ++ * src/dst addressing ++ * - ring_size shoule >= periods * period_size ++ */ ++ dma_addr_t ring_base; /* (in) ring buffer base (pa) */ ++ dma_addr_t ring_size; /* (in) unit of data width */ ++ addr_t dev_addr; /* (in) device data port address */ ++ dma_addr_t periods; /* (in) number of ints per ring */ ++ dma_addr_t period_size; /* (in) size per int, data-width */ ++ ++ ++ /* channel-wise completion callback - called when hw-ptr catches sw-ptr ++ * (i.e., channel stops) ++ * ++ * completion_cb: (in) client supplied callback function, executed in ++ * interrupt context. ++ * completion_data: (in) client private data to be passed to data ++ * argument of completion_cb(). ++ */ ++ void (*completion_cb)(int channel, u16 status, void *data); ++ void *completion_data; ++ /*********************************************************************/ ++ ++ /* channel allocation output */ ++ u32 channel; /* (out) allocated channel */ ++ void *drq; /* (out) internal use (DMAD_DRQ *)*/ ++ ++ /* channel-alloc parameters (channel-wise properties) */ ++ union { ++#ifdef CONFIG_PLATFORM_AHBDMA ++ dmad_ahb_chreq ahb_req; /* (in) for AHB DMA parameters */ ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ dmad_apb_chreq apb_req; /* (in) APB Bridge DMA params */ ++#endif ++ }; ++ ++} dmad_chreq; ++ ++/* drb states are mutual exclusive */ ++enum DMAD_DRB_STATE ++{ ++ DMAD_DRB_STATE_FREE = 0, ++ DMAD_DRB_STATE_READY = 0x00000001, ++ DMAD_DRB_STATE_SUBMITTED = 0x00000002, ++ DMAD_DRB_STATE_EXECUTED = 0x00000004, ++ DMAD_DRB_STATE_COMPLETED = 0x00000008, ++ //DMAD_DRB_STATE_ERROR = 0x00000010, ++ DMAD_DRB_STATE_ABORT = 0x00000020, ++}; ++ ++/* DMA request block ++ * todo: replaced link with kernel struct list_head ?? ++ */ ++typedef struct dmad_drb ++{ ++ u32 prev; /* (internal) previous node */ ++ u32 next; /* (internal) next node */ ++ u32 node; /* (internal) this node */ ++ ++ u32 state; /* (out) DRB's current state */ ++ ++ union { ++ dma_addr_t src_addr; /* (in) source pa */ ++ dma_addr_t addr0; /* (in) bi-direction mode alias */ ++ }; ++ ++ union { ++ dma_addr_t dst_addr; /* (in) destination pa */ ++ dma_addr_t addr1; /* (in) bi-direction mode alias */ ++ }; ++ ++ /* (in) AHB DMA (22 bits): 0 ~ 4M-1, unit is "data width" ++ * APB DMA (24 bits): 0 ~ 16M-1, unit is "data width * burst size" ++ * => for safe without mistakes, use dmad_make_req_cycles() to ++ * compose this value if the addressing mode is incremental ++ * mode (not working yet for decremental mode). ++ */ ++ dma_addr_t req_cycle; ++ ++ /* (in) if non-null, this sync object will be signaled upon dma ++ * completion (for blocked-waiting dma completion) ++ */ ++ struct completion *sync; ++ ++} dmad_drb; ++ ++ ++/****************************************************************************** ++ * Debug Trace Mechanism ++ */ ++#if (DMAD_ERROR_TRACE) ++#define dmad_err(format, arg...) printk(KERN_ERR format , ## arg) ++#else ++#define dmad_err(format, arg...) (void)(0) ++#endif ++ ++#if (DMAD_DEBUG_TRACE) ++#define dmad_dbg(format, arg...) printk(KERN_INFO format , ## arg) ++#else ++#define dmad_dbg(format, arg...) (void)(0) ++#endif ++ ++#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) ++ ++/****************************************************************************** ++ * DMAD Driver Interface ++******************************************************************************/ ++ ++extern int dmad_channel_alloc(dmad_chreq *ch_req); ++extern int dmad_channel_free(dmad_chreq *ch_req); ++extern int dmad_channel_enable(const dmad_chreq *ch_req, u8 enable); ++extern u32 dmad_max_size_per_drb(dmad_chreq *ch_req); ++extern u32 dmad_bytes_to_cycles(dmad_chreq *ch_req, u32 byte_size); ++ ++extern int dmad_kickoff_requests(dmad_chreq *ch_req); ++extern int dmad_drain_requests(dmad_chreq *ch_req, u8 shutdown); ++ ++/* for performance reason, these two functions are platform-specific */ ++#ifdef CONFIG_PLATFORM_AHBDMA ++extern int dmad_probe_irq_source_ahb(void); ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++extern int dmad_probe_irq_source_apb(void); ++#endif ++ ++/* note: hw_ptr here is phyical address of dma source or destination */ ++extern dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq *ch_req); ++extern dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq *ch_req); ++ ++/***************************************************************************** ++ * routines only valid in discrete (non-ring) mode ++ */ ++extern int dmad_config_channel_dir(dmad_chreq *ch_req, u8 dir); ++extern int dmad_alloc_drb(dmad_chreq *ch_req, dmad_drb **drb); ++extern int dmad_free_drb(dmad_chreq *ch_req, dmad_drb *drb); ++extern int dmad_submit_request(dmad_chreq *ch_req, ++ dmad_drb *drb, u8 keep_fired); ++extern int dmad_withdraw_request(dmad_chreq *ch_req, dmad_drb *drb); ++/****************************************************************************/ ++ ++/***************************************************************************** ++ * routines only valid in ring mode ++ * note: sw_ptr and hw_ptr are values offset from the ring buffer base ++ * unit of sw_ptr is data-width ++ * unit of hw_ptr returned is byte ++ */ ++extern int dmad_update_ring(dmad_chreq *ch_req); ++extern int dmad_update_ring_sw_ptr(dmad_chreq *ch_req, ++ dma_addr_t sw_ptr, u8 keep_fired); ++extern dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq *ch_req); ++/****************************************************************************/ ++ ++#else /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */ ++ ++static inline int dmad_channel_alloc(dmad_chreq *ch_req) { return -EFAULT; } ++static inline int dmad_channel_free(dmad_chreq *ch_req) { return -EFAULT; } ++static inline int dmad_channel_enable(const dmad_chreq *ch_req, u8 enable) ++ { return -EFAULT; } ++static inline u32 dmad_max_size_per_drb(dmad_chreq *ch_req) { return 0; } ++static inline u32 dmad_bytes_to_cycles(dmad_chreq *ch_req, u32 byte_size) ++ { return 0; } ++static inline int dmad_kickoff_requests(dmad_chreq *ch_req) { return -EFAULT; } ++static inline int dmad_drain_requests(dmad_chreq *ch_req, u8 shutdown) ++ { return -EFAULT; } ++static inline int dmad_probe_irq_source_ahb(void) { return -EFAULT; } ++static inline int dmad_probe_irq_source_apb(void) { return -EFAULT; } ++static inline dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq *ch_req) ++ { return (dma_addr_t)NULL; } ++static inline dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq *ch_req) ++ { return (dma_addr_t)NULL; } ++static inline int dmad_config_channel_dir(dmad_chreq *ch_req, u8 dir) ++ { return -EFAULT; } ++static inline int dmad_alloc_drb(dmad_chreq *ch_req, dmad_drb **drb) ++ { return -EFAULT; } ++static inline int dmad_free_drb(dmad_chreq *ch_req, dmad_drb *drb) ++ { return -EFAULT; } ++static inline int dmad_submit_request(dmad_chreq *ch_req, ++ dmad_drb *drb, u8 keep_fired) { return -EFAULT; } ++static inline int dmad_withdraw_request(dmad_chreq *ch_req, dmad_drb *drb) ++ { return -EFAULT; } ++static inline int dmad_update_ring(dmad_chreq *ch_req) ++ { return -EFAULT; } ++static inline int dmad_update_ring_sw_ptr(dmad_chreq *ch_req, ++ dma_addr_t sw_ptr, u8 keep_fired) { return -EFAULT; } ++static inline dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq *ch_req) ++ { return (dma_addr_t)NULL; } ++ ++#endif /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */ ++ ++#endif /* __NDS_DMAD_INC__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/dma.h linux-3.4.110/arch/nds32/include/asm/dma.h +--- linux-3.4.110.orig/arch/nds32/include/asm/dma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/dma.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * linux/arch/nds32/include/asm/dma.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_DMA_H__ ++#define __NDS32_DMA_H__ ++ ++#define MAX_DMA_ADDRESS 0xffffffff ++ ++#ifdef CONFIG_PCI ++extern int isa_dma_bridge_buggy; ++#else ++#define isa_dma_bridge_buggy (0) ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/dma-mapping.h linux-3.4.110/arch/nds32/include/asm/dma-mapping.h +--- linux-3.4.110.orig/arch/nds32/include/asm/dma-mapping.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/dma-mapping.h 2016-04-07 10:20:50.894079168 +0200 +@@ -0,0 +1,453 @@ ++/* ++ * linux/arch/nds32/include/asm/dma-mapping.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef ASMNDS32_DMA_MAPPING_H ++#define ASMNDS32_DMA_MAPPING_H ++ ++#ifdef __KERNEL__ ++ ++#include /* need struct page */ ++#include ++ ++#include ++ ++/* ++ * DMA-consistent mapping functions. These allocate/free a region of ++ * uncached, unwrite-buffered mapped memory space for use with DMA ++ * devices. This is the "generic" version. The PCI specific version ++ * is in pci.h ++ */ ++extern void consistent_sync(void *kaddr, size_t size, int rw); ++ ++/* ++ * Return whether the given device DMA address mask can be supported ++ * properly. For example, if your device can only drive the low 24-bits ++ * during bus mastering, then you would pass 0x00ffffff as the mask ++ * to this function. ++ */ ++static inline int dma_supported(struct device *dev, u64 mask) ++{ ++ return dev->dma_mask && *dev->dma_mask != 0; ++} ++ ++static inline int dma_set_mask(struct device *dev, u64 dma_mask) ++{ ++ if (!dev->dma_mask || !dma_supported(dev, dma_mask)) ++ return -EIO; ++ ++ *dev->dma_mask = dma_mask; ++ ++ return 0; ++} ++ ++static inline int dma_is_consistent(dma_addr_t handle) ++{ ++ return 0; ++} ++ ++/* ++ * DMA errors are defined by all-bits-set in the DMA address. ++ */ ++static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) ++{ ++ return dma_addr == ~0; ++} ++ ++/* ++ * Dummy noncoherent implementation. We don't provide a dma_cache_sync ++ * function so drivers using this API are highlighted with build warnings. ++ */ ++static inline void * ++dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) ++{ ++ return NULL; ++} ++ ++static inline void ++dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, ++ dma_addr_t handle) ++{ ++} ++ ++/** ++ * dma_alloc_coherent - allocate consistent memory for DMA ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @size: required memory size ++ * @handle: bus-specific DMA address ++ * ++ * Allocate some uncached, unbuffered memory for a device for ++ * performing DMA. This function allocates pages, and will ++ * return the CPU-viewed address, and sets @handle to be the ++ * device-viewed address. ++ */ ++extern void * ++dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp); ++ ++/** ++ * dma_free_coherent - free memory allocated by dma_alloc_coherent ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @size: size of memory originally requested in dma_alloc_coherent ++ * @cpu_addr: CPU-view address returned from dma_alloc_coherent ++ * @handle: device-view address returned from dma_alloc_coherent ++ * ++ * Free (and unmap) a DMA buffer previously allocated by ++ * dma_alloc_coherent(). ++ * ++ * References to memory and mappings associated with cpu_addr/handle ++ * during and after this call executing are illegal. ++ */ ++extern void ++dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, ++ dma_addr_t handle); ++ ++/** ++ * dma_mmap_coherent - map a coherent DMA allocation into user space ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @vma: vm_area_struct describing requested user mapping ++ * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent ++ * @handle: device-view address returned from dma_alloc_coherent ++ * @size: size of memory originally requested in dma_alloc_coherent ++ * ++ * Map a coherent DMA buffer previously allocated by dma_alloc_coherent ++ * into user space. The coherent DMA buffer must not be freed by the ++ * driver until the user space mapping has been released. ++ */ ++int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, ++ void *cpu_addr, dma_addr_t handle, size_t size); ++ ++ ++/** ++ * dma_alloc_writecombine - allocate writecombining memory for DMA ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @size: required memory size ++ * @handle: bus-specific DMA address ++ * ++ * Allocate some uncached, buffered memory for a device for ++ * performing DMA. This function allocates pages, and will ++ * return the CPU-viewed address, and sets @handle to be the ++ * device-viewed address. ++ */ ++extern void * ++dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp); ++ ++#define dma_free_writecombine(dev,size,cpu_addr,handle) \ ++ dma_free_coherent(dev,size,cpu_addr,handle) ++ ++int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, ++ void *cpu_addr, dma_addr_t handle, size_t size); ++ ++ ++/** ++ * dma_map_single - map a single buffer for streaming DMA ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @cpu_addr: CPU direct mapped address of buffer ++ * @size: size of buffer to map ++ * @dir: DMA transfer direction ++ * ++ * Ensure that any data held in the cache is appropriately discarded ++ * or written back. ++ * ++ * The device owns this memory once this call has completed. The CPU ++ * can regain ownership by calling dma_unmap_single() or ++ * dma_sync_single_for_cpu(). ++ */ ++#ifndef CONFIG_DMABOUNCE ++static inline dma_addr_t ++dma_map_single(struct device *dev, void *cpu_addr, size_t size, ++ enum dma_data_direction dir) ++{ ++ consistent_sync(cpu_addr, size, dir); ++ return virt_to_dma(dev, (unsigned long)cpu_addr); ++} ++#else ++extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction); ++#endif ++ ++/** ++ * dma_map_page - map a portion of a page for streaming DMA ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @page: page that buffer resides in ++ * @offset: offset into page for start of buffer ++ * @size: size of buffer to map ++ * @dir: DMA transfer direction ++ * ++ * Ensure that any data held in the cache is appropriately discarded ++ * or written back. ++ * ++ * The device owns this memory once this call has completed. The CPU ++ * can regain ownership by calling dma_unmap_page() or ++ * dma_sync_single_for_cpu(). ++ */ ++static inline dma_addr_t ++dma_map_page(struct device *dev, struct page *page, ++ unsigned long offset, size_t size, ++ enum dma_data_direction dir) ++{ ++ return dma_map_single(dev, page_address(page) + offset, size, (int)dir); ++} ++ ++/** ++ * dma_unmap_single - unmap a single buffer previously mapped ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @handle: DMA address of buffer ++ * @size: size of buffer to map ++ * @dir: DMA transfer direction ++ * ++ * Unmap a single streaming mode DMA translation. The handle and size ++ * must match what was provided in the previous dma_map_single() call. ++ * All other usages are undefined. ++ * ++ * After this call, reads by the CPU to the buffer are guaranteed to see ++ * whatever the device wrote there. ++ */ ++#ifndef CONFIG_DMABOUNCE ++static inline void ++dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size, ++ enum dma_data_direction dir) ++{ ++ /* nothing to do */ ++} ++#else ++extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction); ++#endif ++ ++/** ++ * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @handle: DMA address of buffer ++ * @size: size of buffer to map ++ * @dir: DMA transfer direction ++ * ++ * Unmap a single streaming mode DMA translation. The handle and size ++ * must match what was provided in the previous dma_map_single() call. ++ * All other usages are undefined. ++ * ++ * After this call, reads by the CPU to the buffer are guaranteed to see ++ * whatever the device wrote there. ++ */ ++static inline void ++dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, ++ enum dma_data_direction dir) ++{ ++ dma_unmap_single(dev, handle, size, (int)dir); ++} ++ ++/** ++ * dma_map_sg - map a set of SG buffers for streaming mode DMA ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @sg: list of buffers ++ * @nents: number of buffers to map ++ * @dir: DMA transfer direction ++ * ++ * Map a set of buffers described by scatterlist in streaming ++ * mode for DMA. This is the scatter-gather version of the ++ * above dma_map_single interface. Here the scatter gather list ++ * elements are each tagged with the appropriate dma address ++ * and length. They are obtained via sg_dma_{address,length}(SG). ++ * ++ * NOTE: An implementation may be able to use a smaller number of ++ * DMA address/length pairs than there are SG table elements. ++ * (for example via virtual mapping capabilities) ++ * The routine returns the number of addr/length pairs actually ++ * used, at most nents. ++ * ++ * Device ownership issues as mentioned above for dma_map_single are ++ * the same here. ++ */ ++#ifndef CONFIG_DMABOUNCE ++static inline int ++dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ int i; ++ ++ for (i = 0; i < nents; i++, sg++) { ++ void *virt; ++ unsigned long pfn; ++ struct page *page = sg_page(sg); ++ ++ sg->dma_address = page_to_dma(dev, page) + sg->offset; ++ pfn = page_to_pfn(page) + sg->offset / PAGE_SIZE; ++ page = pfn_to_page(pfn); ++ if (PageHighMem(page)) { ++ virt = kmap_atomic(page); ++ consistent_sync(virt, sg->length, dir); ++ kunmap_atomic(virt); ++ } else { ++ if (sg->offset > PAGE_SIZE) ++ panic("sg->offset:%08x > PAGE_SIZE\n", sg->offset); ++ virt = page_address(page) + sg->offset; ++ consistent_sync(virt, sg->length, dir); ++ } ++ } ++ return nents; ++} ++#else ++extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); ++#endif ++ ++/** ++ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @sg: list of buffers ++ * @nents: number of buffers to map ++ * @dir: DMA transfer direction ++ * ++ * Unmap a set of streaming mode DMA translations. ++ * Again, CPU read rules concerning calls here are the same as for ++ * dma_unmap_single() above. ++ */ ++#ifndef CONFIG_DMABOUNCE ++static inline void ++dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ ++ /* nothing to do */ ++} ++#else ++extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); ++#endif ++ ++ ++/** ++ * dma_sync_single_for_cpu ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @handle: DMA address of buffer ++ * @size: size of buffer to map ++ * @dir: DMA transfer direction ++ * ++ * Make physical memory consistent for a single streaming mode DMA ++ * translation after a transfer. ++ * ++ * If you perform a dma_map_single() but wish to interrogate the ++ * buffer using the cpu, yet do not wish to teardown the PCI dma ++ * mapping, you must call this function before doing so. At the ++ * next point you give the PCI dma address back to the card, you ++ * must first the perform a dma_sync_for_device, and then the ++ * device again owns the buffer. ++ */ ++#ifndef CONFIG_DMABOUNCE ++static inline void ++dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, ++ enum dma_data_direction dir) ++{ ++ consistent_sync((void *)dma_to_virt(dev, handle), size, dir); ++} ++ ++static inline void ++dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, ++ enum dma_data_direction dir) ++{ ++ consistent_sync((void *)dma_to_virt(dev, handle), size, dir); ++} ++#else ++extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction); ++extern void dma_sync_single_for_device(struct device*, dma_addr_t, size_t, enum dma_data_direction); ++#endif ++ ++ ++/** ++ * dma_sync_sg_for_cpu ++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices ++ * @sg: list of buffers ++ * @nents: number of buffers to map ++ * @dir: DMA transfer direction ++ * ++ * Make physical memory consistent for a set of streaming ++ * mode DMA translations after a transfer. ++ * ++ * The same as dma_sync_single_for_* but for a scatter-gather list, ++ * same rules and usage. ++ */ ++#ifndef CONFIG_DMABOUNCE ++static inline void ++dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ int i; ++ ++ for (i = 0; i < nents; i++, sg++) { ++ char *virt = page_address( (struct page *)sg->page_link) + sg->offset; ++ consistent_sync(virt, sg->length, dir); ++ } ++} ++ ++static inline void ++dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, ++ enum dma_data_direction dir) ++{ ++ int i; ++ ++ for (i = 0; i < nents; i++, sg++) { ++ char *virt = page_address( (struct page *)sg->page_link) + sg->offset; ++ consistent_sync(virt, sg->length, dir); ++ } ++} ++#else ++extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction); ++extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction); ++#endif ++ ++#ifdef CONFIG_DMABOUNCE ++/* ++ * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" ++ * and utilize bounce buffers as needed to work around limited DMA windows. ++ * ++ * On the SA-1111, a bug limits DMA to only certain regions of RAM. ++ * On the IXP425, the PCI inbound window is 64MB (256MB total RAM) ++ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM) ++ * ++ * The following are helper functions used by the dmabounce subystem ++ * ++ */ ++ ++/** ++ * dmabounce_register_dev ++ * ++ * @dev: valid struct device pointer ++ * @small_buf_size: size of buffers to use with small buffer pool ++ * @large_buf_size: size of buffers to use with large buffer pool (can be 0) ++ * ++ * This function should be called by low-level platform code to register ++ * a device as requireing DMA buffer bouncing. The function will allocate ++ * appropriate DMA pools for the device. ++ * ++ */ ++extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long); ++ ++/** ++ * dmabounce_unregister_dev ++ * ++ * @dev: valid struct device pointer ++ * ++ * This function should be called by low-level platform code when device ++ * that was previously registered with dmabounce_register_dev is removed ++ * from the system. ++ * ++ */ ++extern void dmabounce_unregister_dev(struct device *); ++ ++/** ++ * dma_needs_bounce ++ * ++ * @dev: valid struct device pointer ++ * @dma_handle: dma_handle of unbounced buffer ++ * @size: size of region being mapped ++ * ++ * Platforms that utilize the dmabounce mechanism must implement ++ * this function. ++ * ++ * The dmabounce routines call this function whenever a dma-mapping ++ * is requested to determine whether a given buffer needs to be bounced ++ * or not. The function must return 0 if the buffer is OK for ++ * DMA access and 1 if the buffer needs to be bounced. ++ * ++ */ ++extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); ++#endif /* CONFIG_DMABOUNCE */ ++ ++#endif /* __KERNEL__ */ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/elf.h linux-3.4.110/arch/nds32/include/asm/elf.h +--- linux-3.4.110.orig/arch/nds32/include/asm/elf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/elf.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,145 @@ ++/* ++ * linux/arch/nds32/include/asm/elf.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASMNDS32_ELF_H ++#define __ASMNDS32_ELF_H ++ ++/* ++ * ELF register definitions.. ++ */ ++ ++#include ++#include ++ ++typedef unsigned long elf_greg_t; ++typedef unsigned long elf_freg_t[3]; ++ ++extern unsigned int elf_hwcap; ++ ++#define EM_NDS32 167 ++ ++ ++#define R_NDS32_NONE 0 ++#define R_NDS32_16_RELA 19 ++#define R_NDS32_32_RELA 20 ++#define R_NDS32_9_PCREL_RELA 22 ++#define R_NDS32_15_PCREL_RELA 23 ++#define R_NDS32_17_PCREL_RELA 24 ++#define R_NDS32_25_PCREL_RELA 25 ++#define R_NDS32_HI20_RELA 26 ++#define R_NDS32_LO12S3_RELA 27 ++#define R_NDS32_LO12S2_RELA 28 ++#define R_NDS32_LO12S1_RELA 29 ++#define R_NDS32_LO12S0_RELA 30 ++#define R_NDS32_SDA15S3_RELA 31 ++#define R_NDS32_SDA15S2_RELA 32 ++#define R_NDS32_SDA15S1_RELA 33 ++#define R_NDS32_SDA15S0_RELA 34 ++#define R_NDS32_GOT20 37 ++#define R_NDS32_25_PLTREL 38 ++#define R_NDS32_COPY 39 ++#define R_NDS32_GLOB_DAT 40 ++#define R_NDS32_JMP_SLOT 41 ++#define R_NDS32_RELATIVE 42 ++#define R_NDS32_GOTOFF 43 ++#define R_NDS32_GOTPC20 44 ++#define R_NDS32_GOT_HI20 45 ++#define R_NDS32_GOT_LO12 46 ++#define R_NDS32_GOTPC_HI20 47 ++#define R_NDS32_GOTPC_LO12 48 ++#define R_NDS32_GOTOFF_HI20 49 ++#define R_NDS32_GOTOFF_LO12 50 ++#define R_NDS32_INSN16 51 ++#define R_NDS32_LABEL 52 ++#define R_NDS32_LONGCALL1 53 ++#define R_NDS32_LONGCALL2 54 ++#define R_NDS32_LONGCALL3 55 ++#define R_NDS32_LONGJUMP1 56 ++#define R_NDS32_LONGJUMP2 57 ++#define R_NDS32_LONGJUMP3 58 ++#define R_NDS32_LOADSTORE 59 ++#define R_NDS32_9_FIXED_RELA 60 ++#define R_NDS32_15_FIXED_RELA 61 ++#define R_NDS32_17_FIXED_RELA 62 ++#define R_NDS32_25_FIXED_RELA 63 ++#define R_NDS32_PLTREL_HI20 64 ++#define R_NDS32_PLTREL_LO12 65 ++#define R_NDS32_PLT_GOTREL_HI20 66 ++#define R_NDS32_PLT_GOTREL_LO12 67 ++#define R_NDS32_LO12S0_ORI_RELA 72 ++#define R_NDS32_DWARF2_OP1_RELA 77 ++#define R_NDS32_DWARF2_OP2_RELA 78 ++#define R_NDS32_DWARF2_LEB_RELA 79 ++#define R_NDS32_WORD_9_PCREL_RELA 94 ++#define R_NDS32_LONGCALL4 107 ++#define R_NDS32_RELA_NOP_MIX 192 ++#define R_NDS32_RELA_NOP_MAX 255 ++ ++#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) ++typedef elf_greg_t elf_gregset_t[ELF_NGREG]; ++ ++typedef struct user_fp elf_fpregset_t; ++ ++struct elf32_hdr; ++extern int elf_check_arch(const struct elf32_hdr *hdr); ++ ++/* ++ * These are used to set parameters in the core dumps. ++ */ ++#define ELF_CLASS ELFCLASS32 ++#ifdef __NDS32_EB__ ++#define ELF_DATA ELFDATA2MSB; ++#else ++#define ELF_DATA ELFDATA2LSB; ++#endif ++#define ELF_ARCH EM_NDS32 ++#define USE_ELF_CORE_DUMP ++#define ELF_EXEC_PAGESIZE PAGE_SIZE ++ ++/* This is the location that an ET_DYN program is loaded if exec'ed. Typical ++ use of this is to invoke "./ld.so someprog" to test out a new version of ++ the loader. We need to make sure that it is out of the way of the program ++ that it will "exec", and that there is sufficient room for the brk. */ ++ ++#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) ++ ++/* When the program starts, a1 contains a pointer to a function to be ++ registered with atexit, as per the SVR4 ABI. A value of 0 means we ++ have no such handler. */ ++#define ELF_PLAT_INIT(_r, load_addr) (_r)->NDS32_r0 = 0 ++ ++/* This yields a mask that user programs can use to figure out what ++ instruction set this cpu supports. */ ++ ++#define ELF_HWCAP (elf_hwcap) ++ ++/* This yields a string that ld.so will use to load implementation ++ specific libraries for optimization. This is more specific in ++ intent than poking at uname or /proc/cpuinfo. */ ++ ++/* For now we just provide a fairly general string that describes the ++ processor family. This could be made more specific later if someone ++ implemented optimisations that require it. 26-bit CPUs give you ++ "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't ++ supported). 32-bit CPUs give you "v3[lb]" for anything based on an ++ ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1 ++ core. */ ++ ++#define ELF_PLATFORM_SIZE 16 ++extern char elf_platform[]; ++#define ELF_PLATFORM (elf_platform) ++ ++#ifdef __KERNEL__ ++ ++/* Old NetWinder binaries were compiled in such a way that the iBCS ++ heuristic always trips on them. Until these binaries become uncommon ++ enough not to care, don't trust the `ibcs' flag here. In any case ++ there is no other ELF system currently supported by iBCS. ++ @@ Could print a warning message to encourage users to upgrade. */ ++#define SET_PERSONALITY(ex) set_personality(PER_LINUX) ++ ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/emergency-restart.h linux-3.4.110/arch/nds32/include/asm/emergency-restart.h +--- linux-3.4.110.orig/arch/nds32/include/asm/emergency-restart.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/emergency-restart.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/emergency-restart.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_EMERGENCY_RESTART_H__ ++#define __NDS32_EMERGENCY_RESTART_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/errno.h linux-3.4.110/arch/nds32/include/asm/errno.h +--- linux-3.4.110.orig/arch/nds32/include/asm/errno.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/errno.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/errno.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_ERRNO_H__ ++#define __NDS32_ERRNO_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/exec.h linux-3.4.110/arch/nds32/include/asm/exec.h +--- linux-3.4.110.orig/arch/nds32/include/asm/exec.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/exec.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,6 @@ ++#ifndef __ASM_NDS32_EXEC_H ++#define __ASM_NDS32_EXEC_H ++ ++#define arch_align_stack(x) (x) ++ ++#endif /* __ASM_ARM_EXEC_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fb.h linux-3.4.110/arch/nds32/include/asm/fb.h +--- linux-3.4.110.orig/arch/nds32/include/asm/fb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/fb.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * linux/arch/nds32/include/asm/fb.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_FB_H__ ++#define __NDS32_FB_H__ ++ ++ ++#include ++#include ++#include ++ ++static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, ++ unsigned long off) ++{ ++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ++} ++ ++static inline int fb_is_primary_device(struct fb_info *info) ++{ ++ return 0; ++} ++ ++#endif /* __NDS32_FB_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fcntl.h linux-3.4.110/arch/nds32/include/asm/fcntl.h +--- linux-3.4.110.orig/arch/nds32/include/asm/fcntl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/fcntl.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,37 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle ++ */ ++#ifndef _ASM_FCNTL_H ++#define _ASM_FCNTL_H ++ ++/* ++ * The flavours of struct flock. "struct flock" is the ABI compliant ++ * variant. Finally struct flock64 is the LFS variant of struct flock. As ++ * a historic accident and inconsistence with the ABI definition it doesn't ++ * contain all the same fields as struct flock. ++ */ ++ ++#ifdef CONFIG_32BIT ++#include ++ ++struct flock { ++ short l_type; ++ short l_whence; ++ off_t l_start; ++ off_t l_len; ++ long l_sysid; ++ __kernel_pid_t l_pid; ++ long pad[4]; ++}; ++ ++#define HAVE_ARCH_STRUCT_FLOCK ++ ++#endif /* CONFIG_32BIT */ ++ ++#include ++ ++#endif /* _ASM_FCNTL_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fixmap.h linux-3.4.110/arch/nds32/include/asm/fixmap.h +--- linux-3.4.110.orig/arch/nds32/include/asm/fixmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/fixmap.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,88 @@ ++/* ++ * fixmap.h: compile-time virtual memory allocation ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1998 Ingo Molnar ++ * ++ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 ++ */ ++ ++#ifndef __ASM_NDS32_FIXMAP_H ++#define __ASM_NDS32_FIXMAP_H ++ ++#ifdef CONFIG_HIGHMEM ++#include ++#include ++#endif ++ ++/* ++ * Here we define all the compile-time 'special' virtual ++ * addresses. The point is to have a constant address at ++ * compile time, but to set the physical address only ++ * in the boot process. We allocate these special addresses ++ * from the end of the consistent memory region backwards. ++ * Also this lets us do fail-safe vmalloc(), we ++ * can guarantee that these special addresses and ++ * vmalloc()-ed addresses never overlap. ++ * ++ * these 'compile-time allocated' memory buffers are ++ * fixed-size 4k pages. (or larger if used with an increment ++ * higher than 1) use fixmap_set(idx,phys) to associate ++ * physical memory with fixmap indices. ++ * ++ * TLB entries of such buffers will not be flushed across ++ * task switches. ++ */ ++enum fixed_addresses { ++ FIX_KMAP_RESERVED, ++ FIX_KMAP_BEGIN, ++#ifdef CONFIG_HIGHMEM ++ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS), ++#endif ++#ifdef CONFIG_EARLY_PRINTK ++ FIX_EARLY_DEBUG, ++#endif ++ FIX_RETURN_SYSCALL, ++ __end_of_fixed_addresses ++}; ++#define FIXADDR_TOP ((unsigned long) (-(16 * PAGE_SIZE))) ++#define FIXADDR_SIZE ((__end_of_fixed_addresses) << PAGE_SHIFT) ++#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) ++ ++#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) ++#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) ++ ++#define __this_fixmap_does_not_exist() WARN_ON(1) ++/* ++ * 'index to address' translation. If anyone tries to use the idx ++ * directly without tranlation, we catch the bug with a NULL-deference ++ * kernel oops. Illegal ranges of incoming indices are caught too. ++ */ ++ ++static inline unsigned long fix_to_virt(const unsigned int idx) ++{ ++ /* ++ * this branch gets completely eliminated after inlining, ++ * except when someone tries to use fixaddr indices in an ++ * illegal way. (such as mixing up address types or using ++ * out-of-range indices). ++ * ++ * If it doesn't get removed, the linker will complain ++ * loudly with a reasonably clear error message.. ++ */ ++ if (idx >= __end_of_fixed_addresses) ++ __this_fixmap_does_not_exist(); ++ ++ return __fix_to_virt(idx); ++} ++ ++static inline unsigned long virt_to_fix(const unsigned long vaddr) ++{ ++ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); ++ return __virt_to_fix(vaddr); ++} ++ ++#endif /* __ASM_NDS32_FIXMAP_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/fpu.h linux-3.4.110/arch/nds32/include/asm/fpu.h +--- linux-3.4.110.orig/arch/nds32/include/asm/fpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/fpu.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,100 @@ ++/* ++ * linux/arch/nds32/include/asm/fpu.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_FPU_H ++#define __ASM_NDS32_FPU_H ++ ++#ifndef __ASSEMBLY__ ++#include ++#include ++ ++extern void save_fpu(struct task_struct *__tsk); ++extern void fpload(struct fpu_struct *fpregs); ++extern void do_fpu_exception(unsigned long error_code, struct pt_regs *regs); ++extern int do_fpu_inst(unsigned short, struct pt_regs *); ++ ++#ifdef CONFIG_FPU ++ ++#define test_tsk_fpu(regs) (regs->NDS32_FUCOP_CTL & FUCOP_CTL_mskCP0EN) ++ ++struct task_struct; ++ ++static inline void release_fpu(struct pt_regs *regs) ++{ ++ regs->NDS32_FUCOP_CTL &= ~FUCOP_CTL_mskCP0EN; ++} ++ ++static inline void grab_fpu(struct pt_regs *regs) ++{ ++ regs->NDS32_FUCOP_CTL |= FUCOP_CTL_mskCP0EN; ++} ++ ++static inline void enable_fpu(void) ++{ ++ SET_FUCOP_CTL(GET_FUCOP_CTL() | FUCOP_CTL_mskCP0EN); ++} ++ ++static inline void disable_fpu(void) ++{ ++ SET_FUCOP_CTL(GET_FUCOP_CTL() & ~FUCOP_CTL_mskCP0EN); ++} ++ ++static inline void lose_fpu(int save) ++{ ++ preempt_disable(); ++ if (test_tsk_fpu(task_pt_regs(current))) { ++ if (save) ++ { ++ save_fpu(current); ++# ifndef CONFIG_UNLAZY_FPU ++ last_task_used_math=NULL; ++# endif ++ } ++ release_fpu(task_pt_regs(current)); ++ } ++ preempt_enable(); ++} ++ ++static inline void own_fpu(int restore) ++{ ++ preempt_disable(); ++ if (!test_tsk_fpu(task_pt_regs(current))) { ++ if (restore) ++ { ++# ifdef CONFIG_UNLAZY_FPU ++ fpload(¤t->thread.fpu); ++# else ++ if((last_task_used_math!=NULL) ++ &&(last_task_used_math!=current)) ++ save_fpu(last_task_used_math); ++ fpload(¤t->thread.fpu); ++ last_task_used_math=current; ++#endif ++ } ++ grab_fpu(task_pt_regs(current)); ++ } ++ preempt_enable(); ++} ++# ifdef CONFIG_UNLAZY_FPU ++static inline void unlazy_fpu(struct task_struct *tsk) ++{ ++ preempt_disable(); ++ if (test_tsk_fpu(task_pt_regs(tsk))) ++ save_fpu(tsk); ++ preempt_enable(); ++} ++# endif /* CONFIG_UNLAZY_FPU */ ++static inline void clear_fpu(struct pt_regs *regs) ++{ ++ preempt_disable(); ++ if (test_tsk_fpu(regs)) { ++ release_fpu(regs); ++ } ++ preempt_enable(); ++} ++#endif /* CONFIG_FPU */ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* __ASM_NDS32_FPU_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ftpci.h linux-3.4.110/arch/nds32/include/asm/ftpci.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ftpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ftpci.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * linux/arch/nds32/include/asm/ftpci.h ++ * ++ * Faraday FTPCI010 PCI Bridge Device Driver Interface ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ChangeLog ++ * ++ * Peter Liao 09/26/2005 Created, heavily modified from Faraday A320 platform code. ++ */ ++ ++#ifndef __FARADAY_PLATFORM_PCI_HEADER__ ++#define __FARADAY_PLATFORM_PCI_HEADER__ ++ ++ ++#define PCI_BRIDGE_DEVID 0x4321 ++#define PCI_BRIDGE_VENID 0x159b ++ ++extern int ftpci_probed; ++extern void ftpci_clear_irq(unsigned int irq); ++extern void ftpci_mask_irq(unsigned int irq); ++extern void ftpci_unmask_irq(unsigned int irq); ++extern int ftpci_get_irq(void); ++#endif /* __FARADAY_PLATFORM_PCI_HEADER__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ftrace.h linux-3.4.110/arch/nds32/include/asm/ftrace.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ftrace.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ftrace.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _ASM_POWERPC_FTRACE ++#define _ASM_POWERPC_FTRACE ++ ++#ifdef CONFIG_FUNCTION_TRACER ++#define MCOUNT_ADDR ((long)(_mcount)) ++#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ ++ ++#ifdef __ASSEMBLY__ ++ ++#else /* !__ASSEMBLY__ */ ++extern void _mcount(void); ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif ++ ++#endif /* _ASM_POWERPC_FTRACE */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/futex.h linux-3.4.110/arch/nds32/include/asm/futex.h +--- linux-3.4.110.orig/arch/nds32/include/asm/futex.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/futex.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/futex.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_FUTEX_H__ ++#define __NDS32_FUTEX_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/glue.h linux-3.4.110/arch/nds32/include/asm/glue.h +--- linux-3.4.110.orig/arch/nds32/include/asm/glue.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/glue.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,26 @@ ++/* ++ * linux/arch/nds32/include/asm/glue.h ++ * ++ * Copyright (C) 1997-1999 Russell King ++ * Copyright (C) 2000-2002 Deep Blue Solutions Ltd. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This file provides the glue to stick the processor-specific bits ++ * into the kernel in an efficient manner. The idea is to use branches ++ * when we're only targetting one class of TLB, or indirect calls ++ * when we're targetting multiple classes of TLBs. ++ */ ++#ifdef __KERNEL__ ++ ++#ifdef __STDC__ ++#define ____glue(name,fn) name##fn ++#else ++#define ____glue(name,fn) name/**/fn ++#endif ++#define __glue(name,fn) ____glue(name,fn) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/gpio.h linux-3.4.110/arch/nds32/include/asm/gpio.h +--- linux-3.4.110.orig/arch/nds32/include/asm/gpio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/gpio.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,10 @@ ++#ifndef _ARCH_NDS32_GPIO_H ++#define _ARCH_NDS32_GPIO_H ++ ++#include ++#define gpio_get_value __gpio_get_value ++#define gpio_set_value __gpio_set_value ++#define gpio_cansleep __gpio_cansleep ++#define gpio_to_irq __gpio_to_irq ++ ++#endif /* _ARCH_NDS32_GPIO_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/hardirq.h linux-3.4.110/arch/nds32/include/asm/hardirq.h +--- linux-3.4.110.orig/arch/nds32/include/asm/hardirq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/hardirq.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * linux/arch/nds32/include/asm/hardirq.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++#ifndef __ASM_HARDIRQ_H ++#define __ASM_HARDIRQ_H ++ ++#include ++#include ++#include ++ ++typedef struct { ++ unsigned int __softirq_pending; ++} ____cacheline_aligned irq_cpustat_t; ++ ++#include /* Standard mappings for irq_cpustat_t above */ ++ ++#if NR_IRQS > 256 ++#define HARDIRQ_BITS 9 ++#else ++#define HARDIRQ_BITS 8 ++#endif ++ ++/* ++ * The hardirq mask has to be large enough to have space ++ * for potentially all IRQ sources in the system nesting ++ * on a single CPU: ++ */ ++#if (1 << HARDIRQ_BITS) < NR_IRQS ++# error HARDIRQ_BITS is too low! ++#endif ++ ++#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 ++ ++extern void ack_bad_irq(unsigned int irq); ++#endif /* __ASM_HARDIRQ_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/hardware.h linux-3.4.110/arch/nds32/include/asm/hardware.h +--- linux-3.4.110.orig/arch/nds32/include/asm/hardware.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/hardware.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,61 @@ ++/* ++ * linux/arch/nds32/include/asm/hardware.h ++ * ++ * Faraday Platform Independent Hardware Configuration ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/16/2005 Created. ++ * Peter Liao 10/04/2005 Modified for uClinux ++ * Harry Pan 11/02/2007 Added REGxx macros. ++ */ ++ ++#ifndef __FARADAY_PLATFORM_HARDWARE_HEADER__ ++#define __FARADAY_PLATFORM_HARDWARE_HEADER__ ++ ++#include ++ ++#ifndef PCIBIOS_MIN_IO ++/* the mini io address is 0x6000,that is IO will allocate from 0-0x6000 offset*/ ++#define PCIBIOS_MIN_IO 0x0 ++#endif ++ ++#ifndef PCIBIOS_MIN_MEM ++/* the mini MEM address is 0x100000,that is MEM will allocate from 0-0x100000 offset*/ ++#define PCIBIOS_MIN_MEM 0x0 ++#endif ++ ++#define pcibios_assign_all_busses() 1 ++ ++/* Pliauo add 5 to resolve __alloc_bootmem_core return NULL pointer in bootmem.c */ ++#if defined(CPU_MEM_PA_BASE) && defined(CPU_MEM_PA_SIZE) ++ #define PA_SDRAM_BASE (CPU_MEM_PA_BASE) ++#else ++ #define PA_SDRAM_BASE (0x00000000) ++#endif ++ ++/* ++ * Define a simple register accessing method by Harry@Nov.02.2007 ++ */ ++#define REG32(a) (*(volatile unsigned int *)(a)) ++#define REG16(a) (*(volatile unsigned short *)(a)) ++#define REG8(a) (*(volatile unsigned char *)(a)) ++ ++#endif /* __FARADAY_PLATFORM_HARDWARE_HEADER__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/highmem.h linux-3.4.110/arch/nds32/include/asm/highmem.h +--- linux-3.4.110.orig/arch/nds32/include/asm/highmem.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/highmem.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,61 @@ ++#ifndef _ASM_HIGHMEM_H ++#define _ASM_HIGHMEM_H ++ ++#include ++#include ++#include ++ ++/* ++ * Right now we initialize only a single pte table. It can be extended ++ * easily, subsequent pte tables have to be allocated in one physical ++ * chunk of RAM. ++ */ ++/* ++ * Ordering is (from lower to higher memory addresses): ++ * ++ * high_memory ++ * Persistent kmap area ++ * PKMAP_BASE ++ * fixed_addresses ++ * FIXADDR_START ++ * FIXADDR_TOP ++ * Vmalloc area ++ * VMALLOC_START ++ * VMALLOC_END ++ */ ++#define PKMAP_BASE ((FIXADDR_START - PGDIR_SIZE) & (PGDIR_MASK)) ++#define LAST_PKMAP PTRS_PER_PTE ++#define LAST_PKMAP_MASK (LAST_PKMAP - 1) ++#define PKMAP_NR(virt) (((virt) - (PKMAP_BASE)) >> PAGE_SHIFT) ++#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) ++#define kmap_prot PAGE_KERNEL ++ ++static inline void flush_cache_kmaps(void) ++{ ++ cpu_dcache_wbinval_all(); ++} ++ ++/* declarations for highmem.c */ ++extern unsigned long highstart_pfn, highend_pfn; ++ ++extern pte_t *pkmap_page_table; ++ ++extern void *kmap_high(struct page *page); ++extern void kunmap_high(struct page *page); ++ ++extern void kmap_init(void); ++ ++/* ++ * The following functions are already defined by ++ * when CONFIG_HIGHMEM is not set. ++ */ ++#ifdef CONFIG_HIGHMEM ++extern void *kmap(struct page *page); ++extern void kunmap(struct page *page); ++extern void *kmap_atomic(struct page *page); ++extern void __kunmap_atomic(void *kvaddr); ++extern void *kmap_atomic_pfn(unsigned long pfn); ++extern struct page *kmap_atomic_to_page(void *ptr); ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/hw_irq.h linux-3.4.110/arch/nds32/include/asm/hw_irq.h +--- linux-3.4.110.orig/arch/nds32/include/asm/hw_irq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/hw_irq.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/hw_irq.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_HW_IRQ_H__ ++#define __NDS32_HW_IRQ_H__ ++ ++ ++#endif /* __NDS32_HW_IRQ_H__ */ ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/intc.h linux-3.4.110/arch/nds32/include/asm/intc.h +--- linux-3.4.110.orig/arch/nds32/include/asm/intc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/intc.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * linux/arch/nds32/include/asm/intc.h ++ * ++ * Faraday FTINTC010 Interrupt Controller Device Driver Interface ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/14/2005 Created, heavily modified from Faraday CPE platform code. ++ */ ++ ++#ifndef __FARADAY_INTC_FTINTC010_HEADER__ ++#define __FARADAY_INTC_FTINTC010_HEADER__ ++ ++#define IRQ_SOURCE_REG 0 ++#define IRQ_MASK_REG 0x04 ++#define IRQ_CLEAR_REG 0x08 ++#define IRQ_MODE_REG 0x0c ++#define IRQ_LEVEL_REG 0x10 ++#define IRQ_STATUS_REG 0x14 ++ ++#define FIQ_SOURCE_REG 0x20 ++#define FIQ_MASK_REG 0x24 ++#define FIQ_CLEAR_REG 0x28 ++#define FIQ_MODE_REG 0x2c ++#define FIQ_LEVEL_REG 0x30 ++#define FIQ_STATUS_REG 0x34 ++ ++#endif /* __FARADAY_INTC_FTINTC010_HEADER__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ioctl.h linux-3.4.110/arch/nds32/include/asm/ioctl.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ioctl.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/ioctl.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_IOCTL_H__ ++#define __NDS32_IOCTL_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ioctls.h linux-3.4.110/arch/nds32/include/asm/ioctls.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ioctls.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ioctls.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,13 @@ ++/* ++ * linux/arch/nds32/include/asm/ioctls.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_IOCTLS_H ++#define __ASM_NDS32_IOCTLS_H ++ ++#define FIOQSIZE 0x545E ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/io.h linux-3.4.110/arch/nds32/include/asm/io.h +--- linux-3.4.110.orig/arch/nds32/include/asm/io.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/io.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,343 @@ ++/* ++ * linux/arch/nds32/include/asm/io.h ++ * ++ * Copyright (C) 1996-2000 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Modifications: ++ * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both ++ * constant addresses and variable addresses. ++ * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture ++ * specific IO header files. ++ * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. ++ * 04-Apr-1999 PJB Added check_signature. ++ * 12-Dec-1999 RMK More cleanups ++ * 18-Jun-2000 RMK Removed virt_to_* and friends definitions ++ * 05-Oct-2004 BJD Moved memory string functions to use void __iomem ++ */ ++#ifndef __ASM_NDS32_IO_H ++#define __ASM_NDS32_IO_H ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* ++ * ISA I/O bus memory addresses are 1:1 with the physical address. ++ */ ++#define isa_virt_to_bus virt_to_phys ++#define isa_page_to_bus page_to_phys ++#define isa_bus_to_virt phys_to_virt ++ ++/* ++ * Generic IO read/write. These perform native-endian accesses. Note ++ * that some architectures will want to re-define __raw_{read,write}w. ++ */ ++ ++#define __raw_writeb(v,a) (*(volatile unsigned char __force *)(a) = (v)) ++#define __raw_writew(v,a) (*(volatile unsigned short __force *)(a) = (v)) ++#define __raw_writel(v,a) (*(volatile unsigned int __force *)(a) = (v)) ++ ++#define __raw_readb(a) (*(volatile unsigned char __force *)(a)) ++#define __raw_readw(a) (*(volatile unsigned short __force *)(a)) ++#define __raw_readl(a) (*(volatile unsigned int __force *)(a)) ++ ++/* ++ * Bad read/write accesses... ++ */ ++extern void __readwrite_bug(const char *fn); ++ ++/* ++ * Now, pick up the machine-defined IO definitions ++ */ ++#ifndef __FARADAY_PLATFORM_IO_HEADER__ ++#define __FARADAY_PLATFORM_IO_HEADER__ ++ ++#include ++#include ++ ++#ifndef IO_SPACE_LIMIT ++#define IO_SPACE_LIMIT 0xffffffff ++#endif ++ ++#ifndef __io ++#define __io(a) ((void __iomem *)(a)) ++#endif ++#define IO_ADDRESS(a) __io(a) ++#ifndef __mem_pci ++#define __mem_pci(a) (a) ++#endif ++ ++#endif ++ ++#ifdef __io_pci ++#warning machine class uses buggy __io_pci ++#endif ++#if defined(__arch_putb) || defined(__arch_putw) || defined(__arch_putl) || \ ++ defined(__arch_getb) || defined(__arch_getw) || defined(__arch_getl) ++//-Tom for debug ++//#warning machine class uses old __arch_putw or __arch_getw ++#endif ++ ++/* ++ * IO port access primitives ++ * ------------------------- ++ * ++ * The ARM doesn't have special IO access instructions; all IO is memory ++ * mapped. Note that these are defined to perform little endian accesses ++ * only. Their primary purpose is to access PCI and ISA peripherals. ++ * ++ * Note that for a big endian machine, this implies that the following ++ * big endian mode connectivity is in place, as described by numerious ++ * ARM documents: ++ * ++ * PCI: D0-D7 D8-D15 D16-D23 D24-D31 ++ * ARM: D24-D31 D16-D23 D8-D15 D0-D7 ++ * ++ * The machine specific io.h include defines __io to translate an "IO" ++ * address to a memory address. ++ * ++ * Note that we prevent GCC re-ordering or caching values in expressions ++ * by introducing sequence points into the in*() definitions. Note that ++ * __raw_* do not guarantee this behaviour. ++ * ++ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. ++ */ ++#ifdef __io ++#ifdef __NDS32_EB__ ++#define inw(p) ({ unsigned int __v = be16_to_cpu(__raw_readw(__io(p))); __v; }) ++#define inl(p) ({ unsigned int __v = be32_to_cpu(__raw_readl(__io(p))); __v; }) ++#define outw(v,p) __raw_writew(cpu_to_be16(v),__io(p)) ++#define outl(v,p) __raw_writel(cpu_to_be32(v),__io(p)) ++#else ++#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) ++#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; }) ++#define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p)) ++#define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p)) ++#endif ++ ++#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; }) ++#define outb(v,p) __raw_writeb(v,__io(p)) ++ ++#endif ++ ++#define outb_p(val,port) outb((val),(port)) ++#define outw_p(val,port) outw((val),(port)) ++#define outl_p(val,port) outl((val),(port)) ++#define inb_p(port) inb((port)) ++#define inw_p(port) inw((port)) ++#define inl_p(port) inl((port)) ++ ++/* ++ * String version of IO memory access ops: ++ */ ++extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t); ++extern void _memcpy_toio(volatile void __iomem *, const void *, size_t); ++extern void _memset_io(volatile void __iomem *, int, size_t); ++ ++#define mmiowb() ++ ++/* ++ * Memory access primitives ++ * ------------------------ ++ * ++ * These perform PCI memory accesses via an ioremap region. They don't ++ * take an address as such, but a cookie. ++ * ++ * Again, this are defined to perform little endian accesses. See the ++ * IO port primitives for more information. ++ */ ++#ifdef __mem_pci ++#ifdef __NDS32_EB__ ++#define readw(c) ({ unsigned int __v = be16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) ++#define readl(c) ({ unsigned int __v = be32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) ++#define writew(v,c) __raw_writew(cpu_to_be16(v),__mem_pci(c)) ++#define writel(v,c) __raw_writel(cpu_to_be32(v),__mem_pci(c)) ++#else ++#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) ++#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) ++#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c)) ++#define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c)) ++#endif ++ ++#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; }) ++#define writeb(v,c) __raw_writeb(v,__mem_pci(c)) ++ ++#define readb_relaxed(addr) readb(addr) ++#define readw_relaxed(addr) readw(addr) ++#define readl_relaxed(addr) readl(addr) ++ ++#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) ++#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) ++#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) ++ ++#define eth_io_copy_and_sum(s,c,l,b) \ ++ eth_copy_and_sum((s),__mem_pci(c),(l),(b)) ++ ++#elif !defined(readb) ++ ++#define readb(c) (__readwrite_bug("readb"),0) ++#define readw(c) (__readwrite_bug("readw"),0) ++#define readl(c) (__readwrite_bug("readl"),0) ++#define writeb(v,c) __readwrite_bug("writeb") ++#define writew(v,c) __readwrite_bug("writew") ++#define writel(v,c) __readwrite_bug("writel") ++ ++#define eth_io_copy_and_sum(s,c,l,b) __readwrite_bug("eth_io_copy_and_sum") ++ ++#endif /* __mem_pci */ ++ ++/* ++ * If this architecture has ISA IO, then define the isa_read/isa_write ++ * macros. ++ */ ++#ifdef __mem_isa ++ ++#define isa_readb(addr) __raw_readb(__mem_isa(addr)) ++#define isa_readw(addr) __raw_readw(__mem_isa(addr)) ++#define isa_readl(addr) __raw_readl(__mem_isa(addr)) ++#define isa_writeb(val,addr) __raw_writeb(val,__mem_isa(addr)) ++#define isa_writew(val,addr) __raw_writew(val,__mem_isa(addr)) ++#define isa_writel(val,addr) __raw_writel(val,__mem_isa(addr)) ++#define isa_memset_io(a,b,c) _memset_io(__mem_isa(a),(b),(c)) ++#define isa_memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_isa(b),(c)) ++#define isa_memcpy_toio(a,b,c) _memcpy_toio(__mem_isa((a)),(b),(c)) ++ ++#define isa_eth_io_copy_and_sum(a,b,c,d) \ ++ eth_copy_and_sum((a),__mem_isa(b),(c),(d)) ++ ++#else /* __mem_isa */ ++ ++#define isa_readb(addr) (__readwrite_bug("isa_readb"),0) ++#define isa_readw(addr) (__readwrite_bug("isa_readw"),0) ++#define isa_readl(addr) (__readwrite_bug("isa_readl"),0) ++#define isa_writeb(val,addr) __readwrite_bug("isa_writeb") ++#define isa_writew(val,addr) __readwrite_bug("isa_writew") ++#define isa_writel(val,addr) __readwrite_bug("isa_writel") ++#define isa_memset_io(a,b,c) __readwrite_bug("isa_memset_io") ++#define isa_memcpy_fromio(a,b,c) __readwrite_bug("isa_memcpy_fromio") ++#define isa_memcpy_toio(a,b,c) __readwrite_bug("isa_memcpy_toio") ++ ++#define isa_eth_io_copy_and_sum(a,b,c,d) \ ++ __readwrite_bug("isa_eth_io_copy_and_sum") ++ ++#endif /* __mem_isa */ ++ ++/* ++ * ioremap and friends. ++ * ++ * ioremap takes a PCI memory address, as specified in ++ * Documentation/IO-mapping.txt. ++ */ ++extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long); ++extern void __iounmap(void __iomem *addr); ++ ++#ifndef __arch_ioremap ++#define ioremap(cookie,size) __ioremap(cookie,size,0,1) ++#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0,1) ++#define iounmap(cookie) __iounmap(cookie) ++#else ++#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0,1) ++#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0,1) ++#define iounmap(cookie) __arch_iounmap(cookie) ++#endif ++ ++/* ++ * can the hardware map this into one segment or not, given no other ++ * constraints. ++ */ ++#define BIOVEC_MERGEABLE(vec1, vec2) \ ++ ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) ++ ++/* ++ * Convert a physical pointer to a virtual kernel pointer for /dev/mem ++ * access ++ */ ++#define xlate_dev_mem_ptr(p) __va(p) ++ ++/* ++ * Convert a virtual cached pointer to an uncached pointer ++ */ ++#define xlate_dev_kmem_ptr(p) p ++static inline void readsb(const void __iomem *addr, void * data, int bytelen) ++{ ++ unsigned char *ptr = (unsigned char *)addr; ++ unsigned char *ptr2 = (unsigned char *)data; ++ while(bytelen) { ++ *ptr2 = *ptr; ++ ptr2++; ++ bytelen--; ++ } ++} ++ ++static inline void readsw(const void __iomem *addr, void * data, int wordlen) ++{ ++ unsigned short *ptr = (unsigned short *)addr; ++ unsigned short *ptr2 = (unsigned short *)data; ++ while(wordlen) { ++ *ptr2 = *ptr; ++ ptr2++; ++ wordlen--; ++ } ++} ++ ++static inline void readsl(const void __iomem *addr, void * data, int longlen) ++{ ++ unsigned int *ptr = (unsigned int *)addr; ++ unsigned int *ptr2 = (unsigned int *)data; ++ while(longlen) { ++ *ptr2 = *ptr; ++ ptr2++; ++ longlen--; ++ } ++} ++static inline void writesb(void __iomem *addr, const void * data, int bytelen) ++{ ++ unsigned char *ptr = (unsigned char *)addr; ++ unsigned char *ptr2 = (unsigned char *)data; ++ while(bytelen) { ++ *ptr = *ptr2; ++ ptr2++; ++ bytelen--; ++ } ++} ++static inline void writesw(void __iomem *addr, const void * data, int wordlen) ++{ ++ unsigned short *ptr = (unsigned short *)addr; ++ unsigned short *ptr2 = (unsigned short *)data; ++ while(wordlen) { ++ *ptr = *ptr2; ++ ptr2++; ++ wordlen--; ++ } ++} ++static inline void writesl(void __iomem *addr, const void * data, int longlen) ++{ ++ unsigned int *ptr = (unsigned int *)addr; ++ unsigned int *ptr2 = (unsigned int *)data; ++ while(longlen) { ++ *ptr = *ptr2; ++ ptr2++; ++ longlen--; ++ } ++} ++ ++ ++#define insb(p,d,l) BUG() ++#define insw(p,d,l) BUG() ++#define insl(p,d,l) BUG() ++#define outsb(p,d,l) BUG() ++#define outsw(p,d,l) BUG() ++#define outsl(p,d,l) BUG() ++ ++#endif /* __KERNEL__ */ ++#endif /* __ASM_NDS32_IO_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ipcbuf.h linux-3.4.110/arch/nds32/include/asm/ipcbuf.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ipcbuf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ipcbuf.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,34 @@ ++/* ++ * linux/arch/nds32/include/asm/ipcbuf.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASMNDS32_IPCBUF_H ++#define __ASMNDS32_IPCBUF_H ++ ++/* ++ * The ipc64_perm structure for arm architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 32-bit mode_t and seq ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct ipc64_perm ++{ ++ __kernel_key_t key; ++ __kernel_uid32_t uid; ++ __kernel_gid32_t gid; ++ __kernel_uid32_t cuid; ++ __kernel_gid32_t cgid; ++ __kernel_mode_t mode; ++ unsigned short __pad1; ++ unsigned short seq; ++ unsigned short __pad2; ++ unsigned long __unused1; ++ unsigned long __unused2; ++}; ++ ++#endif /* __ASMNDS32_IPCBUF_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/irqflags.h linux-3.4.110/arch/nds32/include/asm/irqflags.h +--- linux-3.4.110.orig/arch/nds32/include/asm/irqflags.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/irqflags.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,65 @@ ++/* ++ * linux/arch/nds32/include/asm/irqflags.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#include ++#include ++ ++#define arch_local_irq_disable() \ ++ GIE_DISABLE(); ++ ++#define arch_local_irq_enable() \ ++ GIE_ENABLE(); ++static inline unsigned long arch_local_irq_save(void) ++{ ++ unsigned long flags; ++ __asm__ __volatile__( ++ "mfsr %0, $PSW\n" ++ "andi %0, %0, #0x1\n" ++ "gie_disable\n" ++ : "=r" (flags) ); ++ return flags; ++} ++static inline unsigned long arch_local_save_flags(void) ++{ ++ unsigned long flags; ++ __asm__ __volatile__( ++ "mfsr %0, $PSW\n" ++ "andi %0, %0, #0x1" ++ : "=r" (flags) ); ++ return flags; ++} ++static inline void arch_local_irq_restore(unsigned long flags) ++{ ++ __asm__ __volatile__( ++ "beqz %0, 1f\n" ++ "gie_enable\n" ++ "1:" ++ :: "r" (flags) ); ++} ++static inline int arch_irqs_disabled_flags(unsigned long flags) ++{ ++ return !flags; ++} ++#if 0 ++#define raw_local_irq_save(x) \ ++ __asm__ __volatile__( \ ++ "mfsr %0, $PSW\n" \ ++ "andi %0, %0, #0x1\n" \ ++ "gie_disable\n" \ ++ : "=r" (x) ) ++#define raw_local_save_flags(x) \ ++ __asm__ __volatile__( \ ++ "mfsr %0, $PSW\n" \ ++ "andi %0, %0, #0x1" \ ++ : "=r" (x) ) ++#define raw_local_irq_restore(x) \ ++ __asm__ __volatile__( \ ++ "beqz %0, 1f\n" \ ++ "gie_enable\n" \ ++ "1:" \ ++ :: "r" (x) ) ++ ++#define raw_irqs_disabled_flags(x) !(x) ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/irq.h linux-3.4.110/arch/nds32/include/asm/irq.h +--- linux-3.4.110.orig/arch/nds32/include/asm/irq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/irq.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,50 @@ ++/* ++ * linux/arch/nds32/include/asm/irq.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_IRQ_H ++#define __ASM_NDS32_IRQ_H ++ ++#include ++ ++#ifndef irq_canonicalize ++#define irq_canonicalize(i) (i) ++#endif ++ ++#ifndef NR_IRQS ++#define NR_IRQS 128 ++#endif ++ ++/* ++ * Use this value to indicate lack of interrupt ++ * capability ++ */ ++#ifndef NO_IRQ ++#define NO_IRQ ((unsigned int)(-1)) ++#endif ++ ++struct irqaction; ++ ++extern void disable_irq_nosync(unsigned int); ++extern void disable_irq(unsigned int); ++extern void enable_irq(unsigned int); ++ ++#define __IRQT_FALEDGE IRQ_TYPE_EDGE_FALLING ++#define __IRQT_RISEDGE IRQ_TYPE_EDGE_RISING ++#define __IRQT_LOWLVL IRQ_TYPE_LEVEL_LOW ++#define __IRQT_HIGHLVL IRQ_TYPE_LEVEL_HIGH ++ ++#define IRQT_NOEDGE (0) ++#define IRQT_RISING (__IRQT_RISEDGE) ++#define IRQT_FALLING (__IRQT_FALEDGE) ++#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE) ++#define IRQT_LOW (__IRQT_LOWLVL) ++#define IRQT_HIGH (__IRQT_HIGHLVL) ++#define IRQT_PROBE IRQ_TYPE_PROBE ++ ++struct irqaction; ++struct pt_regs; ++ ++#endif ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/irq_regs.h linux-3.4.110/arch/nds32/include/asm/irq_regs.h +--- linux-3.4.110.orig/arch/nds32/include/asm/irq_regs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/irq_regs.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,9 @@ ++/* ++ * linux/arch/nds32/include/asm/irq_regs.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_IRQ_REGS_H__ ++#define __NDS32_IRQ_REGS_H__ ++#include ++#endif /* __NDS32_IRQ_REGS_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/Kbuild linux-3.4.110/arch/nds32/include/asm/Kbuild +--- linux-3.4.110.orig/arch/nds32/include/asm/Kbuild 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/Kbuild 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,3 @@ ++include include/asm-generic/Kbuild.asm ++ ++header-y += pfm.h +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kdebug.h linux-3.4.110/arch/nds32/include/asm/kdebug.h +--- linux-3.4.110.orig/arch/nds32/include/asm/kdebug.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/kdebug.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,14 @@ ++/* ++ * linux/arch/nds32/include/asm/kdebug.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_KDEBUG_H__ ++#define __NDS32_KDEBUG_H__ ++ ++enum die_val { ++ DIE_OOPS = 1, ++ DIE_DEBUG, ++}; ++ ++#endif /* __NDS32_KDEBUG_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kexec.h linux-3.4.110/arch/nds32/include/asm/kexec.h +--- linux-3.4.110.orig/arch/nds32/include/asm/kexec.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/kexec.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,31 @@ ++#ifndef _NDS32_KEXEC_H ++#define _NDS32_KEXEC_H ++ ++#ifdef CONFIG_KEXEC ++ ++/* Maximum physical address we can use pages from */ ++#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) ++/* Maximum address we can reach in physical address mode */ ++#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) ++/* Maximum address we can use for the control code buffer */ ++#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) ++ ++#define KEXEC_CONTROL_PAGE_SIZE 4096 ++ ++#define KEXEC_ARCH KEXEC_ARCH_NDS32 ++ ++#define KEXEC_NDS32_ATAGS_OFFSET 0x1000 ++#define KEXEC_NDS32_ZIMAGE_OFFSET 0x500000 ++ ++#ifndef __ASSEMBLY__ ++ ++struct kimage; ++/* Provide a dummy definition to avoid build failures. */ ++static inline void crash_setup_regs(struct pt_regs *newregs, ++ struct pt_regs *oldregs) { } ++ ++#endif /* __ASSEMBLY__ */ ++ ++#endif /* CONFIG_KEXEC */ ++ ++#endif /* _NDS32_KEXEC_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kgdb.h linux-3.4.110/arch/nds32/include/asm/kgdb.h +--- linux-3.4.110.orig/arch/nds32/include/asm/kgdb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/kgdb.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,90 @@ ++/* ============================================================================ ++ * ++ * linux/arch/nds32/include/asm/kgdb.h ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for NDS32 KGDB support. ++ * ++ * Author: Harry Pan ++ * ++ * Revision History: ++ * ++ * Jul.14.2007 Initial ported by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#ifndef __ASM_NDS32_KGDB_H__ ++#define __ASM_NDS32_KGDB_H__ ++ ++#include ++ ++#define BREAK_INSTR_SIZE 2 ++#define CACHE_FLUSH_IS_SAFE 1 ++ ++#ifndef __ASSEMBLY__ ++ ++/* ++ * Define numbers of registers we have in NDS32 arch ++ */ ++#define NDS32_NUM_GR 32 // general registers. ++#define NDS32_NUM_SPR 5 // special registers. (PC, D0, D1) ++#define NDS32_NUM_CR 6 // ctrl registers. ++#define NDS32_NUM_IR 16 // interruption registers. ++#define NDS32_NUM_MR 11 // MMU registers. ++#define NDS32_NUM_DR 48 // debug registers. ++#define NDS32_NUM_PFR 4 // performance monitoring registers. ++#define NDS32_NUM_DMAR 11 // local memory DMA registers ++#define NDS32_NUM_RACR 1 // resource access control registers. ++#define NDS32_NUM_IDR 2 // implementation dependent registers. ++#define NDS32_NUM_SR (NDS32_NUM_CR + NDS32_NUM_IR + NDS32_NUM_MR + \ ++ NDS32_NUM_DR + NDS32_NUM_PFR + NDS32_NUM_DMAR + \ ++ NDS32_NUM_RACR + NDS32_NUM_IDR) ++#define NDS32_NUM_REGS (NDS32_NUM_GR + NDS32_NUM_SPR + NDS32_NUM_SR) ++ ++#define KGDB_MAX_NO_CPUS 1 ++#define BUFMAX 2048 ++#define NUMREGBYTES (NDS32_NUM_REGS << 2) ++ ++/* ++ * NDS32 virtual registers layout for GDB. ++ */ ++enum nds32_regnum ++{ ++ NDS32_R0_REGNUM = 0, // first integer-like argument. ++ NDS32_R5_REGNUM = 5, // last integer-like argument. ++ NDS32_FP_REGNUM = 28, // frame register ++ NDS32_LP_REGNUM = 30, // link pointer ++ NDS32_SP_REGNUM = 31, // address of stack top. ++ NDS32_PC_REGNUM = 32, ++ NDS32_D0LO_REGNUM = 33, ++ NDS32_D0HI_REGNUM = 34, ++ NDS32_D1LO_REGNUM = 35, ++ NDS32_D1HI_REGNUM = 36, ++ NDS32_CR0_REGNUM = 37, ++ NDS32_IR0_REGNUM = (NDS32_CR0_REGNUM + NDS32_NUM_CR), ++ NDS32_MR0_REGNUM = (NDS32_IR0_REGNUM + NDS32_NUM_IR), ++ NDS32_DR0_REGNUM = (NDS32_MR0_REGNUM + NDS32_NUM_MR), ++ NDS32_PFR0_REGNUM = (NDS32_DR0_REGNUM + NDS32_NUM_DR), ++ NDS32_DMAR0_REGNUM = (NDS32_PFR0_REGNUM + NDS32_NUM_PFR), ++ NDS32_RACR0_REGNUM = (NDS32_DMAR0_REGNUM + NDS32_NUM_DMAR), ++ NDS32_IDR0_REGNUM = (NDS32_RACR0_REGNUM + NDS32_NUM_RACR), ++ /* nds32 calling convention. */ ++ NDS32_ARG0_REGNUM = NDS32_R0_REGNUM, ++ NDS32_ARGN_REGNUM = NDS32_R5_REGNUM, ++ NDS32_RET_REGNUM = NDS32_R0_REGNUM, ++}; ++ ++static inline void arch_kgdb_breakpoint(void) ++{ ++ asm __volatile__ ( "break 0x1ff\n" ); ++} ++ ++#endif /* !__ASSEMBLY__ */ ++#endif /* __ASM_NDS32_KGDB_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kmap_types.h linux-3.4.110/arch/nds32/include/asm/kmap_types.h +--- linux-3.4.110.orig/arch/nds32/include/asm/kmap_types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/kmap_types.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,29 @@ ++/* ++ * linux/arch/nds32/include/asm/kmap-types.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_KMAP_TYPES_H ++#define __NDS32_KMAP_TYPES_H ++ ++/* ++ * This is the "bare minimum". AIO seems to require this. ++ */ ++enum km_type { ++ KM_BOUNCE_READ, ++ KM_SKB_SUNRPC_DATA, ++ KM_SKB_DATA_SOFTIRQ, ++ KM_USER0, ++ KM_USER1, ++ KM_BIO_SRC_IRQ, ++ KM_BIO_DST_IRQ, ++ KM_PTE0, ++ KM_PTE1, ++ KM_IRQ0, ++ KM_IRQ1, ++ KM_SOFTIRQ0, ++ KM_SOFTIRQ1, ++ KM_TYPE_NR ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kprobes.h linux-3.4.110/arch/nds32/include/asm/kprobes.h +--- linux-3.4.110.orig/arch/nds32/include/asm/kprobes.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/kprobes.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,86 @@ ++#ifndef _ASM_ANDES_KPROBES_H ++#define _ASM_ANDES_KPROBES_H ++/* ++ * Kernel Probes (KProbes) ++ * ++ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) IBM Corporation, 2002, 2004 ++ * ++ * See arch/x86/kernel/kprobes.c for x86 kprobes history. ++ */ ++#include ++#include ++#include ++ ++#define __ARCH_WANT_KPROBES_INSN_SLOT ++ ++struct pt_regs; ++struct kprobe; ++ ++typedef unsigned short kprobe_opcode_t; ++ ++#define MAX_INSN_SIZE 2 ++#define MAX_STACK_SIZE 64 ++#define MIN_STACK_SIZE(ADDR) \ ++ (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \ ++ THREAD_SIZE - (unsigned long)(ADDR))) \ ++ ? (MAX_STACK_SIZE) \ ++ : (((unsigned long)current_thread_info()) + \ ++ THREAD_SIZE - (unsigned long)(ADDR))) ++#define regs_return_value(regs) ((regs)->NDS32_r0) ++#define flush_insn_slot(p) do { } while (0) ++#define kretprobe_blacklist_size 0 ++ ++void arch_remove_kprobe(struct kprobe *p); ++void kretprobe_trampoline(void); ++ ++/* Architecture specific copy of original instruction*/ ++struct arch_specific_insn { ++ /* copy of the original instruction */ ++ kprobe_opcode_t *insn; ++ /* ++ * boostable = -1: This instruction type is not boostable. ++ * boostable = 0: This instruction type is boostable. ++ * boostable = 1: This instruction has been boosted: we have ++ * added a relative jump after the instruction copy in insn, ++ * so no single-step and fixup are needed (unless there's ++ * a post_handler or break_handler). ++ */ ++ int boostable; ++}; ++ ++struct prev_kprobe { ++ struct kprobe *kp; ++ unsigned long status; ++ unsigned long old_flags; ++ unsigned long saved_flags; ++}; ++ ++/* per-cpu kprobe control block */ ++struct kprobe_ctlblk { ++ unsigned long kprobe_status; ++ unsigned long kprobe_old_flags; ++ unsigned long kprobe_saved_flags; ++ unsigned long *jprobe_saved_sp; ++ struct pt_regs jprobe_saved_regs; ++ kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; ++ struct prev_kprobe prev_kprobe; ++}; ++ ++extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); ++extern int kprobe_exceptions_notify(struct notifier_block *self, ++ unsigned long val, void *data); ++#endif /* _ASM_ANDES_KPROBES_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/kvm.h linux-3.4.110/arch/nds32/include/asm/kvm.h +--- linux-3.4.110.orig/arch/nds32/include/asm/kvm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/kvm.h 2016-04-07 10:20:50.898079322 +0200 +@@ -0,0 +1,9 @@ ++/* ++ * linux/arch/nds32/include/asm/kvm.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_KVM_H__ ++#define __NDS32_KVM_H__ ++ ++#endif /* __NDS32_KVM_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/l2_cache.h linux-3.4.110/arch/nds32/include/asm/l2_cache.h +--- linux-3.4.110.orig/arch/nds32/include/asm/l2_cache.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/l2_cache.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,134 @@ ++/* ++ * linux/arch/nds32/include/asm/l2_cache.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef L2_CACHE_H ++#define L2_CACHE_H ++ ++// CCTL_CMD_OP ++#define L2_CA_CONF_OFF 0x0 ++#define L2_IF_CONF_OFF 0x4 ++#define L2CC_SETUP_OFF 0x8 ++#define L2CC_PROT_OFF 0xC ++#define L2CC_CTRL_OFF 0x10 ++#define L2_INT_EN_OFF 0x20 ++#define L2_STA_OFF 0x24 ++#define RDERR_ADDR_OFF 0x28 ++#define WRERR_ADDR_OFF 0x2c ++#define EVDPTERR_ADDR_OFF 0x30 ++#define IMPL3ERR_ADDR_OFF 0x34 ++#define L2_CNT0_CTRL_OFF 0x40 ++#define L2_EVNT_CNT0_OFF 0x44 ++#define L2_CNT1_CTRL_OFF 0x48 ++#define L2_EVNT_CNT1_OFF 0x4c ++#define L2_CCTL_CMD_OFF 0x60 ++#define L2_CCTL_STATUS_OFF 0x64 ++#define L2_LINE_TAG_OFF 0x68 ++#define L2_LINE_DPT_OFF 0x70 ++ ++#define CCTL_CMD_L2_IX_INVAL 0x0 ++#define CCTL_CMD_L2_PA_INVAL 0x1 ++#define CCTL_CMD_L2_IX_WB 0x2 ++#define CCTL_CMD_L2_PA_WB 0x3 ++#define CCTL_CMD_L2_PA_WBINVAL 0x5 ++#define CCTL_CMD_L2_SYNC 0xa ++// CCTL_CMD_TYPE ++#define CCTL_SINGLE_CMD 0 ++#define CCTL_BLOCK_CMD 0x10 ++#define CCTL_ALL_CMD 0x10 ++ ++/****************************************************************************** ++ * L2_CA_CONF (Cache architecture configuration) ++ *****************************************************************************/ ++#define L2_CA_CONF_offL2SET 0 ++#define L2_CA_CONF_offL2WAY 4 ++#define L2_CA_CONF_offL2CLSZ 8 ++#define L2_CA_CONF_offL2DW 11 ++#define L2_CA_CONF_offL2PT 14 ++#define L2_CA_CONF_offL2VER 16 ++ ++#define L2_CA_CONF_mskL2SET (0xFUL << L2_CA_CONF_offL2SET) ++#define L2_CA_CONF_mskL2WAY (0xFUL << L2_CA_CONF_offL2WAY) ++#define L2_CA_CONF_mskL2CLSZ (0x7UL << L2_CA_CONF_offL2CLSZ) ++#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW) ++#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT) ++#define L2_CA_CONF_mskL2VER (0xFFFFUL << L2_CA_CONF_offL2VER) ++ ++/****************************************************************************** ++ * L2CC_SETUP (L2CC Setup register) ++ *****************************************************************************/ ++#define L2CC_SETUP_offPART 0 ++#define L2CC_SETUP_mskPART (0x3UL << L2CC_SETUP_offPART) ++#define L2CC_SETUP_offDDLATC 4 ++#define L2CC_SETUP_mskDDLATC (0x3UL << L2CC_SETUP_offDDLATC) ++#define L2CC_SETUP_offTDLATC 8 ++#define L2CC_SETUP_mskTDLATC (0x3UL << L2CC_SETUP_offTDLATC) ++ ++/****************************************************************************** ++ * L2CC_PROT (L2CC Protect register) ++ *****************************************************************************/ ++#define L2CC_PROT_offMRWEN 31 ++#define L2CC_PROT_mskMRWEN (0x1UL << L2CC_PROT_offMRWEN) ++//TODO finish this table ++// ++/****************************************************************************** ++ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n) ++ *****************************************************************************/ ++#define L2CC_CTRL_offEN 31 ++#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN) ++ ++/****************************************************************************** ++ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n) ++ *****************************************************************************/ ++#define L2_CCTL_STATUS_offCMD_COMP 31 ++#define L2_CCTL_STATUS_mskCMD_COMP (0x1 << L2_CCTL_STATUS_offCMD_COMP) ++//TODO finish this table ++ ++#ifndef __ASSEMBLY__ ++ ++#include ++#include ++#include ++ ++#define L2C_R_REG(offset) inl(L2CC_VA_BASE + offset) ++#define L2C_W_REG(offset, value) outl(value, L2CC_VA_BASE + offset) ++ ++#define L2_CMD_RDY() \ ++ do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & L2_CCTL_STATUS_mskCMD_COMP) == 0) ++ ++static inline unsigned long L2_CACHE_SET(void){ ++ return 64 << ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> L2_CA_CONF_offL2SET); ++} ++ ++static inline unsigned long L2_CACHE_WAY(void){ ++ return 1 + ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> L2_CA_CONF_offL2WAY); ++} ++ ++static inline unsigned long L2_CACHE_LINE_SIZE(void){ ++ ++ return 4 << ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> L2_CA_CONF_offL2CLSZ); ++} ++ ++static inline unsigned long GET_L2CC_CTRL_CPU(unsigned long cpu){ ++ if(cpu == smp_processor_id()) ++ return L2C_R_REG(L2CC_CTRL_OFF); ++ return L2C_R_REG(L2CC_CTRL_OFF+(cpu<<8)); ++} ++ ++static inline void SET_L2CC_CTRL_CPU(unsigned long cpu , unsigned long val){ ++ if(cpu == smp_processor_id()) ++ L2C_W_REG(L2CC_CTRL_OFF,val); ++ else ++ L2C_W_REG(L2CC_CTRL_OFF+(cpu<<8),val); ++} ++ ++static inline unsigned long GET_L2CC_STATUS_CPU(unsigned long cpu){ ++ if(cpu == smp_processor_id()) ++ return L2C_R_REG(L2_CCTL_STATUS_OFF); ++ return L2C_R_REG(L2_CCTL_STATUS_OFF+(cpu<<8)); ++} ++ ++#endif ++ ++#endif //L2_CACHE_H +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/leds.h linux-3.4.110/arch/nds32/include/asm/leds.h +--- linux-3.4.110.orig/arch/nds32/include/asm/leds.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/leds.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,51 @@ ++/* ++ * linux/arch/nds32/include/asm/leds.h ++ * ++ * Copyright (C) 1998 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Event-driven interface for LEDs on machines ++ * Added led_start and led_stop- Alex Holden, 28th Dec 1998. ++ */ ++#ifndef ASM_NDS32_LEDS_H ++#define ASM_NDS32_LEDS_H ++ ++ ++typedef enum { ++ led_idle_start, ++ led_idle_end, ++ led_timer, ++ led_start, ++ led_stop, ++ led_claim, /* override idle & timer leds */ ++ led_release, /* restore idle & timer leds */ ++ led_start_timer_mode, ++ led_stop_timer_mode, ++ led_green_on, ++ led_green_off, ++ led_amber_on, ++ led_amber_off, ++ led_red_on, ++ led_red_off, ++ led_blue_on, ++ led_blue_off, ++ /* ++ * I want this between led_timer and led_start, but ++ * someone has decided to export this to user space ++ */ ++ led_halted ++} led_event_t; ++ ++/* Use this routine to handle LEDs */ ++ ++#ifdef CONFIG_LEDS ++extern void (*leds_event)(led_event_t); ++#else ++#define leds_event(e) ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/limits.h linux-3.4.110/arch/nds32/include/asm/limits.h +--- linux-3.4.110.orig/arch/nds32/include/asm/limits.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/limits.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * linux/arch/nds32/include/asm/limits.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_PIPE_H ++#define __ASM_PIPE_H ++ ++#ifndef PAGE_SIZE ++#include ++#endif ++ ++#define PIPE_BUF PAGE_SIZE ++ ++#endif ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/linkage.h linux-3.4.110/arch/nds32/include/asm/linkage.h +--- linux-3.4.110.orig/arch/nds32/include/asm/linkage.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/linkage.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,12 @@ ++/* ++ * linux/arch/nds32/include/asm/linkage.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_LINKAGE_H__ ++#define __NDS32_LINKAGE_H__ ++ ++#define __ALIGN .align 2 ++#define __ALIGN_STR ".align 2" ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/local.h linux-3.4.110/arch/nds32/include/asm/local.h +--- linux-3.4.110.orig/arch/nds32/include/asm/local.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/local.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/local.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_LOCAL_H__ ++#define __NDS32_LOCAL_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/arch.h linux-3.4.110/arch/nds32/include/asm/mach/arch.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/arch.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/arch.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,86 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/arch.h ++ * ++ * Copyright (C) 2000 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#ifndef __ASSEMBLY__ ++ ++struct tag; ++struct meminfo; ++struct sys_timer; ++ ++struct machine_desc { ++ /* ++ * Note! The first four elements are used ++ * by assembler code in head-armv.S ++ */ ++ unsigned int nr; /* architecture number */ ++ ++ const char *name; /* architecture name */ ++ unsigned int param_offset; /* parameter page */ ++ ++ unsigned int video_start; /* start of video RAM */ ++ unsigned int video_end; /* end of video RAM */ ++ ++ unsigned int reserve_lp0 :1; /* never has lp0 */ ++ unsigned int reserve_lp1 :1; /* never has lp1 */ ++ unsigned int reserve_lp2 :1; /* never has lp2 */ ++ unsigned int soft_reboot :1; /* soft reboot */ ++ void (*fixup)(struct machine_desc *, ++ struct tag *, char **, ++ struct meminfo *); ++ void (*map_io)(void);/* IO mapping function */ ++ void (*init_irq)(void); ++ struct sys_timer *timer; /* system tick timer */ ++ void (*init_machine)(void); ++}; ++ ++/* ++ * * Current machine - only accessible during boot. ++ * */ ++extern struct machine_desc *machine_desc; ++ ++/* ++ * Set of macros to define architecture features. This is built into ++ * a table by the linker. ++ */ ++#define MACHINE_START(_type,_name) \ ++const struct machine_desc __mach_desc_##_type \ ++ __attribute__((__section__(".arch.info"))) = { \ ++ .nr = MACH_TYPE_##_type, \ ++ .name = _name, ++ ++#define MAINTAINER(n) ++ ++#define BOOT_PARAMS(_params) \ ++ .param_offset = _params, ++ ++#define VIDEO(_start,_end) \ ++ .video_start = _start, \ ++ .video_end = _end, ++ ++#define DISABLE_PARPORT(_n) \ ++ .reserve_lp##_n = 1, ++ ++#define SOFT_REBOOT \ ++ .soft_reboot = 1, ++ ++#define MAPIO(_func) \ ++ .map_io = _func, ++ ++#define INITIRQ(_func) \ ++ .init_irq = _func, ++ ++#define INIT_MACHINE(_func) \ ++ .init_machine = _func, ++ ++#define MACHINE_END \ ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/dma.h linux-3.4.110/arch/nds32/include/asm/mach/dma.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/dma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/dma.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,56 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/dma.h ++ * ++ * Copyright (C) 1998-2000 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This header file describes the interface between the generic DMA handler ++ * (dma.c) and the architecture-specific DMA backends (dma-*.c) ++ */ ++ ++struct dma_struct; ++typedef struct dma_struct dma_t; ++ ++struct dma_ops { ++ int (*request)(dmach_t, dma_t *); /* optional */ ++ void (*free)(dmach_t, dma_t *); /* optional */ ++ void (*enable)(dmach_t, dma_t *); /* mandatory */ ++ void (*disable)(dmach_t, dma_t *); /* mandatory */ ++ int (*residue)(dmach_t, dma_t *); /* optional */ ++ int (*setspeed)(dmach_t, dma_t *, int); /* optional */ ++ char *type; ++}; ++ ++struct dma_struct { ++ struct scatterlist buf; /* single DMA */ ++ int sgcount; /* number of DMA SG */ ++ struct scatterlist *sg; /* DMA Scatter-Gather List */ ++ ++ unsigned int active:1; /* Transfer active */ ++ unsigned int invalid:1; /* Address/Count changed */ ++ unsigned int using_sg:1; /* using scatter list? */ ++ dmamode_t dma_mode; /* DMA mode */ ++ int speed; /* DMA speed */ ++ ++ unsigned int lock; /* Device is allocated */ ++ const char *device_id; /* Device name */ ++ ++ unsigned int dma_base; /* Controller base address */ ++ int dma_irq; /* Controller IRQ */ ++ struct scatterlist cur_sg; /* Current controller buffer */ ++ unsigned int state; ++ ++ struct dma_ops *d_ops; ++}; ++ ++/* Prototype: void arch_dma_init(dma) ++ * Purpose : Initialise architecture specific DMA ++ * Params : dma - pointer to array of DMA structures ++ */ ++extern void arch_dma_init(dma_t *dma); ++ ++extern void isa_init_dma(dma_t *dma); +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/flash.h linux-3.4.110/arch/nds32/include/asm/mach/flash.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/flash.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,35 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/flash.h ++ * ++ * Copyright (C) 2003 Russell King, All Rights Reserved. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef ASMNDS32_MACH_FLASH_H ++#define ASMNDS32_MACH_FLASH_H ++ ++struct mtd_partition; ++ ++/* ++ * map_name: the map probe function name ++ * width: width of mapped device ++ * init: method called at driver/device initialisation ++ * exit: method called at driver/device removal ++ * set_vpp: method called to enable or disable VPP ++ * parts: optional array of mtd_partitions for static partitioning ++ * nr_parts: number of mtd_partitions for static partitoning ++ */ ++struct flash_platform_data { ++ const char *map_name; ++ unsigned int width; ++ int (*init)(void); ++ void (*exit)(void); ++ void (*set_vpp)(int on); ++ struct mtd_partition *parts; ++ unsigned int nr_parts; ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/irda.h linux-3.4.110/arch/nds32/include/asm/mach/irda.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/irda.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/irda.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,21 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/irda.h ++ * ++ * Copyright (C) 2004 Russell King. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_NDS32_MACH_IRDA_H ++#define __ASM_NDS32_MACH_IRDA_H ++ ++struct irda_platform_data { ++ int (*startup)(struct device *); ++ void (*shutdown)(struct device *); ++ int (*set_power)(struct device *, unsigned int state); ++ void (*set_speed)(struct device *, unsigned int speed); ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/map.h linux-3.4.110/arch/nds32/include/asm/mach/map.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/map.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/map.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,37 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/map.h ++ * ++ * Copyright (C) 1999-2000 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Page table mapping constructs and function prototypes ++ */ ++struct map_desc { ++ unsigned long virtual; ++ unsigned long physical; ++ unsigned long length; ++ unsigned int type; ++}; ++ ++struct meminfo; ++ ++#define MT_DEVICE_NCB MT_DEVICE ++#define MT_DEVICE_NCNB MT_DEVICE ++#define MT_DEVICE 0 ++#define MT_CACHECLEAN 1 ++#define MT_MINICLEAN 2 ++#define MT_CACHE_L1 3 ++#define MT_UXKRWX_V1 4 ++#define MT_UXKRWX_V2 5 ++#define MT_MEMORY 6 ++#define MT_ROM 7 ++#define MT_ILM 8 ++#define MT_DLM 9 ++ ++extern void create_memmap_holes(struct meminfo *); ++extern void iotable_init(struct map_desc *, int); ++extern void setup_io_desc(void); +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/mmc.h linux-3.4.110/arch/nds32/include/asm/mach/mmc.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/mmc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/mmc.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/mmc.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++#ifndef ASMNDS32_MACH_MMC_H ++#define ASMNDS32_MACH_MMC_H ++ ++#include ++ ++struct mmc_platform_data { ++ unsigned int ocr_mask; /* available voltages */ ++ u32 (*translate_vdd)(struct device *, unsigned int); ++ unsigned int (*status)(struct device *); ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/pci.h linux-3.4.110/arch/nds32/include/asm/mach/pci.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/pci.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,76 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/pci.h ++ * ++ * Copyright (C) 2000 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++struct pci_sys_data; ++struct pci_bus; ++ ++struct hw_pci { ++ struct list_head buses; ++ int nr_controllers; ++ int (*setup)(int nr, struct pci_sys_data *); ++ struct pci_bus *(*scan)(int nr, struct pci_sys_data *); ++ void (*preinit)(void); ++ void (*postinit)(void); ++ u8 (*swizzle)(struct pci_dev *dev, u8 *pin); ++ int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); ++}; ++ ++/* ++ * Per-controller structure ++ */ ++struct pci_sys_data { ++ struct list_head node; ++ int busnr; /* primary bus number */ ++ unsigned long mem_offset; /* bus->cpu memory mapping offset */ ++ unsigned long io_offset; /* bus->cpu IO mapping offset */ ++ struct pci_bus *bus; /* PCI bus */ ++ struct resource *resource[3]; /* Primary PCI bus resources */ ++ /* Bridge swizzling */ ++ u8 (*swizzle)(struct pci_dev *, u8 *); ++ /* IRQ mapping */ ++ int (*map_irq)(struct pci_dev *, u8, u8); ++ struct hw_pci *hw; ++}; ++ ++/* ++ * This is the standard PCI-PCI bridge swizzling algorithm. ++ */ ++u8 pci_std_swizzle(struct pci_dev *dev, u8 *pinp); ++ ++/* ++ * Call this with your hw_pci struct to initialise the PCI system. ++ */ ++void pci_common_init(struct hw_pci *); ++ ++/* ++ * PCI controllers ++ */ ++extern int iop321_setup(int nr, struct pci_sys_data *); ++extern struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *); ++extern void iop321_init(void); ++ ++extern int iop331_setup(int nr, struct pci_sys_data *); ++extern struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *); ++extern void iop331_init(void); ++ ++extern int dc21285_setup(int nr, struct pci_sys_data *); ++extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); ++extern void dc21285_preinit(void); ++extern void dc21285_postinit(void); ++ ++extern int via82c505_setup(int nr, struct pci_sys_data *); ++extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *); ++extern void via82c505_init(void *sysdata); ++ ++extern int pci_v3_setup(int nr, struct pci_sys_data *); ++extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); ++extern void pci_v3_preinit(void); ++extern void pci_v3_postinit(void); +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/serial_sa1100.h linux-3.4.110/arch/nds32/include/asm/mach/serial_sa1100.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/serial_sa1100.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/serial_sa1100.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,31 @@ ++/* ++ * linux/include/asm-arm/mach/serial_sa1100.h ++ * ++ * Author: Nicolas Pitre ++ * ++ * Moved to include/asm-arm/mach and changed lots, Russell King ++ * ++ * Low level machine dependent UART functions. ++ */ ++ ++struct uart_port; ++struct uart_info; ++ ++/* ++ * This is a temporary structure for registering these ++ * functions; it is intended to be discarded after boot. ++ */ ++struct sa1100_port_fns { ++ void (*set_mctrl)(struct uart_port *, u_int); ++ u_int (*get_mctrl)(struct uart_port *); ++ void (*pm)(struct uart_port *, u_int, u_int); ++ int (*set_wake)(struct uart_port *, u_int); ++}; ++ ++#ifdef CONFIG_SERIAL_SA1100 ++void sa1100_register_uart_fns(struct sa1100_port_fns *fns); ++void sa1100_register_uart(int idx, int port); ++#else ++#define sa1100_register_uart_fns(fns) do { } while (0) ++#define sa1100_register_uart(idx,port) do { } while (0) ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach/time.h linux-3.4.110/arch/nds32/include/asm/mach/time.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach/time.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach/time.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,62 @@ ++/* ++ * linux/arch/nds32/include/asm/mach/time.h ++ * ++ * Copyright (C) 2004 MontaVista Software, Inc. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_NDS32_MACH_TIME_H ++#define __ASM_NDS32_MACH_TIME_H ++ ++//#include ++ ++/* ++ * This is our kernel timer structure. ++ * ++ * - init ++ * Initialise the kernels jiffy timer source, claim interrupt ++ * using setup_irq. This is called early on during initialisation ++ * while interrupts are still disabled on the local CPU. ++ * - suspend ++ * Suspend the kernel jiffy timer source, if necessary. This ++ * is called with interrupts disabled, after all normal devices ++ * have been suspended. If no action is required, set this to ++ * NULL. ++ * - resume ++ * Resume the kernel jiffy timer source, if necessary. This ++ * is called with interrupts disabled before any normal devices ++ * are resumed. If no action is required, set this to NULL. ++ * - offset ++ * Return the timer offset in microseconds since the last timer ++ * interrupt. Note: this must take account of any unprocessed ++ * timer interrupt which may be pending. ++ */ ++ ++/* + Tom from newlib ++ * Have the 32 bit jiffies value wrap 5 minutes after boot ++ * so jiffies wrap bugs show up earlier. ++ */ ++//#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) ++ ++struct sys_timer { ++// struct sys_device dev; ++ void (*init)(void); ++ void (*suspend)(void); ++ void (*resume)(void); ++ unsigned long (*offset)(void); ++}; ++ ++extern struct sys_timer *system_timer; ++extern void timer_tick( void); ++ ++/* ++ * Kernel time keeping support. ++ */ ++extern int (*set_rtc)(void); ++extern void save_time_delta(struct timespec *delta, struct timespec *rtc); ++extern void restore_time_delta(struct timespec *delta, struct timespec *rtc); ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mach-types.h linux-3.4.110/arch/nds32/include/asm/mach-types.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mach-types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mach-types.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,14 @@ ++#ifndef __ASSEMBLY__ ++/* The type of machine we're running on */ ++extern unsigned int __machine_arch_type; ++#endif ++ ++#define MACH_TYPE_FARADAY 758 ++ ++# ifdef machine_arch_type ++# undef machine_arch_type ++# define machine_arch_type __machine_arch_type ++# else ++# define machine_arch_type MACH_TYPE_FARADAY ++# endif ++# define machine_is_faraday() (machine_arch_type == MACH_TYPE_FARADAY) +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/memory.h linux-3.4.110/arch/nds32/include/asm/memory.h +--- linux-3.4.110.orig/arch/nds32/include/asm/memory.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/memory.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,218 @@ ++/* ++ * linux/arch/nds32/include/asm/memory.h ++ * ++ * Copyright (C) 2000-2002 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Note: this file should not be included by non-asm/.h files ++ */ ++#ifndef __ASM_NDS32_MEMORY_H ++#define __ASM_NDS32_MEMORY_H ++ ++#include ++#ifndef __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ ++#define __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ ++ ++#include ++ ++#ifndef __ASSEMBLY__ ++#include ++#endif ++ ++#ifndef PHYS_OFFSET ++#define PHYS_OFFSET CPU_MEM_PA_BASE ++#endif ++ ++#ifndef PAGE_OFFSET ++#define PAGE_OFFSET (0xC0000000) ++#endif ++ ++#ifndef END_MEM ++#define END_MEM (CPU_MEM_PA_LIMIT) ++#endif ++ ++#ifndef __virt_to_bus ++#define __virt_to_bus __virt_to_phys ++#endif ++ ++#ifndef __bus_to_virt ++#define __bus_to_virt __phys_to_virt ++#endif ++ ++#endif /* __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ */ ++ ++#ifndef TASK_SIZE ++/* ++ * TASK_SIZE - the maximum size of a user space task. ++ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area ++ */ ++#define TASK_SIZE (0xbf000000UL) ++#define TASK_UNMAPPED_BASE (0x40000000UL) ++#endif ++ ++/* ++ * Page offset: 3GB ++ */ ++#ifndef PAGE_OFFSET ++#define PAGE_OFFSET (0xc0000000) ++#endif ++ ++/* ++ * Physical vs virtual RAM address space conversion. These are ++ * private definitions which should NOT be used outside memory.h ++ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. ++ */ ++#ifndef __virt_to_phys ++#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) ++#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) ++#endif ++ ++/* ++ * The module space lives between the addresses given by TASK_SIZE ++ * and PAGE_OFFSET - it must be within 32MB of the kernel text. ++ */ ++#define MODULES_END (PAGE_OFFSET) ++#define MODULES_VADDR (MODULES_END - 16*1048576) ++ ++#if TASK_SIZE > MODULES_VADDR ++#error Top of user space clashes with start of module space ++#endif ++ ++#ifndef __ASSEMBLY__ ++ ++/* ++ * The DMA mask corresponding to the maximum bus address allocatable ++ * using GFP_DMA. The default here places no restriction on DMA ++ * allocations. This must be the smallest DMA mask in the system, ++ * so a successful GFP_DMA allocation will always satisfy this. ++ */ ++#ifndef ISA_DMA_THRESHOLD ++#define ISA_DMA_THRESHOLD (0xffffffffULL) ++#endif ++ ++#ifndef arch_adjust_zones ++#define arch_adjust_zones(node,size,holes) do { } while (0) ++#endif ++ ++/* ++ * PFNs are used to describe any physical page; this means ++ * PFN 0 == physical address 0. ++ * ++ * This is the PFN of the first RAM page in the kernel ++ * direct-mapped view. We assume this is the first page ++ * of RAM in the mem_map as well. ++ */ ++#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) ++ ++/* ++ * These are *only* valid on the kernel direct mapped RAM memory. ++ * Note: Drivers should NOT use these. They are the wrong ++ * translation for translating DMA addresses. Use the driver ++ * DMA support - see dma-mapping.h. ++ */ ++static inline unsigned long virt_to_phys(void *x) ++{ ++ return __virt_to_phys((unsigned long)(x)); ++} ++ ++static inline void *phys_to_virt(unsigned long x) ++{ ++ return (void *)(__phys_to_virt((unsigned long)(x))); ++} ++ ++/* ++ * Drivers should NOT use these either. ++ */ ++#define __pa(x) __virt_to_phys((unsigned long)(x)) ++#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) ++ ++/* ++ * Virtual <-> DMA view memory address translations ++ * Again, these are *only* valid on the kernel direct mapped RAM ++ * memory. Use of these is *deprecated* (and that doesn't mean ++ * use the __ prefixed forms instead.) See dma-mapping.h. ++ */ ++static inline __deprecated unsigned long virt_to_bus(void *x) ++{ ++ return __virt_to_bus((unsigned long)x); ++} ++ ++static inline __deprecated void *bus_to_virt(unsigned long x) ++{ ++ return (void *)__bus_to_virt(x); ++} ++ ++/* ++ * Conversion between a struct page and a physical address. ++ * ++ * Note: when converting an unknown physical address to a ++ * struct page, the resulting pointer must be validated ++ * using VALID_PAGE(). It must return an invalid struct page ++ * for any physical address not corresponding to a system ++ * RAM address. ++ * ++ * pfn_valid(pfn) indicates whether a PFN number is valid ++ * ++ * virt_to_page(k) convert a _valid_ virtual address to struct page * ++ * virt_addr_valid(k) indicates whether a virtual address is valid ++ */ ++#ifndef CONFIG_DISCONTIGMEM ++ ++#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET ++#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) ++ ++#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) ++#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) ++ ++#define PHYS_TO_NID(addr) (0) ++ ++#else /* CONFIG_DISCONTIGMEM */ ++ ++/* ++ * This is more complex. We have a set of mem_map arrays spread ++ * around in memory. ++ */ ++#include ++ ++#define pfn_valid(pfn) (PFN_TO_NID(pfn) < MAX_NUMNODES) ++ ++#define virt_to_page(kaddr) \ ++ (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) ++#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES) ++ ++/* ++ * Common discontigmem stuff. ++ * PHYS_TO_NID is used by the NDS32 kernel/setup.c ++ */ ++#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT) ++ ++#endif /* !CONFIG_DISCONTIGMEM */ ++ ++/* ++ * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die. ++ */ ++#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) ++ ++/* ++ * Optional device DMA address remapping. Do _not_ use directly! ++ * We should really eliminate virt_to_bus() here - it's deprecated. ++ */ ++#ifndef __arch_page_to_dma ++#define page_to_dma(dev, page) ((dma_addr_t)__virt_to_bus((unsigned long)page_address(page))) ++#define dma_to_virt(dev, addr) ((void *)__bus_to_virt(addr)) ++#define virt_to_dma(dev, addr) ((dma_addr_t)__virt_to_bus((unsigned long)(addr))) ++#else ++#define page_to_dma(dev, page) (__arch_page_to_dma(dev, page)) ++#define dma_to_virt(dev, addr) (__arch_dma_to_virt(dev, addr)) ++#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr)) ++#endif ++ ++#endif ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/misc_spec.h linux-3.4.110/arch/nds32/include/asm/misc_spec.h +--- linux-3.4.110.orig/arch/nds32/include/asm/misc_spec.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/misc_spec.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,75 @@ ++/* ++ * linux/arch/nds32/include/asm/misc_spec.h ++ * ++ * Faraday A320D platform dependent definitions ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/14/2005 Created ++ * Luke Lee 10/06/2005 Modified for automatic system clock rate ++ */ ++ ++#ifndef __A320_PLATFORM_MANUAL_DEFINITION__ ++#define __A320_PLATFORM_MANUAL_DEFINITION__ ++ ++#define BOOT_PARAMETER_PA_BASE (PHYS_OFFSET + 0x400) ++ ++#ifdef CONFIG_AUTO_SYS_CLK ++ ++#ifndef __ASSEMBLY__ ++extern int ag101_get_ahb_clk(void); ++extern int ag102_get_ahb_clk(void); ++ ++#if defined(CONFIG_PLAT_AG101) ++#define AHB_CLK_IN ag101_get_ahb_clk() ++#elif defined(CONFIG_PLAT_AG102) ++#define AHB_CLK_IN ag102_get_ahb_clk() ++ ++#endif ++ ++#endif ++#define TIMER_CLK_IN (CONFIG_SYS_CLK/2) ++ ++#else ++ ++/* Timer clock input is APB CLOCK */ ++#define TIMER_CLK_IN (CONFIG_SYS_CLK/2) ++#define AHB_CLK_IN (CONFIG_SYS_CLK) ++ ++#endif ++ ++#ifndef __ASSEMBLY__ ++#include ++ ++#ifdef CONFIG_PLATFORM_INTC ++extern void __init intc_ftintc010_init_irq(void); ++#define platform_init_irq intc_ftintc010_init_irq ++#endif ++ ++#ifdef CONFIG_PLATFORM_NOINTC ++extern void __init nointc_init_irq(void); ++#define platform_init_irq nointc_init_irq ++#endif ++ ++#endif ++ ++#define daughter_platform_init_irq(x) /* NOP */ ++ ++#endif /*__A320_PLATFORM_MANUAL_DEFINITION__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mman.h linux-3.4.110/arch/nds32/include/asm/mman.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mman.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mman.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,22 @@ ++/* ++ * linux/arch/nds32/include/asm/mman.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_MMAN_H__ ++#define __NDS32_MMAN_H__ ++ ++#include ++ ++#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ ++#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ ++#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ ++#define MAP_LOCKED 0x2000 /* pages are locked */ ++#define MAP_NORESERVE 0x4000 /* don't check for reservations */ ++#define MAP_POPULATE 0x8000 /* populate (prefault) page tables */ ++#define MAP_NONBLOCK 0x10000 /* do not block on IO */ ++ ++#define MCL_CURRENT 1 /* lock all current mappings */ ++#define MCL_FUTURE 2 /* lock all future mappings */ ++ ++#endif /* __NDS32_MMAN_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mmu_context.h linux-3.4.110/arch/nds32/include/asm/mmu_context.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mmu_context.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mmu_context.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,84 @@ ++/* ++ * linux/arch/nds32/include/asm/mmu_context.h ++ * ++ * Copyright (C) 1996 Russell King. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Changelog: ++ * 27-06-1996 RMK Created ++ */ ++#ifndef __ASM_NDS32_MMU_CONTEXT_H ++#define __ASM_NDS32_MMU_CONTEXT_H ++ ++#include ++#include ++#include ++ ++static inline int ++init_new_context(struct task_struct *tsk, struct mm_struct *mm) ++{ ++ mm->context.id = 0; ++ return 0; ++} ++ ++#define destroy_context(mm) do { } while(0) ++ ++#ifndef CONFIG_CPU_NO_CONTEXT_ID ++#define CID_BITS 9 ++extern spinlock_t cid_lock; ++extern unsigned int cpu_last_cid; ++ ++static inline void ++__new_context(struct mm_struct *mm) ++{ ++ unsigned int cid; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&cid_lock, flags); ++ cid = cpu_last_cid; ++ cpu_last_cid += 1 << TLB_MISC_offCID; ++ if (cpu_last_cid == 0) ++ cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS; ++ spin_unlock_irqrestore(&cid_lock, flags); ++ ++ if ((cid & TLB_MISC_mskCID ) == 0) ++ flush_tlb_all(); ++ ++ mm->context.id = cid; ++} ++ ++static inline void ++check_context(struct mm_struct *mm) ++{ ++ if (unlikely((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS)) ++ __new_context(mm); ++} ++#else ++#define check_context(m) ++#endif ++ ++static inline void ++enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) ++{ ++} ++ ++static inline void ++switch_mm(struct mm_struct *prev, struct mm_struct *next, ++ struct task_struct *tsk) ++{ ++ unsigned int cpu = smp_processor_id(); ++ ++ if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { ++ check_context(next); ++ cpu_switch_mm(next); ++ } ++} ++ ++#define deactivate_mm(tsk,mm) do { } while (0) ++#define activate_mm(prev,next) switch_mm(prev, next, NULL) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mmu.h linux-3.4.110/arch/nds32/include/asm/mmu.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mmu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mmu.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,42 @@ ++/* ++ * linux/arch/nds32/include/asm/mmu.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_MMU_H ++#define __NDS32_MMU_H ++ ++typedef struct { ++ unsigned int id; ++} mm_context_t; ++ ++#define ASID(mm) ((mm)->context.id & (TLB_MISC_mskCID >> TLB_MISC_offCID)) ++inline static unsigned long ACC_PSZ(unsigned long page_size) ++{ ++ switch(page_size) { ++ case(1<<12): ++ return 0; ++ case(1<<13): ++ return 1; ++ case(1<<14): ++ return 2; ++ case(1<<16): ++ return 3; ++ case(1<<18): ++ return 4; ++ case(1<<20): ++ return 5; ++ case(1<<22): ++ return 6; ++ case(1<<24): ++ return 7; ++ case(1<<26): ++ return 8; ++ case(1<<28): ++ return 9; ++ default: ++ printk("Huge Page Size is not supported \n"); ++ return 0xffffffff; ++ } ++} ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/module.h linux-3.4.110/arch/nds32/include/asm/module.h +--- linux-3.4.110.orig/arch/nds32/include/asm/module.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/module.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,23 @@ ++/* ++ * linux/arch/nds32/include/asm/module.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASM_NDS32_MODULE_H ++#define _ASM_NDS32_MODULE_H ++ ++struct mod_arch_specific ++{ ++ int foo; ++}; ++ ++#define Elf_Shdr Elf32_Shdr ++#define Elf_Sym Elf32_Sym ++#define Elf_Ehdr Elf32_Ehdr ++ ++/* ++ * Include the ARM architecture version. ++ */ ++#define MODULE_ARCH_VERMAGIC "NDS32vN10" __stringify(__LINUX_NDS32_ARCH__) " " ++ ++#endif /* _ASM_NDS32_MODULE_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/msgbuf.h linux-3.4.110/arch/nds32/include/asm/msgbuf.h +--- linux-3.4.110.orig/arch/nds32/include/asm/msgbuf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/msgbuf.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * linux/arch/nds32/include/asm/msgbuf.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_MSGBUF_H ++#define _ASMNDS32_MSGBUF_H ++ ++/* ++ * The msqid64_ds structure for arm architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 64-bit time_t to solve y2038 problem ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct msqid64_ds { ++ struct ipc64_perm msg_perm; ++ __kernel_time_t msg_stime; /* last msgsnd time */ ++ unsigned long __unused1; ++ __kernel_time_t msg_rtime; /* last msgrcv time */ ++ unsigned long __unused2; ++ __kernel_time_t msg_ctime; /* last change time */ ++ unsigned long __unused3; ++ unsigned long msg_cbytes; /* current number of bytes on queue */ ++ unsigned long msg_qnum; /* number of messages in queue */ ++ unsigned long msg_qbytes; /* max number of bytes on queue */ ++ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ ++ __kernel_pid_t msg_lrpid; /* last receive pid */ ++ unsigned long __unused4; ++ unsigned long __unused5; ++}; ++ ++#endif /* _ASMNDS32_MSGBUF_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/mutex.h linux-3.4.110/arch/nds32/include/asm/mutex.h +--- linux-3.4.110.orig/arch/nds32/include/asm/mutex.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/mutex.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/mutex.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_MUTEX_H__ ++#define __NDS32_MUTEX_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/namei.h linux-3.4.110/arch/nds32/include/asm/namei.h +--- linux-3.4.110.orig/arch/nds32/include/asm/namei.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/namei.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/namei.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_NAMEI_H__ ++#define __NDS32_NAMEI_H__ ++ ++#define __emul_prefix() NULL ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/nds32.h linux-3.4.110/arch/nds32/include/asm/nds32.h +--- linux-3.4.110.orig/arch/nds32/include/asm/nds32.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/nds32.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,90 @@ ++/* ++ * linux/arch/nds32/include/asm/nds32.h -- Andes NDS32 processor register interface ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2006 Andes Technology Corporation ++ * ++ */ ++#ifndef _ASM_NDS32_NDS32_H_ ++#define _ASM_NDS32_NDS32_H_ ++ ++#include ++#include ++ ++#define MSYNC( subtype) __asm__ ("\n\tmsync "#subtype); ++#define STANDBY( cond) __asm__ ("\n\tstandby "#cond); ++ ++#ifndef __ASSEMBLY__ ++ ++static inline void ISB( void) { __asm__ ("\n\tisb"); } ++static inline void DSB( void) { __asm__ ("\n\tdsb"); } ++ ++static inline void GIE_ENABLE( void) ++{ ++ __asm__ ("gie_enable\n\t"); ++} ++ ++static inline void GIE_DISABLE( void) ++{ ++ __asm__ ("gie_disable\n\t"); ++} ++ ++enum cache_t{ ICACHE, DCACHE}; ++ ++static inline unsigned long CACHE_SET( enum cache_t cache){ ++ ++ if( cache == ICACHE) ++ return 64 << ( ( GET_ICM_CFG() & ICM_CFG_mskISET) >> ICM_CFG_offISET); ++ else ++ return 64 << ( ( GET_DCM_CFG() & DCM_CFG_mskDSET) >> DCM_CFG_offDSET); ++} ++ ++static inline unsigned long CACHE_WAY( enum cache_t cache){ ++ ++ if( cache == ICACHE) ++ return 1 + ( ( GET_ICM_CFG() & ICM_CFG_mskIWAY) >> ICM_CFG_offIWAY); ++ else ++ return 1 + ( ( GET_DCM_CFG() & DCM_CFG_mskDWAY) >> DCM_CFG_offDWAY); ++} ++ ++static inline unsigned long CACHE_LINE_SIZE( enum cache_t cache){ ++ ++ if( cache == ICACHE) ++ return 8 << ( ( ( GET_ICM_CFG() & ICM_CFG_mskISZ) >> ICM_CFG_offISZ) - 1); ++ else ++ return 8 << ( ( ( GET_DCM_CFG() & DCM_CFG_mskDSZ) >> DCM_CFG_offDSZ) - 1); ++} ++ ++static inline void GIE_SAVE( unsigned long *var){ ++ ++ *var = GET_PSW(); ++ GIE_DISABLE(); ++} ++ ++static inline void GIE_RESTORE( unsigned long var){ ++ ++ if( var & PSW_mskGIE){ ++ GIE_ENABLE(); ++ } ++} ++ ++#endif /* __ASSEMBLY__ */ ++ ++#define IVB_BASE PHYS_OFFSET /* in user space for intr/exc/trap/break table base, 64KB aligned ++ * We defined at the start of the physical memory */ ++ ++/* The following dispatching entry */ ++#define ENTRY_TLB_MISC (IVB_BASE + nrTLB_MISC*vENTRY_SZ) /* TLB misc eh# */ ++/* dispatched sub-entry exception handler numbering */ ++#define RD_PROT 0 /* read protrection */ ++#define WRT_PROT 1 /* write protection */ ++#define NOEXEC 2 /* non executable */ ++#define PAGE_MODIFY 3 /* page modified */ ++#define ACC_BIT 4 /* access bit */ ++#define RESVED_PTE 5 /* reserved PTE attribute */ ++/* reserved 6 ~ 16 */ ++ ++#endif /* _ASM_NDS32_NDS32_H_ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/numnodes.h linux-3.4.110/arch/nds32/include/asm/numnodes.h +--- linux-3.4.110.orig/arch/nds32/include/asm/numnodes.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/numnodes.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * linux/arch/nds32/include/asm/numnodes.h ++ * ++ * Copyright (C) 2002 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++/* This declaration for the size of the NUMA (CONFIG_DISCONTIGMEM) ++ * memory node table is the default. ++ * ++ * A good place to override this value is include/asm/arch/memory.h. ++ */ ++ ++#ifndef __ASM_NDS32_NUMNODES_H ++#define __ASM_NDS32_NUMNODES_H ++ ++#ifndef NODES_SHIFT ++# define NODES_SHIFT 2 /* Normally, Max 4 Nodes */ ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/page.h linux-3.4.110/arch/nds32/include/asm/page.h +--- linux-3.4.110.orig/arch/nds32/include/asm/page.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/page.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,153 @@ ++/* ++ * linux/arch/nds32/include/asm/page.h ++ * ++ * Copyright (C) 1995-2003 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef _ASMNDS32_PAGE_H ++#define _ASMNDS32_PAGE_H ++ ++ ++#ifdef CONFIG_ANDES_PAGE_SIZE_4KB ++#define PAGE_SHIFT 12 ++#endif ++#ifdef CONFIG_ANDES_PAGE_SIZE_8KB ++#define PAGE_SHIFT 13 ++#endif ++#include ++#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) ++#define PAGE_MASK (~(PAGE_SIZE-1)) ++#define PTE_MASK PAGE_MASK ++ ++/* PAGE_SHIFT determines the page size */ ++#define EXEC_PAGESIZE PAGE_SIZE ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_16KB ++#define LARGE_PAGE_SHIFT 14 ++#define HPAGE_SHIFT 14 ++#endif ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_64KB ++#define LARGE_PAGE_SHIFT 16 ++#define HPAGE_SHIFT 16 ++#endif ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_256KB ++#define LARGE_PAGE_SHIFT 18 ++#define HPAGE_SHIFT 18 ++#endif ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_1MB ++#define LARGE_PAGE_SHIFT 20 ++#define HPAGE_SHIFT 20 ++#endif ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_4MB ++#define LARGE_PAGE_SHIFT 22 ++#define HPAGE_SHIFT 22 ++#endif ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_16MB ++#define LARGE_PAGE_SHIFT 24 ++#define HPAGE_SHIFT 24 ++#endif ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_64MB ++#define LARGE_PAGE_SHIFT 26 ++#define HPAGE_SHIFT 26 ++#endif ++ ++#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_256MB ++#define LARGE_PAGE_SHIFT 28 ++#define HPAGE_SHIFT 28 ++#endif ++ ++#ifdef CONFIG_HUGETLB_PAGE ++// taken for i386 style ++#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT) ++#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) ++// taken for SH style ++#define HPAGE_SIZE (1UL << HPAGE_SHIFT) ++#define HPAGE_MASK (~(HPAGE_SIZE-1)) ++#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) ++#endif ++ ++ ++#ifdef __KERNEL__ ++ ++#ifndef __ASSEMBLY__ ++ ++struct page; ++struct vm_area_struct; ++#ifndef CONFIG_CPU_CACHE_NONALIASING ++extern void copy_user_highpage(struct page *to, struct page *from, ++ unsigned long vaddr, struct vm_area_struct *vma); ++extern void clear_user_highpage(struct page *page, unsigned long vaddr); ++ ++#define __HAVE_ARCH_COPY_USER_HIGHPAGE ++#define clear_user_highpage clear_user_highpage ++#else ++#define clear_user_page(page, vaddr, pg) clear_page(page) ++#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) ++#endif ++ ++void clear_page(void *page); ++void copy_page(void *to, void *from); ++ ++#undef STRICT_MM_TYPECHECKS ++ ++#ifdef STRICT_MM_TYPECHECKS ++/* ++ * These are used to make use of C type-checking.. ++ */ ++typedef struct { unsigned long pte; } pte_t; ++typedef struct { unsigned long pmd; } pmd_t; ++typedef struct { unsigned long pgd; } pgd_t; ++typedef struct { unsigned long pgprot; } pgprot_t; ++ ++#define pte_val(x) ((x).pte) ++#define pmd_val(x) ((x).pmd) ++#define pgd_val(x) ((x).pgd) ++#define pgprot_val(x) ((x).pgprot) ++ ++#define __pte(x) ((pte_t) { (x) } ) ++#define __pmd(x) ((pmd_t) { (x) } ) ++#define __pgd(x) ((pgd_t) { (x) } ) ++#define __pgprot(x) ((pgprot_t) { (x) } ) ++ ++#else ++/* ++ * .. while these make it easier on the compiler ++ */ ++typedef unsigned long pte_t; ++typedef unsigned long pmd_t; ++typedef unsigned long pgd_t; ++typedef unsigned long pgprot_t; ++ ++#define pte_val(x) (x) ++#define pmd_val(x) (x) ++#define pgd_val(x) (x) ++#define pgprot_val(x) (x) ++ ++#define __pte(x) (x) ++#define __pmd(x) (x) ++#define __pgd(x) (x) ++#define __pgprot(x) (x) ++ ++#endif /* STRICT_MM_TYPECHECKS */ ++typedef struct page *pgtable_t; ++ ++#include ++#include ++ ++#endif /* !__ASSEMBLY__ */ ++ ++#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ ++ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) ++ ++#endif /* __KERNEL__ */ ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/param.h linux-3.4.110/arch/nds32/include/asm/param.h +--- linux-3.4.110.orig/arch/nds32/include/asm/param.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/param.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * linux/arch/nds32/include/asm/param.h ++ * ++ * Copyright (C) 1995-1999 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_PARAM_H ++#define __ASM_PARAM_H ++ ++#ifdef __KERNEL__ ++ ++# ifndef HZ ++# define HZ CONFIG_HZ /* Internal kernel timer frequency */ ++# endif ++ ++# define USER_HZ HZ /* User interfaces are in "ticks" */ ++# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ ++#else ++# define HZ 100 ++#endif ++ ++//#define EXEC_PAGESIZE 4096 ++ ++#ifndef NOGROUP ++#define NOGROUP (-1) ++#endif ++ ++/* max length of hostname */ ++#define MAXHOSTNAMELEN 64 ++ ++#endif ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/parport.h linux-3.4.110/arch/nds32/include/asm/parport.h +--- linux-3.4.110.orig/arch/nds32/include/asm/parport.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/parport.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,19 @@ ++/* ++ * linux/arch/nds32/include/asm/parport.h: NDS32-specific parport initialisation ++ * ++ * Copyright (C) 1999, 2000 Tim Waugh ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This file should only be included by drivers/parport/parport_pc.c. ++ */ ++ ++#ifndef __ASMNDS32_PARPORT_H ++#define __ASMNDS32_PARPORT_H ++ ++static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); ++static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) ++{ ++ return parport_pc_find_isa_ports (autoirq, autodma); ++} ++ ++#endif /* !(_ASMNDS32_PARPORT_H) */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pci.h linux-3.4.110/arch/nds32/include/asm/pci.h +--- linux-3.4.110.orig/arch/nds32/include/asm/pci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/pci.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,77 @@ ++/* ++ * linux/arch/nds32/include/asm/pci.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef ASMNDS32_PCI_H ++#define ASMNDS32_PCI_H ++ ++#ifdef __KERNEL__ ++#include ++ ++#include /* for PCIBIOS_MIN_* */ ++ ++#define pcibios_scan_all_fns(a, b) 0 ++ ++static inline void pcibios_set_master(struct pci_dev *dev) ++{ ++ /* No special bus mastering setup handling */ ++} ++ ++static inline void pcibios_penalize_isa_irq(int irq) ++{ ++ /* We don't do dynamic PCI IRQ allocation */ ++} ++ ++/* ++ * The PCI address space does equal the physical memory address space. ++ * The networking and block device layers use this boolean for bounce ++ * buffer decisions. ++ */ ++#define PCI_DMA_BUS_IS_PHYS (0) ++ ++/* ++ * Whether pci_unmap_{single,page} is a nop depends upon the ++ * configuration. ++ */ ++#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; ++#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; ++#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) ++#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) ++#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) ++#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) ++ ++#define HAVE_PCI_MMAP ++extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, ++ enum pci_mmap_state mmap_state, int write_combine); ++ ++extern void ++pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, ++ struct resource *res); ++ ++extern void ++pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, ++ struct pci_bus_region *region); ++ ++static inline struct resource * ++pcibios_select_root(struct pci_dev *pdev, struct resource *res) ++{ ++ struct resource *root = NULL; ++ ++ if (res->flags & IORESOURCE_IO) ++ root = &ioport_resource; ++ if (res->flags & IORESOURCE_MEM) ++ root = &iomem_resource; ++ ++ return root; ++} ++ ++#endif /* __KERNEL__ */ ++ ++/* Chances are this interrupt is wired PC-style ... */ ++static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) ++{ ++ return channel ? 15 : 14; ++} ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/percpu.h linux-3.4.110/arch/nds32/include/asm/percpu.h +--- linux-3.4.110.orig/arch/nds32/include/asm/percpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/percpu.h 2016-04-07 10:20:50.902079477 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/percpu.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_PERCPU ++#define __NDS32_PERCPU ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pfm.h linux-3.4.110/arch/nds32/include/asm/pfm.h +--- linux-3.4.110.orig/arch/nds32/include/asm/pfm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/pfm.h 2016-04-07 10:20:50.906079632 +0200 +@@ -0,0 +1,16 @@ ++#ifndef __PFM_H_ ++#define __PFM_H_ ++ ++struct pcounter { ++ unsigned long long pfm0; /* value of $PFMC0 */ ++ unsigned long long pfm1; /* value of $PFMC1 */ ++ unsigned long long pfm2; /* value of $PFMC2 */ ++}; ++ ++#ifdef __KERNEL__ ++void sys_pfmctl(int event0, int event1, int event2, int start); ++int sys_getpfm(struct pcounter __user *p); ++int sys_setpfm(int pfm0, int pfm1, int pfm2, struct pcounter __user *p); ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pgalloc.h linux-3.4.110/arch/nds32/include/asm/pgalloc.h +--- linux-3.4.110.orig/arch/nds32/include/asm/pgalloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/pgalloc.h 2016-04-07 10:20:50.906079632 +0200 +@@ -0,0 +1,104 @@ ++/* ++ * linux/arch/nds32/include/asm/pgalloc.h ++ * ++ * Copyright (C) 2000-2001 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef _ASMNDS32_PGALLOC_H ++#define _ASMNDS32_PGALLOC_H ++ ++#include ++#include ++#include ++ ++/* ++ * Since we have only two-level page tables, these are trivial ++ */ ++#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) ++#define pmd_free(mm, pmd) do { } while (0) ++#define pgd_populate(mm, pmd, pte) BUG() ++#define pmd_pgtable(pmd) pmd_page(pmd) ++ ++extern pgd_t *get_pgd_slow(struct mm_struct *mm); ++extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd); ++ ++#define pgd_alloc(mm) get_pgd_slow(mm) ++#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) ++ ++#define check_pgt_cache() do { } while (0) ++ ++static inline pte_t * ++pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) ++{ ++ pte_t *pte; ++ ++ pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); ++ ++ return pte; ++} ++ ++static inline pgtable_t ++pte_alloc_one(struct mm_struct *mm, unsigned long addr) ++{ ++ pgtable_t pte; ++ ++ pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); ++ if (pte) ++ cpu_dcache_wb_page((unsigned long)page_address(pte)); ++ ++ return pte; ++} ++ ++/* ++ * Free one PTE table. ++ */ ++static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) ++{ ++ if (pte) { ++ free_page((unsigned long)pte); ++ } ++} ++ ++static inline void pte_free(struct mm_struct *mm, pgtable_t pte) ++{ ++ __free_page(pte); ++} ++ ++/* ++ * Populate the pmdp entry with a pointer to the pte. This pmd is part ++ * of the mm address space. ++ * ++ * Ensure that we always set both PMD entries. ++ */ ++static inline void ++pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) ++{ ++ unsigned long pte_ptr = (unsigned long)ptep; ++ unsigned long pmdval; ++ ++ BUG_ON(mm != &init_mm); ++ ++ /* ++ * The pmd must be loaded with the physical ++ * address of the PTE table ++ */ ++ pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE; ++ set_pmd(pmdp, __pmd(pmdval)); ++} ++ ++static inline void ++pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) ++{ ++ unsigned long pmdval; ++ ++ BUG_ON(mm == &init_mm); ++ ++ pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE; ++ set_pmd(pmdp, __pmd(pmdval)); ++} ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/pgtable.h linux-3.4.110/arch/nds32/include/asm/pgtable.h +--- linux-3.4.110.orig/arch/nds32/include/asm/pgtable.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/pgtable.h 2016-04-07 10:20:50.910079787 +0200 +@@ -0,0 +1,429 @@ ++/* ++ * linux/arch/nds32/include/asm/pgtable.h ++ * ++ * Copyright (C) 1995-2002 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef _ASMNDS32_PGTABLE_H ++#define _ASMNDS32_PGTABLE_H ++ ++#include ++#include ++ ++#include ++#include ++#include ++#ifndef __ASSEMBLY__ ++#include ++#endif ++ ++#ifdef CONFIG_CACHE_L2 ++#include ++#endif ++ ++#ifdef CONFIG_ANDES_PAGE_SIZE_4KB ++#define PGDIR_SHIFT 22 ++#define PTRS_PER_PGD 1024 ++#define PMD_SHIFT 22 ++#define PTRS_PER_PMD 1 ++#define PTRS_PER_PTE 1024 ++#endif ++ ++#ifdef CONFIG_ANDES_PAGE_SIZE_8KB ++#define PGDIR_SHIFT 24 ++#define PTRS_PER_PGD 256 ++#define PMD_SHIFT 24 ++#define PTRS_PER_PMD 1 ++#define PTRS_PER_PTE 2048 ++#endif ++ ++#ifndef __ASSEMBLY__ ++extern void __pte_error(const char *file, int line, unsigned long val); ++extern void __pmd_error(const char *file, int line, unsigned long val); ++extern void __pgd_error(const char *file, int line, unsigned long val); ++ ++#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) ++#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) ++#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) ++#endif /* !__ASSEMBLY__ */ ++ ++#define PMD_SIZE (1UL << PMD_SHIFT) ++#define PMD_MASK (~(PMD_SIZE-1)) ++#define PGDIR_SIZE (1UL << PGDIR_SHIFT) ++#define PGDIR_MASK (~(PGDIR_SIZE-1)) ++ ++/* ++ * This is the lowest virtual address we can permit any user space ++ * mapping to be mapped at. This is particularly important for ++ * non-high vector CPUs. ++ */ ++#define FIRST_USER_ADDRESS 0x8000 ++ ++#define VMALLOC_OFFSET (8 * 1024 * 1024) ++#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) ++#define VMALLOC_VMADDR(x) ((unsigned long)(x)) ++ ++ ++#ifdef CONFIG_HIGHMEM ++#define CONSISTENT_BASE ((PKMAP_BASE) - (SZ_2M)) ++#define CONSISTENT_END (PKMAP_BASE) ++#else ++#define CONSISTENT_BASE (FIXADDR_START - SZ_2M) ++#define CONSISTENT_END (FIXADDR_START) ++#endif ++#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) ++ ++#ifdef CONFIG_HIGHMEM ++#ifndef __ASSEMBLY__ ++#include ++#endif ++#endif ++ ++//# define VMALLOC_END (CONSISTENT_START - PAGE_SIZE) ++# define VMALLOC_END (0xf9000000) ++ ++#define VMALLOC_RESERVE (128 << 20) ++#define MAXMEM (VMALLOC_END - PAGE_OFFSET - VMALLOC_RESERVE) ++#define MAXMEM_PFN PFN_DOWN(MAXMEM) ++ ++#define FIRST_USER_PGD_NR 0 ++#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + FIRST_USER_PGD_NR) ++ ++/* L2 PTE */ ++#define _PAGE_V (1UL << 0) ++ ++#define _PAGE_M_XKRW (0UL << 1) ++#define _PAGE_M_UR_KR (1UL << 1) ++#define _PAGE_M_UR_KRW (2UL << 1) ++#define _PAGE_M_URW_KRW (3UL << 1) ++#define _PAGE_M_KR (5UL << 1) ++#define _PAGE_M_KRW (7UL << 1) ++ ++#define _PAGE_D (1UL << 4) ++#define _PAGE_E (1UL << 5) ++#define _PAGE_A (1UL << 6) ++#define _PAGE_G (1UL << 7) ++ ++#define _PAGE_C_DEV (0UL << 8) ++#define _PAGE_C_DEV_WB (1UL << 8) ++#define _PAGE_C_MEM (2UL << 8) ++#define _PAGE_C_MEM_SHRD_WB (4UL << 8) ++#define _PAGE_C_MEM_SHRD_WT (5UL << 8) ++#define _PAGE_C_MEM_WB (6UL << 8) ++#define _PAGE_C_MEM_WT (7UL << 8) ++ ++#define _PAGE_L (1UL << 11) ++ ++#ifndef CONFIG_NO_KERNEL_LARGE_PAGE ++#define _HAVE_PAGE_L (_PAGE_L) ++#else ++#define _HAVE_PAGE_L 0 ++#endif ++#define _PAGE_FILE (1UL << 1) ++#define _PAGE_YOUNG 0 ++#define _PAGE_M_MASK _PAGE_M_KRW ++#define _PAGE_C_MASK _PAGE_C_MEM_WT ++ ++#ifdef CONFIG_SMP ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WT ++#else ++#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WB ++#endif ++#else ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WT ++#else ++#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WB ++#endif ++#endif ++ ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++#define _PAGE_CACHE _PAGE_C_MEM_WT ++#else ++#define _PAGE_CACHE _PAGE_C_MEM_WB ++#endif ++ ++/* ++ * + Level 1 descriptor (PMD) ++ */ ++#define PMD_TYPE_TABLE 0 ++ ++#ifndef __ASSEMBLY__ ++ ++#define _PAGE_USER_TABLE PMD_TYPE_TABLE ++#define _PAGE_KERNEL_TABLE PMD_TYPE_TABLE ++ ++#define PAGE_EXEC __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_E) ++#define PAGE_NONE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_A) ++#define PAGE_READ __pgprot(_PAGE_V | _PAGE_M_UR_KR) ++#define PAGE_RDWR __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D) ++#define PAGE_COPY __pgprot(_PAGE_V | _PAGE_M_UR_KR) ++ ++#define PAGE_UXKRWX_V1 __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) ++#define PAGE_UXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) ++#define PAGE_CACHE_L1 __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE) ++#define PAGE_MEMORY __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) ++#define PAGE_KERNEL __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) ++#define PAGE_DEVICE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV) ++#endif /* __ASSEMBLY__ */ ++ ++/* xwr */ ++#define __P000 (PAGE_NONE | _PAGE_CACHE_SHRD) ++#define __P001 (PAGE_READ | _PAGE_CACHE_SHRD) ++#define __P010 (PAGE_COPY | _PAGE_CACHE_SHRD) ++#define __P011 (PAGE_COPY | _PAGE_CACHE_SHRD) ++#define __P100 (PAGE_EXEC | _PAGE_CACHE_SHRD) ++#define __P101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) ++#define __P110 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) ++#define __P111 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) ++ ++#define __S000 (PAGE_NONE | _PAGE_CACHE_SHRD) ++#define __S001 (PAGE_READ | _PAGE_CACHE_SHRD) ++#define __S010 (PAGE_RDWR | _PAGE_CACHE_SHRD) ++#define __S011 (PAGE_RDWR | _PAGE_CACHE_SHRD) ++#define __S100 (PAGE_EXEC | _PAGE_CACHE_SHRD) ++#define __S101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) ++#define __S110 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) ++#define __S111 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) ++ ++#ifndef __ASSEMBLY__ ++/* ++ * ZERO_PAGE is a global shared page that is always zero: used ++ * for zero-mapped memory areas etc.. ++ */ ++extern struct page *empty_zero_page; ++#define ZERO_PAGE(vaddr) (empty_zero_page) ++ ++#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) ++#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) ++ ++#define pte_none(pte) !(pte_val(pte)) ++#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0)) ++#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) ++ ++#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) ++#define pte_offset_kernel(dir, address) ((pte_t *)pmd_page_kernel(*(dir)) + pte_index(address)) ++#define pte_offset_map(dir, address) ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address)) ++#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address) ++#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) ++ ++#define pte_unmap(pte) do { } while (0) ++#define pte_unmap_nested(pte) do { } while (0) ++ ++#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) ++ ++static inline pgd_t *get_pgd( void){ ++ ++ return ( pgd_t *)phys_to_virt( GET_L1_PPTB() & L1_PPTB_mskBASE); ++} ++ ++static inline void set_pgd( pgd_t *pgdp, pgd_t pgd){ ++ ++ /* TODO */ ++} ++/* ++ * Set a level 1 translation table entry, and clean it out of ++ * any caches such that the MMUs can load it correctly. ++ */ ++static inline void set_pmd( pmd_t *pmdp, pmd_t pmd){ ++ ++ *pmdp = pmd; ++#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) ++ __asm__ volatile ( "\n\tcctl %0, L1D_VA_WB" ::"r" ( pmdp) :"memory"); ++ MSYNC( all); ++ DSB(); ++#endif ++} ++ ++/* ++ * Set a PTE and flush it out ++ */ ++static inline void set_pte( pte_t *ptep, pte_t pte){ ++ ++ *ptep = pte; ++#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) ++ __asm__ volatile ( "\n\tcctl %0, L1D_VA_WB" ::"r" ( ptep) :"memory"); ++ MSYNC( all); ++ DSB(); ++#endif ++} ++ ++ ++/* ++ * The following only work if pte_present() is true. ++ * Undefined behaviour if not.. ++ */ ++ ++/* ++ * pte_write: this page is writeable for user mode ++ * pte_read: this page is readable for user mode ++ * pte_kernel_write: this page is writeable for kernel mode ++ * ++ * We don't have pte_kernel_read because kernel always can read. ++ * ++ * */ ++ ++#define pte_present(pte) (pte_val(pte) & _PAGE_V) ++#define pte_write(pte) ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) ++#define pte_read(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KR) || \ ++ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ ++ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW)) ++#define pte_kernel_write(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) || \ ++ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ ++ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_KRW) || \ ++ (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_XKRW) && pte_exec(pte))) ++#define pte_exec(pte) (pte_val(pte) & _PAGE_E) ++#define pte_dirty(pte) (pte_val(pte) & _PAGE_D) ++#define pte_young(pte) (pte_val(pte) & _PAGE_YOUNG) ++ ++/* ++ * The following only works if pte_present() is not true. ++ */ ++#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) ++#define pte_to_pgoff(x) (pte_val(x) >> 2) ++#define pgoff_to_pte(x) __pte(((x) << 2) | _PAGE_FILE) ++ ++#define PTE_FILE_MAX_BITS 29 ++ ++#define PTE_BIT_FUNC(fn,op) \ ++static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } ++ ++static inline pte_t pte_wrprotect(pte_t pte) ++{ ++ pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; ++ pte_val(pte) = pte_val(pte) | _PAGE_M_UR_KR; ++ return pte; ++} ++ ++static inline pte_t pte_mkwrite(pte_t pte) ++{ ++ pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; ++ pte_val(pte) = pte_val(pte) | _PAGE_M_URW_KRW; ++ return pte; ++} ++ ++PTE_BIT_FUNC(exprotect, &= ~_PAGE_E); ++PTE_BIT_FUNC(mkexec, |= _PAGE_E); ++PTE_BIT_FUNC(mkclean, &= ~_PAGE_D); ++PTE_BIT_FUNC(mkdirty, |= _PAGE_D); ++PTE_BIT_FUNC(mkold, &= ~_PAGE_YOUNG); ++PTE_BIT_FUNC(mkyoung, |= _PAGE_YOUNG); ++static inline int pte_special(pte_t pte) { return 0; } ++static inline pte_t pte_mkspecial(pte_t pte) { return pte; } ++ ++/* ++ * Mark the prot value as uncacheable and unbufferable. ++ */ ++#define pgprot_noncached(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV) ++#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV_WB) ++ ++#define pmd_none(pmd) (pmd_val(pmd)&0x1) ++#define pmd_present(pmd) (!pmd_none(pmd)) ++#define pmd_bad(pmd) pmd_none(pmd) ++ ++#define copy_pmd(pmdpd,pmdps) set_pmd((pmdpd), *(pmdps)) ++#define pmd_clear(pmdp) set_pmd((pmdp), __pmd(1)) ++ ++static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot) ++{ ++ unsigned long ptr = (unsigned long)ptep; ++ pmd_t pmd; ++ ++ /* ++ * The pmd must be loaded with the physical ++ * address of the PTE table ++ */ ++ ++ pmd_val(pmd) = __virt_to_phys(ptr) | prot; ++ return pmd; ++} ++ ++ ++#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) ++ ++/* ++ * Permanent address of a page. We never have highmem, so this is trivial. ++ */ ++#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) ++ ++/* ++ * Conversion functions: convert a page and protection to a page entry, ++ * and a page entry and page directory to the page they refer to. ++ */ ++#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) ++ ++/* ++ * The "pgd_xxx()" functions here are trivial for a folded two-level ++ * setup: the pgd is never bad, and a pmd always exists (as it's folded ++ * into the pgd entry) ++ */ ++#define pgd_none(pgd) (0) ++#define pgd_bad(pgd) (0) ++#define pgd_present(pgd) (1) ++#define pgd_clear(pgdp) do { } while (0) ++ ++#define page_pte_prot(page,prot) mk_pte(page, prot) ++#define page_pte(page) mk_pte(page, __pgprot(0)) ++/* Tom: ++ * L1PTE = $mr1 + ((virt >> PMD_SHIFT) << 2); ++ * L2PTE = (((virt >> PAGE_SHIFT) & (PTRS_PER_PTE -1 )) << 2); ++ * PPN = (phys & 0xfffff000); ++ * ++*/ ++ ++/* to find an entry in a page-table-directory */ ++#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) ++#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) ++/* to find an entry in a kernel page-table-directory */ ++#define pgd_offset_k(addr) pgd_offset(&init_mm, addr) ++ ++/* Find an entry in the second-level page table.. */ ++#define pmd_offset(dir, addr) ((pmd_t *)(dir)) ++ ++static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ++{ ++ const unsigned long mask = 0xfff; ++ pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); ++ return pte; ++} ++ ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; ++ ++/* Encode and decode a swap entry. ++ * ++ * We support up to 32GB of swap on 4k machines ++ */ ++#define __swp_type(x) (((x).val >> 2) & 0x7f) ++#define __swp_offset(x) ((x).val >> 9) ++#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) ++#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) ++#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) ++ ++/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ ++/* FIXME: this is not correct */ ++#define kern_addr_valid(addr) (1) ++ ++#include ++ ++/* ++ * We provide our own arch_get_unmapped_area to cope with VIPT caches. ++ */ ++#define HAVE_ARCH_UNMAPPED_AREA ++ ++/* ++ * remap a physical address `phys' of size `size' with page protection `prot' ++ * into virtual address `from' ++ */ ++#define io_remap_pfn_range(vma,from,pfn,size,prot) \ ++ remap_pfn_range(vma, from, pfn, size, prot) ++ ++#define pgtable_cache_init() do { } while (0) ++ ++#endif /* !__ASSEMBLY__ */ ++ ++#endif /* _ASMNDS32_PGTABLE_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/poll.h linux-3.4.110/arch/nds32/include/asm/poll.h +--- linux-3.4.110.orig/arch/nds32/include/asm/poll.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/poll.h 2016-04-07 10:20:50.910079787 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/poll.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASMNDS32_POLL_H ++#define __ASMNDS32_POLL_H ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/posix_types.h linux-3.4.110/arch/nds32/include/asm/posix_types.h +--- linux-3.4.110.orig/arch/nds32/include/asm/posix_types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/posix_types.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,40 @@ ++/* ++ * arch/arm/include/asm/posix_types.h ++ * ++ * Copyright (C) 1996-1998 Russell King. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Changelog: ++ * 27-06-1996 RMK Created ++ */ ++#ifndef __ARCH_NDS32_POSIX_TYPES_H ++#define __ARCH_NDS32_POSIX_TYPES_H ++ ++/* ++ * This file is generally used by user-level software, so you need to ++ * be a little careful about namespace pollution etc. Also, we cannot ++ * assume GCC is being used. ++ */ ++ ++typedef unsigned short __kernel_mode_t; ++#define __kernel_mode_t __kernel_mode_t ++ ++typedef unsigned short __kernel_nlink_t; ++#define __kernel_nlink_t __kernel_nlink_t ++ ++typedef unsigned short __kernel_ipc_pid_t; ++#define __kernel_ipc_pid_t __kernel_ipc_pid_t ++ ++typedef unsigned short __kernel_uid_t; ++typedef unsigned short __kernel_gid_t; ++#define __kernel_uid_t __kernel_uid_t ++ ++typedef unsigned short __kernel_old_dev_t; ++#define __kernel_old_dev_t __kernel_old_dev_t ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/processor.h linux-3.4.110/arch/nds32/include/asm/processor.h +--- linux-3.4.110.orig/arch/nds32/include/asm/processor.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/processor.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,133 @@ ++/* ++ * linux/arch/nds32/include/asm/processor.h ++ */ ++/* Copyright (C) 1995-1999 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is ptrace relative code for Andes NDS32 architecture. ++ * Original referred from ARM, fit to NDS32. ++ * ++ * Revision History: ++ * ++ * Oct.03.2007 Original from Tom, Shawn and Steven, refined by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#ifndef __ASM_NDS32_PROCESSOR_H ++#define __ASM_NDS32_PROCESSOR_H ++ ++/* ++ * Default implementation of macro that returns current ++ * instruction pointer ("program counter"). ++ */ ++#define current_text_addr() ({ __label__ _l; _l: &&_l;}) ++ ++#ifdef __KERNEL__ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define KERNEL_STACK_SIZE PAGE_SIZE ++#define STACK_TOP TASK_SIZE ++#define STACK_TOP_MAX TASK_SIZE ++ ++struct debug_info { ++ u32 address; ++ u16 insn; ++ u8 valid; ++}; ++ ++struct thread_struct { ++ /* fault info */ ++ unsigned long address; ++ unsigned long trap_no; ++ unsigned long error_code; ++ ++ struct fpu_struct fpu; /* Saved fpu/fpu emulator stuff. */ ++ struct audio_struct audio; ++ struct debug_info debug; /* debugging */ ++}; ++ ++#define INIT_THREAD { } ++ ++#ifdef __NDS32_EB__ ++#define PSW_DE PSW_mskBE ++#else ++#define PSW_DE 0x0 ++#endif ++ ++#ifdef CONFIG_WBNA ++#define PSW_valWBNA PSW_mskWBNA ++#else ++#define PSW_valWBNA 0x0 ++#endif ++ ++#define start_thread(regs,pc,sp) \ ++({ \ ++ unsigned long *stack = (unsigned long *)sp; \ ++ set_fs(USER_DS); \ ++ memzero(regs->uregs, sizeof(regs->uregs)); \ ++ regs->NDS32_ipsw = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE); \ ++ regs->NDS32_ir0 = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_SYSTEM | PSW_INTL_1); \ ++ regs->NDS32_ipc = pc; /* pc */ \ ++ regs->NDS32_sp = sp; /* $sp */ \ ++ regs->NDS32_r2 = stack[4]; /* $r2 (envp) */ \ ++ regs->NDS32_r1 = stack[1]; /* $r1 (argv) */ \ ++ regs->NDS32_r0 = stack[0]; /* $r0 (argc) */ \ ++}) ++ ++ ++/* Forward declaration, a strange C thing */ ++struct task_struct; ++ ++/* Free all resources held by a thread. */ ++extern void release_thread(struct task_struct *); ++#ifdef CONFIG_FPU ++#ifndef CONFIG_UNLAZU_FPU //lazy fpu ++extern struct task_struct *last_task_used_math; ++#endif ++#endif ++#ifdef CONFIG_AUDIO ++#ifndef CONFIG_UNLAZY_AUDIO //lazy audio ++extern struct task_struct *last_task_used_audio; ++#endif ++#endif ++ ++/* Prepare to copy thread state - unlazy all lazy status */ ++#define prepare_to_copy(tsk) do { } while (0) ++ ++unsigned long get_wchan(struct task_struct *p); ++ ++#define cpu_relax() barrier() ++ ++#define task_pt_regs(task) \ ++ ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ ++ - 8) - 1) ++ ++/* ++ * Create a new kernel thread ++ */ ++extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); ++ ++#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)task_thread_info(tsk)))[1019]) ++#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)task_thread_info(tsk)))[1017]) ++ ++ ++#endif ++ ++#endif /* __ASM_NDS32_PROCESSOR_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/proc-fns.h linux-3.4.110/arch/nds32/include/asm/proc-fns.h +--- linux-3.4.110.orig/arch/nds32/include/asm/proc-fns.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/proc-fns.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,88 @@ ++/* ++ * linux/arch/nds32/include/asm/proc-fns.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_PROCFNS_H__ ++#define __NDS32_PROCFNS_H__ ++ ++#define CPU_NAME n12 ++ ++#ifdef __KERNEL__ ++ ++#ifdef __STDC__ ++#define ____cpu_fn(name,fn) name##fn ++#else ++#define ____cpu_fn(name,fn) name/**/fn ++#endif ++#define __cpu_fn(name,fn) ____cpu_fn(name,fn) ++ ++#define cpu_proc_init __cpu_fn( CPU_NAME, _proc_init) ++#define cpu_proc_fin __cpu_fn( CPU_NAME, _proc_fin) ++#define cpu_do_idle __cpu_fn( CPU_NAME, _do_idle) ++#define cpu_reset __cpu_fn( CPU_NAME, _reset) ++#define cpu_switch_mm __cpu_fn( CPU_NAME, _switch_mm) ++ ++#define cpu_dcache_inval_all __cpu_fn( CPU_NAME, _dcache_inval_all) ++#define cpu_dcache_wbinval_all __cpu_fn( CPU_NAME, _dcache_wbinval_all) ++#define cpu_dcache_inval_page __cpu_fn( CPU_NAME, _dcache_inval_page) ++#define cpu_dcache_wb_page __cpu_fn( CPU_NAME, _dcache_wb_page) ++#define cpu_dcache_wbinval_page __cpu_fn( CPU_NAME, _dcache_wbinval_page) ++#define cpu_dcache_inval_range __cpu_fn( CPU_NAME, _dcache_inval_range) ++#define cpu_dcache_wb_range __cpu_fn( CPU_NAME, _dcache_wb_range) ++#define cpu_dcache_wbinval_range __cpu_fn( CPU_NAME, _dcache_wbinval_range) ++ ++#define cpu_icache_inval_all __cpu_fn( CPU_NAME, _icache_inval_all) ++#define cpu_icache_inval_page __cpu_fn( CPU_NAME, _icache_inval_page) ++#define cpu_icache_inval_range __cpu_fn( CPU_NAME, _icache_inval_range) ++ ++#define cpu_cache_wbinval_page __cpu_fn( CPU_NAME, _cache_wbinval_page) ++#define cpu_cache_wbinval_range __cpu_fn( CPU_NAME, _cache_wbinval_range) ++#define cpu_cache_wbinval_range_check __cpu_fn( CPU_NAME, _cache_wbinval_range_check) ++ ++#define cpu_dma_wb_range __cpu_fn( CPU_NAME, _dma_wb_range) ++#define cpu_dma_inval_range __cpu_fn( CPU_NAME, _dma_inval_range) ++#define cpu_dma_wbinval_range __cpu_fn( CPU_NAME, _dma_wbinval_range) ++ ++#include ++ ++struct mm_struct; ++struct vm_area_struct; ++extern void cpu_proc_init(void); ++extern void cpu_proc_fin(void); ++extern void cpu_do_idle(void); ++extern void cpu_reset(unsigned long reset); ++extern void cpu_switch_mm(struct mm_struct *mm); ++ ++extern void cpu_dcache_inval_all(void); ++extern void cpu_dcache_wbinval_all(void); ++extern void cpu_dcache_inval_page(unsigned long page); ++extern void cpu_dcache_wb_page(unsigned long page); ++extern void cpu_dcache_wbinval_page(unsigned long page); ++extern void cpu_dcache_inval_range(unsigned long start, unsigned long end); ++extern void cpu_dcache_wb_range(unsigned long start, unsigned long end); ++extern void cpu_dcache_wbinval_range(unsigned long start, unsigned long end); ++ ++extern void cpu_icache_inval_all(void); ++extern void cpu_icache_inval_page(unsigned long page); ++extern void cpu_icache_inval_range(unsigned long start, unsigned long end); ++ ++extern void cpu_cache_wbinval_page(unsigned long page, int flushi); ++extern void cpu_cache_wbinval_range(unsigned long start, ++ unsigned long end, int flushi); ++extern void cpu_cache_wbinval_range_check(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end); ++ ++extern void cpu_dma_wb_range(unsigned long start, unsigned long end); ++extern void cpu_dma_inval_range(unsigned long start, unsigned long end); ++extern void cpu_dma_wbinval_range(unsigned long start, unsigned long end); ++ ++#ifdef CONFIG_CACHE_L2 ++#define cpu_L2cache_inval __cpu_fn(CPU_NAME, _L2cache_inval) ++#define cpu_L2cache_wb __cpu_fn(CPU_NAME, _L2cache_wb) ++extern void cpu_L2cache_inval(void); ++extern void cpu_L2cache_wb(void); ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __NDS32_PROCFNS_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/procinfo.h linux-3.4.110/arch/nds32/include/asm/procinfo.h +--- linux-3.4.110.orig/arch/nds32/include/asm/procinfo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/procinfo.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,71 @@ ++/* ++ * linux/arch/nds32/include/asm/procinfo.h ++ * ++ * Copyright (C) 1996-1999 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_PROCINFO_H ++#define __ASM_PROCINFO_H ++ ++#ifndef __ASSEMBLY__ ++ ++/* ++ * These structure are defined in assembly ++ * ( nds32/mm/proc-nds32.S) ++ */ ++struct proc_info_item { ++ ++ const char *manufacturer; ++ const char *cpu_name; ++}; ++ ++/* ++ * Note! struct processor is always defined if we're ++ * using MULTI_CPU, otherwise this entry is unused, ++ * but still exists. ++ * ++ * NOTE! The following structure is defined by assembly ++ * language, NOT C code. For more information, check: ++ * arch/arm/mm/proc-*.S and arch/arm/kernel/head.S ++ */ ++struct proc_info_list { ++ ++ unsigned int cpu_val; ++ unsigned int cpu_mask; ++ const char *arch_name; ++ const char *elf_name; ++ unsigned int elf_hwcap; ++ struct proc_info_item *info; ++}; ++ ++extern unsigned int elf_hwcap; ++ ++#endif /* __ASSEMBLY__ */ ++ ++#define HWCAP_MFUSR_PC 0x000001 ++#define HWCAP_EXT 0x000002 ++#define HWCAP_EXT2 0x000004 ++#define HWCAP_FPU 0x000008 ++#define HWCAP_AUDIO 0x000010 ++#define HWCAP_BASE16 0x000020 ++#define HWCAP_STRING 0x000040 ++#define HWCAP_REDUCED_REGS 0x000080 ++#define HWCAP_VIDEO 0x000100 ++#define HWCAP_ENCRYPT 0x000200 ++#define HWCAP_EDM 0x000400 ++#define HWCAP_LMDMA 0x000800 ++#define HWCAP_PFM 0x001000 ++#define HWCAP_HSMP 0x002000 ++#define HWCAP_TRACE 0x004000 ++#define HWCAP_DIV 0x008000 ++#define HWCAP_MAC 0x010000 ++#define HWCAP_L2C 0x020000 ++#define HWCAP_FPU_DP 0x040000 ++#define HWCAP_V2 0x080000 ++#define HWCAP_DX_REGS 0x100000 ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ptrace.h linux-3.4.110/arch/nds32/include/asm/ptrace.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ptrace.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ptrace.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,119 @@ ++/* ++ * linux/arch/nds32/include/asm/ptrace.h ++ * ++ * Copyright (C) 1996-2003 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_NDS32_PTRACE_H ++#define __ASM_NDS32_PTRACE_H ++ ++#define PTRACE_GETREGS 12 ++#define PTRACE_SETREGS 13 ++#define PTRACE_GETFPREGS 14 ++#define PTRACE_SETFPREGS 15 ++#define PTRACE_GETAUREGS 18 ++#define PTRACE_SETAUREGS 19 ++ ++#define PTRACE_OLDSETOPTIONS 21 ++ ++#define PTRACE_GET_THREAD_AREA 22 ++ ++#ifndef __ASSEMBLY__ ++/* this struct defines the way the registers are stored on the ++ stack during a system call. */ ++ ++struct pt_regs { ++#if defined(CONFIG_ABI1) ++ long dummy[6]; ++#endif ++ long uregs[44]; ++}; ++#define NDS32_osp uregs[43] ++#define NDS32_FUCOP_CTL uregs[42] ++#define NDS32_lp uregs[41] ++#define NDS32_gp uregs[40] ++#define NDS32_fp uregs[39] ++#define NDS32_r25 uregs[38] ++#define NDS32_r24 uregs[37] ++#define NDS32_r23 uregs[36] ++#define NDS32_r22 uregs[35] ++#define NDS32_r21 uregs[34] ++#define NDS32_r20 uregs[33] ++#define NDS32_r19 uregs[32] ++#define NDS32_r18 uregs[31] ++#define NDS32_r17 uregs[30] ++#define NDS32_r16 uregs[29] ++#define NDS32_r15 uregs[28] ++#define NDS32_r14 uregs[27] ++#define NDS32_r13 uregs[26] ++#define NDS32_r12 uregs[25] ++#define NDS32_r11 uregs[24] ++#define NDS32_r10 uregs[23] ++#define NDS32_r9 uregs[22] ++#define NDS32_r8 uregs[21] ++#define NDS32_r7 uregs[20] ++#define NDS32_r6 uregs[19] ++#define NDS32_r5 uregs[18] ++#define NDS32_r4 uregs[17] ++#define NDS32_r3 uregs[16] ++#define NDS32_r2 uregs[15] ++#define NDS32_r1 uregs[14] ++#define NDS32_r0 uregs[13] ++#if defined(CONFIG_HWZOL) ++#define NDS32_lc uregs[11] ++#define NDS32_le uregs[10] ++#define NDS32_lb uregs[9] ++#endif ++#define NDS32_pp1 uregs[8] ++#define NDS32_pp0 uregs[7] ++#define NDS32_pipc uregs[6] ++#define NDS32_pipsw uregs[5] ++#define NDS32_ORIG_r0 uregs[4] ++#define NDS32_sp uregs[3] ++#define NDS32_ipc uregs[2] ++#define NDS32_ipsw uregs[1] ++#define NDS32_ir0 uregs[0] ++ ++#ifdef __KERNEL__ ++#include ++ ++#define arch_has_single_step() (1) ++struct task_struct; ++extern void user_enable_single_step(struct task_struct *); ++extern void user_disable_single_step(struct task_struct *); ++ ++#define user_mode(regs) (((regs)->NDS32_ipsw & PSW_mskPOM) == 0) ++ ++#define interrupts_enabled(regs) (!((regs)->NDS32_ipsw & ~PSW_mskGIE)) ++ ++extern void show_regs(struct pt_regs *); ++ ++/* Are the current registers suitable for user mode? ++ * (used to maintain security in signal handlers) ++ */ ++static inline int valid_user_regs(struct pt_regs *regs) ++{ ++ return user_mode(regs) && ((regs->NDS32_ipsw & PSW_mskGIE) == 1); ++} ++ ++static inline unsigned long regs_return_value(struct pt_regs *regs) ++{ ++ return regs->NDS32_r0; ++} ++ ++ ++#define instruction_pointer(regs) ((regs)->NDS32_ipc) ++ ++#ifdef CONFIG_SMP ++extern unsigned long profile_pc(struct pt_regs *regs); ++#else ++#define profile_pc(regs) instruction_pointer(regs) ++#endif ++ ++#endif /* __KERNEL__ */ ++#endif /* __ASSEMBLY__ */ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/reg_access.h linux-3.4.110/arch/nds32/include/asm/reg_access.h +--- linux-3.4.110.orig/arch/nds32/include/asm/reg_access.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/reg_access.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,153 @@ ++/* ++ * linux/arch/nds32/include/asm/reg_access.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_REG_ACCESS_H__ ++#define __NDS32_REG_ACCESS_H__ ++ ++#ifndef __ASSEMBLY__ ++#define DEFINE_GET_SYS_REG( reg) \ ++inline static unsigned long GET_##reg( void){ \ ++ unsigned long val; \ ++ __asm__ volatile ( "mfsr %0, $"#reg :"=&r" (val) ::"memory"); \ ++ return val; \ ++} ++ ++#define DEFINE_PUT_SYS_REG( reg) \ ++inline static void SET_##reg( unsigned long val){ \ ++ __asm__ volatile ( "\n\tmtsr %0, $"#reg \ ++ "\n\tdsb" ::"r" ( val) :"memory"); \ ++} ++ ++#define DEFINE_PUT_SYS_REG_i( reg) \ ++inline static void SET_##reg( unsigned long val){ \ ++ __asm__ volatile ( "\n\tmtsr %0, $"#reg \ ++ "\n\tisb" ::"r" ( val) :"memory"); \ ++} ++#define DEFINE_SYS_REG_OP( reg) \ ++DEFINE_GET_SYS_REG( reg); \ ++DEFINE_PUT_SYS_REG( reg); ++ ++#define DEFINE_SYS_REG_OP_i( reg) \ ++DEFINE_GET_SYS_REG( reg); \ ++DEFINE_PUT_SYS_REG_i( reg); ++ ++DEFINE_SYS_REG_OP( CPU_VER); ++DEFINE_SYS_REG_OP( ICM_CFG); ++DEFINE_SYS_REG_OP( DCM_CFG); ++DEFINE_SYS_REG_OP( MMU_CFG); ++DEFINE_SYS_REG_OP( MSC_CFG); ++DEFINE_SYS_REG_OP( CORE_ID); ++DEFINE_SYS_REG_OP( FUCOP_EXIST); ++ ++DEFINE_SYS_REG_OP_i( PSW); ++DEFINE_SYS_REG_OP( IPSW); ++DEFINE_SYS_REG_OP( P_IPSW); ++DEFINE_SYS_REG_OP( IVB); ++DEFINE_SYS_REG_OP( EVA); ++DEFINE_SYS_REG_OP( P_EVA); ++DEFINE_SYS_REG_OP( ITYPE); ++DEFINE_SYS_REG_OP( P_ITYPE); ++DEFINE_SYS_REG_OP( MERR); ++DEFINE_SYS_REG_OP( IPC); ++DEFINE_SYS_REG_OP( P_IPC); ++DEFINE_SYS_REG_OP( OIPC); ++DEFINE_SYS_REG_OP( P_P0); ++DEFINE_SYS_REG_OP( P_P1); ++DEFINE_SYS_REG_OP( INT_MASK); ++DEFINE_SYS_REG_OP( INT_PEND); ++DEFINE_SYS_REG_OP( INT_MASK2); ++DEFINE_SYS_REG_OP( INT_PEND2); ++DEFINE_SYS_REG_OP( INT_TRIGGER); ++ ++DEFINE_SYS_REG_OP( MMU_CTL); ++DEFINE_SYS_REG_OP( L1_PPTB); ++DEFINE_SYS_REG_OP( TLB_VPN); ++DEFINE_SYS_REG_OP( TLB_DATA); ++DEFINE_SYS_REG_OP( TLB_MISC); ++DEFINE_SYS_REG_OP( VLPT_IDX); ++DEFINE_SYS_REG_OP( ILMB); ++DEFINE_SYS_REG_OP( DLMB); ++DEFINE_SYS_REG_OP( CACHE_CTL); ++DEFINE_SYS_REG_OP( HSMP_SADDR); ++DEFINE_SYS_REG_OP( HSMP_EADDR); ++ ++DEFINE_SYS_REG_OP( EDM_CFG); ++DEFINE_SYS_REG_OP( EDMSW); ++DEFINE_SYS_REG_OP( EDM_CTL); ++DEFINE_SYS_REG_OP( EDM_DTR); ++DEFINE_SYS_REG_OP( BPMTC); ++DEFINE_SYS_REG_OP( DIMBR); ++DEFINE_SYS_REG_OP( TECR0); ++DEFINE_SYS_REG_OP( TECR1); ++ ++DEFINE_SYS_REG_OP( BPC0); ++DEFINE_SYS_REG_OP( BPA0); ++DEFINE_SYS_REG_OP( BPAM0); ++DEFINE_SYS_REG_OP( BPV0); ++DEFINE_SYS_REG_OP( BPCID0); ++DEFINE_SYS_REG_OP( BPC1); ++DEFINE_SYS_REG_OP( BPA1); ++DEFINE_SYS_REG_OP( BPAM1); ++DEFINE_SYS_REG_OP( BPV1); ++DEFINE_SYS_REG_OP( BPCID1); ++DEFINE_SYS_REG_OP( BPC2); ++DEFINE_SYS_REG_OP( BPA2); ++DEFINE_SYS_REG_OP( BPAM2); ++DEFINE_SYS_REG_OP( BPV2); ++DEFINE_SYS_REG_OP( BPCID2); ++DEFINE_SYS_REG_OP( BPC3); ++DEFINE_SYS_REG_OP( BPA3); ++DEFINE_SYS_REG_OP( BPAM3); ++DEFINE_SYS_REG_OP( BPV3); ++DEFINE_SYS_REG_OP( BPCID3); ++DEFINE_SYS_REG_OP( BPC4); ++DEFINE_SYS_REG_OP( BPA4); ++DEFINE_SYS_REG_OP( BPAM4); ++DEFINE_SYS_REG_OP( BPV4); ++DEFINE_SYS_REG_OP( BPCID4); ++DEFINE_SYS_REG_OP( BPC5); ++DEFINE_SYS_REG_OP( BPA5); ++DEFINE_SYS_REG_OP( BPAM5); ++DEFINE_SYS_REG_OP( BPV5); ++DEFINE_SYS_REG_OP( BPCID5); ++DEFINE_SYS_REG_OP( BPC6); ++DEFINE_SYS_REG_OP( BPA6); ++DEFINE_SYS_REG_OP( BPAM6); ++DEFINE_SYS_REG_OP( BPV6); ++DEFINE_SYS_REG_OP( BPCID6); ++DEFINE_SYS_REG_OP( BPC7); ++DEFINE_SYS_REG_OP( BPA7); ++DEFINE_SYS_REG_OP( BPAM7); ++DEFINE_SYS_REG_OP( BPV7); ++DEFINE_SYS_REG_OP( BPCID7); ++ ++DEFINE_SYS_REG_OP( PFMC0); ++DEFINE_SYS_REG_OP( PFMC1); ++DEFINE_SYS_REG_OP( PFMC2); ++DEFINE_SYS_REG_OP( PFM_CTL); ++ ++DEFINE_SYS_REG_OP( SDZ_CTL); ++DEFINE_SYS_REG_OP( N12MISC_CTL); ++DEFINE_SYS_REG_OP( PRUSR_ACC_CTL); ++ ++DEFINE_SYS_REG_OP( DMA_CFG); ++DEFINE_SYS_REG_OP( DMA_GCSW); ++DEFINE_SYS_REG_OP( DMA_CHNSEL); ++DEFINE_SYS_REG_OP( DMA_ACT); ++DEFINE_SYS_REG_OP( DMA_SETUP); ++DEFINE_SYS_REG_OP( DMA_ISADDR); ++DEFINE_SYS_REG_OP( DMA_ESADDR); ++DEFINE_SYS_REG_OP( DMA_TCNT); ++DEFINE_SYS_REG_OP( DMA_STATUS); ++DEFINE_SYS_REG_OP( DMA_2DSET); ++DEFINE_SYS_REG_OP( DMA_2DSCTL); ++ ++DEFINE_SYS_REG_OP( FPCSR); ++DEFINE_SYS_REG_OP( FPCFG); ++DEFINE_SYS_REG_OP( FUCOP_CTL); ++ ++#endif /* !__ASSEMBLY__ */ ++ ++#endif /* __NDS32_REG_ACCESS_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/resource.h linux-3.4.110/arch/nds32/include/asm/resource.h +--- linux-3.4.110.orig/arch/nds32/include/asm/resource.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/resource.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/resource.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_RESOURCE_H__ ++#define __NDS32_RESOURCE_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/rtc.h linux-3.4.110/arch/nds32/include/asm/rtc.h +--- linux-3.4.110.orig/arch/nds32/include/asm/rtc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/rtc.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,43 @@ ++/* ++ * linux/arch/nds32/include/asm/rtc.h ++ * ++ * Copyright (C) 2003 Deep Blue Solutions Ltd. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef ASMNDS32_RTC_H ++#define ASMNDS32_RTC_H ++ ++struct module; ++ ++struct rtc_ops { ++ struct module *owner; ++ int (*open)(void); ++ void (*release)(void); ++ int (*ioctl)(unsigned int, unsigned long); ++ ++ int (*read_time)(struct rtc_time *); ++ int (*set_time)(struct rtc_time *); ++ int (*read_alarm)(struct rtc_wkalrm *); ++ int (*set_alarm)(struct rtc_wkalrm *); ++ int (*proc)(char *buf); ++}; ++ ++void rtc_update(unsigned long, unsigned long); ++int register_rtc(struct rtc_ops *); ++void unregister_rtc(struct rtc_ops *); ++ ++static inline int rtc_periodic_alarm(struct rtc_time *tm) ++{ ++ return (tm->tm_year == -1) || ++ ((unsigned)tm->tm_mon >= 12) || ++ ((unsigned)(tm->tm_mday - 1) >= 31) || ++ ((unsigned)tm->tm_hour > 23) || ++ ((unsigned)tm->tm_min > 59) || ++ ((unsigned)tm->tm_sec > 59); ++} ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/scatterlist.h linux-3.4.110/arch/nds32/include/asm/scatterlist.h +--- linux-3.4.110.orig/arch/nds32/include/asm/scatterlist.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/scatterlist.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,35 @@ ++/* ++ * linux/arch/nds32/include/asm/scatterlist.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SCATTERLIST_H ++#define _ASMNDS32_SCATTERLIST_H ++ ++#include ++#include ++#include ++ ++#if 0 ++struct scatterlist { ++#ifdef CONFIG_DEBUG_SG ++ unsigned long sg_magic; ++#endif ++ unsigned long page_link; ++ unsigned int offset; /* buffer offset */ ++ dma_addr_t dma_address; /* dma address */ ++ unsigned int length; /* length */ ++}; ++ ++/* ++ * These macros should be used after a pci_map_sg call has been done ++ * to get bus addresses of each of the SG entries and their lengths. ++ * You should only work with the number of sg entries pci_map_sg ++ * returns, or alternatively stop on the first sg_dma_len(sg) which ++ * is 0. ++ */ ++#define sg_dma_address(sg) ((sg)->dma_address) ++#define sg_dma_len(sg) ((sg)->length) ++#endif ++ ++#endif /* _ASMNDS32_SCATTERLIST_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sections.h linux-3.4.110/arch/nds32/include/asm/sections.h +--- linux-3.4.110.orig/arch/nds32/include/asm/sections.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/sections.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/sections.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __NDS32_SECTIONS_H__ ++#define __NDS32_SECTIONS_H__ ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/segment.h linux-3.4.110/arch/nds32/include/asm/segment.h +--- linux-3.4.110.orig/arch/nds32/include/asm/segment.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/segment.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,16 @@ ++/* ++ * linux/arch/nds32/include/asm/segment.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_SEGMENT_H ++#define __ASM_NDS32_SEGMENT_H ++ ++#define __KERNEL_CS 0x0 ++#define __KERNEL_DS 0x0 ++ ++#define __USER_CS 0x1 ++#define __USER_DS 0x1 ++ ++#endif /* __ASM_NDS32_SEGMENT_H */ ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/semaphore.h linux-3.4.110/arch/nds32/include/asm/semaphore.h +--- linux-3.4.110.orig/arch/nds32/include/asm/semaphore.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/semaphore.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,6 @@ ++/* ++ * linux/arch/nds32/include/asm/semaphore.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#include +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/semaphore-helper.h linux-3.4.110/arch/nds32/include/asm/semaphore-helper.h +--- linux-3.4.110.orig/arch/nds32/include/asm/semaphore-helper.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/semaphore-helper.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,89 @@ ++/* ++ * linux/arch/nds32/include/asm/semaphore-helper.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef ASMNDS32_SEMAPHORE_HELPER_H ++#define ASMNDS32_SEMAPHORE_HELPER_H ++ ++/* ++ * These two _must_ execute atomically wrt each other. ++ */ ++static inline void wake_one_more(struct semaphore * sem) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ if (atomic_read(&sem->count) <= 0) ++ sem->waking++; ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++} ++ ++static inline int waking_non_zero(struct semaphore *sem) ++{ ++ unsigned long flags; ++ int ret = 0; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ if (sem->waking > 0) { ++ sem->waking--; ++ ret = 1; ++ } ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++ return ret; ++} ++ ++/* ++ * waking non zero interruptible ++ * 1 got the lock ++ * 0 go to sleep ++ * -EINTR interrupted ++ * ++ * We must undo the sem->count down_interruptible() increment while we are ++ * protected by the spinlock in order to make this atomic_inc() with the ++ * atomic_read() in wake_one_more(), otherwise we can race. -arca ++ */ ++static inline int waking_non_zero_interruptible(struct semaphore *sem, ++ struct task_struct *tsk) ++{ ++ unsigned long flags; ++ int ret = 0; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ if (sem->waking > 0) { ++ sem->waking--; ++ ret = 1; ++ } else if (signal_pending(tsk)) { ++ atomic_inc(&sem->count); ++ ret = -EINTR; ++ } ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++ return ret; ++} ++ ++/* ++ * waking_non_zero_try_lock: ++ * 1 failed to lock ++ * 0 got the lock ++ * ++ * We must undo the sem->count down_interruptible() increment while we are ++ * protected by the spinlock in order to make this atomic_inc() with the ++ * atomic_read() in wake_one_more(), otherwise we can race. -arca ++ */ ++static inline int waking_non_zero_trylock(struct semaphore *sem) ++{ ++ unsigned long flags; ++ int ret = 1; ++ ++ spin_lock_irqsave(&semaphore_wake_lock, flags); ++ if (sem->waking <= 0) ++ atomic_inc(&sem->count); ++ else { ++ sem->waking--; ++ ret = 0; ++ } ++ spin_unlock_irqrestore(&semaphore_wake_lock, flags); ++ return ret; ++} ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sembuf.h linux-3.4.110/arch/nds32/include/asm/sembuf.h +--- linux-3.4.110.orig/arch/nds32/include/asm/sembuf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/sembuf.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * linux/arch/nds32/include/asm/sembuf.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SEMBUF_H ++#define _ASMNDS32_SEMBUF_H ++ ++/* ++ * The semid64_ds structure for arm architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 64-bit time_t to solve y2038 problem ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct semid64_ds { ++ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ ++ __kernel_time_t sem_otime; /* last semop time */ ++ unsigned long __unused1; ++ __kernel_time_t sem_ctime; /* last change time */ ++ unsigned long __unused2; ++ unsigned long sem_nsems; /* no. of semaphores in array */ ++ unsigned long __unused3; ++ unsigned long __unused4; ++}; ++ ++#endif /* _ASMNDS32_SEMBUF_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/serial.h linux-3.4.110/arch/nds32/include/asm/serial.h +--- linux-3.4.110.orig/arch/nds32/include/asm/serial.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/serial.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * linux/arch/nds32/include/asm/serial.h ++ * ++ * Copyright (C) 1996 Russell King. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Changelog: ++ * 15-10-1996 RMK Created ++ */ ++ ++#ifndef __ASM_SERIAL_H ++#define __ASM_SERIAL_H ++ ++#define BASE_BAUD (CONFIG_UART_CLK / 16) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/setup.h linux-3.4.110/arch/nds32/include/asm/setup.h +--- linux-3.4.110.orig/arch/nds32/include/asm/setup.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/setup.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,232 @@ ++/* ++ * linux/arch/nds32/include/asm/setup.h ++ * ++ * Copyright (C) 1997-1999 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Structure passed to kernel to tell it about the ++ * hardware it's running on. See Documentation/arm/Setup ++ * for more info. ++ */ ++#ifndef __ASMNDS32_SETUP_H ++#define __ASMNDS32_SETUP_H ++ ++#define COMMAND_LINE_SIZE 256 ++ ++/* The list ends with an ATAG_NONE node. */ ++#define ATAG_NONE 0x00000000 ++ ++struct tag_header { ++ u32 size; ++ u32 tag; ++}; ++ ++/* The list must start with an ATAG_CORE node */ ++#define ATAG_CORE 0x54410001 ++ ++struct tag_core { ++ u32 flags; /* bit 0 = read-only */ ++ u32 pagesize; ++ u32 rootdev; ++}; ++ ++/* it is allowed to have multiple ATAG_MEM nodes */ ++#define ATAG_MEM 0x54410002 ++ ++struct tag_mem32 { ++ u32 size; ++ u32 start; /* physical start address */ ++}; ++ ++/* VGA text type displays */ ++#define ATAG_VIDEOTEXT 0x54410003 ++ ++struct tag_videotext { ++ u8 x; ++ u8 y; ++ u16 video_page; ++ u8 video_mode; ++ u8 video_cols; ++ u16 video_ega_bx; ++ u8 video_lines; ++ u8 video_isvga; ++ u16 video_points; ++}; ++ ++/* describes how the ramdisk will be used in kernel */ ++#define ATAG_RAMDISK 0x54410004 ++ ++struct tag_ramdisk { ++ u32 flags; /* bit 0 = load, bit 1 = prompt */ ++ u32 size; /* decompressed ramdisk size in _kilo_ bytes */ ++ u32 start; /* starting block of floppy-based RAM disk image */ ++}; ++ ++/*M Tom ++ * this one accidentally used virtual addresses - as such, ++ * it's deprecated. ++ * describes where the compressed ramdisk image lives (virtual address) ++ */ ++#define ATAG_INITRD 0x54410005 ++ ++/* describes where the compressed ramdisk image lives (physical address) */ ++#define ATAG_INITRD2 0x54420005 ++ ++struct tag_initrd { ++ u32 start; //M Tom va of start addr /* physical start address */ ++ u32 size; //M Tom unzipped size /* size of compressed ramdisk image in bytes */ ++}; ++ ++/* board serial number. "64 bits should be enough for everybody" */ ++#define ATAG_SERIAL 0x54410006 ++ ++struct tag_serialnr { ++ u32 low; ++ u32 high; ++}; ++ ++/* board revision */ ++#define ATAG_REVISION 0x54410007 ++ ++struct tag_revision { ++ u32 rev; ++}; ++ ++/* initial values for vesafb-type framebuffers. see struct screen_info ++ * in include/linux/tty.h ++ */ ++#define ATAG_VIDEOLFB 0x54410008 ++ ++struct tag_videolfb { ++ u16 lfb_width; ++ u16 lfb_height; ++ u16 lfb_depth; ++ u16 lfb_linelength; ++ u32 lfb_base; ++ u32 lfb_size; ++ u8 red_size; ++ u8 red_pos; ++ u8 green_size; ++ u8 green_pos; ++ u8 blue_size; ++ u8 blue_pos; ++ u8 rsvd_size; ++ u8 rsvd_pos; ++}; ++ ++/* command line: \0 terminated string */ ++#define ATAG_CMDLINE 0x54410009 ++ ++struct tag_cmdline { ++ char cmdline[COMMAND_LINE_SIZE];//M Tom ++}; ++ ++/* acorn RiscPC specific information */ ++/*-d Tom ++#define ATAG_ACORN 0x41000101 ++ ++struct tag_acorn { ++ u32 memc_control_reg; ++ u32 vram_pages; ++ u8 sounddefault; ++ u8 adfsdrives; ++}; ++*/ ++#define ATAG_CPE 0x41000101 ++struct tag_cpe { ++ u32 memc_control_reg; ++ u32 vram_pages; ++ u8 sounddefault; ++ u8 adfsdrives; ++}; ++ ++ ++/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */ ++#define ATAG_MEMCLK 0x41000402 ++ ++struct tag_memclk { ++ u32 fmemclk; ++}; ++ ++struct tag { ++ struct tag_header hdr; ++ union { ++ struct tag_core core; ++ struct tag_mem32 mem; ++ struct tag_videotext videotext; ++ struct tag_ramdisk ramdisk; ++ struct tag_initrd initrd; ++ struct tag_serialnr serialnr; ++ struct tag_revision revision; ++ struct tag_videolfb videolfb; ++ struct tag_cmdline cmdline; ++ ++ /* ++ * Andes specific ++ */ ++ struct tag_cpe cpe; ++ ++ /* ++ * DC21285 specific ++ */ ++ struct tag_memclk memclk; ++ } u; ++}; ++ ++struct tagtable { ++ u32 tag; ++ int (*parse)(const struct tag *); ++}; ++ ++#define tag_member_present(tag,member) \ ++ ((unsigned long)(&((struct tag *)0L)->member + 1) \ ++ <= (tag)->hdr.size * 4) ++ ++#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)) ++#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) ++ ++#define for_each_tag(t,base) \ ++ for (t = base; t->hdr.size; t = tag_next(t)) ++ ++#ifdef __KERNEL__ ++ ++#define __tag __used __attribute__((__section__(".taglist"))) ++#define __tagtable(tag, fn) \ ++static struct tagtable __tagtable_##fn __tag = { tag, fn } ++ ++/* ++ * Memory map description ++ */ ++#ifdef CONFIG_ARCH_LH7A40X ++# define NR_BANKS 16 ++#else ++# define NR_BANKS 8 ++#endif ++ ++struct meminfo { ++ int nr_banks; ++ struct { ++ unsigned long start; ++ unsigned long size; ++ int node; ++ } bank[NR_BANKS]; ++}; ++ ++/* ++ * Early command line parameters. ++ */ ++struct early_params { ++ const char *arg; ++ void (*fn)(char **p); ++}; ++ ++#define __early_param(name,fn) \ ++static struct early_params __early_##fn __used \ ++__attribute__((__section__("__early_param"))) = { name, fn } ++ ++#endif ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/shmbuf.h linux-3.4.110/arch/nds32/include/asm/shmbuf.h +--- linux-3.4.110.orig/arch/nds32/include/asm/shmbuf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/shmbuf.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,47 @@ ++/* ++ * linux/arch/nds32/include/asm/shmbuf.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SHMBUF_H ++#define _ASMNDS32_SHMBUF_H ++ ++/* ++ * The shmid64_ds structure for arm architecture. ++ * Note extra padding because this structure is passed back and forth ++ * between kernel and user space. ++ * ++ * Pad space is left for: ++ * - 64-bit time_t to solve y2038 problem ++ * - 2 miscellaneous 32-bit values ++ */ ++ ++struct shmid64_ds { ++ struct ipc64_perm shm_perm; /* operation perms */ ++ size_t shm_segsz; /* size of segment (bytes) */ ++ __kernel_time_t shm_atime; /* last attach time */ ++ unsigned long __unused1; ++ __kernel_time_t shm_dtime; /* last detach time */ ++ unsigned long __unused2; ++ __kernel_time_t shm_ctime; /* last change time */ ++ unsigned long __unused3; ++ __kernel_pid_t shm_cpid; /* pid of creator */ ++ __kernel_pid_t shm_lpid; /* pid of last operator */ ++ unsigned long shm_nattch; /* no. of current attaches */ ++ unsigned long __unused4; ++ unsigned long __unused5; ++}; ++ ++struct shminfo64 { ++ unsigned long shmmax; ++ unsigned long shmmin; ++ unsigned long shmmni; ++ unsigned long shmseg; ++ unsigned long shmall; ++ unsigned long __unused1; ++ unsigned long __unused2; ++ unsigned long __unused3; ++ unsigned long __unused4; ++}; ++ ++#endif /* _ASMNDS32_SHMBUF_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/shmparam.h linux-3.4.110/arch/nds32/include/asm/shmparam.h +--- linux-3.4.110.orig/arch/nds32/include/asm/shmparam.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/shmparam.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,27 @@ ++/* ++ * linux/arch/nds32/include/asm/shmparam.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SHMPARAM_H ++#define _ASMNDS32_SHMPARAM_H ++ ++/* ++ * This should be the size of the virtually indexed cache/ways, ++ * whichever is greater since the cache aliases every size/ways ++ * bytes. ++ */ ++/* ++ * Reference ARM architecture, retain the previous code ++ * #define SHMLBA 0x4000 ++ * #define REALSHMLBA (CACHE_SET( DCACHE) * CACHE_LINE_SIZE( DCACHE)) ++ */ ++#define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */ ++#define REALSHMLBA SHMLBA ++ ++/* ++ * Enforce SHMLBA in shmat ++ */ ++#define __ARCH_FORCE_SHMLBA ++ ++#endif /* _ASMNDS32_SHMPARAM_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sigcontext.h linux-3.4.110/arch/nds32/include/asm/sigcontext.h +--- linux-3.4.110.orig/arch/nds32/include/asm/sigcontext.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/sigcontext.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,81 @@ ++/* ++ * linux/arch/nds32/include/asm/sigcontext.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SIGCONTEXT_H ++#define _ASMNDS32_SIGCONTEXT_H ++ ++/* ++ * Signal context structure - contains all info to do with the state ++ * before the signal handler was invoked. Note: only add new entries ++ * to the end of the structure. ++ */ ++struct fpu_struct { ++ unsigned long fs_regs[32]; ++ unsigned long long fd_regs[16]; ++ unsigned long fpcsr; ++}; ++ ++struct audio_struct { ++ unsigned long auregs[32]; ++}; ++ ++struct zol_struct { ++ unsigned long nds32_lc; /* $LC */ ++ unsigned long nds32_le; /* $LE */ ++ unsigned long nds32_lb; /* $LB */ ++}; ++ ++struct sigcontext { ++ unsigned long trap_no; ++ unsigned long error_code; ++ unsigned long oldmask; ++ unsigned long nds32_r0; ++ unsigned long nds32_r1; ++ unsigned long nds32_r2; ++ unsigned long nds32_r3; ++ unsigned long nds32_r4; ++ unsigned long nds32_r5; ++ unsigned long nds32_r6; ++ unsigned long nds32_r7; ++ unsigned long nds32_r8; ++ unsigned long nds32_r9; ++ unsigned long nds32_r10; ++ unsigned long nds32_r11; ++ unsigned long nds32_r12; ++ unsigned long nds32_r13; ++ unsigned long nds32_r14; ++ unsigned long nds32_r15; ++ unsigned long nds32_r16; ++ unsigned long nds32_r17; ++ unsigned long nds32_r18; ++ unsigned long nds32_r19; ++ unsigned long nds32_r20; ++ unsigned long nds32_r21; ++ unsigned long nds32_r22; ++ unsigned long nds32_r23; ++ unsigned long nds32_r24; ++ unsigned long nds32_r25; ++ unsigned long nds32_fp; /* $r28 */ ++ unsigned long nds32_gp; /* $r29 */ ++ unsigned long nds32_lr; /* $r30 */ ++ unsigned long nds32_sp; /* $r31 */ ++ unsigned long nds32_ipc; ++ unsigned long fault_address; ++#if defined(CONFIG_FPU) ++ unsigned long used_math_flag; ++ /* FPU Registers */ ++ struct fpu_struct fpu; ++#endif ++ /* Audio Registers */ ++#if defined(CONFIG_AUDIO) ++ unsigned long used_audio_flag; ++ struct audio_struct audio; ++#endif ++#if defined(CONFIG_HWZOL) ++ struct zol_struct zol; ++#endif ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/siginfo.h linux-3.4.110/arch/nds32/include/asm/siginfo.h +--- linux-3.4.110.orig/arch/nds32/include/asm/siginfo.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/siginfo.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/siginfo.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SIGINFO_H ++#define _ASMNDS32_SIGINFO_H ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/signal.h linux-3.4.110/arch/nds32/include/asm/signal.h +--- linux-3.4.110.orig/arch/nds32/include/asm/signal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/signal.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,173 @@ ++/* ++ * linux/arch/nds32/include/asm/signal.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SIGNAL_H ++#define _ASMNDS32_SIGNAL_H ++ ++#include ++ ++/* Avoid too many header ordering problems. */ ++struct siginfo; ++ ++#ifdef __KERNEL__ ++/* Most things should be clean enough to redefine this at will, if care ++ is taken to make libc match. */ ++ ++#define _NSIG 64 ++#define _NSIG_BPW 32 ++#define _NSIG_WORDS (_NSIG / _NSIG_BPW) ++ ++typedef unsigned long old_sigset_t; /* at least 32 bits */ ++ ++typedef struct { ++ unsigned long sig[_NSIG_WORDS]; ++} sigset_t; ++ ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++#define NSIG 32 ++typedef unsigned long sigset_t; ++ ++#endif /* __KERNEL__ */ ++ ++#define SIGHUP 1 ++#define SIGINT 2 ++#define SIGQUIT 3 ++#define SIGILL 4 ++#define SIGTRAP 5 ++#define SIGABRT 6 ++#define SIGIOT 6 ++#define SIGBUS 7 ++#define SIGFPE 8 ++#define SIGKILL 9 ++#define SIGUSR1 10 ++#define SIGSEGV 11 ++#define SIGUSR2 12 ++#define SIGPIPE 13 ++#define SIGALRM 14 ++#define SIGTERM 15 ++#define SIGSTKFLT 16 ++#define SIGCHLD 17 ++#define SIGCONT 18 ++#define SIGSTOP 19 ++#define SIGTSTP 20 ++#define SIGTTIN 21 ++#define SIGTTOU 22 ++#define SIGURG 23 ++#define SIGXCPU 24 ++#define SIGXFSZ 25 ++#define SIGVTALRM 26 ++#define SIGPROF 27 ++#define SIGWINCH 28 ++#define SIGIO 29 ++#define SIGPOLL SIGIO ++/* ++#define SIGLOST 29 ++*/ ++#define SIGPWR 30 ++#define SIGSYS 31 ++#define SIGUNUSED 31 ++ ++/* These should not be considered constants from userland. */ ++#define SIGRTMIN 32 ++#define SIGRTMAX _NSIG ++ ++#define SIGSWI 32 ++ ++/* ++ * SA_FLAGS values: ++ * ++ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. ++ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. ++ * SA_SIGINFO deliver the signal with SIGINFO structs ++ * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task ++ * is running in 26-bit. ++ * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)). ++ * SA_RESTART flag to get restarting signals (which were the default long ago) ++ * SA_NODEFER prevents the current signal from being masked in the handler. ++ * SA_RESETHAND clears the handler when the signal is delivered. ++ * ++ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single ++ * Unix names RESETHAND and NODEFER respectively. ++ */ ++#define SA_NOCLDSTOP 0x00000001 ++#define SA_NOCLDWAIT 0x00000002 ++#define SA_SIGINFO 0x00000004 ++#define SA_THIRTYTWO 0x02000000 ++#define SA_RESTORER 0x04000000 ++#define SA_ONSTACK 0x08000000 ++#define SA_RESTART 0x10000000 ++#define SA_NODEFER 0x40000000 ++#define SA_RESETHAND 0x80000000 ++ ++#define SA_NOMASK SA_NODEFER ++#define SA_ONESHOT SA_RESETHAND ++ ++ ++/* ++ * sigaltstack controls ++ */ ++#define SS_ONSTACK 1 ++#define SS_DISABLE 2 ++ ++#define MINSIGSTKSZ 2048 ++#define SIGSTKSZ 8192 ++ ++#ifdef __KERNEL__ ++#define SA_IRQNOMASK 0x08000000 ++#endif ++ ++#include ++ ++#ifdef __KERNEL__ ++struct old_sigaction { ++ __sighandler_t sa_handler; ++ old_sigset_t sa_mask; ++ unsigned long sa_flags; ++ __sigrestore_t sa_restorer; ++}; ++ ++struct sigaction { ++ __sighandler_t sa_handler; ++ unsigned long sa_flags; ++ __sigrestore_t sa_restorer; ++ sigset_t sa_mask; /* mask last for extensibility */ ++}; ++ ++struct k_sigaction { ++ struct sigaction sa; ++}; ++ ++#else ++/* Here we must cater to libcs that poke about in kernel headers. */ ++ ++struct sigaction { ++ union { ++ __sighandler_t _sa_handler; ++ void (*_sa_sigaction)(int, struct siginfo *, void *); ++ } _u; ++ sigset_t sa_mask; ++ unsigned long sa_flags; ++ void (*sa_restorer)(void); ++}; ++ ++#define sa_handler _u._sa_handler ++#define sa_sigaction _u._sa_sigaction ++ ++#endif /* __KERNEL__ */ ++ ++typedef struct sigaltstack { ++ void __user *ss_sp; ++ int ss_flags; ++ size_t ss_size; ++} stack_t; ++ ++#ifdef __KERNEL__ ++#include ++#define ptrace_signal_deliver(regs, cookie) do { } while (0) ++#endif ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sizes.h linux-3.4.110/arch/nds32/include/asm/sizes.h +--- linux-3.4.110.orig/arch/nds32/include/asm/sizes.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/sizes.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,53 @@ ++/* ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++/* DO NOT EDIT!! - this file automatically generated ++ * from .s file by awk -f s2h.awk ++ */ ++/* Size definitions ++ * Copyright (C) ARM Limited 1998. All rights reserved. ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __sizes_h ++#define __sizes_h 1 ++ ++/* handy sizes */ ++#define SZ_1K 0x00000400 ++#define SZ_4K 0x00001000 ++#define SZ_8K 0x00002000 ++#define SZ_16K 0x00004000 ++#define SZ_64K 0x00010000 ++#define SZ_128K 0x00020000 ++#define SZ_256K 0x00040000 ++#define SZ_512K 0x00080000 ++ ++#define SZ_1M 0x00100000 ++#define SZ_2M 0x00200000 ++#define SZ_4M 0x00400000 ++#define SZ_8M 0x00800000 ++#define SZ_16M 0x01000000 ++#define SZ_32M 0x02000000 ++#define SZ_64M 0x04000000 ++#define SZ_128M 0x08000000 ++#define SZ_256M 0x10000000 ++#define SZ_512M 0x20000000 ++ ++#define SZ_1G 0x40000000 ++#define SZ_2G 0x80000000 ++ ++#endif ++ ++/* END */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/smp.h linux-3.4.110/arch/nds32/include/asm/smp.h +--- linux-3.4.110.orig/arch/nds32/include/asm/smp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/smp.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,42 @@ ++/* ++ * linux/arch/nds32/include/asm/smp.h ++ * ++ * Copyright (C) 2004-2005 ARM Ltd. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_NDS32_SMP_H ++#define __ASM_NDS32_SMP_H ++ ++#include ++#include ++#include ++ ++#ifndef CONFIG_SMP ++# error " included in non-SMP build" ++#endif ++ ++/* ++ * at the moment, there's not a big penalty for changing CPUs ++ * (the >big< penalty is running SMP in the first place) ++ */ ++#define PROC_CHANGE_PENALTY 15 ++ ++struct seq_file; ++ ++/* ++ * Move global data into per-processor storage. ++ */ ++extern void smp_store_cpu_info(unsigned int cpuid); ++ ++#define raw_smp_processor_id() (unsigned int)(GET_CORE_ID()&CORE_ID_mskCOREID) ++ ++extern void smp_init_cpus(void); ++extern void smp_send_timer(void); ++extern void arch_send_call_function_single_ipi(int cpu); ++extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); ++ ++#endif /* ifndef __ASM_NDS32_SMP_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/socket.h linux-3.4.110/arch/nds32/include/asm/socket.h +--- linux-3.4.110.orig/arch/nds32/include/asm/socket.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/socket.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/socket.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SOCKET_H ++#define _ASMNDS32_SOCKET_H ++ ++#include ++ ++#endif /* _ASMNDS32_SOCKET_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/sockios.h linux-3.4.110/arch/nds32/include/asm/sockios.h +--- linux-3.4.110.orig/arch/nds32/include/asm/sockios.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/sockios.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * linux/arch/nds32/include/asm/sockios.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ARCH_NDS32_SOCKIOS_H ++#define __ARCH_NDS32_SOCKIOS_H ++ ++/* Socket-level I/O control calls. */ ++#define FIOSETOWN 0x8901 ++#define SIOCSPGRP 0x8902 ++#define FIOGETOWN 0x8903 ++#define SIOCGPGRP 0x8904 ++#define SIOCATMARK 0x8905 ++#define SIOCGSTAMP 0x8906 /* Get stamp */ ++#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spec-ag101.h linux-3.4.110/arch/nds32/include/asm/spec-ag101.h +--- linux-3.4.110.orig/arch/nds32/include/asm/spec-ag101.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/spec-ag101.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,237 @@ ++#ifndef __NDS32_AG101_SPECIFICATION_H__ ++#define __NDS32_AG101_SPECIFICATION_H__ ++ ++#define UART0_PA_BASE 0x99600000 ++#define UART0_VA_BASE 0xF9960000 ++#define UART0_IRQ 7 ++#define UART1_PA_BASE 0x98300000 ++#define UART1_VA_BASE 0xF9830000 ++#define UART1_IRQ 11 ++#define CFC_FTCFC010_0_PA_BASE 0x98D00000 ++#define CFC_FTCFC010_0_VA_BASE 0xF98D0000 ++#define SDC_FTSDC010_0_PA_BASE 0x98e00000 ++#define SDC_FTSDC010_0_VA_BASE 0xF98e0000 ++#define SDMC_FTSDMC021_PA_BASE 0x90300000 ++#define SDMC_FTSDMC021_VA_BASE 0xF9030000 ++#define PCIC_FTPCI100_0_PA_BASE 0x90C00000 ++#define PCIC_FTPCI100_0_VA_BASE 0xF90C0000 ++#define PCIC_FTPCI100_0_VA_LIMIT 0xF90CFFFF ++#define PCIIO_PA_BASE 0x90C01000 ++#define PCIIO_VA_BASE 0xFE901000 ++#define PCIIO_0_PA_BASE 0x90C01000 ++#define PCIIO_0_VA_BASE 0xFE901000 ++#define PCIIO_VA_LIMIT 0xFE9FFFFF ++#define AHB_ATFAHBC020S_0_PA_BASE 0x90100000 ++#define AHB_ATFAHBC020S_0_VA_BASE 0xF9010000 ++ ++/* DMAC */ ++#define DMAC_FTDMAC020_PA_COUNT 1 ++#define DMAC_FTDMAC020_PA_BASE 0x90400000 ++#define DMAC_FTDMAC020_PA_LIMIT 0x90400FFF ++#define DMAC_FTDMAC020_PA_SIZE 0x00001000 ++#define DMAC_FTDMAC020_0_PA_BASE 0x90400000 ++#define DMAC_FTDMAC020_0_PA_LIMIT 0x90400FFF ++#define DMAC_FTDMAC020_0_PA_SIZE 0x00001000 ++#define DMAC_FTDMAC020_VA_COUNT 1 ++#define DMAC_FTDMAC020_VA_BASE 0xF9040000 ++#define DMAC_FTDMAC020_VA_LIMIT 0xF9040FFF ++#define DMAC_FTDMAC020_VA_SIZE 0x00001000 ++#define DMAC_FTDMAC020_0_VA_BASE 0xF9040000 ++#define DMAC_FTDMAC020_0_VA_LIMIT 0xF9040FFF ++#define DMAC_FTDMAC020_0_VA_SIZE 0x00001000 ++ ++/* TIMER */ ++#define TIMER_FTTMR010_PA_COUNT 1 ++#define TIMER_FTTMR010_PA_BASE 0x98400000 ++#define TIMER_FTTMR010_PA_LIMIT 0x98400FFF ++#define TIMER_FTTMR010_PA_SIZE 0x00001000 ++#define TIMER_FTTMR010_0_PA_BASE 0x98400000 ++#define TIMER_FTTMR010_0_PA_LIMIT 0x98400FFF ++#define TIMER_FTTMR010_0_PA_SIZE 0x00001000 ++#define TIMER_FTTMR010_VA_COUNT 1 ++#define TIMER_FTTMR010_VA_BASE 0xF9840000 ++#define TIMER_FTTMR010_VA_LIMIT 0xF9840FFF ++#define TIMER_FTTMR010_VA_SIZE 0x00001000 ++#define TIMER_FTTMR010_0_VA_BASE 0xF9840000 ++#define TIMER_FTTMR010_0_VA_LIMIT 0xF9840FFF ++#define TIMER_FTTMR010_0_VA_SIZE 0x00001000 ++ ++/* RTC */ ++#define RTC_FTRTC010_PA_COUNT 1 ++#define RTC_FTRTC010_PA_BASE 0x98600000 ++#define RTC_FTRTC010_PA_LIMIT 0x98600FFF ++#define RTC_FTRTC010_PA_SIZE 0x00001000 ++#define RTC_FTRTC010_0_PA_BASE 0x98600000 ++#define RTC_FTRTC010_0_PA_LIMIT 0x98600FFF ++#define RTC_FTRTC010_0_PA_SIZE 0x00001000 ++#define RTC_FTRTC010_VA_COUNT 1 ++#define RTC_FTRTC010_VA_BASE 0xF9860000 ++#define RTC_FTRTC010_VA_LIMIT 0xF9860FFF ++#define RTC_FTRTC010_VA_SIZE 0x00001000 ++#define RTC_FTRTC010_0_VA_BASE 0xF9860000 ++#define RTC_FTRTC010_0_VA_LIMIT 0xF9860FFF ++#define RTC_FTRTC010_0_VA_SIZE 0x00001000 ++ ++/* WDT */ ++#define WDT_FTWDT010_PA_COUNT 1 ++#define WDT_FTWDT010_PA_BASE 0x98500000 ++#define WDT_FTWDT010_PA_LIMIT 0x98500FFF ++#define WDT_FTWDT010_PA_SIZE 0x00001000 ++#define WDT_FTWDT010_0_PA_BASE 0x98500000 ++#define WDT_FTWDT010_0_PA_LIMIT 0x98500FFF ++#define WDT_FTWDT010_0_PA_SIZE 0x00001000 ++#define WDT_FTWDT010_VA_COUNT 1 ++#define WDT_FTWDT010_VA_BASE 0xF9850000 ++#define WDT_FTWDT010_VA_LIMIT 0xF9850FFF ++#define WDT_FTWDT010_VA_SIZE 0x00001000 ++#define WDT_FTWDT010_0_VA_BASE 0xF9850000 ++#define WDT_FTWDT010_0_VA_LIMIT 0xF9850FFF ++#define WDT_FTWDT010_0_VA_SIZE 0x00001000 ++ ++/* GPIO */ ++#define GPIO_FTGPIO010_PA_COUNT 1 ++#define GPIO_FTGPIO010_PA_BASE 0x98700000 ++#define GPIO_FTGPIO010_PA_LIMIT 0x98700FFF ++#define GPIO_FTGPIO010_PA_SIZE 0x00001000 ++#define GPIO_FTGPIO010_0_PA_BASE 0x98700000 ++#define GPIO_FTGPIO010_0_PA_LIMIT 0x98700FFF ++#define GPIO_FTGPIO010_0_PA_SIZE 0x00001000 ++#define GPIO_FTGPIO010_VA_COUNT 1 ++#define GPIO_FTGPIO010_VA_BASE 0xF9870000 ++#define GPIO_FTGPIO010_VA_LIMIT 0xF9870FFF ++#define GPIO_FTGPIO010_VA_SIZE 0x00001000 ++#define GPIO_FTGPIO010_0_VA_BASE 0xF9870000 ++#define GPIO_FTGPIO010_0_VA_LIMIT 0xF9870FFF ++#define GPIO_FTGPIO010_0_VA_SIZE 0x00001000 ++ ++ ++/* USB OTG */ ++#define USB_FOTG2XX_0_PA_COUNT 1 ++#define USB_FOTG2XX_0_PA_BASE 0x90B00000 ++#define USB_FOTG2XX_0_PA_LIMIT 0x90B00FFF ++#define USB_FOTG2XX_0_PA_SIZE 0x00001000 ++#define USB_FOTG2XX_0_VA_BASE 0xF90B0000 ++#define USB_FOTG2XX_0_VA_LIMIT 0xF90B0FFF ++#define USB_FOTG2XX_0_VA_SIZE 0x00001000 ++#define USB_FOTG2XX_0_IRQ 26 ++#define USB_FOTG2XX_PA_COUNT 1 ++#define USB_FOTG2XX_PA_BASE 0x90B00000 ++#define USB_FOTG2XX_PA_LIMIT 0x90B00FFF ++#define USB_FOTG2XX_PA_SIZE 0x00001000 ++#define USB_FOTG2XX_VA_BASE 0xF90B0000 ++#define USB_FOTG2XX_VA_LIMIT 0xF90B0FFF ++#define USB_FOTG2XX_VA_SIZE 0x00001000 ++#define USB_FOTG2XX_IRQ 26 ++#define USB_FOTG2XX_IRQ_COUNT 1 ++ ++/* SSP */ ++#define SSP_FTSSP010_PA_COUNT 1 ++#define SSP_FTSSP010_PA_BASE 0x99400000 ++#define SSP_FTSSP010_PA_LIMIT 0x99400FFF ++#define SSP_FTSSP010_PA_SIZE 0x00001000 ++#define SSP_FTSSP010_0_PA_BASE 0x99400000 ++#define SSP_FTSSP010_0_PA_LIMIT 0x99400FFF ++#define SSP_FTSSP010_0_PA_SIZE 0x00001000 ++#define SSP_FTSSP010_VA_COUNT 1 ++#define SSP_FTSSP010_VA_BASE 0xF9940000 ++#define SSP_FTSSP010_VA_LIMIT 0xF9940FFF ++#define SSP_FTSSP010_VA_SIZE 0x00001000 ++#define SSP_FTSSP010_0_VA_BASE 0xF9940000 ++#define SSP_FTSSP010_0_VA_LIMIT 0xF9940FFF ++#define SSP_FTSSP010_0_VA_SIZE 0x00001000 ++ ++/* APBBRG */ ++#define APBBRG_FTAPBBRG020S_PA_COUNT 1 ++#define APBBRG_FTAPBBRG020S_PA_BASE 0x90500000 ++#define APBBRG_FTAPBBRG020S_PA_LIMIT 0x90500FFF ++#define APBBRG_FTAPBBRG020S_PA_SIZE 0x00001000 ++#define APBBRG_FTAPBBRG020S_0_PA_BASE 0x90500000 ++#define APBBRG_FTAPBBRG020S_0_PA_LIMIT 0x90500FFF ++#define APBBRG_FTAPBBRG020S_0_PA_SIZE 0x00001000 ++#define APBBRG_FTAPBBRG020S_1_PA_BASE 0x90E00000 ++#define APBBRG_FTAPBBRG020S_1_PA_LIMIT 0x90E00FFF ++#define APBBRG_FTAPBBRG020S_1_PA_SIZE 0x00001000 ++#define APBBRG_FTAPBBRG020S_VA_COUNT 1 ++#define APBBRG_FTAPBBRG020S_VA_BASE 0xF9050000 ++#define APBBRG_FTAPBBRG020S_VA_LIMIT 0xF9050FFF ++#define APBBRG_FTAPBBRG020S_VA_SIZE 0x00001000 ++#define APBBRG_FTAPBBRG020S_0_VA_BASE 0xF9050000 ++#define APBBRG_FTAPBBRG020S_0_VA_LIMIT 0xF9050FFF ++#define APBBRG_FTAPBBRG020S_0_VA_SIZE 0x00001000 ++#define APBBRG_FTAPBBRG020S_1_VA_BASE 0xF90E0000 ++#define APBBRG_FTAPBBRG020S_1_VA_LIMIT 0xF90E0FFF ++#define APBBRG_FTAPBBRG020S_1_VA_SIZE 0x00001000 ++ ++/* I2C */ ++#define I2C_FTI2C010_PA_COUNT 1 ++#define I2C_FTI2C010_PA_BASE 0x98A00000 ++#define I2C_FTI2C010_PA_LIMIT 0x98A00FFF ++#define I2C_FTI2C010_PA_SIZE 0x00001000 ++#define I2C_FTI2C010_0_PA_BASE 0x98A00000 ++#define I2C_FTI2C010_0_PA_LIMIT 0x98A00FFF ++#define I2C_FTI2C010_0_PA_SIZE 0x00001000 ++#define I2C_FTI2C010_VA_COUNT 1 ++#define I2C_FTI2C010_VA_BASE 0xF98A0000 ++#define I2C_FTI2C010_VA_LIMIT 0xF98A0FFF ++#define I2C_FTI2C010_VA_SIZE 0x00001000 ++#define I2C_FTI2C010_0_VA_BASE 0xF98A0000 ++#define I2C_FTI2C010_0_VA_LIMIT 0xF98A0FFF ++#define I2C_FTI2C010_0_VA_SIZE 0x00001000 ++ ++/* L2CC */ ++#define L2CC_PA_BASE 0x90F00000 /* reserved */ ++#define L2CC_VA_BASE 0xF90F0000 /* FIXME */ ++ ++#define LED_PA_COUNT 1 ++#define LED_PA_BASE 0x902FF000 ++#define LED_PA_LIMIT 0x90200FFF ++#define LED_PA_SIZE 0x00001000 ++#define LED_0_PA_BASE 0x90200000 ++#define LED_0_PA_LIMIT 0x90200FFF ++#define LED_0_PA_SIZE 0x00001000 ++#define LED_VA_COUNT 1 ++#define LED_VA_BASE 0xF9020000 ++#define LED_VA_LIMIT 0xF9020000 ++#define LED_VA_SIZE 0x00001000 ++#define LED_0_VA_BASE 0xF9020000 ++#define LED_0_VA_LIMIT 0xF9020000 ++#define LED_0_VA_SIZE 0x00001000 ++ ++/* MAC */ ++#define MAC_FTMAC100_PA_COUNT 1 ++#define MAC_FTMAC100_PA_BASE 0x90900000 ++#define MAC_FTMAC100_PA_LIMIT 0x90900FFF ++#define MAC_FTMAC100_PA_SIZE 0x00001000 ++#define MAC_FTMAC100_0_PA_BASE 0x90900000 ++#define MAC_FTMAC100_0_PA_LIMIT 0x90900FFF ++#define MAC_FTMAC100_0_PA_SIZE 0x00001000 ++#define MAC_FTMAC100_1_PA_BASE 0x92000000 ++#define MAC_FTMAC100_1_PA_LIMIT 0x92000FFF ++#define MAC_FTMAC100_1_PA_SIZE 0x00001000 ++#define MAC_FTMAC100_VA_COUNT 1 ++#define MAC_FTMAC100_VA_BASE 0xF9090000 ++#define MAC_FTMAC100_VA_LIMIT 0xF9090FFF ++#define MAC_FTMAC100_VA_SIZE 0x00001000 ++#define MAC_FTMAC100_0_VA_BASE 0xF9090000 ++#define MAC_FTMAC100_0_VA_LIMIT 0xF9090FFF ++#define MAC_FTMAC100_0_VA_SIZE 0x00001000 ++#define MAC_FTMAC100_1_VA_BASE 0xF9200000 ++#define MAC_FTMAC100_1_VA_LIMIT 0xF9200FFF ++#define MAC_FTMAC100_1_VA_SIZE 0x00001000 ++ ++/* LCD */ ++#define LCD_FTLCDC100_PA_COUNT 1 ++#define LCD_FTLCDC100_PA_BASE 0x90600000 ++#define LCD_FTLCDC100_PA_LIMIT 0x90600FFF ++#define LCD_FTLCDC100_PA_SIZE 0x00001000 ++#define LCD_FTLCDC100_0_PA_BASE 0x90600000 ++#define LCD_FTLCDC100_0_PA_LIMIT 0x90600FFF ++#define LCD_FTLCDC100_0_PA_SIZE 0x00001000 ++#define LCD_FTLCDC100_VA_COUNT 1 ++#define LCD_FTLCDC100_VA_BASE 0xF9060000 ++#define LCD_FTLCDC100_VA_LIMIT 0xF9060FFF ++#define LCD_FTLCDC100_VA_SIZE 0x00001000 ++#define LCD_FTLCDC100_0_VA_BASE 0xF9060000 ++#define LCD_FTLCDC100_0_VA_LIMIT 0xF9060FFF ++#define LCD_FTLCDC100_0_VA_SIZE 0x00001000 ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spec-ag102.h linux-3.4.110/arch/nds32/include/asm/spec-ag102.h +--- linux-3.4.110.orig/arch/nds32/include/asm/spec-ag102.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/spec-ag102.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,167 @@ ++#ifndef __NDS32_AG102_SPECIFICATION_H__ ++#define __NDS32_AG102_SPECIFICATION_H__ ++ ++#define UART0_PA_BASE 0x94200000 ++#define UART0_VA_BASE 0xF9420000 ++#define UART0_IRQ 10 ++#define UART1_PA_BASE 0x94600000 ++#define UART1_VA_BASE 0xF9460000 ++#define UART1_IRQ 11 ++#define AMIC_PA_BASE 0x90F00000 ++#define AMIC_VA_BASE 0xF90F0000 ++#define GMAC_PA_BASE 0x90B00000 ++#define GMAC_VA_BASE 0xF90B0000 ++#define APBBR_PA_BASE 0x90D00000 ++#define APBBR_VA_BASE 0xF90D0000 ++#define GMAC_IRQ 25 ++#define TIMER_PA_BASE 0x94900000 ++#define TIMER_VA_BASE 0xF9490000 ++#define L2CC_PA_BASE 0x90900000 ++#define L2CC_VA_BASE 0xF9090000 ++#define CFC_FTCFC010_0_PA_BASE 0x94000000 ++#define CFC_FTCFC010_0_VA_BASE 0xF9400000 ++#define SDC_FTSDC010_0_PA_BASE 0x94400000 ++#define SDC_FTSDC010_0_VA_BASE 0xF9440000 ++#define PCU_PA_BASE 0x94800000 ++#define PCU_VA_BASE 0xF9480000 ++#define PCIC_FTPCI100_0_PA_BASE 0x90000000 ++#define PCIC_FTPCI100_0_VA_BASE 0xF9000000 ++#define PCIC_FTPCI100_0_VA_LIMIT 0xF9000FFF ++#define PCIIO_PA_BASE 0x90001000 ++#define PCIIO_VA_BASE 0xF8901000 ++#define PCIIO_0_PA_BASE 0x90001000 ++#define PCIIO_0_VA_BASE 0xF8901000 ++#define PCIIO_VA_LIMIT 0xF89FFFFF ++#define LPC_IO_PA_BASE 0x90100000 ++#define LPC_IO_VA_BASE 0xF9010000 ++#define LPC_REG_PA_BASE 0x90200000 ++#define LPC_REG_VA_BASE 0xF9020000 ++#define LPC_IRQ 29 ++#define GPU_PA_BASE 0x90A00000 ++#define GPU_VA_BASE 0xFEA00000 ++#define IDE_FTIDE020_VA_BASE 0xF9070000 ++#define IDE_FTIDE020_PA_BASE 0x90700000 ++#define IDE_FTIDE020_IRQ 1 ++#define USB_FOTG2XX_0_PA_BASE 0x90800000 ++#define USB_FOTG2XX_0_VA_BASE 0xF9080000 ++#define USB_FOTG2XX_0_IRQ 26 ++#define DDR2C_PA_BASE 0x90500000 ++#define DDR2C_VA_BASE 0xF9050000 ++#define GPIO_VA_BASE 0xF94C0000 ++#define GPIO_PA_BASE 0x94C00000 ++ ++#define PLATFORM_LPC_IRQ_BASE 180 ++#define PLATFORM_LPC_IRQ_TOTALCOUNT 22 ++ ++/* DMAC */ ++#define DMAC_FTDMAC020_PA_COUNT 1 ++#define DMAC_FTDMAC020_PA_BASE 0x90600000 ++#define DMAC_FTDMAC020_PA_LIMIT 0x90600FFF ++#define DMAC_FTDMAC020_PA_SIZE 0x00001000 ++#define DMAC_FTDMAC020_0_PA_BASE 0x90600000 ++#define DMAC_FTDMAC020_0_PA_LIMIT 0x90600FFF ++#define DMAC_FTDMAC020_0_PA_SIZE 0x00001000 ++#define DMAC_FTDMAC020_VA_COUNT 1 ++#define DMAC_FTDMAC020_VA_BASE 0xF9060000 ++#define DMAC_FTDMAC020_VA_LIMIT 0xF9060FFF ++#define DMAC_FTDMAC020_VA_SIZE 0x00001000 ++#define DMAC_FTDMAC020_0_VA_BASE 0xF9060000 ++#define DMAC_FTDMAC020_0_VA_LIMIT 0xF9060FFF ++#define DMAC_FTDMAC020_0_VA_SIZE 0x00001000 ++ ++/* TIMER */ ++#define TIMER_FTTMR010_PA_COUNT 1 ++#define TIMER_FTTMR010_PA_BASE 0x94900000 ++#define TIMER_FTTMR010_PA_LIMIT 0x94900FFF ++#define TIMER_FTTMR010_PA_SIZE 0x00001000 ++#define TIMER_FTTMR010_0_PA_BASE 0x94900000 ++#define TIMER_FTTMR010_0_PA_LIMIT 0x94900FFF ++#define TIMER_FTTMR010_0_PA_SIZE 0x00001000 ++#define TIMER_FTTMR010_VA_COUNT 1 ++#define TIMER_FTTMR010_VA_BASE 0xF9490000 ++#define TIMER_FTTMR010_VA_LIMIT 0xF9490FFF ++#define TIMER_FTTMR010_VA_SIZE 0x00001000 ++#define TIMER_FTTMR010_0_VA_BASE 0xF9490000 ++#define TIMER_FTTMR010_0_VA_LIMIT 0xF9490FFF ++#define TIMER_FTTMR010_0_VA_SIZE 0x00001000 ++ ++/* WDT */ ++#define WDT_FTWDT010_PA_COUNT 1 ++#define WDT_FTWDT010_PA_BASE 0x94A00000 ++#define WDT_FTWDT010_PA_LIMIT 0x94A00FFF ++#define WDT_FTWDT010_PA_SIZE 0x00001000 ++#define WDT_FTWDT010_0_PA_BASE 0x94A00000 ++#define WDT_FTWDT010_0_PA_LIMIT 0x94A00FFF ++#define WDT_FTWDT010_0_PA_SIZE 0x00001000 ++#define WDT_FTWDT010_VA_COUNT 1 ++#define WDT_FTWDT010_VA_BASE 0xF94A0000 ++#define WDT_FTWDT010_VA_LIMIT 0xF94A0FFF ++#define WDT_FTWDT010_VA_SIZE 0x00001000 ++#define WDT_FTWDT010_0_VA_BASE 0xF94A0000 ++#define WDT_FTWDT010_0_VA_LIMIT 0xF94A0FFF ++#define WDT_FTWDT010_0_VA_SIZE 0x00001000 ++ ++/* RTC */ ++#define RTC_FTRTC010_PA_COUNT 1 ++#define RTC_FTRTC010_PA_BASE 0x94B00000 ++#define RTC_FTRTC010_PA_LIMIT 0x94B00FFF ++#define RTC_FTRTC010_PA_SIZE 0x00001000 ++#define RTC_FTRTC010_0_PA_BASE 0x94B00000 ++#define RTC_FTRTC010_0_PA_LIMIT 0x94B00FFF ++#define RTC_FTRTC010_0_PA_SIZE 0x00001000 ++#define RTC_FTRTC010_VA_COUNT 1 ++#define RTC_FTRTC010_VA_BASE 0xF94B0000 ++#define RTC_FTRTC010_VA_LIMIT 0xF94B0FFF ++#define RTC_FTRTC010_VA_SIZE 0x00001000 ++#define RTC_FTRTC010_0_VA_BASE 0xF94B0000 ++#define RTC_FTRTC010_0_VA_LIMIT 0xF94B0FFF ++#define RTC_FTRTC010_0_VA_SIZE 0x00001000 ++ ++/* GPIO */ ++#define GPIO_FTGPIO010_PA_COUNT 1 ++#define GPIO_FTGPIO010_PA_BASE 0x94C00000 ++#define GPIO_FTGPIO010_PA_LIMIT 0x94C00FFF ++#define GPIO_FTGPIO010_PA_SIZE 0x00001000 ++#define GPIO_FTGPIO010_0_PA_BASE 0x94C00000 ++#define GPIO_FTGPIO010_0_PA_LIMIT 0x94C00FFF ++#define GPIO_FTGPIO010_0_PA_SIZE 0x00001000 ++#define GPIO_FTGPIO010_VA_COUNT 1 ++#define GPIO_FTGPIO010_VA_BASE 0xF94C0000 ++#define GPIO_FTGPIO010_VA_LIMIT 0xF94C0FFF ++#define GPIO_FTGPIO010_VA_SIZE 0x00001000 ++#define GPIO_FTGPIO010_0_VA_BASE 0xF94C0000 ++#define GPIO_FTGPIO010_0_VA_LIMIT 0xF94C0FFF ++#define GPIO_FTGPIO010_0_VA_SIZE 0x00001000 ++ ++/* SSP */ ++#define SSP_FTSSP010_PA_BASE 0x94500000 ++#define SSP_FTSSP010_0_PA_BASE 0x94500000 ++#define SSP_FTSSP010_VA_BASE 0xF9450000 ++#define SSP_FTSSP010_0_VA_BASE 0xF9450000 ++ ++/* SPI */ ++#define SPI_FTSSP010_PA_BASE 0x94100000 ++#define SPI_FTSSP010_0_PA_BASE 0x94100000 ++#define SPI_FTSSP010_VA_BASE 0xF9410000 ++#define SPI_FTSSP010_0_VA_BASE 0xF9410000 ++ ++/* AHB Controller */ ++#define AHB_ATFAHBC020S_0_PA_BASE 0x90C00000 ++#define AHB_ATFAHBC020S_0_VA_BASE 0xF90C0000 ++ ++#define I2C_FTI2C010_PA_COUNT 1 ++#define I2C_FTI2C010_PA_BASE 0x94E00000 ++#define I2C_FTI2C010_PA_LIMIT 0x94E00FFF ++#define I2C_FTI2C010_PA_SIZE 0x00001000 ++#define I2C_FTI2C010_0_PA_BASE 0x94E00000 ++#define I2C_FTI2C010_0_PA_LIMIT 0x94E00FFF ++#define I2C_FTI2C010_0_PA_SIZE 0x00001000 ++#define I2C_FTI2C010_VA_COUNT 1 ++#define I2C_FTI2C010_VA_BASE 0xF94E0000 ++#define I2C_FTI2C010_VA_LIMIT 0xF94E0FFF ++#define I2C_FTI2C010_VA_SIZE 0x00001000 ++#define I2C_FTI2C010_0_VA_BASE 0xF94E0000 ++#define I2C_FTI2C010_0_VA_LIMIT 0xF94E0FFF ++#define I2C_FTI2C010_0_VA_SIZE 0x00001000 ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spec.h linux-3.4.110/arch/nds32/include/asm/spec.h +--- linux-3.4.110.orig/arch/nds32/include/asm/spec.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/spec.h 2016-04-07 10:20:50.914079941 +0200 +@@ -0,0 +1,510 @@ ++/* ++ * linux/arch/nds32/include/asm/spec.h ++ * ++ * AG101 Platform Independent Specification ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/14/2005 Created. ++ * 09/15/2005 Completed. ++ */ ++ ++#ifndef __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ ++#define __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ ++ ++#include ++#ifdef CONFIG_PLAT_AG102 ++#include ++#else ++#include ++#endif ++ ++/* ++ * Platform dependent specification ++ */ ++#define PLATFORM_NAME "Andes AG101" ++ ++/* ++ * Component counts ++ */ ++ ++/* INTC */ ++#define INTC_COUNT 2 ++#define INTC_FTINTC010_COUNT 2 ++/* TIMER */ ++#define TIMER_COUNT 1 ++#define TIMER_FTTMR010_COUNT 1 ++/* SSP */ ++#define SSP_COUNT 1 ++#define SSP_FTSSP010_COUNT 1 ++/* PMU */ ++#define PMU_COUNT 1 ++#define PMU_FTPMU010_COUNT 1 ++/* MAC */ ++#define MAC_COUNT 1 ++#define MAC_FTMAC100_COUNT 1 ++ ++/* SDC */ ++#define SDC_COUNT 1 ++#define SDC_FTSDC010_COUNT 1 ++/* AHBDMA */ ++#define AHBDMA_COUNT 1 ++/* APBDMA */ ++#define APBDMA_COUNT 1 ++/* RTC */ ++#define RTC_COUNT 1 ++#define RTC_FTRTC010_COUNT 1 ++/* WDT */ ++#define WDT_COUNT 1 ++#define WDT_FTWDT010_COUNT 1 ++/* GPIO */ ++#define GPIO_COUNT 1 ++#define GPIO_FTGPIO010_COUNT 1 ++/* CFC */ ++#define CFC_COUNT 1 ++#define CFC_FTCFC010_COUNT 1 ++/* LCD */ ++#define LCD_COUNT 1 ++#define LCD_FTLCDC100_COUNT 1 ++/* I2C */ ++#define I2C_COUNT 1 ++#define I2C_FTI2C010_COUNT 1 ++/* USB */ ++#define USB_COUNT 3 ++#define USB_FOTG2XX_COUNT 1 ++#define USB_FUSBH200_COUNT 1 ++#define USB_FUSB220_COUNT 1 ++/* DMAC */ ++#define DMAC_COUNT 1 ++#define DMAC_FTDMAC020_COUNT 1 ++/* KMI */ ++#define KMI_COUNT 2 ++#define KMI_FTKBC010_COUNT 2 ++/* PCI */ ++#define PCI_COUNT 1 ++/* PCIMEM */ ++#define PCIMEM_COUNT 1 ++/* PCIIO */ ++#define PCIIO_COUNT 1 ++/* PCIC */ ++#define PCIC_COUNT 1 ++#define PCIC_FTPCI100_COUNT 1 ++ ++/* ++ * Hierarchial Component IDs ++ */ ++ ++#define PLATFORM_AHBDMA_DMAC_FTDMAC020_ID 0 ++#define PLATFORM_APBDMA_APBBRG_FTAPBBRG020S_ID 0 ++ ++/* ++ * Number of interrupts ++ */ ++ ++#define PLATFORM_IRQ_TOTALCOUNT 32 ++#define PLATFORM_AHBDMA_IRQ_TOTALCOUNT 8 ++#define PLATFORM_APBDMA_IRQ_TOTALCOUNT 4 ++ ++#define PLATFORM_IRQ_BASE 0 ++#define PLATFORM_AHBDMA_IRQ_BASE 64 ++#define PLATFORM_APBDMA_IRQ_BASE 72 ++#define PLATFORM_PCI_IRQ_BASE 176 ++#define PLATFORM_INTERRUPTS 202 ++ ++/* ++ * IRQ trigger level and trigger mode ++ */ ++ ++#define PLATFORM_IRQ_TRIGGER_MODE 0x000EC880 ++#define PLATFORM_IRQ_TRIGGER_LEVEL 0x10000000 ++#define PLATFORM_AHBDMA_IRQ_TRIGGER_MODE 0x00000000 ++#define PLATFORM_AHBDMA_IRQ_TRIGGER_LEVEL 0xFFFFFFFF ++#define PLATFORM_APBDMA_IRQ_TRIGGER_MODE 0x00000000 ++#define PLATFORM_APBDMA_IRQ_TRIGGER_LEVEL 0xFFFFFFFF ++ ++/* ++ * Interrupt numbers of Hierarchical Architecture ++ */ ++ ++/* AHBDMA */ ++#define PLATFORM_AHBDMA_IRQ 21 ++ ++/* APBDMA */ ++#define PLATFORM_APBDMA_IRQ 24 ++ ++/* PCI */ ++#ifdef CONFIG_XC5_PCI ++#define PLATFORM_PCI_IRQ 10 ++#else ++#define PLATFORM_PCI_IRQ 28 ++#endif ++ ++ ++/* ++ * Interrrupt numbers ++ */ ++ ++/* TIMER */ ++#define TIMER_FTTMR010_IRQ_COUNT 3 ++#define TIMER_FTTMR010_IRQ0 19 ++#define TIMER_FTTMR010_0_IRQ0 19 ++#define TIMER_FTTMR010_IRQ1 14 ++#define TIMER_FTTMR010_0_IRQ1 14 ++#define TIMER_FTTMR010_IRQ2 15 ++#define TIMER_FTTMR010_0_IRQ2 15 ++ ++/* SSP */ ++#define SSP_FTSSP010_IRQ_COUNT 1 ++#define SSP_FTSSP010_IRQ 6 ++#define SSP_FTSSP010_0_IRQ 6 ++ ++/* MAC */ ++#define MAC_FTMAC100_IRQ_COUNT 1 ++#define MAC_FTMAC100_IRQ 25 ++#define MAC_FTMAC100_0_IRQ 25 ++#define MAC_FTMAC100_1_IRQ 133 ++ ++/* SDC */ ++#define SDC_FTSDC010_IRQ_COUNT 1 ++#define SDC_FTSDC010_IRQ 5 ++#define SDC_FTSDC010_0_IRQ 5 ++ ++/* RTC */ ++#define RTC_FTRTC010_IRQ_COUNT 2 ++#define RTC_FTRTC010_IRQ0 17 ++#define RTC_FTRTC010_0_IRQ0 17 ++#define RTC_FTRTC010_IRQ1 18 ++#define RTC_FTRTC010_0_IRQ1 18 ++ ++/* WDT */ ++#define WDT_FTWDT010_IRQ_COUNT 1 ++#define WDT_FTWDT010_IRQ 16 ++#define WDT_FTWDT010_0_IRQ 16 ++ ++/* GPIO */ ++#define GPIO_FTGPIO010_IRQ_COUNT 1 ++#define GPIO_FTGPIO010_IRQ 13 ++#define GPIO_FTGPIO010_0_IRQ 13 ++ ++/* CFC */ ++#define CFC_FTCFC010_IRQ_COUNT 2 ++#define CFC_FTCFC010_IRQ0 0 ++#define CFC_FTCFC010_0_IRQ0 0 ++#define CFC_FTCFC010_IRQ1 1 ++#define CFC_FTCFC010_0_IRQ1 1 ++ ++/* LCD */ ++#define LCD_FTLCDC100_IRQ_COUNT 1 ++#define LCD_FTLCDC100_IRQ 20 ++#define LCD_FTLCDC100_0_IRQ 20 ++ ++/* I2C */ ++#define I2C_FTI2C010_IRQ_COUNT 1 ++#define I2C_FTI2C010_IRQ 3 ++#define I2C_FTI2C010_0_IRQ 3 ++ ++/* USB */ ++#define USB_FUSBH200_IRQ_COUNT 1 ++#define USB_FUSBH200_IRQ 29 ++#define USB_FUSBH200_0_IRQ 29 ++#define USB_FUSB220_IRQ_COUNT 1 ++#define USB_FUSB220_IRQ 26 ++#define USB_FUSB220_0_IRQ 26 ++ ++/* DMAC */ ++#define DMAC_FTDMAC020_IRQ_COUNT 8 ++#define DMAC_FTDMAC020_IRQ0 64 ++#define DMAC_FTDMAC020_0_IRQ0 64 ++#define DMAC_FTDMAC020_IRQ1 65 ++#define DMAC_FTDMAC020_0_IRQ1 65 ++#define DMAC_FTDMAC020_IRQ2 66 ++#define DMAC_FTDMAC020_0_IRQ2 66 ++#define DMAC_FTDMAC020_IRQ3 67 ++#define DMAC_FTDMAC020_0_IRQ3 67 ++#define DMAC_FTDMAC020_IRQ4 68 ++#define DMAC_FTDMAC020_0_IRQ4 68 ++#define DMAC_FTDMAC020_IRQ5 69 ++#define DMAC_FTDMAC020_0_IRQ5 69 ++#define DMAC_FTDMAC020_IRQ6 70 ++#define DMAC_FTDMAC020_0_IRQ6 70 ++#define DMAC_FTDMAC020_IRQ7 71 ++#define DMAC_FTDMAC020_0_IRQ7 71 ++ ++/* APBBRG */ ++#define APBBRG_FTAPBBRG020S_IRQ_COUNT 4 ++#define APBBRG_FTAPBBRG020S_IRQ0 72 ++#define APBBRG_FTAPBBRG020S_0_IRQ0 72 ++#define APBBRG_FTAPBBRG020S_IRQ1 73 ++#define APBBRG_FTAPBBRG020S_0_IRQ1 73 ++#define APBBRG_FTAPBBRG020S_IRQ2 74 ++#define APBBRG_FTAPBBRG020S_0_IRQ2 74 ++#define APBBRG_FTAPBBRG020S_IRQ3 75 ++#define APBBRG_FTAPBBRG020S_0_IRQ3 75 ++#define APBBRG_FTAPBBRG020S_1_IRQ0 172 ++#define APBBRG_FTAPBBRG020S_1_IRQ1 173 ++#define APBBRG_FTAPBBRG020S_1_IRQ2 174 ++#define APBBRG_FTAPBBRG020S_1_IRQ3 175 ++ ++/* KMI */ ++#define KMI_FTKBC010_IRQ_COUNT 1 ++#define KMI_FTKBC010_IRQ 30 ++#define KMI_FTKBC010_0_IRQ 30 ++#define KMI_FTKBC010_1_IRQ 31 ++ ++/* PCIC */ ++#define PCIC_FTPCI100_IRQ_COUNT 4 ++#define PCIC_FTPCI100_IRQ0 176 ++#define PCIC_FTPCI100_0_IRQ0 176 ++#define PCIC_FTPCI100_IRQ1 177 ++#define PCIC_FTPCI100_0_IRQ1 177 ++#define PCIC_FTPCI100_IRQ2 178 ++#define PCIC_FTPCI100_0_IRQ2 178 ++#define PCIC_FTPCI100_IRQ3 179 ++#define PCIC_FTPCI100_0_IRQ3 179 ++ ++/* ++ * Base addresses ++ */ ++ ++/* CPU */ ++#define CPU_MEM_PA_BASE CONFIG_MEMORY_START ++ ++ ++/* INTC */ ++#define INTC_FTINTC010_PA_COUNT 1 ++#define INTC_FTINTC010_PA_BASE 0x98800000 ++#define INTC_FTINTC010_PA_LIMIT 0x98800FFF ++#define INTC_FTINTC010_PA_SIZE 0x00001000 ++#define INTC_FTINTC010_0_PA_BASE 0x98800000 ++#define INTC_FTINTC010_0_PA_LIMIT 0x98800FFF ++#define INTC_FTINTC010_0_PA_SIZE 0x00001000 ++#define INTC_FTINTC010_1_PA_BASE 0xB0800000 ++#define INTC_FTINTC010_1_PA_LIMIT 0xB0800FFF ++#define INTC_FTINTC010_1_PA_SIZE 0x00001000 ++#define INTC_FTINTC010_VA_COUNT 1 ++#define INTC_FTINTC010_VA_BASE 0xF9880000 ++#define INTC_FTINTC010_VA_LIMIT 0xF9880FFF ++#define INTC_FTINTC010_VA_SIZE 0x00001000 ++#define INTC_FTINTC010_0_VA_BASE 0xF9880000 ++#define INTC_FTINTC010_0_VA_LIMIT 0xF9880FFF ++#define INTC_FTINTC010_0_VA_SIZE 0x00001000 ++#define INTC_FTINTC010_1_VA_BASE 0xFB080000 ++#define INTC_FTINTC010_1_VA_LIMIT 0xFB080FFF ++#define INTC_FTINTC010_1_VA_SIZE 0x00001000 ++ ++/* PMU */ ++#define PMU_FTPMU010_PA_COUNT 1 ++#define PMU_FTPMU010_PA_BASE 0x98100000 ++#define PMU_FTPMU010_PA_LIMIT 0x98100FFF ++#define PMU_FTPMU010_PA_SIZE 0x00001000 ++#define PMU_FTPMU010_0_PA_BASE 0x98100000 ++#define PMU_FTPMU010_0_PA_LIMIT 0x98100FFF ++#define PMU_FTPMU010_0_PA_SIZE 0x00001000 ++#define PMU_FTPMU010_VA_COUNT 1 ++#define PMU_FTPMU010_VA_BASE 0xF9810000 ++#define PMU_FTPMU010_VA_LIMIT 0xF9810FFF ++#define PMU_FTPMU010_VA_SIZE 0x00001000 ++#define PMU_FTPMU010_0_VA_BASE 0xF9810000 ++#define PMU_FTPMU010_0_VA_LIMIT 0xF9810FFF ++#define PMU_FTPMU010_0_VA_SIZE 0x00001000 ++ ++/* USB */ ++#define USB_FUSBH200_PA_COUNT 1 ++#define USB_FUSBH200_PA_BASE 0x92000000 ++#define USB_FUSBH200_PA_LIMIT 0x92000FFF ++#define USB_FUSBH200_PA_SIZE 0x00001000 ++#define USB_FUSBH200_0_PA_BASE 0x92000000 ++#define USB_FUSBH200_0_PA_LIMIT 0x92000FFF ++#define USB_FUSBH200_0_PA_SIZE 0x00001000 ++#define USB_FUSBH200_VA_COUNT 1 ++#define USB_FUSBH200_VA_BASE 0xF9200000 ++#define USB_FUSBH200_VA_LIMIT 0xF9200FFF ++#define USB_FUSBH200_VA_SIZE 0x00001000 ++#define USB_FUSBH200_0_VA_BASE 0xF9200000 ++#define USB_FUSBH200_0_VA_LIMIT 0xF9200FFF ++#define USB_FUSBH200_0_VA_SIZE 0x00001000 ++#define USB_FUSB220_PA_COUNT 1 ++#define USB_FUSB220_PA_BASE 0x90B00000 ++#define USB_FUSB220_PA_LIMIT 0x90B00FFF ++#define USB_FUSB220_PA_SIZE 0x00001000 ++#define USB_FUSB220_0_PA_BASE 0x90B00000 ++#define USB_FUSB220_0_PA_LIMIT 0x90B00FFF ++#define USB_FUSB220_0_PA_SIZE 0x00001000 ++#define USB_FUSB220_VA_COUNT 1 ++#define USB_FUSB220_VA_BASE 0xF90B0000 ++#define USB_FUSB220_VA_LIMIT 0xF90B0FFF ++#define USB_FUSB220_VA_SIZE 0x00001000 ++#define USB_FUSB220_0_VA_BASE 0xF90B0000 ++#define USB_FUSB220_0_VA_LIMIT 0xF90B0FFF ++#define USB_FUSB220_0_VA_SIZE 0x00001000 ++ ++/* KMI */ ++#define KMI_FTKBC010_PA_COUNT 1 ++#define KMI_FTKBC010_PA_BASE 0x97200000 ++#define KMI_FTKBC010_PA_LIMIT 0x97200FFF ++#define KMI_FTKBC010_PA_SIZE 0x00001000 ++#define KMI_FTKBC010_0_PA_BASE 0x97200000 ++#define KMI_FTKBC010_0_PA_LIMIT 0x97200FFF ++#define KMI_FTKBC010_0_PA_SIZE 0x00001000 ++#define KMI_FTKBC010_1_PA_BASE 0x97300000 ++#define KMI_FTKBC010_1_PA_LIMIT 0x97300FFF ++#define KMI_FTKBC010_1_PA_SIZE 0x00001000 ++#define KMI_FTKBC010_VA_COUNT 1 ++#define KMI_FTKBC010_VA_BASE 0xF9720000 ++#define KMI_FTKBC010_VA_LIMIT 0xF9720FFF ++#define KMI_FTKBC010_VA_SIZE 0x00001000 ++#define KMI_FTKBC010_0_VA_BASE 0xF9720000 ++#define KMI_FTKBC010_0_VA_LIMIT 0xF9720FFF ++#define KMI_FTKBC010_0_VA_SIZE 0x00001000 ++#define KMI_FTKBC010_1_VA_BASE 0xF9730000 ++#define KMI_FTKBC010_1_VA_LIMIT 0xF9730FFF ++#define KMI_FTKBC010_1_VA_SIZE 0x00001000 ++ ++/* PCIMEM */ ++#define PCIMEM_PA_COUNT 1 ++#define PCIMEM_PA_BASE 0xA0000000 ++#define PCIMEM_PA_LIMIT 0xAFFFFFFF ++#define PCIMEM_PA_SIZE 0x10000000 ++#define PCIMEM_0_PA_BASE 0xA0000000 ++#define PCIMEM_0_PA_LIMIT 0xAFFFFFFF ++#define PCIMEM_0_PA_SIZE 0x10000000 ++ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA_MODULE ++#define CONFIG_PLATFORM_AHBDMA ++#endif ++ ++#ifdef CONFIG_PLATFORM_APBDMA_MODULE ++#define CONFIG_PLATFORM_APBDMA ++#endif ++ ++#include /* Manual defined spec */ ++ ++/* ++ * Platform independent specification ++ */ ++ ++#define NR_IRQS PLATFORM_INTERRUPTS ++ ++#ifndef TIMER_CLK_IN ++#error Missing platform dependent symbol TIMER_CLK_IN in file. ++#endif ++ ++/* ++ * Macros for retrieving IP related information ++ */ ++#define IP_IDENTIFIER __glue(__glue(IPMODULE,_),__glue(IPNAME,_)) ++ ++#define IP_COUNT __glue(IP_IDENTIFIER,COUNT) ++ ++#define IP_IRQ_COUNT __glue(IP_IDENTIFIER,IRQ_COUNT) ++#define IP_IRQ(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ) ++#define IP_irq __glue(IP_IDENTIFIER,irq) ++ ++#define IP_PA_COUNT __glue(IP_IDENTIFIER,PA_COUNT) ++#define IP_PA_BASE(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE) ++#define IP_PA_LIMIT(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT) ++#define IP_PA_SIZE(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE) ++#define IP_pa_base __glue(IP_IDENTIFIER,pa_base) ++#define IP_pa_limit __glue(IP_IDENTIFIER,pa_limit) ++#define IP_pa_size __glue(IP_IDENTIFIER,pa_size) ++ ++#define IP_VA_COUNT __glue(IP_IDENTIFIER,VA_COUNT) ++#define IP_VA_BASE(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE) ++#define IP_VA_LIMIT(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT) ++#define IP_VA_SIZE(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE) ++#define IP_va_base __glue(IP_IDENTIFIER,va_base) ++#define IP_va_limit __glue(IP_IDENTIFIER,va_limit) ++#define IP_va_size __glue(IP_IDENTIFIER,va_size) ++ ++/* ++ * Facility macros ++ */ ++/* IRQ0~7 */ ++#define IP_IRQ0(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ0) ++#define IP_IRQ1(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ1) ++#define IP_IRQ2(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ2) ++#define IP_IRQ3(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ3) ++#define IP_IRQ4(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ4) ++#define IP_IRQ5(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ5) ++#define IP_IRQ6(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ6) ++#define IP_IRQ7(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ7) ++ ++/* PA_BASE0~7 */ ++#define IP_PA_BASE0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE0) ++#define IP_PA_BASE1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE1) ++#define IP_PA_BASE2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE2) ++#define IP_PA_BASE3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE3) ++#define IP_PA_BASE4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE4) ++#define IP_PA_BASE5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE5) ++#define IP_PA_BASE6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE6) ++#define IP_PA_BASE7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE7) ++ ++/* PA_LIMIT0~7 */ ++#define IP_PA_LIMIT0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT0) ++#define IP_PA_LIMIT1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT1) ++#define IP_PA_LIMIT2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT2) ++#define IP_PA_LIMIT3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT3) ++#define IP_PA_LIMIT4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT4) ++#define IP_PA_LIMIT5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT5) ++#define IP_PA_LIMIT6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT6) ++#define IP_PA_LIMIT7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT7) ++ ++/* PA_SIZE0~7 */ ++#define IP_PA_SIZE0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE0) ++#define IP_PA_SIZE1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE1) ++#define IP_PA_SIZE2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE2) ++#define IP_PA_SIZE3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE3) ++#define IP_PA_SIZE4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE4) ++#define IP_PA_SIZE5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE5) ++#define IP_PA_SIZE6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE6) ++#define IP_PA_SIZE7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE7) ++ ++/* VA_BASE0~7 */ ++#define IP_VA_BASE0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE0) ++#define IP_VA_BASE1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE1) ++#define IP_VA_BASE2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE2) ++#define IP_VA_BASE3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE3) ++#define IP_VA_BASE4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE4) ++#define IP_VA_BASE5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE5) ++#define IP_VA_BASE6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE6) ++#define IP_VA_BASE7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE7) ++ ++/* VA_LIMIT0~7 */ ++#define IP_VA_LIMIT0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT0) ++#define IP_VA_LIMIT1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT1) ++#define IP_VA_LIMIT2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT2) ++#define IP_VA_LIMIT3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT3) ++#define IP_VA_LIMIT4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT4) ++#define IP_VA_LIMIT5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT5) ++#define IP_VA_LIMIT6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT6) ++#define IP_VA_LIMIT7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT7) ++ ++/* VA_SIZE0~7 */ ++#define IP_VA_SIZE0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE0) ++#define IP_VA_SIZE1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE1) ++#define IP_VA_SIZE2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE2) ++#define IP_VA_SIZE3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE3) ++#define IP_VA_SIZE4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE4) ++#define IP_VA_SIZE5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE5) ++#define IP_VA_SIZE6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE6) ++#define IP_VA_SIZE7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE7) ++ ++#endif /* __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spinlock.h linux-3.4.110/arch/nds32/include/asm/spinlock.h +--- linux-3.4.110.orig/arch/nds32/include/asm/spinlock.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/spinlock.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,183 @@ ++/* ++ * linux/arch/nds32/include/asm/spinlock.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_SPINLOCK_H ++#define __ASM_SPINLOCK_H ++ ++#include ++ ++#define arch_spin_is_locked(x) ((x)->lock != 0) ++ ++#define arch_spin_unlock_wait(lock) \ ++ do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) ++ ++#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) ++ ++static inline void arch_spin_lock(arch_spinlock_t *lock) ++{ ++ unsigned long tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tbnez\t%0, 1b\n" ++ "\tmovi\t%0, #0x1\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (&lock->lock) ++ : "memory"); ++} ++ ++static inline int arch_spin_trylock(arch_spinlock_t *lock) ++{ ++ unsigned long ret, tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%2+$r15]\n" ++ "\tmovi\t%1, #0x1\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ : "=&r" (ret), "=&r" (tmp) ++ : "r" (&lock->lock) ++ : "memory"); ++ ++ return ret == 0; ++} ++ ++static inline void arch_spin_unlock(arch_spinlock_t *lock) ++{ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "\tswi\t$r15, [%0]\n" ++ : ++ : "r" (&lock->lock) ++ : "memory"); ++} ++ ++static inline void arch_write_lock(arch_rwlock_t *rw) ++{ ++ unsigned long tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tbnez\t%0, 1b\n" ++ "\tsethi\t%0, 0x80000\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (&rw->lock) ++ : "memory"); ++} ++ ++static inline void arch_write_unlock(arch_rwlock_t *rw) ++{ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "\tswi\t$r15, [%0]\n" ++ : ++ : "r" (&rw->lock) ++ : "memory"); ++} ++ ++#define arch_write_can_lock(x) ((x)->lock == 0) ++static inline void arch_read_lock(arch_rwlock_t *rw) ++{ ++ int tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\tbltz\t%0, 1b\n" ++ "\taddi\t%0, %0, #1\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (&rw->lock) ++ : "memory"); ++} ++ ++static inline void arch_read_unlock(arch_rwlock_t *rw) ++{ ++ unsigned long tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "1:\n" ++ "\tllw\t%0, [%1+$r15]\n" ++ "\taddi\t%0, %0, #-1\n" ++ "\tscw\t%0, [%1+$r15]\n" ++ "\tbeqz\t%0, 1b\n" ++ : "=&r" (tmp) ++ : "r" (&rw->lock) ++ : "memory"); ++} ++ ++static inline int arch_read_trylock(arch_rwlock_t *rw) ++{ ++ unsigned long ret, tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "\tmovi\t%0, #0x0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\tbltz\t%1, 2f\n" ++ "\taddi\t%1, %1, #1\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ "\tmovi\t%0, #0x1\n" ++ "\tj\t3f\n" ++ "2:\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "3:\n" ++ : "=&r" (ret), "=&r" (tmp) ++ : "r" (&rw->lock) ++ : "memory"); ++ ++ return ret; ++} ++ ++static inline int arch_write_trylock(arch_rwlock_t *rw) ++{ ++ unsigned long ret, tmp; ++ ++ __asm__ __volatile__( ++ "xor\t$r15, $r15, $r15\n" ++ "\tmovi\t%0, #0x0\n" ++ "1:\n" ++ "\tllw\t%1, [%2+$r15]\n" ++ "\tbnez\t%1, 2f\n" ++ "\tsethi\t%1, 0x80000\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "\tbeqz\t%1, 1b\n" ++ "\tmovi\t%0, #0x1\n" ++ "\tj\t3f\n" ++ "2:\n" ++ "\tscw\t%1, [%2+$r15]\n" ++ "3:\n" ++ : "=&r" (ret), "=&r" (tmp) ++ : "r" (&rw->lock) ++ : "memory"); ++ ++ return ret; ++} ++ ++#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) ++#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) ++ ++#define arch_read_can_lock(x) ((x)->lock < 0x80000000) ++ ++#define arch_spin_relax(lock) cpu_relax() ++#define arch_read_relax(lock) cpu_relax() ++#define arch_write_relax(lock) cpu_relax() ++ ++#endif /* __ASM_SPINLOCK_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/spinlock_types.h linux-3.4.110/arch/nds32/include/asm/spinlock_types.h +--- linux-3.4.110.orig/arch/nds32/include/asm/spinlock_types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/spinlock_types.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * linux/arch/nds32/include/asm/spinlock_types.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASM_SPINLOCK_TYPES_H ++#define _ASM_SPINLOCK_TYPES_H ++ ++#ifndef __LINUX_SPINLOCK_TYPES_H ++# error "please don't include this file directly" ++#endif ++ ++typedef struct { ++ volatile unsigned int lock; ++} arch_spinlock_t; ++ ++#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } ++ ++typedef struct { ++ volatile unsigned int lock; ++} arch_rwlock_t; ++ ++#define __ARCH_RW_LOCK_UNLOCKED { 0 } ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/statfs.h linux-3.4.110/arch/nds32/include/asm/statfs.h +--- linux-3.4.110.orig/arch/nds32/include/asm/statfs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/statfs.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/statfs.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_STATFS_H ++#define _ASMNDS32_STATFS_H ++ ++#include ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/stat.h linux-3.4.110/arch/nds32/include/asm/stat.h +--- linux-3.4.110.orig/arch/nds32/include/asm/stat.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/stat.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,101 @@ ++/* ++ * linux/arch/nds32/include/asm/stat.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_STAT_H ++#define _ASMNDS32_STAT_H ++ ++struct __old_kernel_stat { ++ unsigned short st_dev; ++ unsigned short st_ino; ++ unsigned short st_mode; ++ unsigned short st_nlink; ++ unsigned short st_uid; ++ unsigned short st_gid; ++ unsigned short st_rdev; ++ unsigned long st_size; ++ unsigned long st_atime; ++ unsigned long st_mtime; ++ unsigned long st_ctime; ++}; ++ ++#define STAT_HAVE_NSEC ++ ++struct stat { ++#if defined(__NDS32_EB__) ++ unsigned short st_dev; ++ unsigned short __pad1; ++#else ++ unsigned long st_dev; ++#endif ++ unsigned long st_ino; ++ unsigned short st_mode; ++ unsigned short st_nlink; ++ unsigned short st_uid; ++ unsigned short st_gid; ++#if defined(__NDS32_EB__) ++ unsigned short st_rdev; ++ unsigned short __pad2; ++#else ++ unsigned long st_rdev; ++#endif ++ unsigned long st_size; ++ unsigned long st_blksize; ++ unsigned long st_blocks; ++ unsigned long st_atime; ++ unsigned long st_atime_nsec; ++ unsigned long st_mtime; ++ unsigned long st_mtime_nsec; ++ unsigned long st_ctime; ++ unsigned long st_ctime_nsec; ++ unsigned long __unused4; ++ unsigned long __unused5; ++}; ++ ++/* This matches struct stat64 in glibc2.1, hence the absolutely ++ * insane amounts of padding around dev_t's. ++ * Note: The kernel zero's the padded region because glibc might read them ++ * in the hope that the kernel has stretched to using larger sizes. ++ */ ++ ++struct stat64 { ++ unsigned long long st_dev; ++ unsigned long __pad0; ++ ++#define STAT64_HAS_BROKEN_ST_INO 1 ++ unsigned long __st_ino; ++ unsigned int st_mode; ++ unsigned int st_nlink; ++ ++ unsigned long st_uid; ++ unsigned long st_gid; ++ ++ unsigned long long st_rdev; ++ unsigned int __pad3; ++ ++ unsigned long long st_size; ++ unsigned long st_blksize; ++ ++//#if defined(__NDS32EB__) ++// unsigned long __pad4; // Future possible st_blocks hi bits ++ unsigned long long st_blocks; // Number 512-byte blocks allocated. ++//#else // Must be little ++// unsigned long st_blocks; // Number 512-byte blocks allocated. ++// unsigned long __pad4; // Future possible st_blocks hi bits ++//#endif ++ ++ unsigned long st_atime; ++ unsigned long st_atime_nsec; ++ ++ unsigned long st_mtime; ++ unsigned long st_mtime_nsec; ++ ++ unsigned long st_ctime; ++ unsigned long st_ctime_nsec; ++ ++ unsigned long long st_ino; ++}; ++ ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/string.h linux-3.4.110/arch/nds32/include/asm/string.h +--- linux-3.4.110.orig/arch/nds32/include/asm/string.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/string.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * linux/arch/nds32/include/asm/string.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_STRING_H ++#define __ASM_NDS32_STRING_H ++ ++/* ++ * We don't do inline string functions, since the ++ * optimised inline asm versions are not small. ++ */ ++ ++#define __HAVE_ARCH_STRRCHR ++extern char * strrchr(const char * s, int c); ++ ++#define __HAVE_ARCH_STRCHR ++extern char * strchr(const char * s, int c); ++ ++#define __HAVE_ARCH_MEMCPY ++extern void * memcpy(void *, const void *, __kernel_size_t); ++ ++#define __HAVE_ARCH_MEMMOVE ++extern void * memmove(void *, const void *, __kernel_size_t); ++ ++#define __HAVE_ARCH_MEMZERO ++#define __HAVE_ARCH_MEMSET ++extern void * memset(void *, int, __kernel_size_t); ++ ++extern void __memzero(void *ptr, __kernel_size_t n); ++ ++#define memset(p,v,n) \ ++ ({ \ ++ if ((n) != 0) { \ ++ if (__builtin_constant_p((v)) && (v) == 0) \ ++ __memzero((p),(n)); \ ++ else \ ++ memset((p),(v),(n)); \ ++ } \ ++ (p); \ ++ }) ++ ++#define memzero(p,n) ({ if ((n) != 0) __memzero((p),(n)); (p); }) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/suspend.h linux-3.4.110/arch/nds32/include/asm/suspend.h +--- linux-3.4.110.orig/arch/nds32/include/asm/suspend.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/suspend.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,9 @@ ++/* ++ * linux/arch/nds32/include/asm/suspend.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_SUSPEND_H ++#define _ASMNDS32_SUSPEND_H ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/swab.h linux-3.4.110/arch/nds32/include/asm/swab.h +--- linux-3.4.110.orig/arch/nds32/include/asm/swab.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/swab.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,34 @@ ++/* ++ * include/asm/byteorder.h ++ * Copyright (C) 2008 Andes Technology, Inc. ++ */ ++ ++#ifndef __NDS32_SWAB_H__ ++#define __NDS32_SWAB_H__ ++ ++#include ++#include ++ ++static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) ++{ ++ __asm__("wsbh %0, %0\n\t" /* word swap byte within halfword */ ++ "rotri %0, %0, #16\n" ++ : "=r" (x) : "0" (x)); ++ return x; ++} ++ ++static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) ++{ ++ __asm__("wsbh %0, %0\n" /* word swap byte within halfword */ ++ : "=r" (x) : "0" (x)); ++ return x; ++} ++#define __arch_swab32(x) ___arch__swab32(x) ++#define __arch_swab16(x) ___arch__swab16(x) ++ ++#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) ++# define __BYTEORDER_HAS_U64__ ++# define __SWAB_64_THRU_32__ ++#endif ++ ++#endif /* __NDS32_SWAB_H__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/switch_to.h linux-3.4.110/arch/nds32/include/asm/switch_to.h +--- linux-3.4.110.orig/arch/nds32/include/asm/switch_to.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/switch_to.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,18 @@ ++#ifndef __ASM_NDS32_SWITCH_TO_H ++#define __ASM_NDS32_SWITCH_TO_H ++ ++#include ++ ++/* ++ * switch_to(prev, next) should switch from task `prev' to `next' ++ * `prev' will never be the same as `next'. schedule() itself ++ * contains the memory barrier to tell GCC not to cache `current'. ++ */ ++extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); ++ ++#define switch_to( prev, next, last) \ ++do { \ ++ last = __switch_to( prev, task_thread_info( prev), task_thread_info( next)); \ ++} while (0) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/system.h linux-3.4.110/arch/nds32/include/asm/system.h +--- linux-3.4.110.orig/arch/nds32/include/asm/system.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/system.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,4 @@ ++/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */ ++#include ++#include ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/termbits.h linux-3.4.110/arch/nds32/include/asm/termbits.h +--- linux-3.4.110.orig/arch/nds32/include/asm/termbits.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/termbits.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,198 @@ ++#ifndef __ASM_NDS32_TERMBITS_H ++#define __ASM_NDS32_TERMBITS_H ++ ++typedef unsigned char cc_t; ++typedef unsigned int speed_t; ++typedef unsigned int tcflag_t; ++ ++#define NCCS 19 ++struct termios { ++ tcflag_t c_iflag; /* input mode flags */ ++ tcflag_t c_oflag; /* output mode flags */ ++ tcflag_t c_cflag; /* control mode flags */ ++ tcflag_t c_lflag; /* local mode flags */ ++ cc_t c_line; /* line discipline */ ++ cc_t c_cc[NCCS]; /* control characters */ ++}; ++ ++struct termios2 { ++ tcflag_t c_iflag; /* input mode flags */ ++ tcflag_t c_oflag; /* output mode flags */ ++ tcflag_t c_cflag; /* control mode flags */ ++ tcflag_t c_lflag; /* local mode flags */ ++ cc_t c_line; /* line discipline */ ++ cc_t c_cc[NCCS]; /* control characters */ ++ speed_t c_ispeed; /* input speed */ ++ speed_t c_ospeed; /* output speed */ ++}; ++ ++struct ktermios { ++ tcflag_t c_iflag; /* input mode flags */ ++ tcflag_t c_oflag; /* output mode flags */ ++ tcflag_t c_cflag; /* control mode flags */ ++ tcflag_t c_lflag; /* local mode flags */ ++ cc_t c_line; /* line discipline */ ++ cc_t c_cc[NCCS]; /* control characters */ ++ speed_t c_ispeed; /* input speed */ ++ speed_t c_ospeed; /* output speed */ ++}; ++ ++ ++/* c_cc characters */ ++#define VINTR 0 ++#define VQUIT 1 ++#define VERASE 2 ++#define VKILL 3 ++#define VEOF 4 ++#define VTIME 5 ++#define VMIN 6 ++#define VSWTC 7 ++#define VSTART 8 ++#define VSTOP 9 ++#define VSUSP 10 ++#define VEOL 11 ++#define VREPRINT 12 ++#define VDISCARD 13 ++#define VWERASE 14 ++#define VLNEXT 15 ++#define VEOL2 16 ++ ++/* c_iflag bits */ ++#define IGNBRK 0000001 ++#define BRKINT 0000002 ++#define IGNPAR 0000004 ++#define PARMRK 0000010 ++#define INPCK 0000020 ++#define ISTRIP 0000040 ++#define INLCR 0000100 ++#define IGNCR 0000200 ++#define ICRNL 0000400 ++#define IUCLC 0001000 ++#define IXON 0002000 ++#define IXANY 0004000 ++#define IXOFF 0010000 ++#define IMAXBEL 0020000 ++#define IUTF8 0040000 ++ ++/* c_oflag bits */ ++#define OPOST 0000001 ++#define OLCUC 0000002 ++#define ONLCR 0000004 ++#define OCRNL 0000010 ++#define ONOCR 0000020 ++#define ONLRET 0000040 ++#define OFILL 0000100 ++#define OFDEL 0000200 ++#define NLDLY 0000400 ++#define NL0 0000000 ++#define NL1 0000400 ++#define CRDLY 0003000 ++#define CR0 0000000 ++#define CR1 0001000 ++#define CR2 0002000 ++#define CR3 0003000 ++#define TABDLY 0014000 ++#define TAB0 0000000 ++#define TAB1 0004000 ++#define TAB2 0010000 ++#define TAB3 0014000 ++#define XTABS 0014000 ++#define BSDLY 0020000 ++#define BS0 0000000 ++#define BS1 0020000 ++#define VTDLY 0040000 ++#define VT0 0000000 ++#define VT1 0040000 ++#define FFDLY 0100000 ++#define FF0 0000000 ++#define FF1 0100000 ++ ++/* c_cflag bit meaning */ ++#define CBAUD 0010017 ++#define B0 0000000 /* hang up */ ++#define B50 0000001 ++#define B75 0000002 ++#define B110 0000003 ++#define B134 0000004 ++#define B150 0000005 ++#define B200 0000006 ++#define B300 0000007 ++#define B600 0000010 ++#define B1200 0000011 ++#define B1800 0000012 ++#define B2400 0000013 ++#define B4800 0000014 ++#define B9600 0000015 ++#define B19200 0000016 ++#define B38400 0000017 ++#define EXTA B19200 ++#define EXTB B38400 ++#define CSIZE 0000060 ++#define CS5 0000000 ++#define CS6 0000020 ++#define CS7 0000040 ++#define CS8 0000060 ++#define CSTOPB 0000100 ++#define CREAD 0000200 ++#define PARENB 0000400 ++#define PARODD 0001000 ++#define HUPCL 0002000 ++#define CLOCAL 0004000 ++#define CBAUDEX 0010000 ++#define BOTHER 0010000 ++#define B57600 0010001 ++#define B115200 0010002 ++#define B230400 0010003 ++#define B460800 0010004 ++#define B500000 0010005 ++#define B576000 0010006 ++#define B921600 0010007 ++#define B1000000 0010010 ++#define B1152000 0010011 ++#define B1500000 0010012 ++#define B2000000 0010013 ++#define B2500000 0010014 ++#define B3000000 0010015 ++#define B3500000 0010016 ++#define B4000000 0010017 ++#define CIBAUD 002003600000 /* input baud rate */ ++#define CMSPAR 010000000000 /* mark or space (stick) parity */ ++#define CRTSCTS 020000000000 /* flow control */ ++ ++#define IBSHIFT 16 ++ ++/* c_lflag bits */ ++#define ISIG 0000001 ++#define ICANON 0000002 ++#define XCASE 0000004 ++#define ECHO 0000010 ++#define ECHOE 0000020 ++#define ECHOK 0000040 ++#define ECHONL 0000100 ++#define NOFLSH 0000200 ++#define TOSTOP 0000400 ++#define ECHOCTL 0001000 ++#define ECHOPRT 0002000 ++#define ECHOKE 0004000 ++#define FLUSHO 0010000 ++#define PENDIN 0040000 ++#define IEXTEN 0100000 ++#define EXTPROC 0200000 ++ ++/* tcflow() and TCXONC use these */ ++#define TCOOFF 0 ++#define TCOON 1 ++#define TCIOFF 2 ++#define TCION 3 ++ ++/* tcflush() and TCFLSH use these */ ++#define TCIFLUSH 0 ++#define TCOFLUSH 1 ++#define TCIOFLUSH 2 ++ ++/* tcsetattr uses these */ ++#define TCSANOW 0 ++#define TCSADRAIN 1 ++#define TCSAFLUSH 2 ++ ++#endif /* __ASM_NDS32_TERMBITS_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/termios.h linux-3.4.110/arch/nds32/include/asm/termios.h +--- linux-3.4.110.orig/arch/nds32/include/asm/termios.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/termios.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,116 @@ ++/* ++ * linux/arch/nds32/include/asm/termios.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_TERMIOS_H ++#define __ASM_NDS32_TERMIOS_H ++ ++#include ++#include ++ ++struct winsize { ++ unsigned short ws_row; ++ unsigned short ws_col; ++ unsigned short ws_xpixel; ++ unsigned short ws_ypixel; ++}; ++ ++#define NCC 8 ++struct termio { ++ unsigned short c_iflag; /* input mode flags */ ++ unsigned short c_oflag; /* output mode flags */ ++ unsigned short c_cflag; /* control mode flags */ ++ unsigned short c_lflag; /* local mode flags */ ++ unsigned char c_line; /* line discipline */ ++ unsigned char c_cc[NCC]; /* control characters */ ++}; ++ ++#ifdef __KERNEL__ ++/* intr=^C quit=^| erase=del kill=^U ++ eof=^D vtime=\0 vmin=\1 sxtc=\0 ++ start=^Q stop=^S susp=^Z eol=\0 ++ reprint=^R discard=^U werase=^W lnext=^V ++ eol2=\0 ++*/ ++#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" ++#endif ++ ++/* modem lines */ ++#define TIOCM_LE 0x001 ++#define TIOCM_DTR 0x002 ++#define TIOCM_RTS 0x004 ++#define TIOCM_ST 0x008 ++#define TIOCM_SR 0x010 ++#define TIOCM_CTS 0x020 ++#define TIOCM_CAR 0x040 ++#define TIOCM_RNG 0x080 ++#define TIOCM_DSR 0x100 ++#define TIOCM_CD TIOCM_CAR ++#define TIOCM_RI TIOCM_RNG ++#define TIOCM_OUT1 0x2000 ++#define TIOCM_OUT2 0x4000 ++#define TIOCM_LOOP 0x8000 ++ ++/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ ++ ++/* line disciplines */ ++#define N_TTY 0 ++#define N_SLIP 1 ++#define N_MOUSE 2 ++#define N_PPP 3 ++#define N_STRIP 4 ++#define N_AX25 5 ++#define N_X25 6 /* X.25 async */ ++#define N_6PACK 7 ++#define N_MASC 8 /* Reserved for Mobitex module */ ++#define N_R3964 9 /* Reserved for Simatic R3964 module */ ++#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ ++#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ ++#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ ++#define N_HDLC 13 /* synchronous HDLC */ ++#define N_SYNC_PPP 14 ++#define N_HCI 15 /* Bluetooth HCI UART */ ++ ++#ifdef __KERNEL__ ++ ++/* ++ * Translate a "termio" structure into a "termios". Ugh. ++ */ ++#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ ++ unsigned short __tmp; \ ++ get_user(__tmp,&(termio)->x); \ ++ *(unsigned short *) &(termios)->x = __tmp; \ ++} ++ ++#define user_termio_to_kernel_termios(termios, termio) \ ++({ \ ++ SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ ++ SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ ++ SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ ++ SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ ++ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ ++}) ++ ++/* ++ * Translate a "termios" structure into a "termio". Ugh. ++ */ ++#define kernel_termios_to_user_termio(termio, termios) \ ++({ \ ++ put_user((termios)->c_iflag, &(termio)->c_iflag); \ ++ put_user((termios)->c_oflag, &(termio)->c_oflag); \ ++ put_user((termios)->c_cflag, &(termio)->c_cflag); \ ++ put_user((termios)->c_lflag, &(termio)->c_lflag); \ ++ put_user((termios)->c_line, &(termio)->c_line); \ ++ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ ++}) ++ ++#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) ++#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) ++ ++#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) ++#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* __ASM_NDS32_TERMIOS_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/thread_info.h linux-3.4.110/arch/nds32/include/asm/thread_info.h +--- linux-3.4.110.orig/arch/nds32/include/asm/thread_info.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/thread_info.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,145 @@ ++/* ++ * linux/arch/nds32/include/asm/thread_info.h ++ * ++ * Copyright (C) 2002 Russell King. ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef __ASM_NDS32_THREAD_INFO_H ++#define __ASM_NDS32_THREAD_INFO_H ++ ++#ifdef __KERNEL__ ++ ++#define THREAD_SHIFT (13) ++#define THREAD_SIZE (1 << THREAD_SHIFT) ++ ++#ifndef __ASSEMBLY__ ++ ++struct task_struct; ++struct exec_domain; ++ ++#include ++#include ++ ++ ++typedef struct { ++ unsigned long seg; ++} mm_segment_t; ++//typedef unsigned long mm_segment_t; ++ ++struct cpu_context_save { ++ unsigned long r6; ++ unsigned long r7; ++ unsigned long r8; ++ unsigned long r9; ++ unsigned long r10; ++ unsigned long r11; ++ unsigned long r12; ++ unsigned long r13; ++ unsigned long r14; ++ unsigned long fp; ++ unsigned long pc; ++}; ++ ++/* ++ * low level task data that entry.S needs immediate access to. ++ * __switch_to() assumes cpu_context follows immediately after cpu_domain. ++ */ ++struct thread_info { ++ unsigned long flags; /* low level flags */ ++ __s32 preempt_count; /* 0 => preemptable, <0 => bug */ ++ mm_segment_t addr_limit; /* address limit */ ++ struct task_struct *task; /* main task structure */ ++ struct exec_domain *exec_domain; /* execution domain */ ++ __u32 cpu; /* cpu */ ++ struct cpu_context_save* sp_save; /* cpu context */ ++ struct restart_block restart_block; ++}; ++ ++#define INIT_THREAD_INFO(tsk) \ ++{ \ ++ .task = &tsk, \ ++ .exec_domain = &default_exec_domain, \ ++ .flags = 0, \ ++ .cpu = 0, \ ++ .preempt_count = 1, \ ++ .addr_limit = KERNEL_DS, \ ++ .restart_block = { \ ++ .fn = do_no_restart_syscall, \ ++ }, \ ++} ++ ++#define init_thread_info (init_thread_union.thread_info) ++#define init_stack (init_thread_union.stack) ++ ++ ++/* ++ * how to get the thread information struct from C ++ */ ++static inline struct thread_info *current_thread_info(void) __attribute_const__; ++ ++static inline struct thread_info *current_thread_info(void) ++{ ++ register unsigned long sp asm ("$sp"); //M Tom asm -> __asm__ __volatile__ ++ return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); ++} ++ ++#define get_thread_info(ti) get_task_struct((ti)->task) ++#define put_thread_info(ti) put_task_struct((ti)->task) ++ ++#define thread_saved_pc(tsk) \ ++ ((unsigned long)(task_thread_info(tsk)->sp_save->pc)) ++#define thread_saved_fp(tsk) \ ++ ((unsigned long)(task_thread_info(tsk)->sp_save->fp)) ++#endif ++ ++#define THREAD_SIZE_ORDER (1) ++/* ++ * We use bit 30 of the preempt_count to indicate that kernel ++ * preemption is occuring. See include/asm-arm/hardirq.h. ++ */ ++#define PREEMPT_ACTIVE 0x40000000 ++ ++/* ++ * thread information flags: ++ * TIF_SYSCALL_TRACE - syscall trace active ++ * TIF_NOTIFY_RESUME - resumption notification requested ++ * TIF_SIGPENDING - signal pending ++ * TIF_NEED_RESCHED - rescheduling necessary ++ * TIF_USEDFPU - FPU was used by this task this quantum (SMP) ++ * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED ++ * TIF_USEDAUDIO - Audio has been used by this task and no need to init the regs ++ */ ++#define TIF_SIGPENDING 1 ++#define TIF_NEED_RESCHED 2 ++#define TIF_SINGLESTEP 3 ++#define TIF_NOTIFY_RESUME 5 ++#define TIF_SYSCALL_TRACE 8 ++#define TIF_RESTORE_SIGMASK 9 ++#define TIF_USEDFPU 16 ++#define TIF_POLLING_NRFLAG 17 ++#define TIF_MEMDIE 18 ++#define TIF_FREEZE 19 ++#define TIF_USEDAUDIO 20 ++ ++#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) ++#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) ++#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) ++#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) ++#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) ++#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) ++#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) ++#define _TIF_FREEZE (1 << TIF_FREEZE) ++ ++/* ++ * Change these and you break ASM code in entry-common.S ++ */ ++#define _TIF_WORK_MASK 0x000000ff ++#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP) ++#define _TIF_WORK_SYSCALL_LEAVE (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP) ++ ++#endif /* __KERNEL__ */ ++#endif /* __ASM_NDS32_THREAD_INFO_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/timer.h linux-3.4.110/arch/nds32/include/asm/timer.h +--- linux-3.4.110.orig/arch/nds32/include/asm/timer.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/timer.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,94 @@ ++/* ++ * include/arch/nds32/include/asm/timer.h ++ * ++ * Faraday FTTMR010 Timer Device Driver Interface ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Note ++ * ++ * As IP_COUNT might be greater than one, timer ID is computed as follows: ++ * id=0~2 : Timer 1~3 of the first FTTMR010 IP ++ * id=3~5 : Timer 1~3 of the second FTTMR010 IP ++ * ... ++ * Therefore: ++ * (id / 3) : Compute which IP ++ * (id % 3) : Compute which timer in this IP ++ * Notice: ++ * For simplicity's sake, all code does not check for invalid timer id ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/14/2005 Created, heavily modified from Faraday CPE platform code. ++ */ ++ ++ ++#ifndef __FARADAY_TIMER_FTTMR010_HEADER__ ++#define __FARADAY_TIMER_FTTMR010_HEADER__ ++ ++/* ++ * Definition of register offsets ++ */ ++ ++#define TIMER1_COUNT 0x0 ++#define TIMER1_LOAD 0x4 ++#define TIMER1_MATCH1 0x8 ++#define TIMER1_MATCH2 0xC ++ ++#define TIMER2_COUNT 0x10 ++#define TIMER2_LOAD 0x14 ++#define TIMER2_MATCH1 0x18 ++#define TIMER2_MATCH2 0x1C ++ ++#define TIMER3_COUNT 0x20 ++#define TIMER3_LOAD 0x24 ++#define TIMER3_MATCH1 0x28 ++#define TIMER3_MATCH2 0x2C ++ ++#define TIMER_TMCR 0x30 ++#define TIMER_INTRSTATE 0x34 ++#define TIMER_INTRMASK 0x38 ++ ++/* Each timer's register address is offset by 0x10 */ ++#define TIMER_OFFSET 0x10 ++ ++/* ++ * Definition of TMCR bits ++ */ ++ ++#define TM1ENABLE 1 ++#define TM1CLOCK (1<<1) ++#define TM1OFENABLE (1<<2) ++ ++#define TM2ENABLE (1<<3) ++#define TM2CLOCK (1<<4) ++#define TM2OFENABLE (1<<5) ++ ++#define TM3ENABLE (1<<6) ++#define TM3CLOCK (1<<7) ++#define TM3OFENABLE (1<<8) ++ ++#define TM1UPDOWN (1<<9) ++#define TM2UPDOWN (1<<10) ++#define TM3UPDOWN (1<<11) ++ ++ ++#define TM1MATCH1 (1 << 0) ++#define TM1MATCH2 (1 << 1) ++#define TM1OVERFLOW (1 << 2) ++#define TM2MATCH1 (1 << 3) ++#define TM2MATCH2 (1 << 4) ++#define TM2OVERFLOW (1 << 5) ++#define TM3MATCH1 (1 << 6) ++#define TM3MATCH2 (1 << 7) ++#define TM3OVERFLOW (1 << 8) ++ ++struct sys_timer; ++extern struct sys_timer platform_timer; ++ ++#endif // __FARADAY_TIMER_FTTMR010_HEADER__ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/timex.h linux-3.4.110/arch/nds32/include/asm/timex.h +--- linux-3.4.110.orig/arch/nds32/include/asm/timex.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/timex.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * linux/arch/nds32/include/asm/timex.h ++ * ++ * Copyright (C) 1997,1998 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Architecture Specific TIME specifications ++ */ ++#ifndef _ASMNDS32_TIMEX_H ++#define _ASMNDS32_TIMEX_H ++ ++#ifndef __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ ++#define __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ ++ ++#include ++ ++#ifndef CLOCK_TICK_RATE ++#define CLOCK_TICK_RATE (TIMER_CLK_IN) ++#endif ++ ++#endif /* __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ */ ++ ++typedef unsigned long cycles_t; ++ ++extern cycles_t cacheflush_time; ++ ++static inline cycles_t get_cycles (void) ++{ ++ return 0; ++} ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/tlbflush.h linux-3.4.110/arch/nds32/include/asm/tlbflush.h +--- linux-3.4.110.orig/arch/nds32/include/asm/tlbflush.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/tlbflush.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,80 @@ ++/* ++ * linux/arch/nds32/include/asm/tlbflush.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_TLBFLUSH_H ++#define _ASMNDS32_TLBFLUSH_H ++ ++#include ++#include ++#include ++ ++static inline void local_flush_tlb_all(void) ++{ ++ asm("tlbop FLUA\n"); ++ __nds32__isb(); ++} ++static inline void local_flush_tlb_mm(struct mm_struct *mm) ++{ ++ asm("tlbop FLUA\n"); ++ __nds32__isb(); ++} ++static inline void local_flush_tlb_kernel_range(unsigned long start, ++ unsigned long end) ++{ ++ while(start < end) { ++ asm("tlbop %0, INV"::"r" (start)); ++ __nds32__isb(); ++ start += PAGE_SIZE; ++ } ++} ++ ++#ifndef CONFIG_CPU_NO_CONTEXT_ID ++void local_flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end); ++void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); ++#else ++static inline void local_flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++ if ((end - start) > 0x400000) { ++ asm("tlbop FLUA"); ++ __nds32__isb(); ++ return ; ++ } ++ while(start < end) { ++ asm("tlbop %0, INV"::"r" (start)); ++ __nds32__isb(); ++ start += PAGE_SIZE; ++ } ++} ++ ++static inline void local_flush_tlb_page(struct vm_area_struct *vma, ++ unsigned long addr) ++{ ++ asm("tlbop %0, INV"::"r" (addr)); ++ __nds32__isb(); ++} ++#endif ++ ++#ifndef CONFIG_SMP ++#define flush_tlb_all local_flush_tlb_all ++#define flush_tlb_mm local_flush_tlb_mm ++#define flush_tlb_range local_flush_tlb_range ++#define flush_tlb_page local_flush_tlb_page ++#define flush_tlb_kernel_range local_flush_tlb_kernel_range ++#else ++void flush_tlb_all(void); ++void flush_tlb_mm(struct mm_struct *mm); ++void flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end); ++void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); ++void flush_tlb_kernel_range(unsigned long start, unsigned long end); ++#endif ++ ++void update_mmu_cache(struct vm_area_struct *vma, ++ unsigned long address, pte_t* pte); ++void tlb_migrate_finish(struct mm_struct *mm); ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/tlb.h linux-3.4.110/arch/nds32/include/asm/tlb.h +--- linux-3.4.110.orig/arch/nds32/include/asm/tlb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/tlb.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * linux/arch/nds32/include/asm/tlb.h ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++ ++#ifndef __ASMNDS32_TLB_H ++#define __ASMNDS32_TLB_H ++ ++#define tlb_start_vma(tlb,vma) \ ++ do { \ ++ if (!tlb->fullmm) \ ++ flush_cache_range(vma, vma->vm_start, vma->vm_end); \ ++ } while (0) ++ ++#define tlb_end_vma(tlb,vma) \ ++ do { \ ++ if(!tlb->fullmm) \ ++ flush_tlb_range(vma, vma->vm_start, vma->vm_end); \ ++ } while (0) ++ ++#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0) ++ ++#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) ++ ++#include ++ ++#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) ++#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tln)->mm, pmd) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/topology.h linux-3.4.110/arch/nds32/include/asm/topology.h +--- linux-3.4.110.orig/arch/nds32/include/asm/topology.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/topology.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,11 @@ ++/* ++ * linux/arch/nds32/include/asm/topology.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASM_NDS32_TOPOLOGY_H ++#define _ASM_NDS32_TOPOLOGY_H ++ ++#include ++ ++#endif /* _ASM_NDS32_TOPOLOGY_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/traps.h linux-3.4.110/arch/nds32/include/asm/traps.h +--- linux-3.4.110.orig/arch/nds32/include/asm/traps.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/traps.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * linux/arch/nds32/include/asm/traps.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_TRAP_H ++#define _ASMNDS32_TRAP_H ++ ++#include ++ ++struct undef_hook { ++ struct list_head node; ++ u32 instr_mask; ++ u32 instr_val; ++ u32 cpsr_mask; ++ u32 cpsr_val; ++ int (*fn)(struct pt_regs *regs, unsigned int instr); ++}; ++ ++void register_undef_hook(struct undef_hook *hook); ++void unregister_undef_hook(struct undef_hook *hook); ++ ++extern void __init early_trap_init(void); ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/types.h linux-3.4.110/arch/nds32/include/asm/types.h +--- linux-3.4.110.orig/arch/nds32/include/asm/types.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/types.h 2016-04-07 10:20:50.918080096 +0200 +@@ -0,0 +1,16 @@ ++#ifndef __ASM_NDS32_TYPES_H ++#define __ASM_NDS32_TYPES_H ++ ++#include ++ ++/* ++ * These aren't exported outside the kernel to avoid name space clashes ++ */ ++#ifdef __KERNEL__ ++ ++#define BITS_PER_LONG 32 ++ ++#endif /* __KERNEL__ */ ++ ++#endif ++ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/uaccess.h linux-3.4.110/arch/nds32/include/asm/uaccess.h +--- linux-3.4.110.orig/arch/nds32/include/asm/uaccess.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/uaccess.h 2016-04-07 10:20:50.934080715 +0200 +@@ -0,0 +1,428 @@ ++/* ++ * linux/arch/nds32/include/asm/uaccess.h ++ * ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#ifndef _ASMANDES_UACCESS_H ++#define _ASMANDES_UACCESS_H ++ ++/* ++ * User space memory access functions ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define VERIFY_READ 0 ++#define VERIFY_WRITE 1 ++ ++/* ++ * The exception table consists of pairs of addresses: the first is the ++ * address of an instruction that is allowed to fault, and the second is ++ * the address at which the program should continue. No registers are ++ * modified, so it is entirely up to the continuation code to figure out ++ * what to do. ++ * ++ * All the routines below use bits of fixup code that are out of line ++ * with the main instruction path. This means when everything is well, ++ * we don't even have to jump over them. Further, they do not intrude ++ * on our cache or tlb entries. ++ */ ++ ++struct exception_table_entry ++{ ++ unsigned long insn, fixup; ++}; ++ ++extern int fixup_exception(struct pt_regs *regs); ++ ++#define KERNEL_DS ((mm_segment_t) { ~0UL }) ++#define USER_DS ((mm_segment_t) {TASK_SIZE - 1}) ++ ++#define get_ds() (KERNEL_DS) ++#define get_fs() (current_thread_info()->addr_limit) ++ ++static inline void set_fs (mm_segment_t fs) ++{ ++ current_thread_info()->addr_limit = fs; ++} ++ ++#define segment_eq(a, b) ((a.seg) == (b.seg)) ++ ++#define __range_ok(addr, size) (size <= get_fs().seg && addr <= (get_fs().seg -size)) ++ ++#define access_ok(type, addr, size) \ ++ __range_ok((unsigned long)addr, (unsigned long)size) ++/* ++ * Single-value transfer routines. They automatically use the right ++ * size if we just have the right pointer type. Note that the functions ++ * which read from user space (*get_*) need to take care not to leak ++ * kernel data even if the calling code is buggy and fails to check ++ * the return value. This means zeroing out the destination variable ++ * or buffer on error. Normally this is done out of line by the ++ * fixup code, but there are a few places where it intrudes on the ++ * main code path. When we only write to user space, there is no ++ * problem. ++ * ++ * The "__xxx" versions of the user access functions do not verify the ++ * address space - it must have been done previously with a separate ++ * "access_ok()" call. ++ * ++ * The "xxx_error" versions set the third argument to EFAULT if an ++ * error occurs, and leave it unchanged on success. Note that these ++ * versions are void (ie, don't return a value as such). ++ */ ++ ++extern int __get_user_1(void *); ++extern int __get_user_2(void *); ++extern int __get_user_4(void *); ++extern int __get_user_8(void *); ++extern int __get_user_bad(void); ++ ++#define __get_user_x(__r2,__p,__e,__s,__i...) \ ++ __asm__ __volatile__ ( \ ++ __asmeq("%0", "$r0") __asmeq("%1", "$r2") \ ++ "bal __get_user_" #__s \ ++ : "=&r" (__e), "=r" (__r2) \ ++ : "0" (__p) \ ++ : __i, "cc") ++ ++#define get_user(x,p) \ ++ ({ \ ++ const register typeof(*(p)) __user *__p asm("$r0") = (p);\ ++ register unsigned long __r2 asm("$r2"); \ ++ register int __e asm("$r0"); \ ++ switch (sizeof(*(__p))) { \ ++ case 1: \ ++ __get_user_x(__r2, __p, __e, 1, "$lp"); \ ++ break; \ ++ case 2: \ ++ __get_user_x(__r2, __p, __e, 2, "$r3", "$lp"); \ ++ break; \ ++ case 4: \ ++ __get_user_x(__r2, __p, __e, 4, "$lp"); \ ++ break; \ ++ case 8: \ ++ __get_user_x(__r2, __p, __e, 8, "$lp"); \ ++ break; \ ++ default: __e = __get_user_bad(); break; \ ++ } \ ++ x = (typeof(*(p))) __r2; \ ++ __e; \ ++ }) ++ ++#define __get_user(x,ptr) \ ++({ \ ++ long __gu_err = 0; \ ++ __get_user_err((x),(ptr),__gu_err); \ ++ __gu_err; \ ++}) ++ ++#define __get_user_error(x,ptr,err) \ ++({ \ ++ __get_user_err((x),(ptr),err); \ ++ (void) 0; \ ++}) ++ ++#define __get_user_err(x,ptr,err) \ ++do { \ ++ unsigned long __gu_addr = (unsigned long)(ptr); \ ++ unsigned long __gu_val; \ ++ __chk_user_ptr(ptr); \ ++ switch (sizeof(*(ptr))) { \ ++ case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ ++ case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ ++ case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \ ++ default: (__gu_val) = __get_user_bad(); \ ++ } \ ++ (x) = (__typeof__(*(ptr)))__gu_val; \ ++} while (0) ++ ++#define __get_user_asm_byte(x,addr,err) \ ++ __asm__ __volatile__( \ ++ "1: lbi %1,[%2]\n" \ ++ "2:\n" \ ++ " .section .fixup,\"ax\"\n" \ ++ " .align 2\n" \ ++ "3: move %0, %3\n" \ ++ " move %1, #0\n" \ ++ " b 2b\n" \ ++ " .previous\n" \ ++ " .section __ex_table,\"a\"\n" \ ++ " .align 3\n" \ ++ " .long 1b, 3b\n" \ ++ " .previous" \ ++ : "+r" (err), "=&r" (x) \ ++ : "r" (addr), "i" (-EFAULT) \ ++ : "cc") ++ ++#ifndef __NDS32_EB__ ++#define __get_user_asm_half(x,__gu_addr,err) \ ++({ \ ++ unsigned long __b1, __b2; \ ++ __get_user_asm_byte(__b1, __gu_addr, err); \ ++ __get_user_asm_byte(__b2, __gu_addr + 1, err); \ ++ (x) = __b1 | (__b2 << 8); \ ++}) ++#else ++#define __get_user_asm_half(x,__gu_addr,err) \ ++({ \ ++ unsigned long __b1, __b2; \ ++ __get_user_asm_byte(__b1, __gu_addr, err); \ ++ __get_user_asm_byte(__b2, __gu_addr + 1, err); \ ++ (x) = (__b1 << 8) | __b2; \ ++}) ++#endif ++ ++#define __get_user_asm_word(x,addr,err) \ ++ __asm__ __volatile__( \ ++ "1: lwi %1,[%2]\n" \ ++ "2:\n" \ ++ " .section .fixup,\"ax\"\n" \ ++ " .align 2\n" \ ++ "3: move %0, %3\n" \ ++ " move %1, #0\n" \ ++ " b 2b\n" \ ++ " .previous\n" \ ++ " .section __ex_table,\"a\"\n" \ ++ " .align 3\n" \ ++ " .long 1b, 3b\n" \ ++ " .previous" \ ++ : "+r" (err), "=&r" (x) \ ++ : "r" (addr), "i" (-EFAULT) \ ++ : "cc") ++ ++extern int __put_user_1(void *, unsigned int); ++extern int __put_user_2(void *, unsigned int); ++extern int __put_user_4(void *, unsigned int); ++extern int __put_user_8(void *, unsigned long long); ++extern int __put_user_bad(void); ++ ++#ifdef _GCC444 ++#define __put_user_x(__r2,__p,__e,__s) \ ++ __asm__ __volatile__ ( \ ++ __asmeq("%0", "$r0") __asmeq("%2", "$r2") \ ++ "bal __put_user_" #__s \ ++ : "=&r" (__e) \ ++ : "0" (__p), "r" (__r2) \ ++ : "$p0", "$lp", "cc") ++#else ++#define __put_user_x(__r2,__p,__e,__s) \ ++ __asm__ __volatile__ ( \ ++ __asmeq("%0", "$r0") __asmeq("%2", "$r2") \ ++ "bal __put_user_" #__s \ ++ : "=&r" (__e) \ ++ : "0" (__p), "r" (__r2) \ ++ : "$r26", "$lp", "cc") ++#endif ++ ++#define put_user(x,p) \ ++ ({ \ ++ const register typeof(*(p)) __r2 asm("$r2") = (x); \ ++ const register typeof(*(p)) __user *__p asm("$r0") = (p);\ ++ register int __e asm("$r0"); \ ++ switch (sizeof(*(__p))) { \ ++ case 1: \ ++ __put_user_x(__r2, __p, __e, 1); \ ++ break; \ ++ case 2: \ ++ __put_user_x(__r2, __p, __e, 2); \ ++ break; \ ++ case 4: \ ++ __put_user_x(__r2, __p, __e, 4); \ ++ break; \ ++ case 8: \ ++ __put_user_x(__r2, __p, __e, 8); \ ++ break; \ ++ default: __e = __put_user_bad(); break; \ ++ } \ ++ __e; \ ++ }) ++ ++#define __put_user(x,ptr) \ ++({ \ ++ long __pu_err = 0; \ ++ __put_user_err((x),(ptr),__pu_err); \ ++ __pu_err; \ ++}) ++ ++#define __put_user_error(x,ptr,err) \ ++({ \ ++ __put_user_err((x),(ptr),err); \ ++ (void) 0; \ ++}) ++ ++#define __put_user_err(x,ptr,err) \ ++do { \ ++ unsigned long __pu_addr = (unsigned long)(ptr); \ ++ __typeof__(*(ptr)) __pu_val = (x); \ ++ __chk_user_ptr(ptr); \ ++ switch (sizeof(*(ptr))) { \ ++ case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ ++ case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ ++ case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \ ++ case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \ ++ default: __put_user_bad(); \ ++ } \ ++} while (0) ++ ++#define __put_user_asm_byte(x,__pu_addr,err) \ ++ __asm__ __volatile__( \ ++ "1: sbi %1,[%2]\n" \ ++ "2:\n" \ ++ " .section .fixup,\"ax\"\n" \ ++ " .align 2\n" \ ++ "3: move %0, %3\n" \ ++ " b 2b\n" \ ++ " .previous\n" \ ++ " .section __ex_table,\"a\"\n" \ ++ " .align 3\n" \ ++ " .long 1b, 3b\n" \ ++ " .previous" \ ++ : "+r" (err) \ ++ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ ++ : "cc") ++ ++#ifndef __NDS32_EB__ ++#define __put_user_asm_half(x,__pu_addr,err) \ ++({ \ ++ unsigned long __temp = (unsigned long)(x); \ ++ __put_user_asm_byte(__temp, __pu_addr, err); \ ++ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ ++}) ++#else ++#define __put_user_asm_half(x,__pu_addr,err) \ ++({ \ ++ unsigned long __temp = (unsigned long)(x); \ ++ __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ ++ __put_user_asm_byte(__temp, __pu_addr + 1, err); \ ++}) ++#endif ++ ++#define __put_user_asm_word(x,__pu_addr,err) \ ++ __asm__ __volatile__( \ ++ "1: swi %1,[%2]\n" \ ++ "2:\n" \ ++ " .section .fixup,\"ax\"\n" \ ++ " .align 2\n" \ ++ "3: move %0, %3\n" \ ++ " b 2b\n" \ ++ " .previous\n" \ ++ " .section __ex_table,\"a\"\n" \ ++ " .align 3\n" \ ++ " .long 1b, 3b\n" \ ++ " .previous" \ ++ : "+r" (err) \ ++ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ ++ : "cc") ++ ++#ifdef __NDS32_EB__ ++#define __reg_oper0 "%H2" ++#define __reg_oper1 "%L2" ++#else ++#define __reg_oper0 "%L2" ++#define __reg_oper1 "%H2" ++#endif ++ ++#define __put_user_asm_dword(x, __pu_addr, __pu_err) \ ++ __asm__ __volatile__ ( \ ++ "\n1:\tswi " __reg_oper0 ",[%1]\n" \ ++ "\n2:\tswi " __reg_oper1 ",[%1+4]\n" \ ++ "3:\n" \ ++ " .section .fixup,\"ax\"\n" \ ++ " .align 2\n" \ ++ "4: move %0, %3\n" \ ++ " b 3b\n" \ ++ " .previous\n" \ ++ " .section __ex_table,\"a\"\n" \ ++ " .align 3\n" \ ++ " .long 1b, 4b\n" \ ++ " .long 2b, 4b\n" \ ++ " .previous" \ ++ : "+r"(__pu_err) \ ++ : "r"(__pu_addr), "r"(x), "i"(-EFAULT) \ ++ : "cc") ++extern unsigned long __arch_copy_from_user(void *to, const void __user *from, unsigned long n); ++extern unsigned long __arch_copy_to_user(void __user *to, const void *from, unsigned long n); ++extern unsigned long __arch_clear_user(void __user *addr, unsigned long n); ++extern unsigned long __arch_strncpy_from_user(char *to, const char __user *from, unsigned long count); ++extern unsigned long __arch_strnlen_user(const char __user *s, long n); ++ ++static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) ++{ ++ if (access_ok(VERIFY_READ, from, n)) ++ n = __arch_copy_from_user(to, from, n); ++ else /* security hole - plug it */ ++ memzero(to, n); ++ return n; ++} ++ ++static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) ++{ ++ return __arch_copy_from_user(to, from, n); ++} ++ ++static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) ++{ ++ if (access_ok(VERIFY_WRITE, to, n)) ++ n = __arch_copy_to_user(to, from, n); ++ return n; ++} ++ ++static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) ++{ ++ return __arch_copy_to_user(to, from, n); ++} ++ ++#define __copy_to_user_inatomic __copy_to_user ++#define __copy_from_user_inatomic __copy_from_user ++ ++static inline unsigned long clear_user (void __user *to, unsigned long n) ++{ ++ if (access_ok(VERIFY_WRITE, to, n)) ++ n = __arch_clear_user(to, n); ++ return n; ++} ++ ++static inline unsigned long __clear_user (void __user *to, unsigned long n) ++{ ++ return __arch_clear_user(to, n); ++} ++ ++/* ++ * We check the flags of vma here before __arch_strncpy_from_user(). ++ * An alternative way to do it is using lwup instruction in __arch_strncpy_from_user(). ++ * TODO: Should perform performance evaluation of the two. ++ */ ++static inline long strncpy_from_user (char *dst, const char __user *src, long count) ++{ ++ long res = -EFAULT; ++ if (access_ok(VERIFY_READ, src, 1)) ++ res = __arch_strncpy_from_user(dst, src, count); ++ return res; ++} ++ ++static inline long __strncpy_from_user (char *dst, const char __user *src, long count) ++{ ++ return __arch_strncpy_from_user(dst, src, count); ++} ++ ++#define strlen_user(s) strnlen_user(s, ~0UL >> 1) ++ ++static inline long strnlen_user(const char __user *s, long n) ++{ ++ unsigned long res = 0; ++ ++ if (segment_eq(get_fs(),KERNEL_DS) || ((unsigned long)s < get_fs().seg)) ++ res = __arch_strnlen_user(s, n); ++ ++ return res; ++} ++#endif /* _ASMNDS32_UACCESS_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/ucontext.h linux-3.4.110/arch/nds32/include/asm/ucontext.h +--- linux-3.4.110.orig/arch/nds32/include/asm/ucontext.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/ucontext.h 2016-04-07 10:20:50.934080715 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * linux/arch/nds32/include/asm/ucontext.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _ASMNDS32_UCONTEXT_H ++#define _ASMNDS32_UCONTEXT_H ++ ++struct ucontext { ++ unsigned long uc_flags; ++ struct ucontext *uc_link; ++ stack_t uc_stack; ++ struct sigcontext uc_mcontext; ++ sigset_t uc_sigmask; /* mask last for extensibility */ ++}; ++ ++#endif /* !_ASMNDS32_UCONTEXT_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/unaligned.h linux-3.4.110/arch/nds32/include/asm/unaligned.h +--- linux-3.4.110.orig/arch/nds32/include/asm/unaligned.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/unaligned.h 2016-04-07 10:20:50.934080715 +0200 +@@ -0,0 +1,24 @@ ++/* ++ * linux/arch/nds32/include/asm/unaligned.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef __ASM_NDS32_UNALIGNED_H ++#define __ASM_NDS32_UNALIGNED_H ++ ++#include ++#include ++#include ++ ++/* ++ * Select endianness ++ */ ++#if defined(__NDS32_EB__) ++#define get_unaligned __get_unaligned_be ++#define put_unaligned __put_unaligned_be ++#else ++#define get_unaligned __get_unaligned_le ++#define put_unaligned __put_unaligned_le ++#endif ++ ++#endif /* __ASM_NDS32_UNALIGNED_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/uncompress.h linux-3.4.110/arch/nds32/include/asm/uncompress.h +--- linux-3.4.110.orig/arch/nds32/include/asm/uncompress.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/uncompress.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,65 @@ ++/* ++ * linux/arch/nds32/include/asm/uncompress.h ++ * ++ * Faraday Linux Boot Loader UART (FTUART010) Routines ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Note ++ * ++ * The first UART (FTUART010) in the system is used for dumping debug messages. ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/21/2005 Created. Heavily modified from Faraday CPE port. ++ */ ++ ++#include ++ ++#ifdef CONFIG_PLAT_AG102 ++#define UART_PA_BASE 0x94200000 ++#else ++#define UART_PA_BASE 0x99600000 ++#endif ++ ++#define arch_decomp_setup() ++#define arch_decomp_wdog() ++ ++#ifndef STANDALONE_DEBUG ++#define putstr debug_puts ++#endif ++ ++#define SERIAL_THR 0x00 ++#define SERIAL_LSR 0x14 ++#define SERIAL_LSR_THRE 0x20 ++ ++static inline void uncompress_puts(const char *s) ++{ ++ volatile unsigned *status = (volatile unsigned *)(UART_PA_BASE+SERIAL_LSR); ++ while (*s) { ++ while ((*status & SERIAL_LSR_THRE)==0); ++ ++ *(volatile unsigned*)(UART_PA_BASE+SERIAL_THR) = (unsigned)*s; ++ ++ if (*s == '\n') { ++ while ((*status & SERIAL_LSR_THRE)==0); ++ *(volatile unsigned*)(UART_PA_BASE+SERIAL_THR) = '\r'; ++ } ++ s++; ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/unistd.h linux-3.4.110/arch/nds32/include/asm/unistd.h +--- linux-3.4.110.orig/arch/nds32/include/asm/unistd.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/unistd.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,468 @@ ++/* ++ * linux/arch/nds32/include/asm/unistd.h ++ * ++ * Copyright (C) 2001-2003 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Please forward _all_ changes to this file to rmk@arm.linux.org.uk, ++ * no matter what the change is. Thanks! ++ */ ++/* ============================================================================ ++ * ++ * linux/arch/nds32/include/asm/unistd.h ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is syscall scheme for Andes NDS32 architecture. ++ * ++ * Revision History: ++ * ++ * Jul.07.2007 Original from Shawn and Tom, refined by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++ ++#ifndef __ASM_NDS32_UNISTD_H ++#define __ASM_NDS32_UNISTD_H ++ ++#define __NR_SYSCALL_BASE 0x5000 ++#define __NR_NDS32_BASE 0x7000 ++/* ++ * This file contains the system call numbers. ++ */ ++ ++#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0) ++#define __NR_exit (__NR_SYSCALL_BASE+ 1) ++#define __NR_fork (__NR_SYSCALL_BASE+ 2) ++#define __NR_read (__NR_SYSCALL_BASE+ 3) ++#define __NR_write (__NR_SYSCALL_BASE+ 4) ++#define __NR_open (__NR_SYSCALL_BASE+ 5) ++#define __NR_close (__NR_SYSCALL_BASE+ 6) ++#define __NR_waitpid (__NR_SYSCALL_BASE+ 7) ++ /* 7 was sys_waitpid */ ++#define __NR_creat (__NR_SYSCALL_BASE+ 8) ++#define __NR_link (__NR_SYSCALL_BASE+ 9) ++#define __NR_unlink (__NR_SYSCALL_BASE+ 10) ++#define __NR_execve (__NR_SYSCALL_BASE+ 11) ++#define __NR_chdir (__NR_SYSCALL_BASE+ 12) ++#define __NR_time (__NR_SYSCALL_BASE+ 13) ++#define __NR_mknod (__NR_SYSCALL_BASE+ 14) ++#define __NR_chmod (__NR_SYSCALL_BASE+ 15) ++#define __NR_lchown (__NR_SYSCALL_BASE+ 16) ++ /* 17 was sys_break */ ++ /* 18 was sys_oldstat */ ++#define __NR_lseek (__NR_SYSCALL_BASE+ 19) ++#define __NR_getpid (__NR_SYSCALL_BASE+ 20) ++#define __NR_mount (__NR_SYSCALL_BASE+ 21) ++#define __NR_umount (__NR_SYSCALL_BASE+ 22) ++#define __NR_setuid (__NR_SYSCALL_BASE+ 23) ++#define __NR_getuid (__NR_SYSCALL_BASE+ 24) ++#define __NR_stime (__NR_SYSCALL_BASE+ 25) ++#define __NR_ptrace (__NR_SYSCALL_BASE+ 26) ++#define __NR_alarm (__NR_SYSCALL_BASE+ 27) ++ /* 28 was sys_oldfstat */ ++#define __NR_pause (__NR_SYSCALL_BASE+ 29) ++#define __NR_utime (__NR_SYSCALL_BASE+ 30) ++ /* 31 was sys_stty */ ++ /* 32 was sys_gtty */ ++#define __NR_access (__NR_SYSCALL_BASE+ 33) ++#define __NR_nice (__NR_SYSCALL_BASE+ 34) ++ /* 35 was sys_ftime */ ++#define __NR_sync (__NR_SYSCALL_BASE+ 36) ++#define __NR_kill (__NR_SYSCALL_BASE+ 37) ++#define __NR_rename (__NR_SYSCALL_BASE+ 38) ++#define __NR_mkdir (__NR_SYSCALL_BASE+ 39) ++#define __NR_rmdir (__NR_SYSCALL_BASE+ 40) ++#define __NR_dup (__NR_SYSCALL_BASE+ 41) ++#define __NR_pipe (__NR_SYSCALL_BASE+ 42) ++#define __NR_times (__NR_SYSCALL_BASE+ 43) ++ /* 44 was sys_prof */ ++#define __NR_brk (__NR_SYSCALL_BASE+ 45) ++#define __NR_setgid (__NR_SYSCALL_BASE+ 46) ++#define __NR_getgid (__NR_SYSCALL_BASE+ 47) ++ /* 48 was sys_signal */ ++#define __NR_geteuid (__NR_SYSCALL_BASE+ 49) ++#define __NR_getegid (__NR_SYSCALL_BASE+ 50) ++#define __NR_acct (__NR_SYSCALL_BASE+ 51) ++#define __NR_umount2 (__NR_SYSCALL_BASE+ 52) ++ /* 53 was sys_lock */ ++#define __NR_ioctl (__NR_SYSCALL_BASE+ 54) ++#define __NR_fcntl (__NR_SYSCALL_BASE+ 55) ++ /* 56 was sys_mpx */ ++#define __NR_setpgid (__NR_SYSCALL_BASE+ 57) ++ /* 58 was sys_ulimit */ ++ /* 59 was sys_olduname */ ++#define __NR_umask (__NR_SYSCALL_BASE+ 60) ++#define __NR_chroot (__NR_SYSCALL_BASE+ 61) ++#define __NR_ustat (__NR_SYSCALL_BASE+ 62) ++#define __NR_dup2 (__NR_SYSCALL_BASE+ 63) ++#define __NR_getppid (__NR_SYSCALL_BASE+ 64) ++#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65) ++#define __NR_setsid (__NR_SYSCALL_BASE+ 66) ++#define __NR_sigaction (__NR_SYSCALL_BASE+ 67) ++ /* 68 was sys_sgetmask */ ++ /* 69 was sys_ssetmask */ ++#define __NR_setreuid (__NR_SYSCALL_BASE+ 70) ++#define __NR_setregid (__NR_SYSCALL_BASE+ 71) ++#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72) ++#define __NR_sigpending (__NR_SYSCALL_BASE+ 73) ++#define __NR_sethostname (__NR_SYSCALL_BASE+ 74) ++#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75) ++#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */ ++#define __NR_getrusage (__NR_SYSCALL_BASE+ 77) ++#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78) ++#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79) ++#define __NR_getgroups (__NR_SYSCALL_BASE+ 80) ++#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) ++#define __NR_select (__NR_SYSCALL_BASE+ 82) ++#define __NR_symlink (__NR_SYSCALL_BASE+ 83) ++ /* 84 was sys_lstat */ ++#define __NR_readlink (__NR_SYSCALL_BASE+ 85) ++#define __NR_uselib (__NR_SYSCALL_BASE+ 86) ++#define __NR_swapon (__NR_SYSCALL_BASE+ 87) ++#define __NR_reboot (__NR_SYSCALL_BASE+ 88) ++#define __NR_readdir (__NR_SYSCALL_BASE+ 89) ++#define __NR_mmap (__NR_SYSCALL_BASE+ 90) ++#define __NR_munmap (__NR_SYSCALL_BASE+ 91) ++#define __NR_truncate (__NR_SYSCALL_BASE+ 92) ++#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93) ++#define __NR_fchmod (__NR_SYSCALL_BASE+ 94) ++#define __NR_fchown (__NR_SYSCALL_BASE+ 95) ++#define __NR_getpriority (__NR_SYSCALL_BASE+ 96) ++#define __NR_setpriority (__NR_SYSCALL_BASE+ 97) ++ /* 98 was sys_profil */ ++#define __NR_statfs (__NR_SYSCALL_BASE+ 99) ++#define __NR_fstatfs (__NR_SYSCALL_BASE+100) ++ /* 101 was sys_ioperm */ ++#define __NR_socketcall (__NR_SYSCALL_BASE+102) ++#define __NR_syslog (__NR_SYSCALL_BASE+103) ++#define __NR_setitimer (__NR_SYSCALL_BASE+104) ++#define __NR_getitimer (__NR_SYSCALL_BASE+105) ++#define __NR_stat (__NR_SYSCALL_BASE+106) ++#define __NR_lstat (__NR_SYSCALL_BASE+107) ++#define __NR_fstat (__NR_SYSCALL_BASE+108) ++ /* 109 was sys_uname */ ++ /* 110 was sys_iopl */ ++#define __NR_vhangup (__NR_SYSCALL_BASE+111) ++ /* 112 was sys_idle */ ++#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ ++#define __NR_wait4 (__NR_SYSCALL_BASE+114) ++#define __NR_swapoff (__NR_SYSCALL_BASE+115) ++#define __NR_sysinfo (__NR_SYSCALL_BASE+116) ++#define __NR_ipc (__NR_SYSCALL_BASE+117) ++#define __NR_fsync (__NR_SYSCALL_BASE+118) ++#define __NR_sigreturn (__NR_SYSCALL_BASE+119) ++#define __NR_clone (__NR_SYSCALL_BASE+120) ++#define __NR_setdomainname (__NR_SYSCALL_BASE+121) ++#define __NR_uname (__NR_SYSCALL_BASE+122) ++ /* 123 was sys_modify_ldt */ ++#define __NR_adjtimex (__NR_SYSCALL_BASE+124) ++#define __NR_mprotect (__NR_SYSCALL_BASE+125) ++#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) ++ /* 127 was sys_create_module */ ++#define __NR_init_module (__NR_SYSCALL_BASE+128) ++#define __NR_delete_module (__NR_SYSCALL_BASE+129) ++ /* 130 was sys_get_kernel_syms */ ++#define __NR_quotactl (__NR_SYSCALL_BASE+131) ++#define __NR_getpgid (__NR_SYSCALL_BASE+132) ++#define __NR_fchdir (__NR_SYSCALL_BASE+133) ++#define __NR_bdflush (__NR_SYSCALL_BASE+134) ++#define __NR_sysfs (__NR_SYSCALL_BASE+135) ++#define __NR_personality (__NR_SYSCALL_BASE+136) ++ /* 137 was sys_afs_syscall */ ++#define __NR_setfsuid (__NR_SYSCALL_BASE+138) ++#define __NR_setfsgid (__NR_SYSCALL_BASE+139) ++#define __NR__llseek (__NR_SYSCALL_BASE+140) ++#define __NR_getdents (__NR_SYSCALL_BASE+141) ++#define __NR__newselect (__NR_SYSCALL_BASE+142) ++#define __NR_flock (__NR_SYSCALL_BASE+143) ++#define __NR_msync (__NR_SYSCALL_BASE+144) ++#define __NR_readv (__NR_SYSCALL_BASE+145) ++#define __NR_writev (__NR_SYSCALL_BASE+146) ++#define __NR_getsid (__NR_SYSCALL_BASE+147) ++#define __NR_fdatasync (__NR_SYSCALL_BASE+148) ++#define __NR__sysctl (__NR_SYSCALL_BASE+149) ++#define __NR_mlock (__NR_SYSCALL_BASE+150) ++#define __NR_munlock (__NR_SYSCALL_BASE+151) ++#define __NR_mlockall (__NR_SYSCALL_BASE+152) ++#define __NR_munlockall (__NR_SYSCALL_BASE+153) ++#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) ++#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) ++#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) ++#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) ++#define __NR_sched_yield (__NR_SYSCALL_BASE+158) ++#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) ++#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) ++#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) ++#define __NR_nanosleep (__NR_SYSCALL_BASE+162) ++#define __NR_mremap (__NR_SYSCALL_BASE+163) ++#define __NR_setresuid (__NR_SYSCALL_BASE+164) ++#define __NR_getresuid (__NR_SYSCALL_BASE+165) ++#define __NR_getpagesize (__NR_SYSCALL_BASE+166) ++ /* 167 was sys_query_module */ ++#define __NR_poll (__NR_SYSCALL_BASE+168) ++#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) ++#define __NR_setresgid (__NR_SYSCALL_BASE+170) ++#define __NR_getresgid (__NR_SYSCALL_BASE+171) ++#define __NR_prctl (__NR_SYSCALL_BASE+172) ++#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) ++#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) ++#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) ++#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) ++#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) ++#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) ++#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) ++#define __NR_pread64 (__NR_SYSCALL_BASE+180) ++#define __NR_pwrite64 (__NR_SYSCALL_BASE+181) ++#define __NR_chown (__NR_SYSCALL_BASE+182) ++#define __NR_getcwd (__NR_SYSCALL_BASE+183) ++#define __NR_capget (__NR_SYSCALL_BASE+184) ++#define __NR_capset (__NR_SYSCALL_BASE+185) ++#define __NR_sigaltstack (__NR_SYSCALL_BASE+186) ++#define __NR_sendfile (__NR_SYSCALL_BASE+187) ++ /* 188 reserved */ ++ /* 189 reserved */ ++#define __NR_vfork (__NR_SYSCALL_BASE+190) ++#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */ ++#define __NR_mmap2 (__NR_SYSCALL_BASE+192) ++#define __NR_truncate64 (__NR_SYSCALL_BASE+193) ++#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194) ++#define __NR_stat64 (__NR_SYSCALL_BASE+195) ++#define __NR_lstat64 (__NR_SYSCALL_BASE+196) ++#define __NR_fstat64 (__NR_SYSCALL_BASE+197) ++#define __NR_lchown32 (__NR_SYSCALL_BASE+198) ++#define __NR_getuid32 (__NR_SYSCALL_BASE+199) ++#define __NR_getgid32 (__NR_SYSCALL_BASE+200) ++#define __NR_geteuid32 (__NR_SYSCALL_BASE+201) ++#define __NR_getegid32 (__NR_SYSCALL_BASE+202) ++#define __NR_setreuid32 (__NR_SYSCALL_BASE+203) ++#define __NR_setregid32 (__NR_SYSCALL_BASE+204) ++#define __NR_getgroups32 (__NR_SYSCALL_BASE+205) ++#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) ++#define __NR_fchown32 (__NR_SYSCALL_BASE+207) ++#define __NR_setresuid32 (__NR_SYSCALL_BASE+208) ++#define __NR_getresuid32 (__NR_SYSCALL_BASE+209) ++#define __NR_setresgid32 (__NR_SYSCALL_BASE+210) ++#define __NR_getresgid32 (__NR_SYSCALL_BASE+211) ++#define __NR_chown32 (__NR_SYSCALL_BASE+212) ++#define __NR_setuid32 (__NR_SYSCALL_BASE+213) ++#define __NR_setgid32 (__NR_SYSCALL_BASE+214) ++#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215) ++#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216) ++#define __NR_getdents64 (__NR_SYSCALL_BASE+217) ++#define __NR_pivot_root (__NR_SYSCALL_BASE+218) ++#define __NR_mincore (__NR_SYSCALL_BASE+219) ++#define __NR_madvise (__NR_SYSCALL_BASE+220) ++#define __NR_fcntl64 (__NR_SYSCALL_BASE+221) ++ /* 222 for tux */ ++ /* 223 is unused */ ++#define __NR_gettid (__NR_SYSCALL_BASE+224) ++#define __NR_readahead (__NR_SYSCALL_BASE+225) ++#define __NR_setxattr (__NR_SYSCALL_BASE+226) ++#define __NR_lsetxattr (__NR_SYSCALL_BASE+227) ++#define __NR_fsetxattr (__NR_SYSCALL_BASE+228) ++#define __NR_getxattr (__NR_SYSCALL_BASE+229) ++#define __NR_lgetxattr (__NR_SYSCALL_BASE+230) ++#define __NR_fgetxattr (__NR_SYSCALL_BASE+231) ++#define __NR_listxattr (__NR_SYSCALL_BASE+232) ++#define __NR_llistxattr (__NR_SYSCALL_BASE+233) ++#define __NR_flistxattr (__NR_SYSCALL_BASE+234) ++#define __NR_removexattr (__NR_SYSCALL_BASE+235) ++#define __NR_lremovexattr (__NR_SYSCALL_BASE+236) ++#define __NR_fremovexattr (__NR_SYSCALL_BASE+237) ++#define __NR_tkill (__NR_SYSCALL_BASE+238) ++#define __NR_sendfile64 (__NR_SYSCALL_BASE+239) ++#define __NR_futex (__NR_SYSCALL_BASE+240) ++#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241) ++#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242) ++#define __NR_io_setup (__NR_SYSCALL_BASE+243) ++#define __NR_io_destroy (__NR_SYSCALL_BASE+244) ++#define __NR_io_getevents (__NR_SYSCALL_BASE+245) ++#define __NR_io_submit (__NR_SYSCALL_BASE+246) ++#define __NR_io_cancel (__NR_SYSCALL_BASE+247) ++#define __NR_exit_group (__NR_SYSCALL_BASE+248) ++#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) ++#define __NR_epoll_create (__NR_SYSCALL_BASE+250) ++#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251) ++#define __NR_epoll_wait (__NR_SYSCALL_BASE+252) ++#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253) ++ /* 254 for set_thread_area */ ++ /* 255 for get_thread_area */ ++#define __NR_set_tid_address (__NR_SYSCALL_BASE+256) ++#define __NR_timer_create (__NR_SYSCALL_BASE+257) ++#define __NR_timer_settime (__NR_SYSCALL_BASE+258) ++#define __NR_timer_gettime (__NR_SYSCALL_BASE+259) ++#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260) ++#define __NR_timer_delete (__NR_SYSCALL_BASE+261) ++#define __NR_clock_settime (__NR_SYSCALL_BASE+262) ++#define __NR_clock_gettime (__NR_SYSCALL_BASE+263) ++#define __NR_clock_getres (__NR_SYSCALL_BASE+264) ++#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265) ++#define __NR_statfs64 (__NR_SYSCALL_BASE+266) ++#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) ++#define __NR_tgkill (__NR_SYSCALL_BASE+268) ++#define __NR_utimes (__NR_SYSCALL_BASE+269) ++#define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270) ++#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) ++#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) ++#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) ++#define __NR_mq_open (__NR_SYSCALL_BASE+274) ++#define __NR_mq_unlink (__NR_SYSCALL_BASE+275) ++#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276) ++#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277) ++#define __NR_mq_notify (__NR_SYSCALL_BASE+278) ++#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) ++#define __NR_waitid (__NR_SYSCALL_BASE+280) ++#define __NR_add_key (__NR_SYSCALL_BASE+281) ++#define __NR_request_key (__NR_SYSCALL_BASE+282) ++#define __NR_keyctl (__NR_SYSCALL_BASE+283) ++#define __NR_ioprio_set (__NR_SYSCALL_BASE+284) ++#define __NR_ioprio_get (__NR_SYSCALL_BASE+285) ++#define __NR_inotify_init (__NR_SYSCALL_BASE+286) ++#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+287) ++#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+288) ++#define __NR_migrate_pages (__NR_SYSCALL_BASE+289) ++#define __NR_openat (__NR_SYSCALL_BASE+290) ++#define __NR_mkdirat (__NR_SYSCALL_BASE+291) ++#define __NR_mknodat (__NR_SYSCALL_BASE+292) ++#define __NR_fchownat (__NR_SYSCALL_BASE+293) ++#define __NR_futimesat (__NR_SYSCALL_BASE+294) ++#define __NR_fstatat64 (__NR_SYSCALL_BASE+295) ++#define __NR_unlinkat (__NR_SYSCALL_BASE+296) ++#define __NR_renameat (__NR_SYSCALL_BASE+297) ++#define __NR_linkat (__NR_SYSCALL_BASE+298) ++#define __NR_symlinkat (__NR_SYSCALL_BASE+299) ++#define __NR_readlinkat (__NR_SYSCALL_BASE+300) ++#define __NR_fchmodat (__NR_SYSCALL_BASE+301) ++#define __NR_faccessat (__NR_SYSCALL_BASE+302) ++#define __NR_pselect6 (__NR_SYSCALL_BASE+303) ++#define __NR_ppoll (__NR_SYSCALL_BASE+304) ++#define __NR_unshare (__NR_SYSCALL_BASE+305) ++#define __NR_set_robust_list (__NR_SYSCALL_BASE+306) ++#define __NR_get_robust_list (__NR_SYSCALL_BASE+307) ++#define __NR_splice (__NR_SYSCALL_BASE+308) ++#define __NR_sync_file_range2 (__NR_SYSCALL_BASE+309) ++#define __NR_tee (__NR_SYSCALL_BASE+310) ++#define __NR_vmsplice (__NR_SYSCALL_BASE+311) ++#define __NR_move_pages (__NR_SYSCALL_BASE+312) ++#define __NR_fadvise64 (__NR_SYSCALL_BASE+313) ++#define __NR_utimensat (__NR_SYSCALL_BASE+314) ++#define __NR_signalfd (__NR_SYSCALL_BASE+315) ++#define __NR_timerfd_create (__NR_SYSCALL_BASE+316) ++#define __NR_eventfd (__NR_SYSCALL_BASE+317) ++#define __NR_fallocate (__NR_SYSCALL_BASE+318) ++#define __NR_timerfd_settime (__NR_SYSCALL_BASE+319) ++#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+320) ++#define __NR_getcpu (__NR_SYSCALL_BASE+321) ++#define __NR_signalfd4 (__NR_SYSCALL_BASE+322) ++#define __NR_eventfd2 (__NR_SYSCALL_BASE+323) ++#define __NR_epoll_create1 (__NR_SYSCALL_BASE+324) ++#define __NR_dup3 (__NR_SYSCALL_BASE+325) ++#define __NR_pipe2 (__NR_SYSCALL_BASE+326) ++#define __NR_inotify_init1 (__NR_SYSCALL_BASE+327) ++#define __NR_kexec_load (__NR_SYSCALL_BASE+328) ++#define __NR_accept (__NR_SYSCALL_BASE+329) ++#define __NR_bind (__NR_SYSCALL_BASE+330) ++#define __NR_connect (__NR_SYSCALL_BASE+331) ++#define __NR_getpeername (__NR_SYSCALL_BASE+332) ++#define __NR_getsockname (__NR_SYSCALL_BASE+333) ++#define __NR_getsockopt (__NR_SYSCALL_BASE+334) ++#define __NR_listen (__NR_SYSCALL_BASE+335) ++#define __NR_recv (__NR_SYSCALL_BASE+336) ++#define __NR_recvfrom (__NR_SYSCALL_BASE+337) ++#define __NR_recvmsg (__NR_SYSCALL_BASE+338) ++#define __NR_send (__NR_SYSCALL_BASE+339) ++#define __NR_sendmsg (__NR_SYSCALL_BASE+340) ++#define __NR_sendto (__NR_SYSCALL_BASE+341) ++#define __NR_setsockopt (__NR_SYSCALL_BASE+342) ++#define __NR_shutdown (__NR_SYSCALL_BASE+343) ++#define __NR_socket (__NR_SYSCALL_BASE+344) ++#define __NR_socketpair (__NR_SYSCALL_BASE+345) ++#define __NR_prlimit64 (__NR_SYSCALL_BASE+346) ++#define __NR_accept4 (__NR_SYSCALL_BASE+347) ++#define __NR_recvmmsg (__NR_SYSCALL_BASE+348) ++#define __NR_sendmmsg (__NR_SYSCALL_BASE+349) ++#define __NR_fanotify_init (__NR_SYSCALL_BASE+350) ++#define __NR_fanotify_mark (__NR_SYSCALL_BASE+351) ++#define __NR_msgget (__NR_SYSCALL_BASE+352) ++#define __NR_msgctl (__NR_SYSCALL_BASE+353) ++#define __NR_msgrcv (__NR_SYSCALL_BASE+354) ++#define __NR_msgsnd (__NR_SYSCALL_BASE+355) ++#define __NR_semget (__NR_SYSCALL_BASE+356) ++#define __NR_semctl (__NR_SYSCALL_BASE+357) ++#define __NR_semtimedop (__NR_SYSCALL_BASE+358) ++#define __NR_semop (__NR_SYSCALL_BASE+359) ++#define __NR_shmget (__NR_SYSCALL_BASE+360) ++#define __NR_shmctl (__NR_SYSCALL_BASE+361) ++#define __NR_shmat (__NR_SYSCALL_BASE+362) ++#define __NR_shmdt (__NR_SYSCALL_BASE+363) ++#define __NR_syncfs (__NR_SYSCALL_BASE+364) ++#define __NR_setns (__NR_SYSCALL_BASE+365) ++#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+366) ++#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+367) ++#define __NR_process_vm_readv (__NR_SYSCALL_BASE+368) ++#define __NR_process_vm_writev (__NR_SYSCALL_BASE+369) ++#define __NR_clock_adjtime (__NR_SYSCALL_BASE+370) ++#define __NR_get_mempolicy (__NR_SYSCALL_BASE+371) ++#define __NR_mbind (__NR_SYSCALL_BASE+372) ++#define __NR_perf_event_open (__NR_SYSCALL_BASE+373) ++#define __NR_preadv (__NR_SYSCALL_BASE+374) ++#define __NR_pwritev (__NR_SYSCALL_BASE+375) ++#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+376) ++#define __NR_set_mempolicy (__NR_SYSCALL_BASE+377) ++#define __NR_epoll_pwait (__NR_SYSCALL_BASE+378) ++ ++ ++ ++ ++#define __NR_lmmap (__NR_NDS32_BASE+ 1) ++#define __NR_lmunmap (__NR_NDS32_BASE+ 2) ++#define __NR_lmdma (__NR_NDS32_BASE+ 3) ++#define __NR_pfmctl (__NR_NDS32_BASE+ 4) ++#define __NR_getpfm (__NR_NDS32_BASE+ 5) ++#define __NR_setpfm (__NR_NDS32_BASE+ 6) ++#define __NR_wbna (__NR_NDS32_BASE+ 7) ++ ++ ++ ++#ifdef __KERNEL__ ++ ++#define __ARCH_WANT_IPC_PARSE_VERSION ++#define __ARCH_WANT_OLD_READDIR ++#define __ARCH_WANT_STAT64 ++#define __ARCH_WANT_SYS_ALARM ++#define __ARCH_WANT_SYS_GETHOSTNAME ++#define __ARCH_WANT_SYS_PAUSE ++#define __ARCH_WANT_SYS_TIME ++#define __ARCH_WANT_SYS_UTIME ++#define __ARCH_WANT_SYS_SOCKETCALL ++#define __ARCH_WANT_SYS_FADVISE64 ++#define __ARCH_WANT_SYS_GETPGRP ++#define __ARCH_WANT_SYS_LLSEEK ++#define __ARCH_WANT_SYS_NICE ++#define __ARCH_WANT_SYS_OLD_GETRLIMIT ++#define __ARCH_WANT_SYS_OLD_MMAP ++#define __ARCH_WANT_SYS_OLDUMOUNT ++#define __ARCH_WANT_SYS_SIGPENDING ++#define __ARCH_WANT_SYS_SIGPROCMASK ++#define __ARCH_WANT_SYS_RT_SIGACTION ++ ++/* ++ * "Conditional" syscalls ++ * ++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), ++ * but it doesn't work on all toolchains, so we just do it by hand ++ */ ++#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); ++ ++#endif ++#endif /* __ASM_NDS32_UNISTD_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/user.h linux-3.4.110/arch/nds32/include/asm/user.h +--- linux-3.4.110.orig/arch/nds32/include/asm/user.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/user.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,89 @@ ++/* ++ * linux/arch/nds32/include/asm/user.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef _NDS32_USER_H ++#define _NDS32_USER_H ++ ++#include ++#include ++/* Core file format: The core file is written in such a way that gdb ++ can understand it and provide useful information to the user (under ++ linux we use the 'trad-core' bfd). There are quite a number of ++ obstacles to being able to view the contents of the floating point ++ registers, and until these are solved you will not be able to view the ++ contents of them. Actually, you can read in the core file and look at ++ the contents of the user struct to find out what the floating point ++ registers contain. ++ The actual file contents are as follows: ++ UPAGE: 1 page consisting of a user struct that tells gdb what is present ++ in the file. Directly after this is a copy of the task_struct, which ++ is currently not used by gdb, but it may come in useful at some point. ++ All of the registers are stored as part of the upage. The upage should ++ always be only one page. ++ DATA: The data area is stored. We use current->end_text to ++ current->brk to pick up all of the user variables, plus any memory ++ that may have been malloced. No attempt is made to determine if a page ++ is demand-zero or if a page is totally unused, we just cover the entire ++ range. All of the addresses are rounded in such a way that an integral ++ number of pages is written. ++ STACK: We need the stack information in order to get a meaningful ++ backtrace. We need to write the data from (esp) to ++ current->start_stack, so we round each of these off in order to be able ++ to write an integer number of pages. ++ The minimum core file size is 3 pages, or 12288 bytes. ++*/ ++ ++struct user_fp { ++ struct fp_reg { ++ unsigned int sign1:1; ++ unsigned int unused:15; ++ unsigned int sign2:1; ++ unsigned int exponent:14; ++ unsigned int j:1; ++ unsigned int mantissa1:31; ++ unsigned int mantissa0:32; ++ } fpregs[8]; ++ unsigned int fpsr:32; ++ unsigned int fpcr:32; ++ unsigned char ftype[8]; ++ unsigned int init_flag; ++}; ++ ++/* When the kernel dumps core, it starts by dumping the user struct - ++ this will be used by gdb to figure out where the data and stack segments ++ are within the file, and what virtual addresses to use. */ ++struct user{ ++/* We start with the registers, to mimic the way that "memory" is returned ++ from the ptrace(3,...) function. */ ++ struct pt_regs regs; /* Where the registers are actually stored */ ++/* ptrace does not yet supply these. Someday.... */ ++ int u_fpvalid; /* True if math co-processor being used. */ ++ /* for this mess. Not yet used. */ ++/* The rest of this junk is to help gdb figure out what goes where */ ++ unsigned long int u_tsize; /* Text segment size (pages). */ ++ unsigned long int u_dsize; /* Data segment size (pages). */ ++ unsigned long int u_ssize; /* Stack segment size (pages). */ ++ unsigned long start_code; /* Starting virtual address of text. */ ++ unsigned long start_stack; /* Starting virtual address of stack area. ++ This is actually the bottom of the stack, ++ the top of the stack is always found in the ++ esp register. */ ++ long int signal; /* Signal that caused the core dump. */ ++ int reserved; /* No longer used */ ++ struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ ++ /* the registers. */ ++ unsigned long magic; /* To uniquely identify a core file */ ++ char u_comm[32]; /* User command that was responsible */ ++ int u_debugreg[8]; ++ struct user_fp u_fp; /* FP state */ ++ struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */ ++ /* the FP registers. */ ++}; ++#define NBPG PAGE_SIZE ++#define UPAGES 1 ++#define HOST_TEXT_START_ADDR (u.start_code) ++#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) ++ ++#endif /* _NDS32_USER_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/vga.h linux-3.4.110/arch/nds32/include/asm/vga.h +--- linux-3.4.110.orig/arch/nds32/include/asm/vga.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/vga.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,17 @@ ++/* ++ * linux/arch/nds32/include/asm/vga.h ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#ifndef ASMNDS32_VGA_H ++#define ASMNDS32_VGA_H ++ ++#include ++#include ++ ++#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x)) ++ ++#define vga_readb(x) (*((volatile unsigned char *)x)) ++#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/vmalloc.h linux-3.4.110/arch/nds32/include/asm/vmalloc.h +--- linux-3.4.110.orig/arch/nds32/include/asm/vmalloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/vmalloc.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,31 @@ ++/* ++ * linux/arch/nds32/include/asm/vmalloc.h ++ * ++ * Faraday Platform Independent Virtual Memory Configuration ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/16/2005 Copy from Faraday CPE codes. ++ */ ++ ++#ifndef __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ ++#define __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ ++ ++#endif /* __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ */ +diff -Nur linux-3.4.110.orig/arch/nds32/include/asm/xor.h linux-3.4.110/arch/nds32/include/asm/xor.h +--- linux-3.4.110.orig/arch/nds32/include/asm/xor.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/include/asm/xor.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,157 @@ ++/* ++ * linux/arch/nds32/include/asm/xor.h ++ * ++ * Copyright (C) 2001 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++ ++#define __XOR(a1, a2) a1 ^= a2 ++ ++ ++#define GET_BLOCK_2(dst) \ ++ __asm__( \ ++ " lmw.bim %1, [%0], %2 \n"\ ++ : "=r" (dst), "=r" (a1), "=r" (a2) \ ++ : "0" (dst)) ++ ++#define GET_BLOCK_4(dst) \ ++ __asm__( \ ++ " lmw.bim %1, [%0], %1 \n" \ //ldmia %0, {%1, %2, %3, %4} ++ " lmw.bim %2, [%0], %2 \n" \ ++ " lmw.bim %3, [%0], %3 \n" \ ++ " lmw.bim %4, [%0], %4 \n" \ ++ : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ ++ : "0" (dst)) ++ ++#define XOR_BLOCK_2(src) \ ++ __asm__(\ ++ " lmw.bim %1, [%0], %2 \n " \ ++ " lmw.bim %2, [%0], %2 \n" \ ++ : "=r" (src), "=r" (b1), "=r" (b2) \ ++ : "0" (src)); \ ++ __XOR(a1, b1); __XOR(a2, b2); ++ ++ ++#define XOR_BLOCK_4(src) \ ++ __asm__(\ ++ "lmw.bim %1, [%0], %1 \n " \ // ldmia %0!, {%1, %2, %3, %4} ++ "lmw.bim %2, [%0], %2 \n " \ ++ "lmw.bim %3, [%0], %3 \n " \ ++ "lmw.bim %4, [%0], %4 \n " \ ++ : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ ++ : "0" (src)); \ ++ __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) ++ ++#define PUT_BLOCK_2(dst) \ ++ __asm__ __volatile__( \ ++ " smw.bim %2, [%0], %3" \ ++ : "=r" (dst) \ ++ : "0" (dst), "r" (a1), "r" (a2)) ++ ++#define PUT_BLOCK_4(dst) \ ++ __asm__ __volatile__( \ ++ " smw.bim %2, [%0], %5 \n" \ ++ : "=r" (dst) \ ++ : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) ++ ++static void ++xor_nds32regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 4; ++ register unsigned int a1 __asm__("r4"); ++ register unsigned int a2 __asm__("r5"); ++ register unsigned int a3 __asm__("r6"); ++ register unsigned int a4 __asm__("r7"); ++ register unsigned int b1 __asm__("r8"); ++ register unsigned int b2 __asm__("r9"); ++ register unsigned int b3 __asm__("p0"); ++ register unsigned int b4 __asm__("ra"); ++ ++ do { ++ GET_BLOCK_4(p1); ++ XOR_BLOCK_4(p2); ++ PUT_BLOCK_4(p1); ++ } while (--lines); ++} ++ ++static void ++xor_nds32regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 4; ++ register unsigned int a1 __asm__("r4"); ++ register unsigned int a2 __asm__("r5"); ++ register unsigned int a3 __asm__("r6"); ++ register unsigned int a4 __asm__("r7"); ++ register unsigned int b1 __asm__("r8"); ++ register unsigned int b2 __asm__("r9"); ++ register unsigned int b3 __asm__("p0"); ++ register unsigned int b4 __asm__("ra"); ++ ++ do { ++ GET_BLOCK_4(p1); ++ XOR_BLOCK_4(p2); ++ XOR_BLOCK_4(p3); ++ PUT_BLOCK_4(p1); ++ } while (--lines); ++} ++ ++static void ++xor_nds32regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 2; ++ register unsigned int a1 __asm__("r8"); ++ register unsigned int a2 __asm__("r9"); ++ register unsigned int b1 __asm__("p0"); ++ register unsigned int b2 __asm__("ra"); ++ ++ do { ++ GET_BLOCK_2(p1); ++ XOR_BLOCK_2(p2); ++ XOR_BLOCK_2(p3); ++ XOR_BLOCK_2(p4); ++ PUT_BLOCK_2(p1); ++ } while (--lines); ++} ++ ++static void ++xor_nds32regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, ++ unsigned long *p3, unsigned long *p4, unsigned long *p5) ++{ ++ unsigned int lines = bytes / sizeof(unsigned long) / 2; ++ register unsigned int a1 __asm__("r8"); ++ register unsigned int a2 __asm__("r9"); ++ register unsigned int b1 __asm__("p0"); ++ register unsigned int b2 __asm__("ra"); ++ ++ do { ++ GET_BLOCK_2(p1); ++ XOR_BLOCK_2(p2); ++ XOR_BLOCK_2(p3); ++ XOR_BLOCK_2(p4); ++ XOR_BLOCK_2(p5); ++ PUT_BLOCK_2(p1); ++ } while (--lines); ++} ++ ++static struct xor_block_template xor_block_nds32regs = { ++ .name = "nds32regs", ++ .do_2 = xor_nds32regs_2, ++ .do_3 = xor_nds32regs_3, ++ .do_4 = xor_nds32regs_4, ++ .do_5 = xor_nds32regs_5, ++}; ++ ++#undef XOR_TRY_TEMPLATES ++#define XOR_TRY_TEMPLATES \ ++ do { \ ++ xor_speed(&xor_block_nds32regs); \ ++ xor_speed(&xor_block_8regs); \ ++ xor_speed(&xor_block_32regs); \ ++ } while (0) +diff -Nur linux-3.4.110.orig/arch/nds32/Kconfig linux-3.4.110/arch/nds32/Kconfig +--- linux-3.4.110.orig/arch/nds32/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/Kconfig 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,249 @@ ++# ++# For a description of the syntax of this configuration file, ++# see Documentation/kbuild/kconfig-language.txt. ++# ++ ++config NDS32 ++ bool ++ default y ++ select RTC_LIB ++ select HAVE_OPROFILE ++ select HAVE_ARCH_KGDB ++ select HAVE_KPROBES ++ select HAVE_KRETPROBES ++ select HAVE_FUNCTION_TRACER ++ select HAVE_FUNCTION_GRAPH_TRACER ++ select HAVE_FUNCTION_TRACE_MCOUNT_TEST ++ select SYS_SUPPORTS_APM_EMULATION ++ select HAVE_IDE ++ select HAVE_MEMBLOCK ++ select HAVE_MEMBLOCK_NODE_MAP ++ ++config GENERIC_GPIO ++ bool ++ default n ++ ++config GENERIC_TIME ++ bool ++ default y ++ ++config GENERIC_CLOCKEVENTS ++ bool ++ default y ++ ++config NO_IOPORT ++ bool ++ default y ++ ++config GENERIC_IOMAP ++ def_bool y ++ ++config GENERIC_LOCKBREAK ++ bool ++ default y ++ depends on SMP && PREEMPT ++ ++config RWSEM_GENERIC_SPINLOCK ++ bool ++ default y ++ ++config RWSEM_XCHGADD_ALGORITHM ++ bool ++ ++config GENERIC_HWEIGHT ++ bool ++ default y ++ ++config GENERIC_FIND_NEXT_BIT ++ bool ++ default y ++ ++config GENERIC_CALIBRATE_DELAY ++ bool ++ default y ++ ++config GENERIC_BUST_SPINLOCK ++ bool ++ ++config GENERIC_HARDIRQS ++ bool ++ default y ++ ++config GENERIC_HARDIRQS_NO__DO_IRQ ++ def_bool y ++ ++config LOCKDEP_SUPPORT ++ bool ++ default y ++ ++config STACKTRACE_SUPPORT ++ bool ++ default y ++ ++config HAVE_LATENCYTOP_SUPPORT ++ def_bool y ++ ++source "init/Kconfig" ++source "kernel/Kconfig.freezer" ++ ++menu "System Type" ++source "arch/nds32/platforms/Kconfig" ++source "arch/nds32/Kconfig.cpu" ++ ++config VECTORS_BASE ++ hex ++ default 0xfeff0000 if MMU || CPU_HIGH_VECTOR ++ default DRAM_BASE if REMAP_VECTORS_TO_RAM ++ default 0x00000000 ++ help ++ The base address of exception vectors. ++ ++config MMU ++ bool ++ default y ++ ++endmenu ++ ++menu "Kernel Features" ++source "kernel/time/Kconfig" ++ ++config SMP ++ bool "Symmetric Multi-Processing" ++ depends on PLATFORM_AMIC ++ select USE_GENERIC_SMP_HELPERS ++ help ++ This enables support for systems with more than one CPU. If you have ++ a system with only one CPU, like most personal computers, say N. If ++ you have a system with more than one CPU, say Y. ++ ++ If you say N here, the kernel will run on single and multiprocessor ++ machines, but will use only one CPU of a multiprocessor machine. If ++ you say Y here, the kernel will run on many, but not all, single ++ processor machines. On a single processor machine, the kernel will ++ run faster if you say N here. ++ ++ See also the , ++ , , ++ and the SMP-HOWTO available at ++ . ++ ++ If you don't know what to do here, say N. ++ ++config NR_CPUS ++ int "Maximum number of CPUs (2-32)" ++ depends on SMP ++ default "4" ++ ++source "kernel/Kconfig.preempt" ++source "mm/Kconfig" ++ ++config FORCE_MAX_ZONEORDER ++ int "MAX_ORDER for the Page Allocator" ++ default "11" ++ ++source "kernel/Kconfig.hz" ++ ++config CMDLINE ++ string "Default kernel command string" ++ default "mem=64M@0x0 initrd=0x800000,8M root=/dev/ram0 rw console=ttyS0,38400n8 rootfstype=ext2 init=/sbin/init -s" ++ ++endmenu ++ ++menu "Power management options" ++ ++config SYS_SUPPORTS_APM_EMULATION ++ bool ++ ++config ARCH_SUSPEND_POSSIBLE ++ def_bool y ++ ++source "kernel/power/Kconfig" ++ ++if PLAT_AG101 || PLAT_AG102 ++source "drivers/cpufreq/Kconfig" ++ ++if PLAT_AG101 ++choice ++ prompt "Default CPUFreq Implementation" ++ depends on CPU_FREQ ++ default AG101_CPU_FREQ_SCALING_MODE ++ help ++ This option sets which CPUFreq governor shall be loaded at ++ startup. If in doubt, select 'performance'. ++config AG101_CPU_FREQ_SCALING_MODE ++ bool "AG101 Frequency Scaling Mode" ++ help ++ Rescale CPU frequency and Bus clock without changing PLL. ++ ++config AG101_CPU_FREQ_FCS ++ bool "AG101 Frequency Change Sequence (FCS)" ++ help ++ The Frequency Change Sequence (FCS) is used to change the system ++ clock frequency. While in the FCS, the system clocks stop. This ++ mode is intended for setting a different frequency to overwrite ++ the default value at initial boot-up. This can be used as a powr- ++ saving feature that allows the AG101 to run at the minimum required ++ frequency ++endchoice ++endif ++ ++if PLAT_AG102 ++choice ++ prompt "Default CPUFreq Implementation" ++ depends on CPU_FREQ ++ default AG102_CPU_FREQ_SCALING_MODE ++ help ++ This option sets which CPUFreq governor shall be loaded at ++ startup. If in doubt, select 'performance'. ++config AG102_CPU_FREQ_SCALING_MODE ++ bool "AG102 Frequency Scaling Mode" ++ help ++ Rescale CPU frequency and Bus clock without changing PLL. ++ ++config AG102_CPU_FREQ_FCS ++ bool "AG102 Frequency Change Sequence (FCS)" ++ help ++ The Frequency Change Sequence (FCS) is used to change the system ++ clock frequency. While in the FCS, the system clocks stop. This ++ mode is intended for setting a different frequency to overwrite ++ the default value at initial boot-up. This can be used as a powr- ++ saving feature that allows the AG101 to run at the minimum required ++ frequency ++endchoice ++endif ++ ++ ++endif ++ ++endmenu ++ ++menu "Bus options" ++ ++config PCI ++ bool "PCI support" ++ help ++ Find out whether you have a PCI motherboard. PCI is the name of a ++ bus system, i.e. the way the CPU talks to the other stuff inside ++ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or ++ VESA. If you have PCI, say Y, otherwise N. ++ ++ The PCI-HOWTO, available from ++ , contains valuable ++ information about which PCI hardware does work under Linux and which ++ doesn't. ++ ++source "drivers/pci/Kconfig" ++ ++endmenu ++ ++menu "Executable file formats" ++source "fs/Kconfig.binfmt" ++endmenu ++ ++source "net/Kconfig" ++source "drivers/Kconfig" ++source "fs/Kconfig" ++source "arch/nds32/Kconfig.debug" ++source "security/Kconfig" ++source "crypto/Kconfig" ++source "lib/Kconfig" +diff -Nur linux-3.4.110.orig/arch/nds32/Kconfig.cpu linux-3.4.110/arch/nds32/Kconfig.cpu +--- linux-3.4.110.orig/arch/nds32/Kconfig.cpu 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/Kconfig.cpu 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,148 @@ ++comment "Processor Features" ++config CPU_N1213 ++ bool ++ ++config CPU_N1213_43U1HA0 ++ bool ++ ++config CPU_N1233F ++ bool ++ ++config CPU_CUSTOM ++ bool ++ ++config FPU ++ bool "fpu support" ++ ++config UNLAZY_FPU ++ bool "Unlazy FPU support" ++ depends on FPU ++ help ++ Say Y here to enable unlazy FPU and disable lazy FPU. ++ ++ ++config AUDIO ++ bool "audio support" if CPU_CUSTOM ++ ++config HWZOL ++ bool "hardware zero overhead loop support" ++ default y ++ ++config UNLAZY_AUDIO ++ bool "Unlazy audio support" ++ depends on AUDIO ++ help ++ Say Y here to enable unlazy audio and disable lazy audio. ++choice ++ prompt "Vector Interrupt Controller mode" ++ default IVIC_INTC ++config IVIC_INTC ++ bool "IVIC mode with Interrupt Controller" ++config IVIC ++ bool "IVIC mode" ++config EVIC ++ bool "EVIC mode" ++endchoice ++ ++config CPU_NO_CONTEXT_ID ++ def_bool CPU_N1213_43U1HA0 || SMP ++ ++config CPU_CACHE_NONALIASING ++ bool "Non-aliasing cache" ++ ++choice ++ prompt "Paging -- page size " ++ default ANDES_PAGE_SIZE_4KB ++config ANDES_PAGE_SIZE_4KB ++ bool "use 4KB page size" ++config ANDES_PAGE_SIZE_8KB ++ bool "use 8KB page size" ++endchoice ++ ++config NO_KERNEL_LARGE_PAGE ++ def_bool CPU_N1213_43U1HA0 || SMP ++ ++config CPU_ICACHE_DISABLE ++ bool "Disable I-Cache" ++ help ++ Say Y here to disable the processor instruction cache. Unless ++ you have a reason not to or are unsure, say N. ++ ++config CPU_DCACHE_DISABLE ++ bool "Disable D-Cache" ++ help ++ Say Y here to disable the processor data cache. Unless ++ you have a reason not to or are unsure, say N. ++ ++config CPU_DCACHE_WRITETHROUGH ++ bool "Force write through D-cache" ++ depends on !CPU_DCACHE_DISABLE ++ help ++ Say Y here to use the data cache in writethrough mode. Unless you ++ specifically require this or are unsure, say N. ++ ++config KEXEC ++ bool "Kexec system call (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ help ++ kexec is a system call that implements the ability to shutdown your ++ current kernel, and to start another kernel. It is like a reboot ++ but it is independent of the system firmware. And like a reboot ++ you can start any kernel with it, not just Linux. ++ ++ It is an ongoing process to be certain the hardware in a machine ++ is properly shutdown, so do not be surprised if this code does not ++ initially work for you. It may help to enable device hotplugging ++ support. ++ ++config ABI1 ++ bool "Allow ABI 1 binaries to run with this kernel (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ default n ++ help ++ This option preserves the old syscall interface of ABI 1. If ++ you know you'll be using ABI 2 or 2fp then you can say N here. ++ If this option is not selected and you attempt to execute a ++ legacy ABI binary then the result will be UNPREDICTABLE ++ (in fact it can be predicted that it won't work at all). If ++ in doubt say Y. ++ ++config WBNA ++ bool "WBNA" ++ default n ++ help ++ Say Y here to enable write-back memory with no-write-allocation policy. ++ ++config HSS ++ bool "Using Hardware Single-Step (HSS) instead of software breakpoint" ++ default y ++ ++config ALIGNMENT_TRAP ++ tristate "Kernel support unaligned access handling" ++ depends on EXPERIMENTAL ++ default y ++ help ++ Andes processors cannot fetch/store information which is not ++ naturally aligned on the bus, i.e., a 4 byte fetch must start at an ++ address divisible by 4. On 32-bit Andes processors, these non-aligned ++ fetch/store instructions will be emulated in software if you say ++ here, which has a severe performance impact. This is necessary for ++ correct operation of some network protocols. With an IP-only ++ configuration it is safe to say N, otherwise say Y. ++ ++config HIGHMEM ++ bool "High Memory Support" ++ depends on MMU ++ help ++ The address space of ARM processors is only 4 Gigabytes large ++ and it has to accommodate user address space, kernel address ++ space as well as some memory mapped IO. That means that, if you ++ have a large amount of physical memory and/or IO, not all of the ++ memory can be "permanently mapped" by the kernel. The physical ++ memory that is not permanently mapped is called "high memory". ++ ++ Depending on the selected kernel/user memory split, minimum ++ vmalloc space and actual amount of RAM, you may not need this ++ option which should result in a slightly faster kernel. ++ ++ If unsure, say n. +diff -Nur linux-3.4.110.orig/arch/nds32/Kconfig.debug linux-3.4.110/arch/nds32/Kconfig.debug +--- linux-3.4.110.orig/arch/nds32/Kconfig.debug 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/Kconfig.debug 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,82 @@ ++menu "Kernel hacking" ++ ++config TRACE_IRQFLAGS_SUPPORT ++ bool ++ default y ++ ++source "lib/Kconfig.debug" ++ ++config FRAME_POINTER ++ bool ++ default y ++ help ++ If you say N here, the resulting kernel will be slightly smaller and ++ faster. However, when a problem occurs with the kernel, the ++ information that is reported is severely limited. Most people ++ should say Y here. ++ ++config DEBUG_USER ++ bool "Verbose user fault messages" ++ help ++ When a user program crashes due to an exception, the kernel can ++ print a brief message explaining what the problem was. This is ++ sometimes helpful for debugging but serves no purpose on a ++ production system. Most people should say N here. ++ ++ In addition, you need to pass user_debug=N on the kernel command ++ line to enable this feature. N consists of the sum of: ++ ++ 1 - undefined instruction events ++ 2 - system calls ++ 4 - invalid data aborts ++ 8 - SIGSEGV faults ++ 16 - SIGBUS faults ++ ++config DEBUG_ERRORS ++ bool "Verbose kernel error messages" ++ depends on DEBUG_KERNEL ++ help ++ This option controls verbose debugging information which can be ++ printed when the kernel detects an internal error. This debugging ++ information is useful to kernel hackers when tracking down problems, ++ but mostly meaningless to other people. It's safe to say Y unless ++ you are concerned with the code size or don't want to see these ++ messages. ++ ++config DEBUG_LL ++ bool "Kernel low-level debugging functions" ++ depends on DEBUG_KERNEL ++ help ++ Say Y here to include definitions of printascii, printchar, printhex ++ in the kernel. This is helpful if you are debugging code that ++ executes before the console is initialized. ++ ++config CCTL ++ tristate "User space cache control support (EXPERIMENTAL)" ++ depends on EXPERIMENTAL ++ help ++ export cache control to user space via /proc ++ ++ If unsure, say N. ++ ++config ELFCHK_DEFAULT_ENABLE ++ bool "Enable ELF-Core Checking by default" ++ default n ++ select PROC_FS ++ help ++ ELF-Core Checking is a mechanism which prevents ELF binary from ++ being loaded if it requires any feature that the underlying platform ++ doesn't support. ++ ++ If you say Y here, the resulting kernel enables ELF-Core Checking ++ mechanism by default. ++config EARLY_PRINTK ++ bool "Early printk support" ++ default y ++ help ++ Say Y here if you want to have an early console using the ++ earlyprintk=[,][,] kernel parameter. It ++ is assumed that the early console device has been initialised ++ by the boot loader prior to starting the Linux kernel. ++ ++endmenu +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/asm-offsets.c linux-3.4.110/arch/nds32/kernel/asm-offsets.c +--- linux-3.4.110.orig/arch/nds32/kernel/asm-offsets.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/asm-offsets.c 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 1995-2003 Russell King ++ * 2001-2002 Keith Owens ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * Generate definitions needed by assembly language modules. ++ * This code generates raw asm output which is post-processed to extract ++ * and format the required data. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Make sure that the compiler and target are compatible. ++ */ ++ ++#if __GNUC__ < 3 || \ ++ (__GNUC__ == 3 && __GNUC_MINOR__ < 4) || \ ++ (__GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ != 0 && \ ++ __GNUC_PATCHLEVEL__ < 4) || \ ++ (__GNUC__ == 4 && __GNUC_MINOR__ < 2) ++#error Your compiler is too buggy; it is known to miscompile kernels. ++#error Known good compilers: 3.4.4, 4.2 ++#endif ++ ++/* Use marker if you need to separate the values later */ ++ ++#define DEFINE(sym, val) \ ++ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) ++ ++#define BLANK() asm volatile("\n->" : : ) ++ ++int main(void) ++{ ++ DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); ++ BLANK(); ++ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); ++ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); ++ DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); ++ DEFINE(TI_TASK, offsetof(struct thread_info, task)); ++ DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); ++ DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); ++// DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); ++ DEFINE(TI_SP_SAVE, offsetof(struct thread_info, sp_save)); ++ BLANK(); ++ DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); ++ BLANK(); ++ DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); ++ BLANK(); ++ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); ++ DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags)); ++ BLANK(); ++ DEFINE(VM_EXEC, VM_EXEC); ++ BLANK(); ++ DEFINE(VIRT_OFFSET, PAGE_OFFSET); ++ BLANK(); ++ DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); ++ DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr)); ++ DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); ++ BLANK(); ++ DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list)); ++ ++ return 0; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/audio.c linux-3.4.110/arch/nds32/kernel/audio.c +--- linux-3.4.110.orig/arch/nds32/kernel/audio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/audio.c 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,218 @@ ++/* ++ * arch/nds32/kernel/audio.c ++ * ++ * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli ++ * Copyright (C) 2002 STMicroelectronics Limited ++ * Author : Stuart Menefy ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * Started from SH4 version: ++ * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "audio.h" ++/* ++ * Initially load the audio with signalling NANS. This bit pattern ++ * has the property that no matter whether considered as single or as ++ * double precision, it still represents a signalling NAN. ++ */ ++ ++static struct audio_struct init_audioregs = { ++ .auregs = {[0...31] = NAN32} ++}; ++ ++void save_audio(struct task_struct *tsk) ++{ ++ unsigned int tmp; ++ enable_audio(); ++ asm volatile ("mfsr %0, $MSC_CFG\n\t" ++ "andi %0, %0, %2\n\t" ++ "srli %0, %0, %3\n\t" ++ "slti %0, %0, 2\n\t" ++ "bnez %0, 99f\n\t" ++ "amfar %0, $D0.L24\n\t" ++ "swi %0, [%1+0x0]\n\t" ++ "amfar %0, $D1.L24\n\t" ++ "swi %0, [%1+0x4]\n\t" ++ "99:\n\t" ++ "amfar %0, $I0\n\t" ++ "swi %0, [%1+0x8]\n\t" ++ "amfar %0, $I1\n\t" ++ "swi %0, [%1+0xc]\n\t" ++ "amfar %0, $I2\n\t" ++ "swi %0, [%1+0x10]\n\t" ++ "amfar %0, $I3\n\t" ++ "swi %0, [%1+0x14]\n\t" ++ "amfar %0, $I4\n\t" ++ "swi %0, [%1+0x18]\n\t" ++ "amfar %0, $I5\n\t" ++ "swi %0, [%1+0x1c]\n\t" ++ "amfar %0, $I6\n\t" ++ "swi %0, [%1+0x20]\n\t" ++ "amfar %0, $I7\n\t" ++ "swi %0, [%1+0x24]\n\t" ++ "amfar %0, $M1\n\t" ++ "swi %0, [%1+0x28]\n\t" ++ "amfar %0, $M2\n\t" ++ "swi %0, [%1+0x2c]\n\t" ++ "amfar %0, $M3\n\t" ++ "swi %0, [%1+0x30]\n\t" ++ "amfar %0, $M5\n\t" ++ "swi %0, [%1+0x34]\n\t" ++ "amfar %0, $M6\n\t" ++ "swi %0, [%1+0x38]\n\t" ++ "amfar %0, $M7\n\t" ++ "swi %0, [%1+0x3c]\n\t" ++ "amfar %0, $MOD\n\t" ++ "swi %0, [%1+0x40]\n\t" ++ "amfar %0, $LB\n\t" ++ "swi %0, [%1+0x44]\n\t" ++ "amfar %0, $LE\n\t" ++ "swi %0, [%1+0x48]\n\t" ++ "amfar %0, $LC\n\t" ++ "swi %0, [%1+0x4c]\n\t" ++ "amfar %0, $ADM_VBASE\n\t" ++ "swi %0, [%1+0x50]\n\t" ++ "amfar %0, $SHFT_CTL0\n\t" ++ "swi %0, [%1+0x54]\n\t" ++ "amfar %0, $SHFT_CTL1\n\t" ++ "swi %0, [%1+0x58]\n\t" ++ "amfar2 %0, $CB_CTL\n\t" ++ "swi %0, [%1+0x5c]\n\t" ++ "amfar2 %0, $CBB0\n\t" ++ "swi %0, [%1+0x60]\n\t" ++ "amfar2 %0, $CBB1\n\t" ++ "swi %0, [%1+0x64]\n\t" ++ "amfar2 %0, $CBB2\n\t" ++ "swi %0, [%1+0x68]\n\t" ++ "amfar2 %0, $CBB3\n\t" ++ "swi %0, [%1+0x6c]\n\t" ++ "amfar2 %0, $CBE0\n\t" ++ "swi %0, [%1+0x70]\n\t" ++ "amfar2 %0, $CBE1\n\t" ++ "swi %0, [%1+0x74]\n\t" ++ "amfar2 %0, $CBE2\n\t" ++ "swi %0, [%1+0x78]\n\t" ++ "amfar2 %0, $CBE3\n\t" ++ "swi %0, [%1+0x7c]\n\t":"=&r" (tmp) ++ :"r"(&tsk->thread.audio), "i"(MSC_CFG_mskAUDIO), ++ "i"(MSC_CFG_offAUDIO) ++ :"memory"); ++ disable_audio(); ++} ++ ++void audioload(struct audio_struct *audioregs) ++{ ++ unsigned int tmp; ++ enable_audio(); ++ asm volatile ("mfsr %0, $MSC_CFG\n\t" ++ "andi %0, %0, %2\n\t" ++ "srli %0, %0, %3\n\t" ++ "slti %0, %0, 2\n\t" ++ "bnez %0, 98f\n\t" ++ "lwi %0, [%1+0x0]\n\t" ++ "amtar %0, $D0.L24\n\t" ++ "lwi %0, [%1+0x4]\n\t" ++ "amtar %0, $D1.L24\n\t" ++ "98:\n\t" ++ "lwi %0, [%1+0x8]\n\t" ++ "amtar %0, $I0\n\t" ++ "lwi %0, [%1+0xc]\n\t" ++ "amtar %0, $I1\n\t" ++ "lwi %0, [%1+0x10]\n\t" ++ "amtar %0, $I2\n\t" ++ "lwi %0, [%1+0x14]\n\t" ++ "amtar %0, $I3\n\t" ++ "lwi %0, [%1+0x18]\n\t" ++ "amtar %0, $I4\n\t" ++ "lwi %0, [%1+0x1c]\n\t" ++ "amtar %0, $I5\n\t" ++ "lwi %0, [%1+0x20]\n\t" ++ "amtar %0, $I6\n\t" ++ "lwi %0, [%1+0x24]\n\t" ++ "amtar %0, $I7\n\t" ++ "lwi %0, [%1+0x28]\n\t" ++ "amtar %0, $M1\n\t" ++ "lwi %0, [%1+0x2c]\n\t" ++ "amtar %0, $M2\n\t" ++ "lwi %0, [%1+0x30]\n\t" ++ "amtar %0, $M3\n\t" ++ "lwi %0, [%1+0x34]\n\t" ++ "amtar %0, $M5\n\t" ++ "lwi %0, [%1+0x38]\n\t" ++ "amtar %0, $M6\n\t" ++ "lwi %0, [%1+0x3c]\n\t" ++ "amtar %0, $M7\n\t" ++ "lwi %0, [%1+0x40]\n\t" ++ "amtar %0, $MOD\n\t" ++ "lwi %0, [%1+0x44]\n\t" ++ "amtar %0, $LB\n\t" ++ "lwi %0, [%1+0x48]\n\t" ++ "amtar %0, $LE\n\t" ++ "lwi %0, [%1+0x4c]\n\t" ++ "amtar %0, $LC\n\t" ++ "lwi %0, [%1+0x50]\n\t" ++ "amtar %0, $ADM_VBASE\n\t" ++ "lwi %0, [%1+0x54]\n\t" ++ "amtar %0, $SHFT_CTL0\n\t" ++ "lwi %0, [%1+0x58]\n\t" ++ "amtar %0, $SHFT_CTL1\n\t" ++ "lwi %0, [%1+0x5c]\n\t" ++ "amtar2 %0, $CB_CTL\n\t" ++ "lwi %0, [%1+0x60]\n\t" ++ "amtar2 %0, $CBB0\n\t" ++ "lwi %0, [%1+0x64]\n\t" ++ "amtar2 %0, $CBB1\n\t" ++ "lwi %0, [%1+0x68]\n\t" ++ "amtar2 %0, $CBB2\n\t" ++ "lwi %0, [%1+0x6c]\n\t" ++ "amtar2 %0, $CBB3\n\t" ++ "lwi %0, [%1+0x70]\n\t" ++ "amtar2 %0, $CBE0\n\t" ++ "lwi %0, [%1+0x74]\n\t" ++ "amtar2 %0, $CBE1\n\t" ++ "lwi %0, [%1+0x78]\n\t" ++ "amtar2 %0, $CBE2\n\t" ++ "lwi %0, [%1+0x7c]\n\t" ++ "amtar2 %0, $CBE3\n\t":"=&r" (tmp) ++ :"r"(audioregs), "i"(MSC_CFG_mskAUDIO), ++ "i"(MSC_CFG_offAUDIO)); ++ disable_audio(); ++} ++ ++void do_audio_context_switch(unsigned long error_code, struct pt_regs *regs) ++{ ++ struct task_struct *tsk = current; ++ ++ if (!user_mode(regs)) ++ die("Audio used in kernel", regs, error_code); ++ ++ /* Enable to use audio. */ ++ grab_audio(regs); ++#ifndef CONFIG_UNLAZY_AUDIO //Lazy audio is used ++ if (last_task_used_audio == current) ++ return; ++ ++ if (last_task_used_audio != NULL) ++ /* Other processes audio state, save away */ ++ save_audio(last_task_used_audio); ++ last_task_used_audio = current; ++#endif ++ if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { ++ audioload(¤t->thread.audio); ++ } else { ++ /* First time audio user. */ ++ audioload(&init_audioregs); ++ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/audio.h linux-3.4.110/arch/nds32/kernel/audio.h +--- linux-3.4.110.orig/arch/nds32/kernel/audio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/audio.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,2 @@ ++ ++#define NAN32 0x0UL +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/bios32.c linux-3.4.110/arch/nds32/kernel/bios32.c +--- linux-3.4.110.orig/arch/nds32/kernel/bios32.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/bios32.c 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,711 @@ ++/* ++ * linux/arch/nds32/kernel/bios32.c ++ * ++ * PCI bios-type initialisation for PCI machines ++ * ++ * Bits taken from various places. ++ * ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++static int debug_pci; ++static int use_firmware; ++ ++/* ++ * We can't use pci_find_device() here since we are ++ * called from interrupt context. ++ */ ++static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, ++ int warn) ++{ ++ struct pci_dev *dev; ++ ++ list_for_each_entry(dev, &bus->devices, bus_list) { ++ u16 status; ++ ++ /* ++ * ignore host bridge - we handle ++ * that separately ++ */ ++ if (dev->bus->number == 0 && dev->devfn == 0) ++ continue; ++ ++ pci_read_config_word(dev, PCI_STATUS, &status); ++ if (status == 0xffff) ++ continue; ++ ++ if ((status & status_mask) == 0) ++ continue; ++ ++ /* clear the status errors */ ++ pci_write_config_word(dev, PCI_STATUS, status & status_mask); ++ ++ if (warn) ++ printk("(%s: %04X) ", pci_name(dev), status); ++ } ++ ++ list_for_each_entry(dev, &bus->devices, bus_list) ++ if (dev->subordinate) ++ pcibios_bus_report_status(dev->subordinate, status_mask, warn); ++} ++ ++void pcibios_report_status(u_int status_mask, int warn) ++{ ++ struct list_head *l; ++ ++ list_for_each(l, &pci_root_buses) { ++ struct pci_bus *bus = pci_bus_b(l); ++ ++ pcibios_bus_report_status(bus, status_mask, warn); ++ } ++} ++ ++/* ++ * We don't use this to fix the device, but initialisation of it. ++ * It's not the correct use for this, but it works. ++ * Note that the arbiter/ISA bridge appears to be buggy, specifically in ++ * the following area: ++ * 1. park on CPU ++ * 2. ISA bridge ping-pong ++ * 3. ISA bridge master handling of target RETRY ++ * ++ * Bug 3 is responsible for the sound DMA grinding to a halt. We now ++ * live with bug 2. ++ */ ++static void __devinit pci_fixup_83c553(struct pci_dev *dev) ++{ ++ /* ++ * Set memory region to start at address 0, and enable IO ++ */ ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ++ PCI_BASE_ADDRESS_SPACE_MEMORY); ++ pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO); ++ ++ dev->resource[0].end -= dev->resource[0].start; ++ dev->resource[0].start = 0; ++ ++ /* ++ * All memory requests from ISA to be channelled to PCI ++ */ ++ pci_write_config_byte(dev, 0x48, 0xff); ++ ++ /* ++ * Enable ping-pong on bus master to ISA bridge transactions. ++ * This improves the sound DMA substantially. The fixed ++ * priority arbiter also helps (see below). ++ */ ++ pci_write_config_byte(dev, 0x42, 0x01); ++ ++ /* ++ * Enable PCI retry ++ */ ++ pci_write_config_byte(dev, 0x40, 0x22); ++ ++ /* ++ * We used to set the arbiter to "park on last master" (bit ++ * 1 set), but unfortunately the CyberPro does not park the ++ * bus. We must therefore park on CPU. Unfortunately, this ++ * may trigger yet another bug in the 553. ++ */ ++ pci_write_config_byte(dev, 0x83, 0x02); ++ ++ /* ++ * Make the ISA DMA request lowest priority, and disable ++ * rotating priorities completely. ++ */ ++ pci_write_config_byte(dev, 0x80, 0x11); ++ pci_write_config_byte(dev, 0x81, 0x00); ++ ++ /* ++ * Route INTA input to IRQ 11, and set IRQ11 to be level ++ * sensitive. ++ */ ++ pci_write_config_word(dev, 0x44, 0xb000); ++ outb(0x08, 0x4d1); ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, ++ pci_fixup_83c553); ++ ++static void __devinit pci_fixup_unassign(struct pci_dev *dev) ++{ ++ dev->resource[0].end -= dev->resource[0].start; ++ dev->resource[0].start = 0; ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F, ++ pci_fixup_unassign); ++ ++/* ++ * Prevent the PCI layer from seeing the resources allocated to this device ++ * if it is the host bridge by marking it as such. These resources are of ++ * no consequence to the PCI layer (they are handled elsewhere). ++ */ ++static void __devinit pci_fixup_dec21285(struct pci_dev *dev) ++{ ++ int i; ++ ++ if (dev->devfn == 0) { ++ dev->class &= 0xff; ++ dev->class |= PCI_CLASS_BRIDGE_HOST << 8; ++ for (i = 0; i < PCI_NUM_RESOURCES; i++) { ++ dev->resource[i].start = 0; ++ dev->resource[i].end = 0; ++ dev->resource[i].flags = 0; ++ } ++ } ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, ++ pci_fixup_dec21285); ++ ++/* ++ * PCI IDE controllers use non-standard I/O port decoding, respect it. ++ */ ++static void __devinit pci_fixup_ide_bases(struct pci_dev *dev) ++{ ++ struct resource *r; ++ int i; ++ ++ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) ++ return; ++ ++ for (i = 0; i < PCI_NUM_RESOURCES; i++) { ++ r = dev->resource + i; ++ if ((r->start & ~0x80) == 0x374) { ++ r->start |= 2; ++ r->end = r->start; ++ } ++ } ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); ++ ++/* ++ * Put the DEC21142 to sleep ++ */ ++static void __devinit pci_fixup_dec21142(struct pci_dev *dev) ++{ ++ pci_write_config_dword(dev, 0x40, 0x80000000); ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, ++ pci_fixup_dec21142); ++ ++/* ++ * The CY82C693 needs some rather major fixups to ensure that it does ++ * the right thing. Idea from the Alpha people, with a few additions. ++ * ++ * We ensure that the IDE base registers are set to 1f0/3f4 for the ++ * primary bus, and 170/374 for the secondary bus. Also, hide them ++ * from the PCI subsystem view as well so we won't try to perform ++ * our own auto-configuration on them. ++ * ++ * In addition, we ensure that the PCI IDE interrupts are routed to ++ * IRQ 14 and IRQ 15 respectively. ++ * ++ * The above gets us to a point where the IDE on this device is ++ * functional. However, The CY82C693U _does not work_ in bus ++ * master mode without locking the PCI bus solid. ++ */ ++static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) ++{ ++ if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { ++ u32 base0, base1; ++ ++ if (dev->class & 0x80) { /* primary */ ++ base0 = 0x1f0; ++ base1 = 0x3f4; ++ } else { /* secondary */ ++ base0 = 0x170; ++ base1 = 0x374; ++ } ++ ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, ++ base0 | PCI_BASE_ADDRESS_SPACE_IO); ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, ++ base1 | PCI_BASE_ADDRESS_SPACE_IO); ++ ++ dev->resource[0].start = 0; ++ dev->resource[0].end = 0; ++ dev->resource[0].flags = 0; ++ ++ dev->resource[1].start = 0; ++ dev->resource[1].end = 0; ++ dev->resource[1].flags = 0; ++ } else if (PCI_FUNC(dev->devfn) == 0) { ++ /* ++ * Setup IDE IRQ routing. ++ */ ++ pci_write_config_byte(dev, 0x4b, 14); ++ pci_write_config_byte(dev, 0x4c, 15); ++ ++ /* ++ * Disable FREQACK handshake, enable USB. ++ */ ++ pci_write_config_byte(dev, 0x4d, 0x41); ++ ++ /* ++ * Enable PCI retry, and PCI post-write buffer. ++ */ ++ pci_write_config_byte(dev, 0x44, 0x17); ++ ++ /* ++ * Enable ISA master and DMA post write buffering. ++ */ ++ pci_write_config_byte(dev, 0x45, 0x03); ++ } ++} ++ ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, ++ pci_fixup_cy82c693); ++ ++void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) ++{ ++ if (debug_pci) ++ printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); ++} ++ ++/* ++ * If the bus contains any of these devices, then we must not turn on ++ * parity checking of any kind. Currently this is CyberPro 20x0 only. ++ */ ++static inline int pdev_bad_for_parity(struct pci_dev *dev) ++{ ++ return (dev->vendor == PCI_VENDOR_ID_INTERG && ++ (dev->device == PCI_DEVICE_ID_INTERG_2000 || ++ dev->device == PCI_DEVICE_ID_INTERG_2010)); ++} ++ ++/* ++ * Adjust the device resources from bus-centric to Linux-centric. ++ */ ++static void __devinit ++pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) ++{ ++ resource_size_t offset; ++ int i; ++ ++ for (i = 0; i < PCI_NUM_RESOURCES; i++) { ++ if (dev->resource[i].start == 0) ++ continue; ++ if (dev->resource[i].flags & IORESOURCE_MEM) ++ offset = root->mem_offset; ++ else ++ offset = root->io_offset; ++ ++ dev->resource[i].start += offset; ++ dev->resource[i].end += offset; ++ } ++} ++ ++static void __devinit ++pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root) ++{ ++ struct pci_dev *dev = bus->self; ++ int i; ++ ++ if (!dev) { ++ /* ++ * Assign root bus resources. ++ */ ++ for (i = 0; i < 3; i++) ++ bus->resource[i] = root->resource[i]; ++ } ++} ++ ++/* ++ * pcibios_fixup_bus - Called after each bus is probed, ++ * but before its children are examined. ++ */ ++void __devinit pcibios_fixup_bus(struct pci_bus *bus) ++{ ++ struct pci_sys_data *root = bus->sysdata; ++ struct pci_dev *dev; ++ u16 features = ++ PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK; ++ ++ pbus_assign_bus_resources(bus, root); ++ ++ /* ++ * Walk the devices on this bus, working out what we can ++ * and can't support. ++ */ ++ list_for_each_entry(dev, &bus->devices, bus_list) { ++ u16 status; ++ ++ pdev_fixup_device_resources(root, dev); ++ ++ pci_read_config_word(dev, PCI_STATUS, &status); ++ ++ /* ++ * If any device on this bus does not support fast back ++ * to back transfers, then the bus as a whole is not able ++ * to support them. Having fast back to back transfers ++ * on saves us one PCI cycle per transaction. ++ */ ++ if (!(status & PCI_STATUS_FAST_BACK)) ++ features &= ~PCI_COMMAND_FAST_BACK; ++ ++ if (pdev_bad_for_parity(dev)) ++ features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); ++ ++ switch (dev->class >> 8) { ++#if defined(CONFIG_ISA) || defined(CONFIG_EISA) ++ case PCI_CLASS_BRIDGE_ISA: ++ case PCI_CLASS_BRIDGE_EISA: ++ /* ++ * If this device is an ISA bridge, set isa_bridge ++ * to point at this device. We will then go looking ++ * for things like keyboard, etc. ++ */ ++ isa_bridge = dev; ++ break; ++#endif ++ case PCI_CLASS_BRIDGE_PCI: ++ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status); ++ status |= ++ PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_MASTER_ABORT; ++ status &= ++ ~(PCI_BRIDGE_CTL_BUS_RESET | ++ PCI_BRIDGE_CTL_FAST_BACK); ++ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status); ++ break; ++ ++ case PCI_CLASS_BRIDGE_CARDBUS: ++ pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL, ++ &status); ++ status |= ++ PCI_CB_BRIDGE_CTL_PARITY | ++ PCI_CB_BRIDGE_CTL_MASTER_ABORT; ++ pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL, ++ status); ++ break; ++ } ++ } ++ ++ /* ++ * Now walk the devices again, this time setting them up. ++ */ ++ list_for_each_entry(dev, &bus->devices, bus_list) { ++ u16 cmd; ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= features; ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, ++ L1_CACHE_BYTES >> 2); ++ } ++ ++ /* ++ * Propagate the flags to the PCI bridge. ++ */ ++ if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) { ++ if (features & PCI_COMMAND_FAST_BACK) ++ bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK; ++ if (features & PCI_COMMAND_PARITY) ++ bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY; ++ } ++ ++ /* ++ * Report what we did for this bus ++ */ ++ printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", ++ bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); ++} ++ ++/* ++ * Convert from Linux-centric to bus-centric addresses for bridge devices. ++ */ ++void ++pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, ++ struct resource *res) ++{ ++ struct pci_sys_data *root = dev->sysdata; ++ unsigned long offset = 0; ++ ++ if (res->flags & IORESOURCE_IO) ++ offset = root->io_offset; ++ if (res->flags & IORESOURCE_MEM) ++ offset = root->mem_offset; ++ ++ region->start = res->start - offset; ++ region->end = res->end - offset; ++} ++ ++void __devinit ++pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, ++ struct pci_bus_region *region) ++{ ++ struct pci_sys_data *root = dev->sysdata; ++ unsigned long offset = 0; ++ ++ if (res->flags & IORESOURCE_IO) ++ offset = root->io_offset; ++ if (res->flags & IORESOURCE_MEM) ++ offset = root->mem_offset; ++ ++ res->start = region->start + offset; ++ res->end = region->end + offset; ++} ++ ++#ifdef CONFIG_HOTPLUG ++EXPORT_SYMBOL(pcibios_fixup_bus); ++EXPORT_SYMBOL(pcibios_resource_to_bus); ++EXPORT_SYMBOL(pcibios_bus_to_resource); ++#endif ++ ++/* ++ * This is the standard PCI-PCI bridge swizzling algorithm: ++ * ++ * Dev: 0 1 2 3 ++ * A A B C D ++ * B B C D A ++ * C C D A B ++ * D D A B C ++ * ^^^^^^^^^^ irq pin on bridge ++ */ ++u8 __devinit pci_std_swizzle(struct pci_dev *dev, u8 * pinp) ++{ ++ int pin = *pinp - 1; ++ ++ while (dev->bus->self) { ++ pin = (pin + PCI_SLOT(dev->devfn)) & 3; ++ /* ++ * move up the chain of bridges, ++ * swizzling as we go. ++ */ ++ dev = dev->bus->self; ++ } ++ *pinp = pin + 1; ++ ++ return PCI_SLOT(dev->devfn); ++} ++ ++/* ++ * Swizzle the device pin each time we cross a bridge. ++ * This might update pin and returns the slot number. ++ */ ++static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 * pin) ++{ ++ struct pci_sys_data *sys = dev->sysdata; ++ int slot = 0, oldpin = *pin; ++ ++ if (sys->swizzle) ++ slot = sys->swizzle(dev, pin); ++ ++ if (debug_pci) ++ printk("PCI: %s swizzling pin %d => pin %d slot %d\n", ++ pci_name(dev), oldpin, *pin, slot); ++ ++ return slot; ++} ++ ++/* ++ * Map a slot/pin to an IRQ. ++ */ ++static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ struct pci_sys_data *sys = dev->sysdata; ++ int irq = -1; ++ ++ if (sys->map_irq) ++ irq = sys->map_irq(dev, slot, pin); ++ ++ if (debug_pci) ++ printk("PCI: %s mapping slot %d pin %d => irq %d\n", ++ pci_name(dev), slot, pin, irq); ++ ++ return irq; ++} ++ ++static void __init pcibios_init_hw(struct hw_pci *hw) ++{ ++ struct pci_sys_data *sys = NULL; ++ int ret; ++ int nr, busnr; ++ ++ for (nr = busnr = 0; nr < hw->nr_controllers; nr++) { ++ sys = kmalloc(sizeof(struct pci_sys_data), GFP_KERNEL); ++ if (!sys) ++ panic("PCI: unable to allocate sys data!"); ++ ++ memset(sys, 0, sizeof(struct pci_sys_data)); ++ ++ sys->hw = hw; ++ sys->busnr = busnr; ++ sys->swizzle = hw->swizzle; ++ sys->map_irq = hw->map_irq; ++ sys->resource[0] = &ioport_resource; ++ sys->resource[1] = &iomem_resource; ++ ++ ret = hw->setup(nr, sys); ++ ++ if (ret > 0) { ++ sys->bus = hw->scan(nr, sys); ++ ++ if (!sys->bus) ++ panic("PCI: unable to scan bus!"); ++ ++ busnr = sys->bus->subordinate + 1; ++ ++ list_add(&sys->node, &hw->buses); ++ } else { ++ kfree(sys); ++ if (ret < 0) ++ break; ++ } ++ } ++} ++ ++void __init pci_common_init(struct hw_pci *hw) ++{ ++ struct pci_sys_data *sys; ++ ++ INIT_LIST_HEAD(&hw->buses); ++ ++ if (hw->preinit) ++ hw->preinit(); ++ pcibios_init_hw(hw); ++ if (hw->postinit) ++ hw->postinit(); ++ ++ pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); ++ ++ list_for_each_entry(sys, &hw->buses, node) { ++ struct pci_bus *bus = sys->bus; ++ ++ if (!use_firmware) { ++ /* ++ * Size the bridge windows. ++ */ ++ pci_bus_size_bridges(bus); ++ ++ /* ++ * Assign resources. ++ */ ++ pci_bus_assign_resources(bus); ++ } ++ ++ /* ++ * Tell drivers about devices found. ++ */ ++ pci_bus_add_devices(bus); ++ } ++} ++ ++char *__devinit pcibios_setup(char *str) ++{ ++ if (!strcmp(str, "debug")) { ++ debug_pci = 1; ++ return NULL; ++ } else if (!strcmp(str, "firmware")) { ++ use_firmware = 1; ++ return NULL; ++ } ++ return str; ++} ++ ++/* ++ * From arch/i386/kernel/pci-i386.c: ++ * ++ * We need to avoid collisions with `mirrored' VGA ports ++ * and other strange ISA hardware, so we always want the ++ * addresses to be allocated in the 0x000-0x0ff region ++ * modulo 0x400. ++ * ++ * Why? Because some silly external IO cards only decode ++ * the low 10 bits of the IO address. The 0x00-0xff region ++ * is reserved for motherboard devices that decode all 16 ++ * bits, so it's ok to allocate at, say, 0x2800-0x28ff, ++ * but we want to try to avoid allocating at 0x2900-0x2bff ++ * which might be mirrored at 0x0100-0x03ff.. ++ */ ++void pcibios_align_resource(void *data, struct resource *res, ++ resource_size_t size, resource_size_t align) ++{ ++ resource_size_t start = res->start; ++ ++ if (res->flags & IORESOURCE_IO && start & 0x300) ++ start = (start + 0x3ff) & ~0x3ff; ++ ++ res->start = (start + align - 1) & ~(align - 1); ++} ++ ++/** ++ * pcibios_enable_device - Enable I/O and memory. ++ * @dev: PCI device to be enabled ++ */ ++int pcibios_enable_device(struct pci_dev *dev, int mask) ++{ ++ u16 cmd, old_cmd; ++ int idx; ++ struct resource *r; ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ old_cmd = cmd; ++ for (idx = 0; idx < 6; idx++) { ++ /* Only set up the requested stuff */ ++ if (!(mask & (1 << idx))) ++ continue; ++ ++ r = dev->resource + idx; ++ if (!r->start && r->end) { ++ printk(KERN_ERR "PCI: Device %s not available because" ++ " of resource collisions\n", pci_name(dev)); ++ return -EINVAL; ++ } ++ if (r->flags & IORESOURCE_IO) ++ cmd |= PCI_COMMAND_IO; ++ if (r->flags & IORESOURCE_MEM) ++ cmd |= PCI_COMMAND_MEMORY; ++ } ++ ++ /* ++ * Bridges (eg, cardbus bridges) need to be fully enabled ++ */ ++ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) ++ cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; ++ ++ if (cmd != old_cmd) { ++ printk("PCI: enabling device %s (%04x -> %04x)\n", ++ pci_name(dev), old_cmd, cmd); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ } ++ return 0; ++} ++ ++int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, ++ enum pci_mmap_state mmap_state, int write_combine) ++{ ++ struct pci_sys_data *root = dev->sysdata; ++ unsigned long phys; ++ ++ if (mmap_state == pci_mmap_io) { ++ return -EINVAL; ++ } else { ++ phys = vma->vm_pgoff + (root->mem_offset >> PAGE_SHIFT); ++ } ++ ++ /* ++ * Mark this as IO ++ */ ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ ++ if (remap_pfn_range(vma, vma->vm_start, phys, ++ vma->vm_end - vma->vm_start, vma->vm_page_prot)) ++ return -EAGAIN; ++ ++ return 0; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/calls.S linux-3.4.110/arch/nds32/kernel/calls.S +--- linux-3.4.110.orig/arch/nds32/kernel/calls.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/calls.S 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,400 @@ ++/* ++ * linux/arch/nds32/kernel/calls.S ++ * ++ * Copyright (C) 1995-2004 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This file is included twice in entry-common.S ++ */ ++ ++/* 0 */ CALL(sys_restart_syscall) ++ CALL(sys_exit) ++ CALL(sys_fork_wrapper) ++ CALL(sys_read) ++ CALL(sys_write) ++/* 5 */ CALL(sys_open) ++ CALL(sys_close) ++ CALL(sys_waitpid) ++ CALL(sys_creat) ++ CALL(sys_link) ++/* 10 */ CALL(sys_unlink) ++ CALL(sys_execve_wrapper) ++ CALL(sys_chdir) ++ CALL(sys_time) /* used by libc4 */ ++ CALL(sys_mknod) ++/* 15 */ CALL(sys_chmod) ++ CALL(sys_lchown16) ++ CALL(sys_ni_syscall) /* was sys_break */ ++ CALL(sys_ni_syscall) /* was sys_stat */ ++ CALL(sys_lseek) ++/* 20 */ CALL(sys_getpid) ++ CALL(sys_mount) ++ CALL(sys_oldumount) /* used by libc4 */ ++ CALL(sys_setuid16) ++ CALL(sys_getuid16) ++/* 25 */ CALL(sys_stime) ++ CALL(sys_ptrace) ++ CALL(sys_alarm) /* used by libc4 */ ++ CALL(sys_ni_syscall) /* was sys_fstat */ ++ CALL(sys_pause) ++/* 30 */ CALL(sys_utime) /* used by libc4 */ ++ CALL(sys_ni_syscall) /* was sys_stty */ ++ CALL(sys_ni_syscall) /* was sys_getty */ ++ CALL(sys_access) ++ CALL(sys_nice) ++/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */ ++ CALL(sys_sync) ++ CALL(sys_kill) ++ CALL(sys_rename) ++ CALL(sys_mkdir) ++/* 40 */ CALL(sys_rmdir) ++ CALL(sys_dup) ++ CALL(sys_pipe) ++ CALL(sys_times) ++ CALL(sys_ni_syscall) /* was sys_prof */ ++/* 45 */ CALL(sys_brk) ++ CALL(sys_setgid16) ++ CALL(sys_getgid16) ++ CALL(sys_ni_syscall) /* was sys_signal */ ++ CALL(sys_geteuid16) ++/* 50 */ CALL(sys_getegid16) ++ CALL(sys_acct) ++ CALL(sys_umount) ++ CALL(sys_ni_syscall) /* was sys_lock */ ++ CALL(sys_ioctl) ++/* 55 */ CALL(sys_fcntl) ++ CALL(sys_ni_syscall) /* was sys_mpx */ ++ CALL(sys_setpgid) ++ CALL(sys_ni_syscall) /* was sys_ulimit */ ++ CALL(sys_cacheflush) /* was sys_olduname */ ++/* 60 */ CALL(sys_umask) ++ CALL(sys_chroot) ++ CALL(sys_ustat) ++ CALL(sys_dup2) ++ CALL(sys_getppid) ++/* 65 */ CALL(sys_getpgrp) ++ CALL(sys_setsid) ++ CALL(sys_sigaction) ++ CALL(sys_ni_syscall) /* was sys_sgetmask */ ++ CALL(sys_ni_syscall) /* was sys_ssetmask */ ++/* 70 */ CALL(sys_setreuid16) ++ CALL(sys_setregid16) ++ CALL(sys_sigsuspend_wrapper) ++ CALL(sys_sigpending) ++ CALL(sys_sethostname) ++/* 75 */ CALL(sys_setrlimit) ++ CALL(sys_old_getrlimit) /* used by libc4 */ ++ CALL(sys_getrusage) ++ CALL(sys_gettimeofday) ++ CALL(sys_settimeofday) ++/* 80 */ CALL(sys_getgroups16) ++ CALL(sys_setgroups16) ++ CALL(old_select) /* used by libc4 */ ++ CALL(sys_symlink) ++ CALL(sys_ni_syscall) /* was sys_lstat */ ++/* 85 */ CALL(sys_readlink) ++ CALL(sys_uselib) ++ CALL(sys_swapon) ++ CALL(sys_reboot) ++ CALL(sys_old_readdir) /* used by libc4 */ ++/* 90 */ CALL(sys_old_mmap) /* used by libc4 */ ++ CALL(sys_munmap) ++ CALL(sys_truncate) ++ CALL(sys_ftruncate) ++ CALL(sys_fchmod) ++/* 95 */ CALL(sys_fchown16) ++ CALL(sys_getpriority) ++ CALL(sys_setpriority) ++ CALL(sys_ni_syscall) /* was sys_profil */ ++ CALL(sys_statfs) ++/* 100 */ CALL(sys_fstatfs) ++ CALL(sys_ni_syscall) ++ CALL(sys_socketcall) ++ CALL(sys_syslog) ++ CALL(sys_setitimer) ++/* 105 */ CALL(sys_getitimer) ++ CALL(sys_newstat) ++ CALL(sys_newlstat) ++ CALL(sys_newfstat) ++ CALL(sys_ni_syscall) /* was sys_uname */ ++/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */ ++ CALL(sys_vhangup) ++ CALL(sys_ni_syscall) ++ CALL(sys_syscall) /* call a syscall */ ++ CALL(sys_wait4) ++/* 115 */ CALL(sys_swapoff) ++ CALL(sys_sysinfo) ++ CALL(sys_ipc) ++ CALL(sys_fsync) ++ CALL(sys_sigreturn_wrapper) ++/* 120 */ CALL(sys_clone_wrapper) ++ CALL(sys_setdomainname) ++ CALL(sys_newuname) ++ CALL(sys_ni_syscall) ++ CALL(sys_adjtimex) ++/* 125 */ CALL(sys_mprotect) ++ CALL(sys_sigprocmask) ++ CALL(sys_ni_syscall) /* was sys_create_module */ ++ CALL(sys_init_module) ++ CALL(sys_delete_module) ++/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */ ++ CALL(sys_quotactl) ++ CALL(sys_getpgid) ++ CALL(sys_fchdir) ++ CALL(sys_bdflush) ++/* 135 */ CALL(sys_sysfs) ++ CALL(sys_personality) ++ CALL(sys_ni_syscall) /* was _sys_afs_syscall */ ++ CALL(sys_setfsuid16) ++ CALL(sys_setfsgid16) ++/* 140 */ CALL(sys_llseek) ++ CALL(sys_getdents) ++ CALL(sys_select) ++ CALL(sys_flock) ++ CALL(sys_msync) ++/* 145 */ CALL(sys_readv) ++ CALL(sys_writev) ++ CALL(sys_getsid) ++ CALL(sys_fdatasync) ++ CALL(sys_sysctl) ++/* 150 */ CALL(sys_mlock) ++ CALL(sys_munlock) ++ CALL(sys_mlockall) ++ CALL(sys_munlockall) ++ CALL(sys_sched_setparam) ++/* 155 */ CALL(sys_sched_getparam) ++ CALL(sys_sched_setscheduler) ++ CALL(sys_sched_getscheduler) ++ CALL(sys_sched_yield) ++ CALL(sys_sched_get_priority_max) ++/* 160 */ CALL(sys_sched_get_priority_min) ++ CALL(sys_sched_rr_get_interval) ++ CALL(sys_nanosleep) ++ CALL(sys_nds32_mremap) ++ CALL(sys_setresuid16) ++/* 165 */ CALL(sys_getresuid16) ++ CALL(sys_getpagesize) ++ CALL(sys_ni_syscall) /* was sys_query_module */ ++ CALL(sys_poll) ++ CALL(sys_ni_syscall) /* was nfsservctl */ ++/* 170 */ CALL(sys_setresgid16) ++ CALL(sys_getresgid16) ++ CALL(sys_prctl) ++ CALL(sys_rt_sigreturn_wrapper) ++ CALL(sys_rt_sigaction) ++/* 175 */ CALL(sys_rt_sigprocmask) ++ CALL(sys_rt_sigpending) ++ CALL(sys_rt_sigtimedwait) ++ CALL(sys_rt_sigqueueinfo) ++ CALL(sys_rt_sigsuspend_wrapper) ++/* 180 */ CALL(sys_pread64) ++ CALL(sys_pwrite64) ++ CALL(sys_chown16) ++ CALL(sys_getcwd) ++ CALL(sys_capget) ++/* 185 */ CALL(sys_capset) ++ CALL(sys_sigaltstack_wrapper) ++ CALL(sys_sendfile) ++ CALL(sys_ni_syscall) ++ CALL(sys_ni_syscall) ++/* 190 */ CALL(sys_vfork_wrapper) ++ CALL(sys_getrlimit) ++ CALL(sys_mmap2) ++ CALL(sys_truncate64) ++ CALL(sys_ftruncate64) ++/* 195 */ CALL(sys_stat64) ++ CALL(sys_lstat64) ++ CALL(sys_fstat64) ++ CALL(sys_lchown) ++ CALL(sys_getuid) ++/* 200 */ CALL(sys_getgid) ++ CALL(sys_geteuid) ++ CALL(sys_getegid) ++ CALL(sys_setreuid) ++ CALL(sys_setregid) ++/* 205 */ CALL(sys_getgroups) ++ CALL(sys_setgroups) ++ CALL(sys_fchown) ++ CALL(sys_setresuid) ++ CALL(sys_getresuid) ++/* 210 */ CALL(sys_setresgid) ++ CALL(sys_getresgid) ++ CALL(sys_chown) ++ CALL(sys_setuid) ++ CALL(sys_setgid) ++/* 215 */ CALL(sys_setfsuid) ++ CALL(sys_setfsgid) ++ CALL(sys_getdents64) ++ CALL(sys_pivot_root) ++ CALL(sys_mincore) ++/* 220 */ CALL(sys_madvise) ++ CALL(sys_fcntl64) ++ CALL(sys_ni_syscall) /* TUX */ ++ CALL(sys_ni_syscall) ++ CALL(sys_gettid) ++/* 225 */ CALL(sys_readahead) ++ CALL(sys_setxattr) ++ CALL(sys_lsetxattr) ++ CALL(sys_fsetxattr) ++ CALL(sys_getxattr) ++/* 230 */ CALL(sys_lgetxattr) ++ CALL(sys_fgetxattr) ++ CALL(sys_listxattr) ++ CALL(sys_llistxattr) ++ CALL(sys_flistxattr) ++/* 235 */ CALL(sys_removexattr) ++ CALL(sys_lremovexattr) ++ CALL(sys_fremovexattr) ++ CALL(sys_tkill) ++ CALL(sys_sendfile64) ++/* 240 */ CALL(sys_futex_wrapper) ++ CALL(sys_sched_setaffinity) ++ CALL(sys_sched_getaffinity) ++ CALL(sys_io_setup) ++ CALL(sys_io_destroy) ++/* 245 */ CALL(sys_io_getevents) ++ CALL(sys_io_submit) ++ CALL(sys_io_cancel) ++ CALL(sys_exit_group) ++ CALL(sys_lookup_dcookie) ++/* 250 */ CALL(sys_epoll_create) ++ CALL(sys_epoll_ctl) ++ CALL(sys_epoll_wait) ++ CALL(sys_remap_file_pages) ++ CALL(sys_ni_syscall) /* sys_set_thread_area */ ++/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */ ++ CALL(sys_set_tid_address) ++ CALL(sys_timer_create) ++ CALL(sys_timer_settime) ++ CALL(sys_timer_gettime) ++/* 260 */ CALL(sys_timer_getoverrun) ++ CALL(sys_timer_delete) ++ CALL(sys_clock_settime) ++ CALL(sys_clock_gettime) ++ CALL(sys_clock_getres) ++/* 265 */ CALL(sys_clock_nanosleep) ++ CALL(sys_statfs64) ++ CALL(sys_fstatfs64) ++ CALL(sys_tgkill) ++ CALL(sys_utimes) ++/* 270 */ CALL(sys_fadvise64_64_wrapper) ++ CALL(sys_pciconfig_iobase) ++ CALL(sys_pciconfig_read) ++ CALL(sys_pciconfig_write) ++ CALL(sys_mq_open) ++/* 275 */ CALL(sys_mq_unlink) ++ CALL(sys_mq_timedsend) ++ CALL(sys_mq_timedreceive) ++ CALL(sys_mq_notify) ++ CALL(sys_mq_getsetattr) ++/* 280 */ CALL(sys_waitid) ++ CALL(sys_add_key) ++ CALL(sys_request_key) ++ CALL(sys_keyctl) ++ CALL(sys_ioprio_set) ++/* 285 */ CALL(sys_ioprio_get) ++ CALL(sys_inotify_init) ++ CALL(sys_inotify_add_watch) ++ CALL(sys_inotify_rm_watch) ++ CALL(sys_migrate_pages) ++/* 290 */ CALL(sys_openat) ++ CALL(sys_mkdirat) ++ CALL(sys_mknodat) ++ CALL(sys_fchownat) ++ CALL(sys_futimesat) ++/* 295 */ CALL(sys_fstatat64) ++ CALL(sys_unlinkat) ++ CALL(sys_renameat) ++ CALL(sys_linkat) ++ CALL(sys_symlinkat) ++/* 300 */ CALL(sys_readlinkat) ++ CALL(sys_fchmodat) ++ CALL(sys_faccessat) ++ CALL(sys_pselect6) /* sys_pselect6 */ ++ CALL(sys_ppoll) /* sys_ppoll */ ++/* 305 */ CALL(sys_unshare) ++ CALL(sys_set_robust_list) ++ CALL(sys_get_robust_list) ++ CALL(sys_splice) ++ CALL(sys_sync_file_range2) ++/* 310 */ CALL(sys_tee) ++ CALL(sys_vmsplice) ++ CALL(sys_move_pages) ++ CALL(sys_fadvise64) ++ CALL(sys_utimensat) ++/* 315 */ CALL(sys_signalfd) ++ CALL(sys_timerfd_create) ++ CALL(sys_eventfd) ++ CALL(sys_fallocate) ++ CALL(sys_timerfd_settime) ++/* 320 */ CALL(sys_timerfd_gettime) ++ CALL(sys_getcpu) ++ CALL(sys_signalfd4) ++ CALL(sys_eventfd2) ++ CALL(sys_epoll_create1) ++/* 325 */ CALL(sys_dup3) ++ CALL(sys_pipe2) ++ CALL(sys_inotify_init1) ++ CALL(sys_kexec_load) ++ CALL(sys_accept) ++/* 330 */ CALL(sys_bind) ++ CALL(sys_connect) ++ CALL(sys_getpeername) ++ CALL(sys_getsockname) ++ CALL(sys_getsockopt) ++/* 335 */ CALL(sys_listen) ++ CALL(sys_recv) ++ CALL(sys_recvfrom) ++ CALL(sys_recvmsg) ++ CALL(sys_send) ++/* 340 */ CALL(sys_sendmsg) ++ CALL(sys_sendto) ++ CALL(sys_setsockopt) ++ CALL(sys_shutdown) ++ CALL(sys_socket) ++/* 345 */ CALL(sys_socketpair) ++ CALL(sys_prlimit64) ++ CALL(sys_accept4) ++ CALL(sys_recvmmsg) ++ CALL(sys_sendmmsg) ++/* 350 */ CALL(sys_fanotify_init) ++ CALL(sys_fanotify_mark) ++ CALL(sys_msgget) ++ CALL(sys_msgctl) ++ CALL(sys_msgrcv) ++/* 355 */ CALL(sys_msgsnd) ++ CALL(sys_semget) ++ CALL(sys_semctl) ++ CALL(sys_semtimedop) ++ CALL(sys_semop) ++/* 360 */ CALL(sys_shmget) ++ CALL(sys_shmctl) ++ CALL(sys_shmat) ++ CALL(sys_shmdt) ++ CALL(sys_syncfs) ++/* 365 */ CALL(sys_setns) ++ CALL(sys_name_to_handle_at) ++ CALL(sys_open_by_handle_at) ++ CALL(sys_process_vm_readv) ++ CALL(sys_process_vm_writev) ++/* 370 */ CALL(sys_clock_adjtime) ++ CALL(sys_get_mempolicy) ++ CALL(sys_mbind) ++ CALL(sys_perf_event_open) ++ CALL(sys_preadv) ++/* 375 */ CALL(sys_pwritev) ++ CALL(sys_rt_tgsigqueueinfo) ++ CALL(sys_set_mempolicy) ++ CALL(sys_epoll_pwait) ++ ++#ifndef syscalls_counted ++.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls ++#define syscalls_counted ++#endif ++ .rept syscalls_padding ++ CALL(sys_ni_syscall) ++ .endr +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/early_printk.c linux-3.4.110/arch/nds32/kernel/early_printk.c +--- linux-3.4.110.orig/arch/nds32/kernel/early_printk.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/early_printk.c 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,126 @@ ++/* ++ * Earlyprintk support. ++ * ++ * Copyright (C) 2012 ARM Ltd. ++ * Author: Catalin Marinas ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 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, see . ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++extern void __iomem *early_io_map(phys_addr_t phys); ++static void __iomem *early_base; ++static void (*printch) (char ch); ++ ++/* ++ * 8250/16550 (8-bit aligned registers) single character TX. ++ */ ++static void uart8250_8bit_printch(char ch) ++{ ++ while (!(readb(early_base + UART_LSR) & UART_LSR_THRE)) ; ++ writeb(ch, early_base + UART_TX); ++} ++ ++/* ++ * 8250/16550 (32-bit aligned registers) single character TX. ++ */ ++static void uart8250_32bit_printch(char ch) ++{ ++ while (!(readl(early_base + (UART_LSR << 2)) & UART_LSR_THRE)) ; ++ writel(ch, early_base + (UART_TX << 2)); ++} ++ ++struct earlycon_match { ++ const char *name; ++ void (*printch) (char ch); ++}; ++ ++static const struct earlycon_match earlycon_match[] __initconst = { ++ {.name = "uart8250-8bit",.printch = uart8250_8bit_printch,}, ++ {.name = "uart8250-32bit",.printch = uart8250_32bit_printch,}, ++ {} ++}; ++ ++static void early_write(struct console *con, const char *s, unsigned n) ++{ ++ while (n-- > 0) { ++ if (*s == '\n') ++ printch('\r'); ++ printch(*s); ++ s++; ++ } ++} ++ ++static struct console early_console_dev = { ++ .name = "earlycon", ++ .write = early_write, ++ .flags = CON_PRINTBUFFER | CON_BOOT, ++ .index = -1, ++}; ++ ++/* ++ * Parse earlyprintk=... parameter in the format: ++ * ++ * [,][,] ++ * ++ * and register the early console. It is assumed that the UART has been ++ * initialised by the bootloader already. ++ */ ++static int __init setup_early_printk(char *buf) ++{ ++ const struct earlycon_match *match = earlycon_match; ++ phys_addr_t paddr = 0; ++ ++ if (!buf) { ++ pr_warning("No earlyprintk arguments passed.\n"); ++ return 0; ++ } ++ ++ while (match->name) { ++ size_t len = strlen(match->name); ++ if (!strncmp(buf, match->name, len)) { ++ buf += len; ++ break; ++ } ++ match++; ++ } ++ if (!match->name) { ++ pr_warning("Unknown earlyprintk arguments: %s\n", buf); ++ return 0; ++ } ++ ++ /* I/O address */ ++ if (!strncmp(buf, ",0x", 3)) { ++ char *e; ++ paddr = simple_strtoul(buf + 1, &e, 16); ++ buf = e; ++ } ++ ++ if (paddr) ++ early_base = early_io_map(paddr); ++ printch = match->printch; ++ //early_console = &early_console_dev; ++ register_console(&early_console_dev); ++ ++ return 0; ++} ++ ++early_param("earlyprintk", setup_early_printk); +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/elfchk.c linux-3.4.110/arch/nds32/kernel/elfchk.c +--- linux-3.4.110.orig/arch/nds32/kernel/elfchk.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/elfchk.c 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,190 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ELF_CHECKING_OS ++#include "nds32-elf.h" ++ ++extern struct proc_dir_entry *proc_dir_cpu; ++ ++#ifdef CONFIG_ELFCHK_DEFAULT_ENABLE ++static int elf_check_en = 1; ++#else ++static int elf_check_en = 0; ++#endif ++ ++struct reg_struct { ++ ++ const char *name; ++ int idx; ++}; ++ ++static struct reg_struct regs[] = { ++ ++ {"cpu_ver", CPU_SR_INDEX(0, 0, 0)}, ++ {"icm_cfg", CPU_SR_INDEX(0, 1, 0)}, ++ {"dcm_cfg", CPU_SR_INDEX(0, 2, 0)}, ++ {"mmu_cfg", CPU_SR_INDEX(0, 3, 0)}, ++ {"msc_cfg", CPU_SR_INDEX(0, 4, 0)}, ++#ifdef CONFIG_FPU ++ {"fucop_exist", CPU_SR_INDEX(0, 5, 0)} ++#endif ++}; ++ ++#ifdef CONFIG_FPU ++static unsigned int read_fpu_fpcfg(void) ++{ ++ unsigned int fpcfg = 0; ++ ++ enable_fpu(); ++ asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg)); ++ disable_fpu(); ++ ++ return fpcfg; ++} ++#endif ++ ++static unsigned int read_cpu_sr(unsigned int idx) ++{ ++ switch (idx) { ++ ++ case CPU_SR_INDEX(0, 0, 0): ++ return GET_CPU_VER(); ++ case CPU_SR_INDEX(0, 1, 0): ++ return GET_ICM_CFG(); ++ case CPU_SR_INDEX(0, 2, 0): ++ return GET_DCM_CFG(); ++ case CPU_SR_INDEX(0, 3, 0): ++ return GET_MMU_CFG(); ++ case CPU_SR_INDEX(0, 4, 0): ++ return GET_MSC_CFG(); ++ case CPU_SR_INDEX(0, 5, 0): ++ return GET_FUCOP_EXIST(); ++ ++ default: ++ printk(KERN_ERR ++ "%s: invalid system register index (%d, %d, %d)\n", ++ __func__, (idx >> 7) & 0x7, (idx >> 3) & 0xf, idx & 0x7); ++ ++ return SR_NOT_EXIST; ++ } ++} ++ ++static unsigned int reg_read_callback(unsigned int idx) ++{ ++ if (HW_IS_CPU(idx)) { ++ ++ return read_cpu_sr(SR_INDEX(idx)); ++ } else if (HW_IS_FPU(idx)) { ++ ++#ifdef CONFIG_FPU ++ if (SR_FPU_FPCFG == SR_INDEX(idx)) ++ return read_fpu_fpcfg(); ++ else ++ return SR_NOT_EXIST; ++#endif ++ } else if (HW_IS_AUDIO(idx)) { ++ ++ return SR_NOT_EXIST; ++ } ++ ++ return SR_NOT_EXIST; ++} ++ ++#define BUFLEN 1024 ++ ++int do_elf_check_arch(const struct elf32_hdr *hdr) ++{ ++ static char msg_buf[BUFLEN]; ++ unsigned int err; ++ int buf_status = 0; ++ ++ if (!elf_check_en) ++ return 1; ++ ++ err = ++ elf_check((void *)hdr, reg_read_callback, msg_buf, BUFLEN, ++ &buf_status); ++ ++ if (err) ++ printk(KERN_WARNING "%s", msg_buf); ++ ++ return !err; ++} ++ ++static int proc_elf_check_read(char *page, char **start, off_t off, int count, ++ int *eof, void *data) ++{ ++ return sprintf(page, "%d\n", elf_check_en); ++} ++ ++#define INPUTLEN 10 ++static int proc_elf_check_write(struct file *file, const char __user * buffer, ++ unsigned long count, void *data) ++{ ++ unsigned long en; ++ char inbuf[INPUTLEN]; ++ ++ if (count > INPUTLEN - 1) ++ count = INPUTLEN - 1; ++ ++ if (copy_from_user(inbuf, buffer, count)) ++ return -EFAULT; ++ ++ inbuf[count] = '\0'; ++ ++ if (!sscanf(inbuf, "%lu", &en) || en > 3) ++ return -EFAULT; ++ ++ elf_check_en = en & 0x01; ++ ++ return count; ++} ++ ++static int proc_elf_check_read_reg(char *page, char **start, ++ off_t off, int count, int *eof, void *data) ++{ ++ unsigned long val = read_cpu_sr(*(int *)data); ++ ++ return sprintf(page, "0x%08lx\n", val); ++} ++ ++int __init elf_check_init(void) ++{ ++ static struct proc_dir_entry *res_elf_check; ++ int i; ++ ++ if (!proc_dir_cpu) { ++ if (!(proc_dir_cpu = proc_mkdir("cpu", NULL))) ++ return -ENOMEM; ++ } ++ ++ res_elf_check = ++ create_proc_entry("elf_core_checking", S_IWUSR | S_IRUGO, ++ proc_dir_cpu); ++ if (!res_elf_check) ++ return -ENOMEM; ++ ++ res_elf_check->read_proc = proc_elf_check_read; ++ res_elf_check->write_proc = proc_elf_check_write; ++ ++ for (i = 0; i < ARRAY_SIZE(regs); i++) { ++ ++ if (!create_proc_read_entry(regs[i].name, S_IWUSR | S_IRUGO, ++ proc_dir_cpu, ++ proc_elf_check_read_reg, ++ ®s[i].idx)) ++ ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++module_init(elf_check_init); +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ex-entry.S linux-3.4.110/arch/nds32/kernel/ex-entry.S +--- linux-3.4.110.orig/arch/nds32/kernel/ex-entry.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/ex-entry.S 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,294 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ .macro push_zol ++#ifdef CONFIG_HWZOL ++ mfusr $r10, $LB ++ mfusr $r11, $LE ++ mfusr $r12, $LC ++#endif ++ .endm ++ .macro save_user_regs ++ /* $p1 is VA of percpu data */ ++ sethi $p0, hi20(PAGE_OFFSET - PHYS_OFFSET) ++ add $p1, $p1, $p0 ++ ++ /* change to kernel stack */ ++ mfsr $p0, $IPSW ++ andi $p0, $p0, #PSW_mskPOM ++ cmovz $sp, $r25, $p0 ++ ++ /* 8 byte aligned */ ++ movi $r25, #~7 ++ and $r25, $sp, $r25 ++ smw.adm $sp, [$r25], $sp, #0x1 ++ move $sp, $r25 ++ ++#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO) ++ mfsr $r25, $FUCOP_CTL ++ push $r25 ++ bclr $r25, $r25, #FUCOP_CTL_offCP0EN ++ mtsr $r25, $FUCOP_CTL ++#else ++ addi $sp, $sp, -4 ++#endif ++ pushm $r28, $r30 ++ ++ /* zero fp if user mode*/ ++ movi $r25, #0x0 ++ cmovz $fp, $r25, $p0 ++ ++ lwi $r25, [$p1+#0x0] ++ pushm $r0, $r25 ++#ifdef CONFIG_HWZOL ++ push_zol ++#endif ++ mfsr $r9, $P_P1 ++ mfsr $r8, $P_P0 ++ mfsr $r7, $P_IPC ++ mfsr $r6, $P_IPSW ++ mfsr $r18, $IPC ++ mfsr $r17, $IPSW ++ mfsr $r16, $PSW ++ pushm $r6, $r13 ++ push $r0 ++ lwi $p0, [$p1+#0x8] ++ push $p0 ++ pushm $r16, $r18 ++ ++ andi $r19, $r16, #PSW_mskINTL ++ slti $r20, $r19, #4 ++ bnez $r20, 1f ++ addi $r21, $r16, #-2 ++ mtsr $r21, $PSW ++ isb ++1: ++ addi $sp, $sp, -S_OFF ++ .endm ++ ++ .text ++ ++/* ++ * Exception Vector ++ */ ++exception_handlers: ++ .long unhandled_exceptions !Reset/NMI ++ .long unhandled_exceptions !TLB fill ++ .long do_page_fault !PTE not present ++ .long do_dispatch_tlb_misc !TLB misc ++ .long unhandled_exceptions !TLB VLPT ++ .long unhandled_exceptions !Machine Error ++ .long do_debug_trap !Debug related ++ .long do_dispatch_general !General exception ++ .long eh_syscall !Syscall ++ .long asm_do_IRQ !IRQ ++ ++common_exception_handler: ++ save_user_regs ++ lwi $p0, [$p1+#0x4] ++ andi $p1, $p0, #0x78 ++ bnez $p1, 1f ++ sethi $lp, hi20(ret_from_exception) ++ ori $lp, $lp, lo12(ret_from_exception) ++ sethi $p1, hi20(exception_handlers) ++ ori $p1, $p1, lo12(exception_handlers) ++ lw $p1, [$p1+$p0<<2] ++ move $r0, $p0 ++ mfsr $r1, $EVA ++ mfsr $r2, $ITYPE ++ move $r3, $sp ++ mfsr $r4, $OIPC ++ /* enable gie if it is enabled in IPSW. */ ++ mfsr $r21, $PSW ++ andi $r17, $r17, #0x1 ++ or $r21, $r21, $r17 ++ mtsr $r21, $PSW ++ dsb ++ jr $p1 ++ ++ /* syscall */ ++1: ++ addi $p1, $p0, #-8 ++ bnez $p1, 2f ++ sethi $lp, hi20(ret_from_exception) ++ ori $lp, $lp, lo12(ret_from_exception) ++ sethi $p1, hi20(exception_handlers) ++ ori $p1, $p1, lo12(exception_handlers) ++ lwi $p1, [$p1+#0x8<<2] ++ jr $p1 ++ ++ /* interrupt */ ++2: ++#ifdef CONFIG_TRACE_IRQFLAGS ++ jal arch_trace_hardirqs_off ++#endif ++#if defined(CONFIG_EVIC) || defined(CONFIG_IVIC) ++ addi $r0, $p0, #-9 ++#else ++# ifdef CONFIG_IVIC_INTC ++ jal get_IntSrc ++# else ++# error "Not configure Vector Interrupt Controller mode" ++# endif ++#endif ++ move $r1, $sp ++ sethi $lp, hi20(ret_from_intr) ++ ori $lp, $lp, lo12(ret_from_intr) ++ sethi $p0, hi20(exception_handlers) ++ ori $p0, $p0, lo12(exception_handlers) ++ lwi $p0, [$p0+#0x9<<2] ++ jr $p0 ++ ++ .macro EXCEPTION_VECTOR, num ++ .align 6 ++ .ifc \num, 6 ++ mfsr $p0, $EDM_CTL ++ andi $p0, $p0, EDM_CTL_mskV3_EDM_MODE ++ tnez $p0, 0x1a ++ .endif ++ /* $p1 is PA of percpu data */ ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ movi $p1, #0x0 ++#else ++ mfsr $p1, $CORE_ID ++#endif ++ slli $p1, $p1, #0x9 ++ li $p0, #(PHYS_OFFSET+0x6000) ++ or $p1, $p1, $p0 ++ ++ /* ++ * 0x0 saved $r25 ++ * 0x4 vector number ++ * 0x8 user stack pointer ++ * 0xc kernel stack pointer ++ */ ++ swi $r25, [$p1+0x0] ++ movi $p0, \num ++ swi $p0, [$p1+#0x4] ++ swi $sp, [$p1+#0x8] ++ lwi $r25, [$p1+#0xc] ++ sethi $p0, hi20(common_exception_handler) ++ ori $p0, $p0, lo12(common_exception_handler) ++ jral.ton $p0, $p0 ++ .endm ++ ++ .macro IPI_VECTOR, num ++ .align 6 ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ movi $p1, #0x0 ++#else ++ mfsr $p1, $CORE_ID ++#endif ++ slli $p1, $p1, #0x9 ++ li $p0, #(PHYS_OFFSET+0x6000) ++ or $p1, $p1, $p0 ++ ++ /* ++ * 0x10 indicator of CPU is initialized ++ * 0x14 CPU init function ++ */ ++ swi $r25, [$p1+0x0] ++ movi $p0, \num ++ swi $p0, [$p1+#0x4] ++ swi $sp, [$p1+#0x8] ++ lwi $r25, [$p1+#0xc] ++ lwi $p0, [$p1+#0x10] ++ beqz $p0, 1f ++ sethi $p0, hi20(common_exception_handler) ++ ori $p0, $p0, lo12(common_exception_handler) ++ jral.ton $p0, $p0 ++1: ++ lwi $p0, [$p1+#0x14] ++ jr $p0 ++ ++ .endm ++ ++ .section ".text.init", #alloc, #execinstr ++ .global exception_vector ++exception_vector: ++ EXCEPTION_VECTOR 0 ++ EXCEPTION_VECTOR 1 ++ EXCEPTION_VECTOR 2 ++ EXCEPTION_VECTOR 3 ++ EXCEPTION_VECTOR 4 ++ EXCEPTION_VECTOR 5 ++ EXCEPTION_VECTOR 6 ++ EXCEPTION_VECTOR 7 ++ EXCEPTION_VECTOR 8 ++#ifdef CONFIG_EVIC ++ EXCEPTION_VECTOR 9 ++#else ++ IPI_VECTOR 9 ++#endif ++ EXCEPTION_VECTOR 10 ++ EXCEPTION_VECTOR 11 ++ EXCEPTION_VECTOR 12 ++ EXCEPTION_VECTOR 13 ++ EXCEPTION_VECTOR 14 ++ EXCEPTION_VECTOR 15 ++ EXCEPTION_VECTOR 16 ++ EXCEPTION_VECTOR 17 ++ EXCEPTION_VECTOR 18 ++ EXCEPTION_VECTOR 19 ++ EXCEPTION_VECTOR 20 ++ EXCEPTION_VECTOR 21 ++ EXCEPTION_VECTOR 22 ++ EXCEPTION_VECTOR 23 ++ EXCEPTION_VECTOR 24 ++ EXCEPTION_VECTOR 25 ++ EXCEPTION_VECTOR 26 ++ EXCEPTION_VECTOR 27 ++ EXCEPTION_VECTOR 28 ++ EXCEPTION_VECTOR 29 ++ EXCEPTION_VECTOR 30 ++ EXCEPTION_VECTOR 31 ++ EXCEPTION_VECTOR 32 ++ EXCEPTION_VECTOR 33 ++ EXCEPTION_VECTOR 34 ++ EXCEPTION_VECTOR 35 ++ EXCEPTION_VECTOR 36 ++ EXCEPTION_VECTOR 37 ++ EXCEPTION_VECTOR 38 ++ EXCEPTION_VECTOR 39 ++ EXCEPTION_VECTOR 40 ++#ifdef CONFIG_EVIC ++ IPI_VECTOR 41 ++#else ++ EXCEPTION_VECTOR 41 ++#endif ++ EXCEPTION_VECTOR 42 ++ EXCEPTION_VECTOR 43 ++ EXCEPTION_VECTOR 44 ++ EXCEPTION_VECTOR 45 ++ EXCEPTION_VECTOR 46 ++ EXCEPTION_VECTOR 47 ++ EXCEPTION_VECTOR 48 ++ EXCEPTION_VECTOR 49 ++ EXCEPTION_VECTOR 50 ++ EXCEPTION_VECTOR 51 ++ EXCEPTION_VECTOR 52 ++ EXCEPTION_VECTOR 53 ++ EXCEPTION_VECTOR 54 ++ EXCEPTION_VECTOR 55 ++ EXCEPTION_VECTOR 56 ++ EXCEPTION_VECTOR 57 ++ EXCEPTION_VECTOR 58 ++ EXCEPTION_VECTOR 59 ++ EXCEPTION_VECTOR 60 ++ EXCEPTION_VECTOR 61 ++ EXCEPTION_VECTOR 62 ++ EXCEPTION_VECTOR 63 ++ EXCEPTION_VECTOR 64 ++ EXCEPTION_VECTOR 65 ++ EXCEPTION_VECTOR 66 ++ EXCEPTION_VECTOR 67 ++ EXCEPTION_VECTOR 68 ++ EXCEPTION_VECTOR 69 ++ EXCEPTION_VECTOR 70 ++ EXCEPTION_VECTOR 71 ++ EXCEPTION_VECTOR 72 +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ex-exit.S linux-3.4.110/arch/nds32/kernel/ex-exit.S +--- linux-3.4.110.orig/arch/nds32/kernel/ex-exit.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/ex-exit.S 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,220 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define why $r8 // Linux syscall (!= 0) ++#define tsk $r9 // current thread_info ++ ++ ++ .macro pop_zol ++#ifdef CONFIG_HWZOL ++ mtusr $r10, $LB ++ mtusr $r11, $LE ++ mtusr $r12, $LC ++#endif ++ .endm ++ ++ .macro restore_user_regs_first ++ setgie.d ++ isb ++ /* $p1 is VA of percpu data */ ++#ifdef CONFIG_CPU_N1213_43U1HA0 ++ movi $p1, #0x0 ++#else ++ mfsr $p1, $CORE_ID ++#endif ++ andi $p1, $p1, #0x3 ++ slli $p1, $p1, #0x9 ++ sethi $p0, #0xc0006 ++ or $p1, $p1, $p0 ++ ++ addi $sp, $sp, S_OFF ++ popm $r16, $r18 ++ mtsr $r16, $PSW ++ pop $r16 ++ swi $r16, [$p1+#0x8] ++ addi $sp, $sp, #4 !pop $r0 ++ popm $r6, $r13 ++ mtsr $r17, $IPSW ++ mtsr $r18, $IPC ++ mtsr $r6, $P_IPSW ++ mtsr $r7, $P_IPC ++ mtsr $r8, $P_P0 ++ mtsr $r9, $P_P1 ++#ifdef CONFIG_HWZOL ++ pop_zol ++#endif ++ .endm ++ ++ .macro restore_user_regs_last ++ popm $r28, $r30 ++#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO) ++ pop $p0 ++ mtsr $p0, $FUCOP_CTL ++#else ++ addi $sp, $sp, 4 ++#endif ++ ++ pop $p0 ++ cmovn $sp, $p0, $p0 ++ ++ mfsr $p0, $IPSW ++ andi $p0, $p0, #PSW_mskPOM ++ bnez $p0, 1f ++ swi $sp, [$p1+#0xc] ++ lwi $sp, [$p1+#0x8] ++1: ++ // This is SW workaround for Bug #6294 ++ li $p0, 0xc0000000 ++ cctl $p0, L1D_VA_INVAL ++ lwi $p1, [$p0] ++ ++ iret ++ nop ++ ++ .endm ++ ++ .macro restore_user_regs ++ restore_user_regs_first ++ popm $r0, $r25 ++ restore_user_regs_last ++ .endm ++ ++ .macro fast_restore_user_regs ++ restore_user_regs_first ++ addi $sp, $sp, #4 ++ popm $r1, $r25 ++ restore_user_regs_last ++ .endm ++ ++#ifdef CONFIG_PREEMPT ++ .macro preempt_stop ++ .endm ++#else ++ .macro preempt_stop ++ setgie.d ++ isb ++ .endm ++#define resume_kernel no_work_pending ++#endif ++ ++ENTRY(ret_from_exception) ++ preempt_stop ++ENTRY(ret_from_intr) ++ get_thread_info tsk ++ move why, #0 ! not system call ++ ++/* ++ * judge Kernel or user mode ++ * ++ */ ++ lwi $p0, [$sp+(#S_IPSW+#S_OFF)] ++! mfsr $p0, $IPSW ! Check if in nested interrupt ++ andi $p0, $p0, #PSW_mskINTL ++ bnez $p0, resume_kernel ! done with iret ++ j resume_userspace ++ ++ ++/* ++ * This is the fast syscall return path. We do as little as ++ * possible here, and this includes saving $r0 back into the SVC ++ * stack. ++ * fixed: tsk - $r9, why - $r8, $r7 - syscall #, $r8 - syscall table pointer ++ */ ++ENTRY(ret_fast_syscall) ++ gie_disable ++ lwi $r1, [tsk+#TI_FLAGS] ++ andi $p1, $r1, #_TIF_WORK_MASK ++ bnez $p1, fast_work_pending ++ fast_restore_user_regs ! iret ++ ++/* ++ * Ok, we need to do extra processing, ++ * enter the slow path returning from syscall, while pending work. ++ */ ++fast_work_pending: ++ swi $r0, [$sp+(#S_R0+#S_OFF)] ! what is different from ret_from_exception ++ ! addi $sp, $sp, S_OFF ++ move why, #1 ! come from a syscall ++work_pending: ++ andi $p1, $r1, #_TIF_NEED_RESCHED ++ bnez $p1, work_resched ++ ++ andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME ++ beqz $p1, no_work_pending ++ ++ move $r0, $sp ! 'regs' ++ move $r2, why ++ gie_enable ++ bal do_notify_resume ++ ++ b ret_slow_syscall ! return from slow_restore_user_regs ++ ++work_resched: ++ bal schedule ! path, return to user mode ++ ++/* ++ * "slow" syscall return path. ++ * "why" tells us if this was a real syscall. ++ */ ++ENTRY(resume_userspace) ++ENTRY(ret_slow_syscall) ++ gie_disable ++ lwi $p0, [$sp+(#S_IPSW+#S_OFF)] ++! mfsr $p0, $IPSW ! Check if in nested interrupt ++ andi $p0, $p0, #PSW_mskINTL ++ bnez $p0, no_work_pending ! done with iret ++ lwi $r1, [tsk+#TI_FLAGS] ++ andi $p1, $r1, #_TIF_WORK_MASK ++ bnez $p1, work_pending ! handle work_resched, sig_pend ++ ++no_work_pending: ++#ifdef CONFIG_TRACE_IRQFLAGS ++ lwi $p0, [$sp+(#S_IPSW+#S_OFF)] ++ andi $p0, $p0, #0x1 ++ la $r10, arch_trace_hardirqs_off ++ la $r9, arch_trace_hardirqs_on ++ cmovz $r9, $p0, $r10 ++ jral $r9 ++#endif ++ restore_user_regs ! return from iret ++ ++ ++/* ++ * preemptive kernel ++ */ ++#ifdef CONFIG_PREEMPT ++resume_kernel: ++ gie_disable ++ lwi $t0, [tsk+#TI_PREEMPT] ++ bnez $t0, no_work_pending ++need_resched: ++ lwi $t0, [tsk+#TI_FLAGS] ++ andi $p1, $t0, #_TIF_NEED_RESCHED ++ beqz $p1, no_work_pending ++ ++ lwi $t0, [$sp+(#S_IPSW+#S_OFF)] ! Interrupts off? ++ andi $t0, $t0, #1 ++ beqz $t0, no_work_pending ++ ++ jal preempt_schedule_irq ++ b need_resched ++#endif ++ ++/* ++ * This is how we return from a fork. ++ */ ++ENTRY(ret_from_fork) ++ bal schedule_tail ++ get_thread_info tsk ++ lwi $r1, [tsk+#TI_FLAGS] ! check for syscall tracing ++ move why, #1 ++ andi $p1, $r1, #_TIF_WORK_SYSCALL_LEAVE ! are we tracing syscalls? ++ beqz $p1, ret_slow_syscall ++ move $r0, $sp ++ bal syscall_trace_leave ++ b ret_slow_syscall ++ +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ex-scall.S linux-3.4.110/arch/nds32/kernel/ex-scall.S +--- linux-3.4.110.orig/arch/nds32/kernel/ex-scall.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/ex-scall.S 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,288 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * $r0 = previous task_struct, ++ * $r1 = previous thread_info, ++ * $r2 = next thread_info ++ * previous and next are guaranteed not to be the same. ++ */ ++ ++ENTRY(_switch) ++ smw.adm $r6, [$sp], $r14, #0xa ++ swi $sp, [$r1+ TI_SP_SAVE] /* Save $sp to task structure */ ++ lwi $sp, [$r2+ TI_SP_SAVE] /* Get $sp from task structure */ ++ lmw.bim $r6, [$sp], $r14, #0xa ++ ret ++ ++/* ++ * These are the registers used in the syscall handler, and allow us ++ * to have in theory up to 6 arguments to a function - $r0 to $r5. ++ * $r7 is reserved for the system call number for Andes architecture. ++ * ++ * Note that tbl == why is intentional. ++ * We must set at least "tsk" and "why" when calling ret_with_reschedule. ++ */ ++#define tbl $r8 // syscall table pointer ++#define why $r8 // Linux syscall (!= 0) ++#define tsk $r9 // current thread_info ++ ++/* ++ * Get the system call number. let $r7 take a system call nr. ++ * ++ * if it is called from library function, $r7 is filled by library call ++ * when user program make a system call. and swid bitfield of $ir6 will ++ * always be encoded as 0x7fff. ++ * ++ * if it is called from kernel code, $r7 will be writen as syscall nr ++ * by retrieving from $ir6 'swid' bitfiled ++ */ ++ .macro get_scno ++ mfsr $r7, $ITYPE ++#ifdef CONFIG_PLAT_QEMU ++ slli $r7, $r7, #1 ++ srli $r7, $r7, #ITYPE_offSWID+1 ++#else ++ srli $r7, $r7, #ITYPE_offSWID ++#endif ++ .endm ++ ++ .macro updateipc ++ addi $r17, $r18, #4 ++ swi $r17, [$sp + S_OFF + S_IPC] ++ .endm ++ ++ .equ NR_syscalls,0 ++#define CALL(x) .equ NR_syscalls,NR_syscalls+1 ++#include "calls.S" ++#undef CALL ++#define CALL(x) .long x ++ ++ENTRY(eh_syscall) ++ updateipc ++ ++ get_scno ++ gie_enable ++ get_thread_info tsk ++ lwi $p0, [tsk+#TI_FLAGS] ! check for syscall tracing ++ ++ andi $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY ! are we tracing syscalls? ++ bnez $p1, __sys_trace ++ ++ la $lp, ret_fast_syscall ! return address ++ ++ li $p0, __NR_NDS32_BASE ++ addi $p0, $p0, -1 ++ slt $p0, $p0, $r7 ++ beqz $p0, 1f ++ addi $r1, $SP, #0 ++ move $r0, $r7 ++ b nds32_syscall ++1: ++ ! check upper syscall limit, ++ andi $r7, $r7, #0xfff ++ addi $p1, $r7, #-NR_syscalls ! syscall number of syscall instruction is guarded by addembler ++ bgez $p1, _SCNO_EXCEED ! call sys_* routine ++ la tbl, sys_call_table ! load syscall table pointer ++ slli $p1, $r7, #2 ++ add $p1, tbl, $p1 ++ lwi $p1, [$p1] ++ jr $p1 ! no return ++ ++_SCNO_EXCEED: ++ ori $r0, $r7, #0 ++ ori $r1, $sp, #0 ++ b bad_syscall ++ ++/* ++ * This is the really slow path. We're going to be doing ++ * context switches, and waiting for our parent to respond. ++ */ ++__sys_trace: ++ move $r1, $sp ++ move $r0, $r7 ! trace entry [IP = 0] ++ bal syscall_trace_enter ++ move $r7, $r0 ++ la $lp, __sys_trace_return ! return address ++ ++ li $p0, __NR_NDS32_BASE ++ addi $p0, $p0, -1 ++ slt $p0, $p0, $r7 ++ beqz $p0, 1f ++ addi $r1, $SP, #0 ++ b nds32_syscall ++1: ++ andi $r7, $r7, #0xfff ++ addi $p1, $sp, #S_R0+S_OFF ! pointer to regs ++ addi $p0, $r7, -#NR_syscalls ! check upper syscall limit ++ bgez $p0, _SCNO_EXCEED ++ lmw.bi $r0, [$p1], $r5 ! have to reload $r0 - $r5 ++ ++ slli $p0, $r7, #2 ! call sys_* routine ++ la tbl, sys_call_table ! load syscall table pointer ++ add $p0, tbl, $p0 ++ lwi $p0, [$p0] ++ jr $p0 ++ ++__sys_trace_return: ++ swi $r0, [$sp+(#S_R0+S_OFF)] ! T: save returned $r0 ++ bal syscall_trace_leave ++ b ret_slow_syscall ++ ++ .type sys_call_table, #object ++ENTRY(sys_call_table) ++#include "calls.S" ++ ++/* ++ * Special system call wrappers ++ * ++ * $r0 = syscall number ++ * $r8 = syscall table ++ */ ++ .type sys_syscall, #function ++sys_syscall: ++ ++ li $p0, __NR_NDS32_BASE ++ addi $p0, $p0, -1 ++ slt $p0, $p0, $r0 ++ beqz $p0, 1f ++ addi $r1, $SP, #0 ++ b nds32_syscall ++1: ++ bltz $r0, 3f ! Guard whether syscall number is between 0~0x7fff. ++ andi $r0, $r0, #0xfff ++ addi $p1, $r0, #-NR_syscalls ++ bgtz $p1, 3f ++ move $p1, $r0 ++ move $r0, $r1 ++ move $r1, $r2 ++ move $r2, $r3 ++ move $r3, $r4 ++ move $r4, $r5 ++! add for syscall 6 args ++ lwi $r5, [$sp + (#S_SP + #S_OFF) ] ++ lwi $r5, [$r5 + #S_OFF] ++! ~add for syscall 6 args ++ ++ lw $p1, [tbl+$p1<<2] ++ jr $p1 ++3: b sys_ni_syscall ++ ++sys_fork_wrapper: ++ addi $r0, $sp, #0 ++ b sys_fork ++ ++sys_vfork_wrapper: ++ addi $r0, $sp, #0 ++ b sys_vfork ++ ++sys_execve_wrapper: ++ addi $r3, $sp, #0 ++ b sys_execve ++ ++sys_clone_wrapper: ++ addi $r5, $SP, #0 ++ b sys_clone ++ ++sys_sigsuspend_wrapper: ++ addi $r3, $sp, #0 ++ b sys_sigsuspend ++ ++sys_rt_sigsuspend_wrapper: ++ addi $r2, $sp, #0 ++ b sys_rt_sigsuspend ++ ++sys_sigreturn_wrapper: ++ addi $r0, $sp, #0 ++ b sys_sigreturn ++ ++sys_rt_sigreturn_wrapper: ++ addi $r0, $sp, #0 ++ b sys_rt_sigreturn ++ ++sys_sigaltstack_wrapper: ++ lwi $r2, [$sp+(#S_OFF + S_SP)] ++ b do_sigaltstack ++ ++sys_futex_wrapper: ++ b sys_futex ++ ++#ifdef CONFIG_FUNCTION_TRACER ++ .global _mcount ++ .global ftrace_stub ++_mcount: ++ sethi $r15, hi20(function_trace_stop) ++ lwi $r15, [$r15 + lo12(function_trace_stop)] ++ bnez $r15, _ftrace_stub ++ ++ sethi $r15, hi20(ftrace_trace_function) ++ lwi $p0, [$r15 + lo12(ftrace_trace_function)] ++ sethi $r15, hi20(ftrace_stub) ++ ori $r15, $r15, lo12(ftrace_stub) ++ bne $r15, $p0, trace ++ ++#ifdef CONFIG_FUNCTION_GRAPH_TRACER ++ sethi $p0, hi20(ftrace_graph_return) ++ lwi $p0, [$p0 + lo12(ftrace_graph_return)] ++ bne $r15, $p0, _ftrace_graph_caller ++ ++ sethi $r15, hi20(ftrace_graph_entry) ++ lwi $r15, [$r15 + lo12(ftrace_graph_entry)] ++ sethi $p0, hi20(ftrace_graph_entry_stub) ++ ori $p0, $p0, lo12(ftrace_graph_entry_stub) ++ bne $r15, $p0, _ftrace_graph_caller ++#endif ++ ++_ftrace_stub: ++ftrace_stub: ++ ret ++ ++trace: ++ smw.adm $r0, [$sp], $r5, #10 ++ move $r0, $lp ++ sethi $r15, hi20(get_selfpc) ++ ori $r15, $r15, lo12(get_selfpc) ++ jral $r15 ++ move $r1, $r0 ++ lwi $r0, [$sp+36] ++ jral $p0 ++ lmw.bim $r0, [$sp], $r5, #10 ++ ret ++#endif ++ ++#ifdef CONFIG_FUNCTION_GRAPH_TRACER ++ .global ftrace_graph_caller ++ .global return_to_handler ++_ftrace_graph_caller: ++ftrace_graph_caller: ++ sethi $p1, hi20(function_trace_stop) ++ lwi $p1, [$p1 + lo12(function_trace_stop)] ++ bnez $p1, ftrace_stub ++ ++ sethi $p1, hi20(prepare_ftrace_return) ++ ori $p1, $p1, lo12(prepare_ftrace_return) ++ ++ smw.adm $r0, [$sp], $r5, #10 ++ move $r0, $lp ++ sethi $p0, hi20(get_selfpc) ++ ori $p0, $p0, lo12(get_selfpc) ++ jral $p0 ++ move $r1, $r0 ++ addi $r0, $sp, #36 ++ jral $p1 ++ lmw.bim $r0, [$sp], $r5, #10 ++ ret ++ ++return_to_handler: ++ smw.adm $r0, [$sp], $r5, #10 ++ sethi $r15, hi20(ftrace_return_to_handler) ++ ori $r15, $r15, lo12(ftrace_return_to_handler) ++ jral $r15 ++ move $r15, $r0 ++ lmw.bim $r0, [$sp], $r5, #10 ++ jr $r15 ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/fpu.c linux-3.4.110/arch/nds32/kernel/fpu.c +--- linux-3.4.110.orig/arch/nds32/kernel/fpu.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/fpu.c 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,306 @@ ++/* ++ * arch/nds32/kernel/fpu.c ++ * ++ * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli ++ * Copyright (C) 2002 STMicroelectronics Limited ++ * Author : Stuart Menefy ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * Started from SH4 version: ++ * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "fpu.h" ++ ++extern void do_revinsn(struct pt_regs *regs); ++extern int do_fpu_denorm(struct pt_regs *regs, struct fpu_struct *fpu); ++ ++static struct fpu_struct init_fpuregs = { ++ .fs_regs = {[0 ... 31] = sNAN32}, ++ .fd_regs = {[0 ... 15] = sNAN64}, ++ .fpcsr = FPCSR_INIT ++}; ++ ++void save_fpu(struct task_struct *tsk) ++{ ++ unsigned int fpcfg, fpcsr; ++ enable_fpu(); ++ asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg)); ++ fpcfg = ((fpcfg & FPCFG_mskFREG) >> FPCFG_offFREG); ++ ++ switch (fpcfg) { ++ case 3: ++ asm volatile ("fsdi $fd31, [%0+0xf8]\n\t" ++ "fsdi $fd30, [%0+0xf0]\n\t" ++ "fsdi $fd29, [%0+0xe8]\n\t" ++ "fsdi $fd28, [%0+0xe0]\n\t" ++ "fsdi $fd27, [%0+0xd8]\n\t" ++ "fsdi $fd26, [%0+0xd0]\n\t" ++ "fsdi $fd25, [%0+0xc8]\n\t" ++ "fsdi $fd24, [%0+0xc0]\n\t" ++ "fsdi $fd23, [%0+0xb8]\n\t" ++ "fsdi $fd22, [%0+0xb0]\n\t" ++ "fsdi $fd21, [%0+0xa8]\n\t" ++ "fsdi $fd20, [%0+0xa0]\n\t" ++ "fsdi $fd19, [%0+0x98]\n\t" ++ "fsdi $fd18, [%0+0x90]\n\t" ++ "fsdi $fd17, [%0+0x88]\n\t" ++ "fsdi $fd16, [%0+0x80]\n\t" ++ : /* no output */ ++ :"r" (&tsk->thread.fpu) ++ :"memory"); ++ /* fall through */ ++ case 2: ++ asm volatile ("fssi $fs31, [%0+0x7c]\n\t" ++ "fssi $fs30, [%0+0x78]\n\t" ++ "fssi $fs29, [%0+0x74]\n\t" ++ "fssi $fs28, [%0+0x70]\n\t" ++ "fssi $fs27, [%0+0x6c]\n\t" ++ "fssi $fs26, [%0+0x68]\n\t" ++ "fssi $fs25, [%0+0x64]\n\t" ++ "fssi $fs24, [%0+0x60]\n\t" ++ "fssi $fs23, [%0+0x5c]\n\t" ++ "fssi $fs22, [%0+0x58]\n\t" ++ "fssi $fs21, [%0+0x54]\n\t" ++ "fssi $fs20, [%0+0x50]\n\t" ++ "fssi $fs19, [%0+0x4c]\n\t" ++ "fssi $fs18, [%0+0x48]\n\t" ++ "fssi $fs17, [%0+0x44]\n\t" ++ "fssi $fs16, [%0+0x40]\n\t" ++ : /* no output */ ++ :"r" (&tsk->thread.fpu) ++ :"memory"); ++ /* fall through */ ++ case 1: ++ asm volatile ("fssi $fs15, [%0+0x3c]\n\t" ++ "fssi $fs14, [%0+0x38]\n\t" ++ "fssi $fs13, [%0+0x34]\n\t" ++ "fssi $fs12, [%0+0x30]\n\t" ++ "fssi $fs11, [%0+0x2c]\n\t" ++ "fssi $fs10, [%0+0x28]\n\t" ++ "fssi $fs9, [%0+0x24]\n\t" ++ "fssi $fs8, [%0+0x20]\n\t" ++ : /* no output */ ++ :"r" (&tsk->thread.fpu) ++ :"memory"); ++ /* fall through */ ++ case 0: ++ asm volatile ("fssi $fs7, [%1+0x1c]\n\t" ++ "fssi $fs6, [%1+0x18]\n\t" ++ "fssi $fs5, [%1+0x14]\n\t" ++ "fssi $fs4, [%1+0x10]\n\t" ++ "fssi $fs3, [%1+0xc]\n\t" ++ "fssi $fs2, [%1+0x8]\n\t" ++ "fssi $fs1, [%1+0x4]\n\t" ++ "fssi $fs0, [%1+0x0]\n\t" ++ "fmfcsr %0\n\t" ++ "swi %0, [%1+0x100]\n\t" ++ :"=&r" (fpcsr) ++ :"r"(&tsk->thread.fpu) ++ :"memory"); ++ } ++ disable_fpu(); ++} ++ ++void fpload(struct fpu_struct *fpregs) ++{ ++ unsigned int fpcfg, fpcsr; ++ enable_fpu(); ++ ++ asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg)); ++ fpcfg = ((fpcfg & FPCFG_mskFREG) >> FPCFG_offFREG); ++ ++ switch (fpcfg) { ++ case 3: ++ asm volatile ("fldi $fd31, [%0+0xf8]\n\t" ++ "fldi $fd30, [%0+0xf0]\n\t" ++ "fldi $fd29, [%0+0xe8]\n\t" ++ "fldi $fd28, [%0+0xe0]\n\t" ++ "fldi $fd27, [%0+0xd8]\n\t" ++ "fldi $fd26, [%0+0xd0]\n\t" ++ "fldi $fd25, [%0+0xc8]\n\t" ++ "fldi $fd24, [%0+0xc0]\n\t" ++ "fldi $fd23, [%0+0xb8]\n\t" ++ "fldi $fd22, [%0+0xb0]\n\t" ++ "fldi $fd21, [%0+0xa8]\n\t" ++ "fldi $fd20, [%0+0xa0]\n\t" ++ "fldi $fd19, [%0+0x98]\n\t" ++ "fldi $fd18, [%0+0x90]\n\t" ++ "fldi $fd17, [%0+0x88]\n\t" ++ "fldi $fd16, [%0+0x80]\n\t" ++ : /* no output */ ++ :"r" (fpregs)); ++ /* fall through */ ++ case 2: ++ asm volatile ("flsi $fs31, [%0+0x7c]\n\t" ++ "flsi $fs30, [%0+0x78]\n\t" ++ "flsi $fs29, [%0+0x74]\n\t" ++ "flsi $fs28, [%0+0x70]\n\t" ++ "flsi $fs27, [%0+0x6c]\n\t" ++ "flsi $fs26, [%0+0x68]\n\t" ++ "flsi $fs25, [%0+0x64]\n\t" ++ "flsi $fs24, [%0+0x60]\n\t" ++ "flsi $fs23, [%0+0x5c]\n\t" ++ "flsi $fs22, [%0+0x58]\n\t" ++ "flsi $fs21, [%0+0x54]\n\t" ++ "flsi $fs20, [%0+0x50]\n\t" ++ "flsi $fs19, [%0+0x4c]\n\t" ++ "flsi $fs18, [%0+0x48]\n\t" ++ "flsi $fs17, [%0+0x44]\n\t" ++ "flsi $fs16, [%0+0x40]\n\t" ++ : /* no output */ ++ :"r" (fpregs)); ++ /* fall through */ ++ case 1: ++ asm volatile ("flsi $fs15, [%0+0x3c]\n\t" ++ "flsi $fs14, [%0+0x38]\n\t" ++ "flsi $fs13, [%0+0x34]\n\t" ++ "flsi $fs12, [%0+0x30]\n\t" ++ "flsi $fs11, [%0+0x2c]\n\t" ++ "flsi $fs10, [%0+0x28]\n\t" ++ "flsi $fs9, [%0+0x24]\n\t" ++ "flsi $fs8, [%0+0x20]\n\t" ++ : /* no output */ ++ :"r" (fpregs)); ++ /* fall through */ ++ case 0: ++ asm volatile ("flsi $fs7, [%1+0x1c]\n\t" ++ "flsi $fs6, [%1+0x18]\n\t" ++ "flsi $fs5, [%1+0x14]\n\t" ++ "flsi $fs4, [%1+0x10]\n\t" ++ "flsi $fs3, [%1+0xc]\n\t" ++ "flsi $fs2, [%1+0x8]\n\t" ++ "flsi $fs1, [%1+0x4]\n\t" ++ "flsi $fs0, [%1+0x0]\n\t" ++ "lwi %0, [%1+0x100]\n\t" ++ "fmtcsr %0\n\t":"=&r" (fpcsr) ++ :"r"(fpregs)); ++ } ++ disable_fpu(); ++} ++ ++void do_fpu_context_switch(unsigned long error_code, struct pt_regs *regs) ++{ ++ /* Enable to use FPU. */ ++ ++ if (!user_mode(regs)) { ++ printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); ++ BUG(); ++ return; ++ } ++ ++ grab_fpu(regs); ++#ifndef CONFIG_UNLAZY_FPU //Lazy FPU is used ++ if (last_task_used_math == current) ++ return; ++ if (last_task_used_math != NULL) ++ /* Other processes fpu state, save away */ ++ save_fpu(last_task_used_math); ++ last_task_used_math = current; ++#endif ++ if (used_math()) { ++ fpload(¤t->thread.fpu); ++ } else { ++ /* First time FPU user. */ ++ fpload(&init_fpuregs); ++ set_used_math(); ++ } ++ ++} ++ ++void do_fpu_exception(unsigned long error_code, struct pt_regs *regs) ++{ ++ unsigned int subtype = ++ ((GET_ITYPE() & ITYPE_mskSTYPE) >> ITYPE_offSTYPE); ++ unsigned int cpid = ((GET_ITYPE() & ITYPE_mskCPID) >> ITYPE_offCPID); ++ ++ /* FPU */ ++ if ((cpid == 0) && (GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) { ++ /* Coprocessor disabled exception */ ++ if (subtype == 1) { ++ preempt_disable(); ++ do_fpu_context_switch(error_code, regs); ++ preempt_enable(); ++ } ++ /* Coprocessor exception */ ++ else if (subtype == 2) { ++ siginfo_t si = { 0 }; ++ unsigned int fpcsr; ++ enable_fpu(); ++ asm volatile ("fmfcsr %0\n\t":"=&r" (fpcsr)); ++ disable_fpu(); ++ ++ if (fpcsr & FPCSR_mskALLT) { ++ si.si_signo = SIGFPE; ++ /* Exception handling, denorm input, UDF and OVF */ ++ if (fpcsr & FPCSR_mskDNIT) { ++ unsigned int rfpcsr; ++ lose_fpu(1); ++ si.si_signo = ++ do_fpu_denorm(regs, ++ ¤t->thread.fpu); ++ own_fpu(1); ++ ++ if (si.si_signo == SIGFPE) { ++ rfpcsr = ++ current->thread.fpu.fpcsr; ++ ++ if (rfpcsr & FPCSR_mskIVO) ++ si.si_code = FPE_FLTINV; ++ if (rfpcsr & FPCSR_mskDBZ) ++ si.si_code = FPE_FLTDIV; ++ if (rfpcsr & FPCSR_mskOVF) ++ si.si_code = FPE_FLTOVF; ++ if (rfpcsr & FPCSR_mskUDF) ++ si.si_code = FPE_FLTUND; ++ if (rfpcsr & FPCSR_mskIEX) ++ si.si_code = FPE_FLTRES; ++ } else if (si.si_code == SIGILL) ++ show_regs(regs); ++ else if (si.si_code == SIGBUS) ++ si.si_code = BUS_ADRERR; ++ } else if (fpcsr & FPCSR_mskRIT) { ++ printk("Reserved Instruction\n"); ++ show_regs(regs); ++ if (!user_mode(regs)) ++ do_exit(SIGILL); ++ si.si_signo = SIGILL; ++ } else if (fpcsr & FPCSR_mskUDFT) ++ si.si_code = FPE_FLTUND; ++ else if (fpcsr & FPCSR_mskOVFT) ++ si.si_code = FPE_FLTOVF; ++ else if (fpcsr & FPCSR_mskIVOT) ++ si.si_code = FPE_FLTINV; ++ else if (fpcsr & FPCSR_mskDBZT) ++ si.si_code = FPE_FLTDIV; ++ else if (fpcsr & FPCSR_mskIEXT) ++ si.si_code = FPE_FLTRES; ++ /* If something went wrong, signal */ ++ if (si.si_signo) { ++ if (si.si_code == SIGILL) { ++ force_sig(si.si_signo, current); ++ } else { ++ si.si_addr = ++ (void __user *) ++ instruction_pointer(regs); ++ force_sig_info(si.si_signo, &si, ++ current); ++ } ++ } ++ } else { ++ printk("Bad FPU exception\n"); ++ BUG(); ++ } ++ } ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/fpu.h linux-3.4.110/arch/nds32/kernel/fpu.h +--- linux-3.4.110.orig/arch/nds32/kernel/fpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/fpu.h 2016-04-07 10:20:50.938080870 +0200 +@@ -0,0 +1,13 @@ ++ ++ ++/* ++ * Initially load the FPU with signalling NANS. This bit pattern ++ * has the property that no matter whether considered as single or as ++ * double precision, it still represents a signalling NAN. ++ */ ++ ++ #define sNAN64 0xFFFFFFFFFFFFFFFFULL ++ #define sNAN32 0xFFFFFFFFUL ++ ++ #define FPCSR_INIT 0x0 /* Hardware reset value */ ++ +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ftrace.c linux-3.4.110/arch/nds32/kernel/ftrace.c +--- linux-3.4.110.orig/arch/nds32/kernel/ftrace.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/ftrace.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,219 @@ ++/* ++ * Code for replacing ftrace calls with jumps. ++ * ++ * Copyright (C) 2007-2008 Steven Rostedt ++ * ++ * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box. ++ * ++ * Added function graph tracer code, taken from x86 that was written ++ * by Frederic Weisbecker, and ported to PPC by Steven Rostedt. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++# define GET_ADDR(addr) (*(unsigned long *)addr) ++ ++#ifdef CONFIG_DYNAMIC_FTRACE ++static unsigned int ftrace_nop_replace(void) ++{ ++// return PPC_INST_NOP; ++ return 0; ++} ++ ++static unsigned int ++ftrace_call_replace(unsigned long ip, unsigned long addr, int link) ++{ ++ unsigned int op; ++ ++ addr = GET_ADDR(addr); ++ ++ /* if (link) set op to 'bl' else 'b' */ ++// op = create_branch((unsigned int *)ip, addr, link ? 1 : 0); ++ ++ return op; ++} ++ ++static int ++ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) ++{ ++ unsigned int replaced; ++ ++ /* ++ * Note: Due to modules and __init, code can ++ * disappear and change, we need to protect against faulting ++ * as well as code changing. We do this by using the ++ * probe_kernel_* functions. ++ * ++ * No real locking needed, this code is run through ++ * kstop_machine, or before SMP starts. ++ */ ++ ++ /* read the text we want to modify */ ++ if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE)) ++ return -EFAULT; ++ ++ /* Make sure it is what we expect it to be */ ++ if (replaced != old) ++ return -EINVAL; ++ ++ /* replace the text with the new text */ ++ if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE)) ++ return -EPERM; ++ ++ flush_icache_range(ip, ip + 8); ++ ++ return 0; ++} ++ ++int ftrace_make_nop(struct module *mod, ++ struct dyn_ftrace *rec, unsigned long addr) ++{ ++ unsigned long ip = rec->ip; ++ unsigned int old, new; ++ ++ old = ftrace_call_replace(ip, addr, 1); ++ new = ftrace_nop_replace(); ++ return ftrace_modify_code(ip, old, new); ++} ++ ++int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) ++{ ++ unsigned long ip = rec->ip; ++ unsigned int old, new; ++ ++ old = ftrace_nop_replace(); ++ new = ftrace_call_replace(ip, addr, 1); ++ return ftrace_modify_code(ip, old, new); ++} ++ ++int ftrace_update_ftrace_func(ftrace_func_t func) ++{ ++ unsigned long ip = (unsigned long)(&ftrace_call); ++ unsigned int old, new; ++ int ret; ++ ++ old = *(unsigned int *)&ftrace_call; ++ new = ftrace_call_replace(ip, (unsigned long)func, 1); ++ ret = ftrace_modify_code(ip, old, new); ++ ++ return ret; ++} ++ ++int __init ftrace_dyn_arch_init(void *data) ++{ ++ /* caller expects data to be zero */ ++ unsigned long *p = data; ++ ++ *p = 0; ++ ++ return 0; ++} ++#endif /* CONFIG_DYNAMIC_FTRACE */ ++ ++#ifdef CONFIG_FUNCTION_GRAPH_TRACER ++ ++#ifdef CONFIG_DYNAMIC_FTRACE ++extern void ftrace_graph_call(void); ++extern void ftrace_graph_stub(void); ++ ++int ftrace_enable_ftrace_graph_caller(void) ++{ ++ unsigned long ip = (unsigned long)(&ftrace_graph_call); ++ unsigned long addr = (unsigned long)(&ftrace_graph_caller); ++ unsigned long stub = (unsigned long)(&ftrace_graph_stub); ++ unsigned int old, new; ++ ++ old = ftrace_call_replace(ip, stub, 0); ++ new = ftrace_call_replace(ip, addr, 0); ++ ++ return ftrace_modify_code(ip, old, new); ++} ++ ++int ftrace_disable_ftrace_graph_caller(void) ++{ ++ unsigned long ip = (unsigned long)(&ftrace_graph_call); ++ unsigned long addr = (unsigned long)(&ftrace_graph_caller); ++ unsigned long stub = (unsigned long)(&ftrace_graph_stub); ++ unsigned int old, new; ++ ++ old = ftrace_call_replace(ip, addr, 0); ++ new = ftrace_call_replace(ip, stub, 0); ++ ++ return ftrace_modify_code(ip, old, new); ++} ++#endif /* CONFIG_DYNAMIC_FTRACE */ ++int get_selfpc(unsigned long mcount_lp) ++{ ++ unsigned long symbol_size, offset; ++ kallsyms_lookup_size_offset(mcount_lp, &symbol_size, &offset); ++ return mcount_lp - offset; ++} ++ ++/* ++ * Hook the return address and push it in the stack of return addrs ++ * in current thread info. ++ */ ++void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) ++{ ++ unsigned long old; ++ int faulted; ++ struct ftrace_graph_ent trace; ++ unsigned long return_hooker = (unsigned long)&return_to_handler; ++ ++ if (unlikely(atomic_read(¤t->tracing_graph_pause))) ++ return; ++ ++ /* ++ * Protect against fault, even if it shouldn't ++ * happen. This tool is too much intrusive to ++ * ignore such a protection. ++ */ ++ asm volatile ("1: lwi %[old], [%[parent]]\n" ++ "2: swi %[return_hooker], [%[parent]]\n" ++ " movi %[faulted], 0\n" ++ "3:\n" ++ ".section .fixup, \"ax\"\n" ++ ".align 2 \n" ++ "4: movi %[faulted], 1\n" ++ " b 3b\n" ++ ".previous\n" ++ ".section __ex_table,\"a\"\n" ++ ".align 3 \n" ++ ".long 1b,4b\n" ++ ".long 2b,4b\n" ++ ".previous":[old] "=&r"(old),[faulted] "=r"(faulted) ++ :[parent] "r"(parent),[return_hooker] "r"(return_hooker) ++ :"memory"); ++ ++ if (unlikely(faulted)) { ++ ftrace_graph_stop(); ++ WARN_ON(1); ++ return; ++ } ++ ++ trace.func = self_addr; ++ trace.depth = current->curr_ret_stack + 1; ++ ++ /* Only trace if the calling function expects to */ ++ if (!ftrace_graph_entry(&trace)) { ++ *parent = old; ++ return; ++ } ++ ++ if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) { ++ *parent = old; ++ return; ++ } ++} ++#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/head.S linux-3.4.110/arch/nds32/kernel/head.S +--- linux-3.4.110.orig/arch/nds32/kernel/head.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/head.S 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,350 @@ ++/* ++ * arch/nds32/kernel/head.S ++ * ++ * NDS32 Kernel startup code ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++//#include ++#include ++#include ++#include ++#include ++ ++/* ++ * We place the page tables 16K below TEXTADDR. Therefore, we must make sure ++ * that TEXTADDR is correctly set. Currently, we expect the least significant ++ * 16 bits to be 0x8000, but we could probably relax this restriction to ++ * TEXTADDR >= PAGE_OFFSET + 0x4000 ++ * ++ * Note that swapper_pg_dir is the virtual address of the page tables, and ++ * pgtbl gives us a position-independent reference to these tables. We can ++ * do this because _stext == TEXTADDR ++ */ ++ ++ .globl swapper_pg_dir ++ .equ swapper_pg_dir, TEXTADDR - 0x4000 ++ ++/* ++ * Kernel startup entry point. ++ * --------------------------- ++ * ++ * This is normally called from the decompressor code. The requirements ++ * are: MMU = off, D-cache = off, I-cache = dont care, $r0 = 0, ++ * $r1 = machine nr. ++ * ++ * This code is mostly position independent, so if you link the kernel at ++ * 0xc0008000, you call this at __pa(0xc0008000). ++ * ++ * See linux/arch/nds32/tools/mach-types for the complete list of machine ++ * numbers for $r1. ++ * ++ * We're trying to keep crap to a minimum; DO NOT add any machine specific ++ * crap here - that's what the boot loader (or in extreme, well justified ++ * circumstances, zImage) is for. ++ */ ++ .section ".head.text", "ax" ++ .type _stext, %function ++ENTRY(_stext) ++ setgie.d ! Disable interrupt ++ isb ++ move $r1, #MACH_TYPE_FARADAY ! Note: as far, we are in the Superuser mode ++ jal __lookup_processor_type ! get processor id, $r5=procinfo, $r9=cpuid, invalid processor $r5=0 ++ li $r2, 'p' ++ beqz $r5, __error ! yes, error 'p' ++ jal __lookup_machine_type ! $r5=machinfo ++ li $r2, 'a' ++ beqz $r5, __error ++ ++/* ++ * Create a temporary mapping area for booting, before start_kernel ++ */ ++ sethi $r4, hi20(swapper_pg_dir) ++ li $p0, (PAGE_OFFSET - PHYS_OFFSET) ++ sub $r4, $r4, $p0 ++ tlbop FlushAll ! invalidate TLB\n" ++ isb ++ mtsr $r4, $L1_PPTB ! load page table pointer\n" ++ ++/* set NTC0 cacheable/writeback, mutliple page size in use */ ++ mfsr $r3, $MMU_CTL ++ li $r0, ~0x6 ++ and $r3, $r3, $r0 ++ ori $r3, $r3, 0x404 ++ mtsr $r3, $MMU_CTL ++ isb ++ ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ li $r2, #(PHYS_OFFSET + 0x7bf) ++#else ++ li $r2, #(PHYS_OFFSET + 0x6bf) ! to remember here ++#endif ++ movi $r3, #0x5 ++ mtsr $r3, $TLB_MISC ++ ++ sethi $r3, hi20(PAGE_OFFSET) ++ li $r0, #PHYS_OFFSET ++ sethi $r5, hi20(SZ_1M) ! Use 1MB pages ++ sethi $r6, hi20(PHYS_OFFSET+SZ_32M) ! Create 32MB first, leave the rest in paging_init() ++_tlb: ++ mtsr $r3, $TLB_VPN ++ dsb ++ tlbop $r2, RWR ++ isb ++ add $r0, $r0, $r5 ++ add $r3, $r3, $r5 ++ add $r2, $r2, $r5 ++ bne $r0, $r6, _tlb ++ ++ mtsr $r3, $TLB_MISC ! setup access page size ++ li $r2, #~0xf ++ and $r3, $r3, $r2 ++#ifdef CONFIG_ANDES_PAGE_SIZE_8KB ++ ori $r3, $r3, #0x1 ++#endif ++ mtsr $r3, $TLB_MISC ++ ++ mfsr $r0, $MISC_CTL ! Enable BTB and RTP ++ li $r1, #~0x3 ++ and $r0, $r0, $r1 ++ mtsr $r0, $MISC_CTL ++ ++/* ++ * Disable L2CC and wait until L2CC registers are mapped into memory to use L2$. ++ */ ++#ifdef CONFIG_CACHE_L2 ++ li $p0, L2CC_PA_BASE ++ li $p1, 0 ++ swi $p1, [$p0 + L2CC_CTRL_OFF] ++#endif ++ ++#ifdef CONFIG_PLAT_AG102 ++/* ++ * Set GPUBA to 0x0c000006. GPUB 0x1c000000, FB size 64MB. ++ */ ++ li $p0, DDR2C_PA_BASE + 0x02a4 ++ li $p1, 0x0c000006 ++ swi $p1, [$p0] ++#endif ++ ++ mfsr $p1, $PSW ++ li $r15, #~0x43df ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE ++ and $p1, $p1, $r15 ++#ifdef __NDS32_EB__ ++ #ifdef CONFIG_WBNA ++ ori $p1, $p1, #0x40ea ! set WBNA|DT|IT|BE|POM:super|INTL:1 ++ #else ++ ori $p1, $p1, #0xea ! set ----|DT|IT|BE|POM:super|INTL:1 ++ #endif ++#else ++ #ifdef CONFIG_WBNA ++ ori $p1, $p1, #0x40ca ! set WBNA|DT|IT|--|POM:super|INTL:1 ++ #else ++ ori $p1, $p1, #0xca ! set ----|DT|IT|--|POM:super|INTL:1 ++ #endif ++#endif ++ ++ mtsr $p1, $IPSW ! when iret, it will automatically enable MMU ++ la $lp, __mmap_switched ++ mtsr $lp, $IPC ++ iret ++ nop ++ ++ .type __switch_data, %object ++__switch_data: ++ .long __mmap_switched ++ .long _sdata ! $r5 ++ .long __bss_start ! $r6 ++ .long _end ! $r7 ++ .long __machine_arch_type ! $r5 ++ .long init_thread_union + 8192 ! $sp ++ ++ ++/* ++ * The following fragment of code is executed with the MMU on in MMU mode, ++ * and uses absolute addresses; this is not position independent. ++ * ++ * $r0 ++ * $r10 = points to proc info ++ * $r8 = points to machine info, ++ * $r1 = machine ID, 0x2c8 for Andes AG101 board ++ * $r9 = processor ID of value in version register ++ */ ++ .align ++ .type __mmap_switched, %function ++__mmap_switched: ++ la $r3, __switch_data + 4 ++ lmw.bim $r5, [$r3], $r7 ++ ++ move $fp, #0 ! Clear BSS (and zero $fp) ++ beq $r7, $r6, _RRT ++1: swi.bi $fp, [$r6], #4 ++ bne $r7, $r6, 1b ++ ++_RRT: ++ lmw.bim $r4, [$r3], $r4, #0b0001 ++ sw $r1, [$r4] ! Save machine type to memory ++ b start_kernel ++ ++ ++/* ++ * Read processor ID register (CP#15, $CR0), and look up in the linker-built ++ * supported processor list. Note that we can't use the absolute addresses ++ * for the __proc_info lists since we aren't running with the MMU on ++ * (and therefore, we are not in the correct address space). We have to ++ * calculate the offset. ++ * ++ * $r9 = cpuid, get from $CPU_VER ++ * Returns: ++ * $r3, $r4, $r6 corrupted ++ * $r5 = proc_info pointer in physical address space ++ * $r9 = cpuid ++ */ ++ ++ .type __lookup_processor_type, %function ++__lookup_processor_type: ++ la $r5, __proc_info_begin ++ la $r6, __proc_info_end ++ mfsr $r9, $CPU_VER ! get cpu version ++ li $p0, (PAGE_OFFSET - PHYS_OFFSET) ++1: ++ sub $p1, $r5, $p0 ++ lmw.bi $r3, [$p1], $r4 ! value, mask ++ and $r4, $r4, $r9 ! mask wanted bits ++ xor $p1, $r3, $r4 ++ beqz $p1, 2f ++ addi $r5, $r5, #PROC_INFO_SZ ! sizeof(proc_info_list) ++ bne $r5, $r6, 1b ++ ++ move $r5, #0 ! unknown processor -> exit ++2: ret ++ ++ ++ ++/* ++ * Lookup machine architecture in the linker-build list of architectures. ++ * Note that we can't use the absolute addresses for the __arch_info ++ * lists since we aren't running with the MMU on (and therefore, we are ++ * not in the correct address space). We have to calculate the offset. ++ * ++ * $r1 = machine architecture number ++ * Returns: ++ * $r3, $r4, $r6 corrupted ++ * $r5 = mach_info pointer in physical address space ++ */ ++ .type __lookup_machine_type, %function ++__lookup_machine_type: ++ la $r5, __arch_info_begin ++ la $r6, __arch_info_end ++1: ++ li $p0, (PAGE_OFFSET - PHYS_OFFSET) ++ sub $p1, $r5, $p0 ++ lwi $r3, [$p1] ! use PA to get machine type ++ xor $p1, $r3, $r1 ! matches loader number? ++ beqz $p1, 2f ! found ++ addi $r5, $r5, #SIZEOF_MACHINE_DESC ! next machine_desc ++ bne $r5, $r6, 1b ++ move $r5, #0 ! unknown machine ++2: ret ++ ++ ++/* ++ * Exception handling. Something went wrong and we can't proceed. We ++ * ought to tell the user, but since we don't have any guarantee that ++ * we're even running on the right architecture, we do virtually nothing. ++ * ++ * a = invalid architecture ++ * p = invalid processor ++ * ++ * Generally, only serious errors cause this. ++ */ ++__error: ++ li $r1, UART0_PA_BASE ++ sw $r2, [$r1] ++die: b die ++ ++ ++ ++#ifdef CONFIG_SMP ++ ++ .type secondary_startup, %function ++ENTRY(secondary_startup) ++ /* ++ * Common entry point for secondary CPUs. ++ * ++ * Lookup the processor type - there is no need to check the ++ * machine type as it has already been validated by the ++ * primary processor. ++ */ ++ mfsr $r0, $MMU_CTL ++ ori $r0, $r0, #4 ++#ifndef CONFIG_NO_KERNEL_LARGE_PAGE ++ ori $r0, $r0, #0x400 ++#endif ++ mtsr $r0, $MMU_CTL ++ ++ movi $r15, #0x01 ++ swi $r15, [$p1+#0x10] ++ lwi $sp, [$p1+#0x18] ++ ++ /* ++ * Set stack, L1_PPTB, and enable mmu ++ */ ++ sethi $r4, hi20(swapper_pg_dir) ++ li $p0, (PAGE_OFFSET - PHYS_OFFSET) ++ sub $r4, $r4, $p0 ++ ++ tlbop FlushAll ++ isb ++ mtsr $r4, $L1_PPTB ++ ++#ifdef CONFIG_CACHE_L2 ++ li $r0, #0x1801 ++ mtsr $r0, $HSMP_SADDR ++ isb ++ li $r0, #(L2CC_PA_BASE+0x10) ! L2CC Control ++ lwi $r1, [$r0] ++ li $r2, #~(0xf << 28) ++ and $r1, $r1, $r2 ++ bset $r1, $r1, #29 ++ bset $r1, $r1, #31 ++ swi $r1, [$r0] ++#endif ++ ++ move $fp, #0 ++ ++ mfsr $p1, $PSW ++ li $r15, #~0x43df ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE ++ and $p1, $p1, $r15 ++#ifdef __NDS32_EB__ ++ #ifdef CONFIG_WBNA ++ ori $p1, $p1, #0x40ea ! set WBNA|DT|IT|BE|POM:super|INTL:1 ++ #else ++ ori $p1, $p1, #0xea ! set ----|DT|IT|BE|POM:super|INTL:1 ++ #endif ++#else ++ #ifdef CONFIG_WBNA ++ ori $p1, $p1, #0x40ca ! set WBNA|DT|IT|--|POM:super|INTL:1 ++ #else ++ ori $p1, $p1, #0xca ! set ----|DT|IT|--|POM:super|INTL:1 ++ #endif ++#endif ++ ++ mtsr $p1, $IPSW ! when iret, it will automatically enable MMU ++ la $lp, secondary_start_kernel ++ mtsr $lp, $IPC ++ iret ++ nop ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/init_task.c linux-3.4.110/arch/nds32/kernel/init_task.c +--- linux-3.4.110.orig/arch/nds32/kernel/init_task.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/init_task.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,25 @@ ++/* ++ * linux/arch/nds32/kernel/init_task.c ++ * ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++ ++static struct signal_struct init_signals = INIT_SIGNALS(init_signals); ++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); ++ ++/* Initial task structure */ ++struct task_struct init_task = INIT_TASK(init_task); ++EXPORT_SYMBOL(init_task); ++ ++/* ++ * Initial thread structure. Alignment of this is handled by a special ++ * linker map entry. ++ */ ++union thread_union init_thread_union __init_task_data = ++ { INIT_THREAD_INFO(init_task) }; +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/io.c linux-3.4.110/arch/nds32/kernel/io.c +--- linux-3.4.110.orig/arch/nds32/kernel/io.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/io.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,51 @@ ++#include ++#include ++ ++#include ++ ++/* ++ * Copy data from IO memory space to "real" memory space. ++ * This needs to be optimized. ++ */ ++void _memcpy_fromio(void *to, const volatile void __iomem * from, size_t count) ++{ ++ unsigned char *t = to; ++ while (count) { ++ count--; ++ *t = readb(from); ++ t++; ++ from++; ++ } ++} ++ ++/* ++ * Copy data from "real" memory space to IO memory space. ++ * This needs to be optimized. ++ */ ++void _memcpy_toio(volatile void __iomem * to, const void *from, size_t count) ++{ ++ const unsigned char *f = from; ++ while (count) { ++ count--; ++ writeb(*f, to); ++ f++; ++ to++; ++ } ++} ++ ++/* ++ * "memset" on IO memory space. ++ * This needs to be optimized. ++ */ ++void _memset_io(volatile void __iomem * dst, int c, size_t count) ++{ ++ while (count) { ++ count--; ++ writeb(c, dst); ++ dst++; ++ } ++} ++ ++EXPORT_SYMBOL(_memcpy_fromio); ++EXPORT_SYMBOL(_memcpy_toio); ++EXPORT_SYMBOL(_memset_io); +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/irq.c linux-3.4.110/arch/nds32/kernel/irq.c +--- linux-3.4.110.orig/arch/nds32/kernel/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/irq.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,122 @@ ++/* ++ * linux/arch/nds32/kernel/irq.c ++ * ++ * Copyright (C) 1992 Linus Torvalds ++ * Modifications for ARM processor Copyright (C) 1995-2000 Russell King. ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This file contains the code used by various IRQ handling routines: ++ * asking for different IRQ's should be done through these routines ++ * instead of just grabbing them. Thus setups with different IRQ numbers ++ * shouldn't result in any weird surprises, and installing new handlers ++ * should be easier. ++ * ++ * IRQ's are in fact implemented a bit like signal handlers for the kernel. ++ * Naturally it's not a 1:1 relation, but there are similarities. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void (*init_arch_irq) (void)__initdata = NULL; ++unsigned long irq_err_count; ++ ++void ack_bad_irq(unsigned int irq) ++{ ++ printk("bad IRQ %d\n", irq); ++} ++ ++int show_interrupts(struct seq_file *p, void *v) ++{ ++ int i = *(loff_t *) v, cpu; ++ struct irqaction *action; ++ unsigned long flags; ++ ++ if (i == 0) { ++ char cpuname[12]; ++ ++ seq_printf(p, " "); ++ for_each_present_cpu(cpu) { ++ sprintf(cpuname, "CPU%d", cpu); ++ seq_printf(p, " %10s", cpuname); ++ } ++ seq_putc(p, '\n'); ++ } ++ ++ if (i < NR_IRQS) { ++ raw_spin_lock_irqsave(&irq_desc[i].lock, flags); ++ action = irq_desc[i].action; ++ if (!action) ++ goto unlock; ++ ++ seq_printf(p, "%3d: ", i); ++ for_each_present_cpu(cpu) ++ seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); ++ seq_printf(p, " %s", action->name); ++ for (action = action->next; action; action = action->next) ++ seq_printf(p, ", %s", action->name); ++ ++ seq_putc(p, '\n'); ++unlock: ++ raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); ++ } else if (i == NR_IRQS) { ++ seq_printf(p, "Err: %10lu\n", irq_err_count); ++ } ++ return 0; ++} ++ ++/* ++ * do_IRQ handles all hardware IRQ's. Decoded IRQs should not ++ * come via this function. Instead, they should provide their ++ * own 'handler' ++ */ ++asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) ++{ ++ struct pt_regs *old_regs = set_irq_regs(regs); ++ ++ /* ++ * Some hardware gives randomly wrong interrupts. Rather ++ * than crashing, do something sensible. ++ */ ++ if (unlikely(irq >= NR_IRQS)) { ++ printk(KERN_EMERG "IRQ exceeds NR_IRQS\n"); ++ BUG(); ++ } ++ ++ irq_enter(); ++ generic_handle_irq(irq); ++ irq_exit(); ++ set_irq_regs(old_regs); ++ ++} ++ ++void __init init_IRQ(void) ++{ ++ int irq; ++ ++ for (irq = 0; irq < NR_IRQS; irq++) ++ irq_set_noprobe(irq); ++ ++ init_arch_irq(); ++} ++ ++#ifdef CONFIG_TRACE_IRQFLAGS ++void notrace arch_trace_hardirqs_on(void) ++{ ++ trace_hardirqs_on(); ++} ++ ++void notrace arch_trace_hardirqs_off(void) ++{ ++ trace_hardirqs_off(); ++} ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/kgdb.c linux-3.4.110/arch/nds32/kernel/kgdb.c +--- linux-3.4.110.orig/arch/nds32/kernel/kgdb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/kgdb.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,291 @@ ++/* ============================================================================ ++ * ++ * arch/nds32/kernel/kgdb.c ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for NDS32 KGDB support. ++ * ++ * Author: Harry Pan ++ * ++ * Revision History: ++ * ++ * Nov.23.2007 Initial ported by Harry, ++ * inherited from the KGDB in 2.6.11 and 2.4.35. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// ============================================================================ ++// regs_to_gdb_regs() ++// ++// Make a local copy of the registers passed into the handler (bletch). ++// ============================================================================ ++void pt_regs_to_gdb_regs(unsigned long *gregs, struct pt_regs *kregs) ++{ ++ int regno; ++ ++ /* Initialize all to zero (??) */ ++ for (regno = 0; regno < NDS32_NUM_REGS; regno++) ++ gregs[regno] = 0; ++ ++ gregs[0] = kregs->NDS32_r0; ++ gregs[1] = kregs->NDS32_r1; ++ gregs[2] = kregs->NDS32_r2; ++ gregs[3] = kregs->NDS32_r3; ++ gregs[4] = kregs->NDS32_r4; ++ gregs[5] = kregs->NDS32_r5; ++ gregs[6] = kregs->NDS32_r6; ++ gregs[7] = kregs->NDS32_r7; ++ gregs[8] = kregs->NDS32_r8; ++ gregs[9] = kregs->NDS32_r9; ++ gregs[10] = kregs->NDS32_r10; ++ gregs[11] = kregs->NDS32_r11; ++ gregs[12] = kregs->NDS32_r12; ++ gregs[13] = kregs->NDS32_r13; ++ gregs[14] = kregs->NDS32_r14; ++ gregs[15] = kregs->NDS32_r15; ++ gregs[16] = kregs->NDS32_r16; ++ gregs[17] = kregs->NDS32_r17; ++ gregs[18] = kregs->NDS32_r18; ++ gregs[19] = kregs->NDS32_r19; ++ gregs[20] = kregs->NDS32_r20; ++ gregs[21] = kregs->NDS32_r21; ++ gregs[22] = kregs->NDS32_r22; ++ gregs[23] = kregs->NDS32_r23; ++ gregs[24] = kregs->NDS32_r24; ++ gregs[25] = kregs->NDS32_r25; ++ gregs[26] = kregs->NDS32_pp0; ++ gregs[27] = kregs->NDS32_pp1; ++ gregs[28] = kregs->NDS32_fp; ++ gregs[29] = kregs->NDS32_gp; ++ gregs[30] = kregs->NDS32_lp; ++ gregs[31] = kregs->NDS32_sp; ++ gregs[32] = kregs->NDS32_ipc; ++ gregs[33] = kregs->NDS32_d0lo; ++ gregs[34] = kregs->NDS32_d0hi; ++ gregs[35] = kregs->NDS32_d1lo; ++ gregs[36] = kregs->NDS32_d1hi; ++ gregs[NDS32_IR0_REGNUM] = kregs->NDS32_ipsw; ++} ++ ++// ============================================================================ ++// gdb_regs_to_regs() ++// ++// Copy local gdb registers back to kgdb regs, for later copy to kernel. ++// ============================================================================ ++void gdb_regs_to_pt_regs(unsigned long *gregs, struct pt_regs *kregs) ++{ ++ kregs->NDS32_r0 = gregs[0]; ++ kregs->NDS32_r1 = gregs[1]; ++ kregs->NDS32_r2 = gregs[2]; ++ kregs->NDS32_r3 = gregs[3]; ++ kregs->NDS32_r4 = gregs[4]; ++ kregs->NDS32_r5 = gregs[5]; ++ kregs->NDS32_r6 = gregs[6]; ++ kregs->NDS32_r7 = gregs[7]; ++ kregs->NDS32_r8 = gregs[8]; ++ kregs->NDS32_r9 = gregs[9]; ++ kregs->NDS32_r10 = gregs[10]; ++ kregs->NDS32_r11 = gregs[11]; ++ kregs->NDS32_r12 = gregs[12]; ++ kregs->NDS32_r13 = gregs[13]; ++ kregs->NDS32_r14 = gregs[14]; ++ kregs->NDS32_r15 = gregs[15]; ++ kregs->NDS32_r16 = gregs[16]; ++ kregs->NDS32_r17 = gregs[17]; ++ kregs->NDS32_r18 = gregs[18]; ++ kregs->NDS32_r19 = gregs[19]; ++ kregs->NDS32_r20 = gregs[20]; ++ kregs->NDS32_r21 = gregs[21]; ++ kregs->NDS32_r22 = gregs[22]; ++ kregs->NDS32_r23 = gregs[23]; ++ kregs->NDS32_r24 = gregs[24]; ++ kregs->NDS32_r25 = gregs[25]; ++ kregs->NDS32_pp0 = gregs[26]; ++ kregs->NDS32_pp1 = gregs[27]; ++ kregs->NDS32_fp = gregs[28]; ++ kregs->NDS32_gp = gregs[29]; ++ kregs->NDS32_lp = gregs[30]; ++ kregs->NDS32_sp = gregs[31]; ++ kregs->NDS32_ipc = gregs[32]; ++ kregs->NDS32_d0lo = gregs[33]; ++ kregs->NDS32_d0hi = gregs[34]; ++ kregs->NDS32_d1lo = gregs[35]; ++ kregs->NDS32_d1hi = gregs[36]; ++ kregs->NDS32_ipsw = gregs[NDS32_IR0_REGNUM]; ++} ++ ++// ---------------------------------------------------------------------------- ++// kgdb_get_user_regs() ++// ++// Get user process registers. ++// ---------------------------------------------------------------------------- ++static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task) ++{ ++ return (struct pt_regs *) ++ ((unsigned long)task_thread_info(task) + THREAD_SIZE - ++ 8 - sizeof(struct pt_regs)); ++} ++ ++// ============================================================================ ++// sleeping_thread_to_gdb_regs() ++// ++// ============================================================================ ++void sleeping_thread_to_gdb_regs(unsigned long *gregs, struct task_struct *task) ++{ ++ int regno; ++ struct pt_regs *tregs; ++ ++ /* Just making sure... */ ++ if (task == NULL) ++ return; ++ ++ /* Initialize to zero */ ++ for (regno = 0; regno < NDS32_NUM_REGS; regno++) ++ gregs[regno] = 0; ++ ++ /* Otherwise, we have only some registers from switch_to() */ ++ tregs = kgdb_get_user_regs(task); ++ ++ gregs[0] = tregs->NDS32_r0; ++ gregs[1] = tregs->NDS32_r1; ++ gregs[2] = tregs->NDS32_r2; ++ gregs[3] = tregs->NDS32_r3; ++ gregs[4] = tregs->NDS32_r4; ++ gregs[5] = tregs->NDS32_r5; ++ gregs[6] = tregs->NDS32_r6; ++ gregs[7] = tregs->NDS32_r7; ++ gregs[8] = tregs->NDS32_r8; ++ gregs[9] = tregs->NDS32_r9; ++ gregs[10] = tregs->NDS32_r10; ++ gregs[11] = tregs->NDS32_r11; ++ gregs[12] = tregs->NDS32_r12; ++ gregs[13] = tregs->NDS32_r13; ++ gregs[14] = tregs->NDS32_r14; ++ gregs[15] = tregs->NDS32_r15; ++ gregs[16] = tregs->NDS32_r16; ++ gregs[17] = tregs->NDS32_r17; ++ gregs[18] = tregs->NDS32_r18; ++ gregs[19] = tregs->NDS32_r19; ++ gregs[20] = tregs->NDS32_r20; ++ gregs[21] = tregs->NDS32_r21; ++ gregs[22] = tregs->NDS32_r22; ++ gregs[23] = tregs->NDS32_r23; ++ gregs[24] = tregs->NDS32_r24; ++ gregs[25] = tregs->NDS32_r25; ++ gregs[26] = tregs->NDS32_pp0; ++ gregs[27] = tregs->NDS32_pp1; ++ gregs[28] = tregs->NDS32_fp; ++ gregs[29] = tregs->NDS32_gp; ++ gregs[30] = tregs->NDS32_lp; ++ gregs[31] = tregs->NDS32_sp; ++ gregs[32] = tregs->NDS32_ipc; ++ gregs[33] = tregs->NDS32_d0lo; ++ gregs[34] = tregs->NDS32_d0hi; ++ gregs[35] = tregs->NDS32_d1lo; ++ gregs[36] = tregs->NDS32_d1hi; ++ gregs[NDS32_IR0_REGNUM] = tregs->NDS32_ipsw; ++} ++ ++int kgdb_arch_handle_exception(int exception_vector, int signo, ++ int err_code, char *remcom_in_buffer, ++ char *remcom_out_buffer, ++ struct pt_regs *linux_regs) ++{ ++ long addr; ++ char *ptr; ++ ++ if (0 == atomic_dec_if_positive(&kgdb_setting_breakpoint)) ++ linux_regs->NDS32_ipc += 2; ++ ++ switch (remcom_in_buffer[0]) { ++ case 'k': ++ case 'D': ++ case 'c': ++ case 's': ++ kgdb_contthread = NULL; ++ ++ /* ++ * Try to read optional parameter, pc unchanged if no parm. ++ * If this was a compiled breakpoint, we need to move ++ * to the next instruction or we will just breakpoint ++ * over and over again. ++ */ ++ ptr = &remcom_in_buffer[1]; ++ if (kgdb_hex2long(&ptr, &addr)) { ++ linux_regs->NDS32_ipc = addr; ++ } ++ linux_regs->NDS32_ipsw &= ~0x800; ++ if (remcom_in_buffer[0] == 's') { ++ linux_regs->NDS32_ipsw |= 0x800; ++ } ++ ++ return 0; ++ } ++ ++ return -1; ++} ++ ++static int kgdb_notify(struct notifier_block *self, ++ unsigned long cmd, void *ptr) ++{ ++ struct die_args *args = ptr; ++ unsigned long addr = args->err; ++ if (addr > TASK_SIZE) { ++ kgdb_handle_exception(args->trapnr, args->signr, ++ args->err, args->regs); ++ return NOTIFY_STOP; ++ } ++ return NOTIFY_DONE; ++} ++ ++static struct notifier_block kgdb_notifier = { ++ .notifier_call = kgdb_notify, ++}; ++ ++int kgdb_arch_init(void) ++{ ++ register_die_notifier(&kgdb_notifier); ++} ++ ++void kgdb_arch_exit(void) ++{ ++ unregister_die_notifier(&kgdb_notifier); ++} ++ ++struct kgdb_arch arch_kgdb_ops = { ++#ifdef __NDS32_EL__ ++ .gdb_bpt_instr = {0xeb, 0xff} ++#else ++ .gdb_bpt_instr = {0xff, 0xeb} ++#endif ++}; +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/kprobes.c linux-3.4.110/arch/nds32/kernel/kprobes.c +--- linux-3.4.110.orig/arch/nds32/kernel/kprobes.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/kprobes.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,869 @@ ++/* ++ * Kernel Probes (KProbes) ++ * ++ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * Copyright (C) IBM Corporation, 2002, 2004 ++ * ++ * 2002-Oct Created by Vamsi Krishna S Kernel ++ * Probes initial implementation ( includes contributions from ++ * Rusty Russell). ++ * 2004-July Suparna Bhattacharya added jumper probes ++ * interface to access function arguments. ++ * 2004-Oct Jim Keniston and Prasanna S Panchamukhi ++ * adapted for x86_64 from i386. ++ * 2005-Mar Roland McGrath ++ * Fixed to handle %rip-relative addressing mode correctly. ++ * 2005-May Hien Nguyen , Jim Keniston ++ * and Prasanna S Panchamukhi ++ * added function-return probes. ++ * 2005-May Rusty Lynch ++ * Added function return probes functionality ++ * 2006-Feb Masami Hiramatsu added ++ * kprobe-booster and kretprobe-booster for i386. ++ * 2007-Dec Masami Hiramatsu added kprobe-booster ++ * and kretprobe-booster for x86-64 ++ * 2007-Dec Masami Hiramatsu , Arjan van de Ven ++ * and Jim Keniston ++ * unified x86 kprobes code. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef __NDS32_EL__ ++#define SZINSN(insn) (((insn & 0x00000080) == 0) ? 4 : 2) ++#define BREAK16_1FE 0xFEEB ++#else ++#define SZINSN(insn) (((insn & 0x80000000) == 0) ? 4 : 2) ++#define BREAK16_1FE 0xEBFE ++#endif ++ ++void jprobe_return_point(void); ++ ++DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; ++DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); ++ ++#if 0 ++/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/ ++static void __kprobes set_jmp_op(void *from, void *to) ++{ ++ struct __arch_jmp_op { ++ char op; ++ s32 raddr; ++ } __attribute__ ((packed)) * jop; ++ jop = (struct __arch_jmp_op *)from; ++ jop->raddr = (s32) ((long)(to) - ((long)(from) + 5)); ++ jop->op = RELATIVEJUMP_INSTRUCTION; ++} ++ ++/* ++ * Check for the REX prefix which can only exist on X86_64 ++ * X86_32 always returns 0 ++ */ ++static int __kprobes is_REX_prefix(kprobe_opcode_t * insn) ++{ ++#ifdef CONFIG_X86_64 ++ if ((*insn & 0xf0) == 0x40) ++ return 1; ++#endif ++ return 0; ++} ++ ++/* ++ * Returns non-zero if opcode is boostable. ++ * RIP relative instructions are adjusted at copying time in 64 bits mode ++ */ ++static int __kprobes can_boost(kprobe_opcode_t * opcodes) ++{ ++ kprobe_opcode_t opcode; ++ kprobe_opcode_t *orig_opcodes = opcodes; ++ ++ if (search_exception_tables(opcodes)) ++ return 0; /* Page fault may occur on this address. */ ++ ++retry: ++ if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) ++ return 0; ++ opcode = *(opcodes++); ++ ++ /* 2nd-byte opcode */ ++ if (opcode == 0x0f) { ++ if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) ++ return 0; ++ return test_bit(*opcodes, ++ (unsigned long *)twobyte_is_boostable); ++ } ++ ++ switch (opcode & 0xf0) { ++#ifdef CONFIG_X86_64 ++ case 0x40: ++ goto retry; /* REX prefix is boostable */ ++#endif ++ case 0x60: ++ if (0x63 < opcode && opcode < 0x67) ++ goto retry; /* prefixes */ ++ /* can't boost Address-size override and bound */ ++ return (opcode != 0x62 && opcode != 0x67); ++ case 0x70: ++ return 0; /* can't boost conditional jump */ ++ case 0xc0: ++ /* can't boost software-interruptions */ ++ return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; ++ case 0xd0: ++ /* can boost AA* and XLAT */ ++ return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); ++ case 0xe0: ++ /* can boost in/out and absolute jmps */ ++ return ((opcode & 0x04) || opcode == 0xea); ++ case 0xf0: ++ if ((opcode & 0x0c) == 0 && opcode != 0xf1) ++ goto retry; /* lock/rep(ne) prefix */ ++ /* clear and set flags are boostable */ ++ return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); ++ default: ++ /* segment override prefixes are boostable */ ++ if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e) ++ goto retry; /* prefixes */ ++ /* CS override prefix and call are not boostable */ ++ return (opcode != 0x2e && opcode != 0x9a); ++ } ++} ++ ++/* ++ * Returns non-zero if opcode modifies the interrupt flag. ++ */ ++static int __kprobes is_IF_modifier(kprobe_opcode_t * insn) ++{ ++ switch (*insn) { ++ case 0xfa: /* cli */ ++ case 0xfb: /* sti */ ++ case 0xcf: /* iret/iretd */ ++ case 0x9d: /* popf/popfd */ ++ return 1; ++ } ++ ++ /* ++ * on X86_64, 0x40-0x4f are REX prefixes so we need to look ++ * at the next byte instead.. but of course not recurse infinitely ++ */ ++ if (is_REX_prefix(insn)) ++ return is_IF_modifier(++insn); ++ ++ return 0; ++} ++ ++/* ++ * Adjust the displacement if the instruction uses the %rip-relative ++ * addressing mode. ++ * If it does, Return the address of the 32-bit displacement word. ++ * If not, return null. ++ * Only applicable to 64-bit x86. ++ */ ++static void __kprobes fix_riprel(struct kprobe *p) ++{ ++#ifdef CONFIG_X86_64 ++ u8 *insn = p->ainsn.insn; ++ s64 disp; ++ int need_modrm; ++ ++ /* Skip legacy instruction prefixes. */ ++ while (1) { ++ switch (*insn) { ++ case 0x66: ++ case 0x67: ++ case 0x2e: ++ case 0x3e: ++ case 0x26: ++ case 0x64: ++ case 0x65: ++ case 0x36: ++ case 0xf0: ++ case 0xf3: ++ case 0xf2: ++ ++insn; ++ continue; ++ } ++ break; ++ } ++ ++ /* Skip REX instruction prefix. */ ++ if (is_REX_prefix(insn)) ++ ++insn; ++ ++ if (*insn == 0x0f) { ++ /* Two-byte opcode. */ ++ ++insn; ++ need_modrm = test_bit(*insn, ++ (unsigned long *)twobyte_has_modrm); ++ } else ++ /* One-byte opcode. */ ++ need_modrm = test_bit(*insn, ++ (unsigned long *)onebyte_has_modrm); ++ ++ if (need_modrm) { ++ u8 modrm = *++insn; ++ if ((modrm & 0xc7) == 0x05) { ++ /* %rip+disp32 addressing mode */ ++ /* Displacement follows ModRM byte. */ ++ ++insn; ++ /* ++ * The copied instruction uses the %rip-relative ++ * addressing mode. Adjust the displacement for the ++ * difference between the original location of this ++ * instruction and the location of the copy that will ++ * actually be run. The tricky bit here is making sure ++ * that the sign extension happens correctly in this ++ * calculation, since we need a signed 32-bit result to ++ * be sign-extended to 64 bits when it's added to the ++ * %rip value and yield the same 64-bit result that the ++ * sign-extension of the original signed 32-bit ++ * displacement would have given. ++ */ ++ disp = (u8 *) p->addr + *((s32 *) insn) - ++ (u8 *) p->ainsn.insn; ++ BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ ++ *(s32 *) insn = (s32) disp; ++ } ++ } ++#endif ++} ++#endif ++ ++static void __kprobes arch_copy_kprobe(struct kprobe *p) ++{ ++ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); ++ flush_icache_range((unsigned long)p->ainsn.insn, ++ (unsigned long)p->ainsn.insn + ++ MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); ++ ++// fix_riprel(p); ++ ++// if (can_boost(p->addr)) ++// p->ainsn.boostable = 0; ++// else ++ p->ainsn.boostable = -1; ++ ++ p->opcode = *p->addr; ++} ++ ++int __kprobes arch_prepare_kprobe(struct kprobe *p) ++{ ++ /* insn: must be on special executable page on x86. */ ++ p->ainsn.insn = get_insn_slot(); ++ if (!p->ainsn.insn) ++ return -ENOMEM; ++ arch_copy_kprobe(p); ++ return 0; ++} ++ ++void __kprobes arch_arm_kprobe(struct kprobe *p) ++{ ++ *p->addr = BREAK16_1FE; ++ flush_icache_range((unsigned long)p->addr, ++ (unsigned long)p->addr + sizeof(kprobe_opcode_t)); ++} ++ ++void __kprobes arch_disarm_kprobe(struct kprobe *p) ++{ ++ *p->addr = p->opcode; ++ flush_icache_range((unsigned long)p->addr, ++ (unsigned long)p->addr + sizeof(kprobe_opcode_t)); ++} ++ ++void __kprobes arch_remove_kprobe(struct kprobe *p) ++{ ++ if (p->ainsn.insn) { ++ free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1)); ++ p->ainsn.insn = NULL; ++ } ++} ++ ++static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) ++{ ++ kcb->prev_kprobe.kp = kprobe_running(); ++ kcb->prev_kprobe.status = kcb->kprobe_status; ++ kcb->prev_kprobe.old_flags = kcb->kprobe_old_flags; ++ kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags; ++} ++ ++static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) ++{ ++ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; ++ kcb->kprobe_status = kcb->prev_kprobe.status; ++ kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags; ++ kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags; ++} ++ ++static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, ++ struct kprobe_ctlblk *kcb) ++{ ++ __get_cpu_var(current_kprobe) = p; ++// kcb->kprobe_saved_flags = kcb->kprobe_old_flags ++// = regs->NDS32_ipsw & PSW_mskHSS; ++} ++ ++static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) ++{ ++ regs->NDS32_ipsw |= PSW_mskHSS; ++ /* single step inline if the instruction is an int3 */ ++// if (p->opcode == BREAK16_1FE) ++// regs->NDS32_ipc = (unsigned long)p->addr; ++// else ++ regs->NDS32_ipc = (unsigned long)p->ainsn.insn; ++} ++ ++void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, ++ struct pt_regs *regs) ++{ ++ ri->ret_addr = (kprobe_opcode_t *) regs->NDS32_lp; ++ regs->NDS32_lp = (unsigned long)&kretprobe_trampoline; ++} ++ ++static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs, ++ struct kprobe_ctlblk *kcb) ++{ ++#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER) ++ if (p->ainsn.boostable == 1 && !p->post_handler) { ++ /* Boost up -- we can execute copied instructions directly */ ++ reset_current_kprobe(); ++ regs->NDS32_ipc = (unsigned long)p->ainsn.insn; ++ preempt_enable_no_resched(); ++ return; ++ } ++#endif ++ prepare_singlestep(p, regs); ++ kcb->kprobe_status = KPROBE_HIT_SS; ++} ++ ++/* ++ * We have reentered the kprobe_handler(), since another probe was hit while ++ * within the handler. We save the original kprobes variables and just single ++ * step on the instruction of the new probe without calling any user handlers. ++ */ ++static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs, ++ struct kprobe_ctlblk *kcb) ++{ ++ switch (kcb->kprobe_status) { ++#if 0 ++ case KPROBE_HIT_SSDONE: ++#ifdef CONFIG_X86_64 ++ /* TODO: Provide re-entrancy from post_kprobes_handler() and ++ * avoid exception stack corruption while single-stepping on ++ * the instruction of the new probe. ++ */ ++ arch_disarm_kprobe(p); ++ regs->ip = (unsigned long)p->addr; ++ reset_current_kprobe(); ++ preempt_enable_no_resched(); ++ break; ++#endif ++#endif ++ case KPROBE_HIT_ACTIVE: ++ save_previous_kprobe(kcb); ++ set_current_kprobe(p, regs, kcb); ++ kprobes_inc_nmissed_count(p); ++ prepare_singlestep(p, regs); ++ kcb->kprobe_status = KPROBE_REENTER; ++ break; ++ case KPROBE_HIT_SS: ++ if (p == kprobe_running()) { ++ regs->NDS32_ipc &= ~PSW_mskHSS; ++// regs->NDS32_ipc |= kcb->kprobe_saved_flags; ++ return 0; ++ } else { ++ /* A probe has been hit in the codepath leading up ++ * to, or just after, single-stepping of a probed ++ * instruction. This entire codepath should strictly ++ * reside in .kprobes.text section. Raise a warning ++ * to highlight this peculiar case. ++ */ ++ } ++ default: ++ /* impossible cases */ ++ WARN_ON(1); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* ++ * Interrupts are disabled on entry as trap3 is an interrupt gate and they ++ * remain disabled thorough out this function. ++ */ ++static int __kprobes kprobe_handler(struct pt_regs *regs) ++{ ++ kprobe_opcode_t *addr; ++ struct kprobe *p; ++ struct kprobe_ctlblk *kcb; ++ ++ addr = (kprobe_opcode_t *) regs->NDS32_ipc; ++ if (*addr != BREAK16_1FE) { ++ /* ++ * The breakpoint instruction was removed right ++ * after we hit it. Another cpu has removed ++ * either a probepoint or a debugger breakpoint ++ * at this address. In either case, no further ++ * handling of this interrupt is appropriate. ++ * Back up over the (now missing) int3 and run ++ * the original instruction. ++ */ ++ return 1; ++ } ++ ++ /* ++ * We don't want to be preempted for the entire ++ * duration of kprobe processing. We conditionally ++ * re-enable preemption at the end of this function, ++ * and also in reenter_kprobe() and setup_singlestep(). ++ */ ++ preempt_disable(); ++ ++ kcb = get_kprobe_ctlblk(); ++ p = get_kprobe(addr); ++ ++ if (p) { ++ if (kprobe_running()) { ++ if (reenter_kprobe(p, regs, kcb)) ++ return 1; ++ } else { ++ set_current_kprobe(p, regs, kcb); ++ kcb->kprobe_status = KPROBE_HIT_ACTIVE; ++ ++ /* ++ * If we have no pre-handler or it returned 0, we ++ * continue with normal processing. If we have a ++ * pre-handler and it returned non-zero, it prepped ++ * for calling the break_handler below on re-entry ++ * for jprobe processing, so get out doing nothing ++ * more here. ++ */ ++ if (!p->pre_handler || !p->pre_handler(p, regs)) ++ setup_singlestep(p, regs, kcb); ++ return 1; ++ } ++ } else if (kprobe_running()) { ++ p = __get_cpu_var(current_kprobe); ++ if (p->break_handler && p->break_handler(p, regs)) { ++ setup_singlestep(p, regs, kcb); ++ return 1; ++ } ++ } ++ /* else: not a kprobe fault; let the kernel handle it */ ++ preempt_enable_no_resched(); ++ return 0; ++} ++ ++/* ++ * When a retprobed function returns, this code saves registers and ++ * calls trampoline_handler() runs, which calls the kretprobe's handler. ++ */ ++static void __used __kprobes kretprobe_trampoline_holder(void) ++{ ++ asm volatile (".global kretprobe_trampoline \n" ++ "kretprobe_trampoline: \n" ++ "smw.adm $r15, [$sp], $r15, #0x0\n" ++ "smw.adm $r0, [$sp], $r5, #0x1 \n" ++ "addi $r0, $sp, #-76 \n" ++ "bal trampoline_handler \n" ++ "move $lp, $r0 \n" ++ "lmw.bim $r0, [$sp], $r5, #0x1 \n" ++ "lmw.bim $r15, [$sp], $r15, #0x0\n" ++ "ret \n"); ++} ++ ++/* ++ * Called from kretprobe_trampoline ++ */ ++static __used __kprobes void *trampoline_handler(struct pt_regs *regs) ++{ ++ struct kretprobe_instance *ri = NULL; ++ struct hlist_head *head, empty_rp; ++ struct hlist_node *node, *tmp; ++ unsigned long flags, orig_ret_address = 0; ++ unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; ++ ++ INIT_HLIST_HEAD(&empty_rp); ++ kretprobe_hash_lock(current, &head, &flags); ++ ++ /* ++ * It is possible to have multiple instances associated with a given ++ * task either because multiple functions in the call path have ++ * return probes installed on them, and/or more than one ++ * return probe was registered for a target function. ++ * ++ * We can handle this because: ++ * - instances are always pushed into the head of the list ++ * - when multiple return probes are registered for the same ++ * function, the (chronologically) first instance's ret_addr ++ * will be the real return address, and all the rest will ++ * point to kretprobe_trampoline. ++ */ ++ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { ++ if (ri->task != current) ++ /* another task is sharing our hash bucket */ ++ continue; ++ ++ if (ri->rp && ri->rp->handler) { ++ __get_cpu_var(current_kprobe) = &ri->rp->kp; ++ get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; ++ ri->rp->handler(ri, regs); ++ __get_cpu_var(current_kprobe) = NULL; ++ } ++ ++ orig_ret_address = (unsigned long)ri->ret_addr; ++ recycle_rp_inst(ri, &empty_rp); ++ ++ if (orig_ret_address != trampoline_address) ++ /* ++ * This is the real return address. Any other ++ * instances associated with this task are for ++ * other calls deeper on the call stack ++ */ ++ break; ++ } ++ ++ kretprobe_assert(ri, orig_ret_address, trampoline_address); ++ ++ kretprobe_hash_unlock(current, &flags); ++ ++ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { ++ hlist_del(&ri->hlist); ++ kfree(ri); ++ } ++ return (void *)orig_ret_address; ++} ++ ++/* ++ * Called after single-stepping. p->addr is the address of the ++ * instruction whose first byte has been replaced by the "int 3" ++ * instruction. To avoid the SMP problems that can occur when we ++ * temporarily put back the original opcode to single-step, we ++ * single-stepped a copy of the instruction. The address of this ++ * copy is p->ainsn.insn. ++ * ++ * This function prepares to return from the post-single-step ++ * interrupt. We have to fix up the stack as follows: ++ * ++ * 0) Except in the case of absolute or indirect jump or call instructions, ++ * the new ip is relative to the copied instruction. We need to make ++ * it relative to the original instruction. ++ * ++ * 1) If the single-stepped instruction was pushfl, then the TF and IF ++ * flags are set in the just-pushed flags, and may need to be cleared. ++ * ++ * 2) If the single-stepped instruction was a call, the return address ++ * that is atop the stack is the address following the copied instruction. ++ * We need to make it the address following the original instruction. ++ * ++ * If this is the first time we've single-stepped the instruction at ++ * this probepoint, and the instruction is boostable, boost it: add a ++ * jump instruction after the copied instruction, that jumps to the next ++ * instruction after the probepoint. ++ */ ++static void __kprobes resume_execution(struct kprobe *p, ++ struct pt_regs *regs, ++ struct kprobe_ctlblk *kcb) ++{ ++// unsigned long *tos = stack_addr(regs); ++// unsigned long copy_ip = (unsigned long)p->ainsn.insn; ++// unsigned long orig_ip = (unsigned long)p->addr; ++ kprobe_opcode_t *insn = p->ainsn.insn; ++ unsigned long rawinsn = *(unsigned long *)insn; ++ int size = SZINSN(rawinsn); ++ regs->NDS32_ipc = (unsigned long)p->addr + size; ++ regs->NDS32_ipsw &= ~PSW_mskHSS; ++#if 0 ++ ++ /*skip the REX prefix */ ++ if (is_REX_prefix(insn)) ++ insn++; ++ ++ regs->flags &= ~X86_EFLAGS_TF; ++ switch (*insn) { ++ case 0x9c: /* pushfl */ ++ *tos &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF); ++ *tos |= kcb->kprobe_old_flags; ++ break; ++ case 0xc2: /* iret/ret/lret */ ++ case 0xc3: ++ case 0xca: ++ case 0xcb: ++ case 0xcf: ++ case 0xea: /* jmp absolute -- ip is correct */ ++ /* ip is already adjusted, no more changes required */ ++ p->ainsn.boostable = 1; ++ goto no_change; ++ case 0xe8: /* call relative - Fix return addr */ ++ *tos = orig_ip + (*tos - copy_ip); ++ break; ++#ifdef CONFIG_X86_32 ++ case 0x9a: /* call absolute -- same as call absolute, indirect */ ++ *tos = orig_ip + (*tos - copy_ip); ++ goto no_change; ++#endif ++ case 0xff: ++ if ((insn[1] & 0x30) == 0x10) { ++ /* ++ * call absolute, indirect ++ * Fix return addr; ip is correct. ++ * But this is not boostable ++ */ ++ *tos = orig_ip + (*tos - copy_ip); ++ goto no_change; ++ } else if (((insn[1] & 0x31) == 0x20) || ++ ((insn[1] & 0x31) == 0x21)) { ++ /* ++ * jmp near and far, absolute indirect ++ * ip is correct. And this is boostable ++ */ ++ p->ainsn.boostable = 1; ++ goto no_change; ++ } ++ default: ++ break; ++ } ++ ++ if (p->ainsn.boostable == 0) { ++ if ((regs->ip > copy_ip) && ++ (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) { ++ /* ++ * These instructions can be executed directly if it ++ * jumps back to correct address. ++ */ ++ set_jmp_op((void *)regs->ip, ++ (void *)orig_ip + (regs->ip - copy_ip)); ++ p->ainsn.boostable = 1; ++ } else { ++ p->ainsn.boostable = -1; ++ } ++ } ++ ++ regs->ip += orig_ip - copy_ip; ++ ++no_change: ++ restore_btf(); ++#endif ++} ++ ++/* ++ * Interrupts are disabled on entry as trap1 is an interrupt gate and they ++ * remain disabled thoroughout this function. ++ */ ++static int __kprobes post_kprobe_handler(struct pt_regs *regs) ++{ ++ struct kprobe *cur = kprobe_running(); ++ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); ++ ++ if (!cur) ++ return 0; ++ ++ resume_execution(cur, regs, kcb); ++ regs->NDS32_ipsw |= kcb->kprobe_saved_flags; ++ ++ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { ++ kcb->kprobe_status = KPROBE_HIT_SSDONE; ++ cur->post_handler(cur, regs, 0); ++ } ++ ++ /* Restore back the original saved kprobes variables and continue. */ ++ if (kcb->kprobe_status == KPROBE_REENTER) { ++ restore_previous_kprobe(kcb); ++ goto out; ++ } ++ reset_current_kprobe(); ++out: ++ preempt_enable_no_resched(); ++ ++ /* ++ * if somebody else is singlestepping across a probe point, flags ++ * will have TF set, in which case, continue the remaining processing ++ * of do_debug, as if this is not a probe hit. ++ */ ++ if (regs->NDS32_ipsw & PSW_mskHSS) ++ return 0; ++ ++ return 1; ++} ++ ++int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) ++{ ++ struct kprobe *cur = kprobe_running(); ++ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); ++ ++ switch (kcb->kprobe_status) { ++ case KPROBE_HIT_SS: ++ case KPROBE_REENTER: ++ /* ++ * We are here because the instruction being single ++ * stepped caused a page fault. We reset the current ++ * kprobe and the ip points back to the probe address ++ * and allow the page fault handler to continue as a ++ * normal page fault. ++ */ ++ regs->NDS32_ipc = (unsigned long)cur->addr; ++ regs->NDS32_ipsw |= kcb->kprobe_old_flags; ++ if (kcb->kprobe_status == KPROBE_REENTER) ++ restore_previous_kprobe(kcb); ++ else ++ reset_current_kprobe(); ++ preempt_enable_no_resched(); ++ break; ++ case KPROBE_HIT_ACTIVE: ++ case KPROBE_HIT_SSDONE: ++ /* ++ * We increment the nmissed count for accounting, ++ * we can also use npre/npostfault count for accounting ++ * these specific fault cases. ++ */ ++ kprobes_inc_nmissed_count(cur); ++ ++ /* ++ * We come here because instructions in the pre/post ++ * handler caused the page_fault, this could happen ++ * if handler tries to access user space by ++ * copy_from_user(), get_user() etc. Let the ++ * user-specified handler try to fix it first. ++ */ ++ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) ++ return 1; ++ ++ /* ++ * In case the user-specified fault handler returned ++ * zero, try to fix up. ++ */ ++ if (fixup_exception(regs)) ++ return 1; ++ ++ /* ++ * fixup routine could not handle it, ++ * Let do_page_fault() fix it. ++ */ ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++/* ++ * Wrapper routine for handling exceptions. ++ */ ++int __kprobes kprobe_exceptions_notify(struct notifier_block *self, ++ unsigned long val, void *data) ++{ ++ struct die_args *args = data; ++ int ret = NOTIFY_DONE; ++ int why = args->trapnr & 0xf; ++ ++ if (args->regs && user_mode(args->regs)) ++ return ret; ++ ++ switch (why) { ++ case 1: ++ if (kprobe_handler(args->regs)) ++ ret = NOTIFY_STOP; ++ break; ++ case 7: ++ if (post_kprobe_handler(args->regs)) ++ ret = NOTIFY_STOP; ++ break; ++ default: ++ break; ++ } ++ return ret; ++} ++ ++int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) ++{ ++ struct jprobe *jp = container_of(p, struct jprobe, kp); ++ unsigned long addr; ++ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); ++ ++ kcb->jprobe_saved_regs = *regs; ++ kcb->jprobe_saved_sp = regs->NDS32_sp; ++ addr = (unsigned long)(kcb->jprobe_saved_sp); ++ ++ /* ++ * As Linus pointed out, gcc assumes that the callee ++ * owns the argument space and could overwrite it, e.g. ++ * tailcall optimization. So, to be absolutely safe ++ * we also save and restore enough stack bytes to cover ++ * the argument area. ++ */ ++ memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr, ++ MIN_STACK_SIZE(addr)); ++ regs->NDS32_ipsw &= ~PSW_mskGIE; ++ trace_hardirqs_off(); ++ regs->NDS32_ipc = (unsigned long)(jp->entry); ++ return 1; ++} ++ ++void __kprobes jprobe_return(void) ++{ ++ struct kprobe_ctlblk *kcd = get_kprobe_ctlblk(); ++ asm volatile (" move $sp, %0\n" ++ " .globl jprobe_return_point\n" ++ " jprobe_return_point: \n" ++ " break #0x1fe \n"::"r" (kcd-> ++ jprobe_saved_sp)); ++} ++ ++int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) ++{ ++ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); ++ struct jprobe *jp = container_of(p, struct jprobe, kp); ++ ++ if (regs->NDS32_ipc == jprobe_return_point) { ++ if (regs->NDS32_sp != kcb->jprobe_saved_sp) { ++ struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; ++ printk(KERN_ERR ++ "current sp %p does not match saved sp %p\n", ++ regs->NDS32_sp, kcb->jprobe_saved_sp); ++ printk(KERN_ERR "Saved registers for jprobe %p\n", jp); ++ show_regs(saved_regs); ++ printk(KERN_ERR "Current registers\n"); ++ show_regs(regs); ++ BUG(); ++ } ++ *regs = kcb->jprobe_saved_regs; ++ memcpy((kprobe_opcode_t *) (kcb->jprobe_saved_sp), ++ kcb->jprobes_stack, ++ MIN_STACK_SIZE(kcb->jprobe_saved_sp)); ++ preempt_enable_no_resched(); ++ return 1; ++ } ++ return 0; ++} ++ ++int __init arch_init_kprobes(void) ++{ ++ return 0; ++} ++ ++int __kprobes arch_trampoline_kprobe(struct kprobe *p) ++{ ++ return 0; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/machine_kexec.c linux-3.4.110/arch/nds32/kernel/machine_kexec.c +--- linux-3.4.110.orig/arch/nds32/kernel/machine_kexec.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/machine_kexec.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,80 @@ ++/* ++ * machine_kexec.c - handle transition of Linux booting another kernel ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern const unsigned char relocate_new_kernel[]; ++extern const unsigned int relocate_new_kernel_size; ++ ++extern void setup_mm_for_reboot(char mode); ++ ++extern unsigned long kexec_start_address; ++extern unsigned long kexec_indirection_page; ++extern unsigned long kexec_mach_type; ++extern unsigned long kexec_boot_atags; ++ ++/* ++ * Provide a dummy crash_notes definition while crash dump arrives to nds32. ++ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. ++ */ ++ ++int machine_kexec_prepare(struct kimage *image) ++{ ++ return 0; ++} ++ ++void machine_kexec_cleanup(struct kimage *image) ++{ ++} ++ ++void machine_shutdown(void) ++{ ++} ++ ++void machine_crash_shutdown(struct pt_regs *regs) ++{ ++} ++ ++void machine_kexec(struct kimage *image) ++{ ++ unsigned long page_list; ++ unsigned long reboot_code_buffer_phys; ++ void *reboot_code_buffer; ++ ++ page_list = image->head & PAGE_MASK; ++ ++ /* we need both effective and real address here */ ++ reboot_code_buffer_phys = ++ page_to_pfn(image->control_code_page) << PAGE_SHIFT; ++ reboot_code_buffer = page_address(image->control_code_page); ++ ++ /* Prepare parameters for reboot_code_buffer */ ++ kexec_start_address = image->start; ++ kexec_indirection_page = page_list; ++ kexec_mach_type = machine_arch_type; ++ kexec_boot_atags = ++ image->start - KEXEC_NDS32_ZIMAGE_OFFSET + KEXEC_NDS32_ATAGS_OFFSET; ++ ++ /* copy our kernel relocation code to the control code page */ ++ memcpy(reboot_code_buffer, ++ relocate_new_kernel, relocate_new_kernel_size); ++ ++ flush_icache_range((unsigned long)reboot_code_buffer, ++ (unsigned long)reboot_code_buffer + ++ KEXEC_CONTROL_PAGE_SIZE); ++ printk(KERN_INFO "Bye!\n"); ++ ++ cpu_proc_fin(); ++ setup_mm_for_reboot(0); /* mode is not used, so just pass 0 */ ++ cpu_reset(reboot_code_buffer_phys); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/Makefile linux-3.4.110/arch/nds32/kernel/Makefile +--- linux-3.4.110.orig/arch/nds32/kernel/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/Makefile 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,45 @@ ++# ++# Makefile for the linux kernel. ++# ++ ++CPPFLAGS_vmlinux.lds +=-DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) ++AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) ++ ++# Object file lists. ++ ++obj-y := ex-entry.o ex-exit.o ex-scall.o irq.o \ ++ process.o ptrace.o setup.o signal.o \ ++ sys_nds32.o time.o traps.o io.o proc.o \ ++ elfchk.o ++ifdef CONFIG_FUNCTION_TRACER ++CFLAGS_REMOVE_ftrace.o = -pg ++CFLAGS_REMOVE_ex-entry.o = -pg ++CFLAGS_REMOVE_ex-exit.o = -pg ++CFLAGS_REMOVE_ex-scall.o = -pg ++CFLAGS_REMOVE_stacktrace.o = -pg ++CFLAGS_REMOVE_traps.o = -pg ++endif ++ ++obj-$(CONFIG_MODULES) += nds32_ksyms.o module.o ++obj-$(CONFIG_ISA_DMA) += dma-isa.o ++obj-$(CONFIG_PCI) += bios32.o ++obj-$(CONFIG_SMP) += smp.o ++obj-$(CONFIG_KGDB) += kgdb.o ++obj-$(CONFIG_STACKTRACE) += stacktrace.o ++obj-$(CONFIG_KPROBES) += kprobes.o ++obj-$(CONFIG_FPU) += fpu.o ++obj-$(CONFIG_AUDIO) += audio.o ++obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o ++obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o ++obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++ ++extra-y := head.o init_task.o vmlinux.lds ++ ++CFLAGS_fpu.o += \ ++ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | sed -e 's/NDS32_EXT_FPU_SP/-mext-fpu-sp/') \ ++ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | sed -e 's/NDS32_EXT_FPU_DP/-mext-fpu-dp/') ++ifdef CONFIG_FPU ++CFLAGS_elfchk.o += \ ++ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | sed -e 's/NDS32_EXT_FPU_SP/-mext-fpu-sp/') \ ++ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | sed -e 's/NDS32_EXT_FPU_DP/-mext-fpu-dp/') ++endif +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/module.c linux-3.4.110/arch/nds32/kernel/module.c +--- linux-3.4.110.orig/arch/nds32/kernel/module.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/module.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,314 @@ ++/* ++ * linux/arch/nds32/kernel/module.c ++ * ++ * Copyright (C) 2002 Russell King. ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Module allocation method suggested by Andi Kleen. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define DEBUG 0 ++#if DEBUG ++#define PRINTK printk ++#else ++#define PRINTK(x...) ++#endif ++ ++void *module_alloc(unsigned long size) ++{ ++#ifdef CONFIG_KPROBES ++ if (size == 0) ++ return NULL; ++ return vmalloc_exec(size); ++#else ++ return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, ++ GFP_KERNEL, PAGE_KERNEL, -1, ++ __builtin_return_address(0)); ++#endif ++} ++ ++void module_free(struct module *module, void *region) ++{ ++ vfree(region); ++} ++ ++int module_frob_arch_sections(Elf_Ehdr * hdr, ++ Elf_Shdr * sechdrs, ++ char *secstrings, struct module *mod) ++{ ++ return 0; ++} ++ ++void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask, ++ unsigned int val_shift, unsigned int loc_mask, ++ unsigned int partial_in_place, unsigned int swap) ++{ ++ unsigned int tmp = 0, tmp2 = 0; ++ ++ __asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n" ++ "\tbeqz\t%3, 1f\n" ++ "\twsbh\t%0, %1\n" ++ "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap) ++ ); ++ ++ tmp2 = tmp & loc_mask; ++ if (partial_in_place) { ++ tmp &= (!loc_mask); ++ tmp = ++ tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask); ++ } else { ++ tmp = tmp2 | ((val & val_mask) >> val_shift); ++ } ++ ++ __asm__ __volatile__("\tbeqz\t%3, 2f\n" ++ "\twsbh\t%0, %1\n" ++ "2:\n" ++ "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp), ++ "r"(loc), "r"(swap) ++ ); ++} ++ ++void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask, ++ unsigned int val_shift, unsigned int loc_mask, ++ unsigned int partial_in_place, unsigned int swap) ++{ ++ unsigned int tmp = 0, tmp2 = 0; ++ ++ __asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n" ++ "\tbeqz\t%3, 1f\n" ++ "\twsbh\t%0, %1\n" ++ "\trotri\t%0, %1, 16\n" ++ "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap) ++ ); ++ ++ tmp2 = tmp & loc_mask; ++ if (partial_in_place) { ++ tmp &= (!loc_mask); ++ tmp = ++ tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask); ++ } else { ++ tmp = tmp2 | ((val & val_mask) >> val_shift); ++ } ++ ++ __asm__ __volatile__("\tbeqz\t%3, 2f\n" ++ "\twsbh\t%0, %1\n" ++ "\trotri\t%0, %1, 16\n" ++ "2:\n" ++ "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp), ++ "r"(loc), "r"(swap) ++ ); ++} ++ ++static inline int exceed_limit(int offset, unsigned int val_mask, ++ struct module *module, Elf32_Rela * rel, ++ unsigned int relindex, unsigned int reloc_order) ++{ ++ int abs_off = offset < 0 ? ~offset : offset; ++ ++ if (abs_off & (~val_mask)) { ++ printk(KERN_ERR "\n%s: relocation type %d out of range.\n" ++ "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n", ++ module->name, ELF32_R_TYPE(rel->r_info)); ++ PRINTK("section %d reloc %d offset 0x%x relative 0x%x.\n" ++ relindex, reloc_order, rel->r_offset, offset); ++ return true; ++ } ++ return false; ++} ++ ++#ifdef __NDS32_EL__ ++#define NEED_SWAP 1 ++#else ++#define NEED_SWAP 0 ++#endif ++ ++int ++apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab, ++ unsigned int symindex, unsigned int relindex, ++ struct module *module) ++{ ++ Elf32_Shdr *symsec = sechdrs + symindex; ++ Elf32_Shdr *relsec = sechdrs + relindex; ++ Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; ++ Elf32_Rela *rel = (void *)relsec->sh_addr; ++ unsigned int i; ++ ++ for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) { ++ Elf32_Addr *loc; ++ Elf32_Sym *sym; ++ Elf32_Addr v; ++ s32 offset; ++ ++ offset = ELF32_R_SYM(rel->r_info); ++ if (offset < 0 ++ || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { ++ printk(KERN_ERR "%s: bad relocation\n", module->name); ++ PRINTK("section %d reloc %d\n", module->name, relindex, ++ i); ++ return -ENOEXEC; ++ } ++ ++ sym = ((Elf32_Sym *) symsec->sh_addr) + offset; ++ ++ if (rel->r_offset < 0 ++ || rel->r_offset > dstsec->sh_size - sizeof(u16)) { ++ printk(KERN_ERR "%s: out of bounds relocation\n", ++ module->name); ++ PRINTK("section %d reloc %d offset 0x%0x size %d\n", ++ relindex, i, rel->r_offset, dstsec->sh_size); ++ return -ENOEXEC; ++ } ++ ++ loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset); ++ v = sym->st_value + rel->r_addend; ++ ++ switch (ELF32_R_TYPE(rel->r_info)) { ++ case R_NDS32_NONE: ++ case R_NDS32_INSN16: ++ case R_NDS32_LABEL: ++ case R_NDS32_LONGCALL1: ++ case R_NDS32_LONGCALL2: ++ case R_NDS32_LONGCALL3: ++ case R_NDS32_LONGCALL4: ++ case R_NDS32_LONGJUMP1: ++ case R_NDS32_LONGJUMP2: ++ case R_NDS32_LONGJUMP3: ++ case R_NDS32_9_FIXED_RELA: ++ case R_NDS32_15_FIXED_RELA: ++ case R_NDS32_17_FIXED_RELA: ++ case R_NDS32_25_FIXED_RELA: ++ case R_NDS32_LOADSTORE: ++ case R_NDS32_DWARF2_OP1_RELA: ++ case R_NDS32_DWARF2_OP2_RELA: ++ case R_NDS32_DWARF2_LEB_RELA: ++ case R_NDS32_RELA_NOP_MIX...R_NDS32_RELA_NOP_MAX: ++ break; ++ ++ case R_NDS32_32_RELA: ++ do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0); ++ break; ++ ++ case R_NDS32_HI20_RELA: ++ do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0, ++ NEED_SWAP); ++ break; ++ ++ case R_NDS32_LO12S3_RELA: ++ do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0, ++ NEED_SWAP); ++ break; ++ ++ case R_NDS32_LO12S2_RELA: ++ do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0, ++ NEED_SWAP); ++ break; ++ ++ case R_NDS32_LO12S1_RELA: ++ do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0, ++ NEED_SWAP); ++ break; ++ ++ case R_NDS32_LO12S0_RELA: ++ case R_NDS32_LO12S0_ORI_RELA: ++ do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0, ++ NEED_SWAP); ++ break; ++ ++ case R_NDS32_9_PCREL_RELA: ++ if (exceed_limit ++ ((v - (Elf32_Addr) loc), 0x000000ff, module, rel, ++ relindex, i)) ++ return -ENOEXEC; ++ do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1, ++ 0xffffff00, 0, NEED_SWAP); ++ break; ++ ++ case R_NDS32_15_PCREL_RELA: ++ if (exceed_limit ++ ((v - (Elf32_Addr) loc), 0x00003fff, module, rel, ++ relindex, i)) ++ return -ENOEXEC; ++ do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1, ++ 0xffffc000, 0, NEED_SWAP); ++ break; ++ ++ case R_NDS32_17_PCREL_RELA: ++ if (exceed_limit ++ ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel, ++ relindex, i)) ++ return -ENOEXEC; ++ do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1, ++ 0xffff0000, 0, NEED_SWAP); ++ break; ++ ++ case R_NDS32_25_PCREL_RELA: ++ if (exceed_limit ++ ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel, ++ relindex, i)) ++ return -ENOEXEC; ++ do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1, ++ 0xff000000, 0, NEED_SWAP); ++ break; ++ case R_NDS32_WORD_9_PCREL_RELA: ++ if (exceed_limit ++ ((v - (Elf32_Addr) loc), 0x000000ff, module, rel, ++ relindex, i)) ++ return -ENOEXEC; ++ do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1, ++ 0xffffff00, 0, NEED_SWAP); ++ break; ++ ++ case R_NDS32_SDA15S3_RELA: ++ case R_NDS32_SDA15S2_RELA: ++ case R_NDS32_SDA15S1_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ printk(KERN_ERR "%s: unsupported relocation type %d.\n", ++ module->name, ELF32_R_TYPE(rel->r_info)); ++ printk(KERN_ERR ++ "Small data section access doesn't work in the kernel space; " ++ "please rebuild the kernel module with gcc option -G0.\n"); ++ PRINTK("section %d reloc %d offset 0x%x size %d\n", ++ relindex, i, rel->r_offset, dstsec->sh_size); ++ break; ++ ++ default: ++ printk(KERN_ERR "%s: unsupported relocation type %d.\n", ++ module->name, ELF32_R_TYPE(rel->r_info)); ++ PRINTK("section %d reloc %d offset 0x%x size %d\n", ++ relindex, i, rel->r_offset, dstsec->sh_size); ++ } ++ } ++ return 0; ++} ++ ++int ++apply_relocate(Elf32_Shdr * sechdrs, const char *strtab, ++ unsigned int symindex, unsigned int relsec, ++ struct module *module) ++{ ++// printk(KERN_ERR "module %s: non-ADD RELOCATION unsupported\n", module->name); ++// return -ENOEXEC; ++ return 0; ++} ++ ++int ++module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs, ++ struct module *module) ++{ ++ return 0; ++} ++ ++void module_arch_cleanup(struct module *mod) ++{ ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/nds32-elf.h linux-3.4.110/arch/nds32/kernel/nds32-elf.h +--- linux-3.4.110.orig/arch/nds32/kernel/nds32-elf.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/nds32-elf.h 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,855 @@ ++#ifndef _NDS32_ELF_CHECK ++#define _NDS32_ELF_CHECK ++ ++//#define TEST_ELF_CHECK_FUNC ++#ifdef TEST_ELF_CHECK_FUNC ++#include ++#include ++#endif ++ ++//#include ++//#include ++ ++#ifdef __cplusplus ++extern "C" ++{ ++#else ++#include ++#endif //#ifdef __cplusplus ++ ++ ++ enum ELF_HEADER_FLAG_FIELD ++ { ++ EHFF_ARCH_VER = 0xF0000000, EHFF_ARCH_VER_SHIFT = 28, ++ //EHFF_RESERVED = 0x08000000, ++ EHFF_HAS_ZOL = 0x04000000, ++ EHFF_ISA_DSP = 0x02000000, ++ EHFF_ISA_FPU_MAC = 0x01000000, ++ EHFF_FPU_REG = 0x00C00000, EHFF_FPU_REG_SHIFT = 22, ++ EHFF_ISA_L2C = 0x00200000, ++ EHFF_ISA_NO_MAC = 0x00100000, ++ EHFF_ISA_MAC_DX = 0x00100000, ++ EHFF_ISA_FPU_DP = 0x00080000, ++ //EHFF_RESERVED = 0x00040000, ++ EHFF_ISA_SATURATION = 0x00020000, ++ EHFF_REDUCED_REGS = 0x00010000, ++ EHFF_ISA_STRING = 0x00008000, ++ EHFF_ISA_16BIT = 0x00004000, ++ EHFF_ISA_IFC = 0x00004000, ++ EHFF_ISA_DIV = 0x00002000, ++ EHFF_ISA_DIV_DX = 0x00002000, ++ EHFF_ISA_AUDIO = 0x00001000, ++ EHFF_ISA_FPU_SP = 0x00000800, ++ EHFF_ISA_EXT2 = 0x00000400, ++ EHFF_ISA_EXT = 0x00000200, ++ EHFF_ISA_EIT = 0x00000100, ++ EHFF_ISA_MFUSR_PC = 0x00000100, ++ EHFF_ABI_VER = 0x000000F0, ++ EHFF_ELF_VER = 0x0000000F, EHFF_ELF_VER_SHIFT = 0, ++ }; ++ ++ ++ enum ELF_HEADER_FLAG_FIELD_ARCH_VER ++ { ++ EHFF_ARCH_VER_RESERVED = 0x0, ++ EHFF_ARCH_VER_V1 = 0x1, ++ EHFF_ARCH_VER_V2 = 0x2, ++ EHFF_ARCH_VER_V3 = 0x3, ++ EHFF_ARCH_VER_V3M = 0x4, ++ }; ++ ++ static const char *EHFF_ARCH_VER_MSG[] = ++ { ++ "RESERVED", ++ "BASE V1", ++ "BASE V2", ++ "BASE V3", ++ "BASE V3M", ++ }; ++ ++ ++ ++ ++ /* ----------------------------------------------------------- */ ++ /* 4-bit for ABI signature, allow up to 16 ABIs */ ++ /* 0 : for OLD ABI V0, phase out ++ * 1 : for V1 , starting with V0 toolchain ++ * 2 : for V2 ++ * 3 : for V2FP (fs0, fs1 as function parameter) ++ * 4 : for AABI */ ++ /* only old N1213HC use V0 */ ++ /* New ABI is used due to return register is changed to r0 from r5 */ ++ /* ----------------------------------------------------------- */ ++#define E_NDS_ABI_V0 0x00000000 ++#define E_NDS_ABI_V1 0x00000010 ++#define E_NDS_ABI_V2 0x00000020 ++#define E_NDS_ABI_V2FP 0x00000030 ++#define E_NDS_ABI_AABI 0x00000040 ++#define E_NDS_ABI_V2FP_PLUS 0x00000050 ++ ++ /* ---------------------------------------------------------------------------- */ ++ /* This flag signifies the version of Andes ELF */ ++ /* note : */ ++ /* 1. v1.3.1 and beyond is accompanying with Baseline ISA 1.0b/2.0/... in ELF. */ ++ /* 2. v1.3.1 is accompanying with Baseline ISA 1.0b in ELF. */ ++ /* ... | MAC | ... | DIV | ... */ ++ /* 3. v1.3.1 is accompanying with Baseline ISA 2.0 and beyond in ELF. */ ++ /* ... | MAC_DX | ... | DIV_DX | ... */ ++ /* ---------------------------------------------------------------------------- */ ++ ++ enum ELF_HEADER_FLAG_FIELD_ELF_VER ++ { ++ EHFF_ELF_VER_1_3_0 = 0x0, ++ EHFF_ELF_VER_1_3_1 = 0x1, ++ EHFF_ELF_VER_1_4_0 = 0x2, ++ }; ++ ++ static const char *EHFF_ELF_VER_MSG[] = ++ { ++ "1.3.0", ++ "1.3.1", ++ "1.4.0", ++ }; ++ /* */ ++ /* sr layout : */ ++ /* sr[14..10] : hardware components */ ++ /* cpu / fpu / audio / ... */ ++ /* sr[9..0] : sr index number dedicated for sr[14..10] */ ++ /* */ ++ ++ // ++ // sr[14..10] definition: ++ // 0 : cpu ++ // 1 : fpu ++ // 2 : audio ++#define INDEX_HW_MASK 0x00007c00 ++#define INDEX_HW_CPU 0x00000000 ++#define INDEX_HW_FPU 0x00000400 ++#define INDEX_HW_AUDIO 0x00000800 ++#define HW_IS_CPU(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_CPU) ++#define HW_IS_FPU(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_FPU) ++#define HW_IS_AUDIO(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_AUDIO) ++ ++ // ++ // sr[9..0] definition: ++ // if (HW_IS_CPU(sr)) // cpu score ++ // sr[9..0] defined in chap 9 of Andes-Privilege-Architecture spec. ++ // else if (HW_IS_FPU(sr)) // fpu score ++ // sr[9..0] == SR_FPU_FPCFG, FPCFG defined in FPU_ISA_EXT spec. ++ // else if (HW_IS_AUDIO(sr)) // audio score ++ // //none register is used in loader checking mechanism ++ // ++#define SR_INDEX_MASK 0x000003ff ++#define SR_INDEX(sr) (sr & SR_INDEX_MASK) ++#define CPU_SR_INDEX(x,y,z) ((x << 7) + (y << 3) + z) ++#define FPU_SR_FPCFG() (INDEX_HW_FPU) ++ ++ //FPU-belonged system registers ++#define SR_FPU_FPCFG 0x00 ++ ++#define SR_NOT_EXIST 0xffffffff ++ ++ typedef unsigned int (* CALLBACK_FUNC) (unsigned int index); ++ ++ ++ static const char *NEC_MSG_FPU_reg[5] = ++ { ++ "N/A", ++ " 8SP/ 4DP", ++ "16SP/ 8DP", ++ "32SP/16DP", ++ "32SP/32DP" ++ }; ++ static const char *NEC_MSG_endian[2] = ++ { ++ "little", ++ "big" ++ }; ++ ++#define EM_NDS32 167 ++#if defined elf_check_swap_2 || defined elf_check_swap_4 ++#error "ERROR : elf_check_swap_2 and elf_check_swap_4 are multiple defined" ++#endif ++#define elf_check_swap_2(data) (((data&0x0000ff00)>>8) | ((data&0x000000ff)<<8)) ++#define elf_check_swap_4(data) (((data&0xff000000)>>24) | \ ++ ((data&0x00ff0000)>>8) | \ ++ ((data&0x0000ff00)<<8) | \ ++ ((data&0x000000ff)<<24)) ++ ++#define MSC_CFG_BASEV 0x0000e000 ++ ++#define CPU_VER_EXT 0x00000001 ++#define CPU_VER_A16 0x00000002 ++#define CPU_VER_EXT2 0x00000004 ++#define CPU_VER_FPU 0x00000008 ++#define CPU_VER_STRING 0x00000010 ++#define CPU_VER_SATURATION 0x00000020 ++ ++#define MSC_CFG_DIV 0x00000020 ++#define MSC_CFG_MAC 0x00000040 ++#define MSC_CFG_L2C 0x00000200 ++#define MSC_CFG_REDUCED_REG 0x00000400 ++#define MSC_CFG_NOD 0x00010000 ++#define MSC_CFG_AUDIO 0x00000180 ++#define MSC_CFG_AUDIO_NONE 0x00000000 ++#define MSC_CFG_IFC 0x00080000 ++#define MSC_CFG_MCU 0x00100000 ++#define MSC_CFG_EX9IT 0x01000000 ++#define MSC_CFG_MSC_EXT 0xc0000000 ++ ++#define MSC_CFG2_DSPPF 0x00000018 ++#define MSC_CFG2_ZOL 0x00000020 ++ ++#define MMU_CFG_DE 0x04000000 ++ ++ typedef struct nds32_elfinfo_s ++ { ++ unsigned int endian; // 1.local-used constant definition ++ // 0 : little , 1 : big ++ // 2.system-used constant definition ++ // little / big depends on system definition ++ unsigned int machine; //magic number (167 for nds32 machine) ++ unsigned int mfusr_pc; //reclaim in baseline v2 ++ unsigned int abi; // abi version ++ unsigned int base16; // 0 : not support , 1 : support ++ unsigned int pex1; ++ unsigned int div; //reclaim in baseline v2 ++ unsigned int pex2; ++ unsigned int fpu; //fpu single precision ++ unsigned int audio; ++ unsigned int string; ++ unsigned int reduced_regs; ++ unsigned int saturation; ++ unsigned int ifc; ++ unsigned int elf_ver; //elf version number, 0 for v1.3.0, 1 for v1.3.1 ++ unsigned int l2c; ++ unsigned int mac; //reclaim in baseline v2 ++ //unsigned int isa_ver;//0x0, baseline = baseline V1 - 16 bit ISA ++ //0x1, baseline = baseline V1 ++ //0x2, baseline = baseline V1 + V2 extension ISA ++ //unsigned int fpu_sp; //fpu double precision ++ //unsigned int fpu_reg; //fpu registers capacity ++ } nds32_elfinfo_t; ++ ++ typedef enum nds32_elfchk_e ++ { ++ endian_chk = 0, ++ machine_chk, ++ isa_chk, ++ abi_chk ++ } nds32_elfchk_t; ++ ++ typedef enum ELF_Fail_Type ++ { ++ EFT_NONE, ++ EFT_WARNING, ++ EFT_ERROR ++ }ELF_Fail_Type; ++ ++ static inline void NEC_itoa(unsigned int value, char *buf, const unsigned int base) ++ { ++ char temp[10] = "\0", ch; ++ int len = 1, index; ++ ++ while(value > 0) ++ { ++ ch = value%base; ++ value = value/base; ++ if(ch >= 10) ++ ch = ch+'a'-10; ++ else ++ ch = ch+'0'; ++ temp[len++] = ch; ++ } ++ len--; ++ ++ index = len; ++ while(index >= 0) ++ { ++ buf[index] = temp[len-index]; ++ index--; ++ } ++ } ++ ++ static inline void NEC_format(char *buf, unsigned int width) ++ { ++ unsigned int len = strlen(buf); ++ memmove(buf+(width-len), buf, len+1); ++ memset(buf, ' ', (width-len)); ++ } ++ ++ static void NEC_sprintf(char *buf, const char *str, ...) ++ { ++ int width, len = 0; ++ va_list ap; ++ char token, temp[100]; ++ buf[0] = '\0'; ++ ++ ++ va_start(ap, str); ++ while(*str != '\0') ++ { ++ if(*str != '%') ++ buf[len++] = *str; ++ else //*str == '%' ++ { ++ token = *(++str); ++ ++ width = 0; ++ while(token >= '0' && token <= '9') ++ { ++ width *= 10; ++ width += token-'0'; ++ token = *(++str); ++ } ++ ++ switch(token) ++ { ++ case 'd': ++ NEC_itoa(va_arg(ap, unsigned int), temp, 10); ++ break; ++ case 'x': ++ NEC_itoa(va_arg(ap, unsigned int), temp, 16); ++ break; ++ case 's': ++ strcpy(temp, va_arg(ap, char *)); ++ break; ++ } ++ ++ if(width != 0) ++ NEC_format(temp, width); ++ ++ buf[len++] = '\0'; ++ strcat(buf, temp); ++ len = strlen(buf); ++ } ++ ++ str++; ++ } ++ buf[len] = '\0'; ++ } ++ ++ //NDS32 strcat for avoiding buf overflow ++ static inline void NEC_strcat_safety(char *destination, unsigned int destination_size, char *source) ++ { ++ strncat(destination, source, destination_size - strlen(destination) - 1); ++ } ++ ++ //NDS32 Elf Check print ++ static inline void NEC_print(char *buf, unsigned int len, ELF_Fail_Type type, const char *name, const char *cpu, const char *elf, const char *error_message) ++ { ++ char temp[100]; ++ switch(type) ++ { ++ case EFT_NONE: ++ NEC_sprintf(temp, "\t | %9s | %9s | %14s\n", cpu, elf, name); ++ break; ++ case EFT_WARNING: ++ NEC_sprintf(temp, "\t?| %9s | %9s | %14s Warning: %s\n", cpu, elf, name, error_message); ++ break; ++ case EFT_ERROR: ++ NEC_sprintf(temp, "\t!| %9s | %9s | %14s Error: %s\n", cpu, elf, name, error_message); ++ break; ++ } ++ NEC_strcat_safety(buf, len, temp); ++ } ++ ++ static inline bool NEC_check_bool(char *buf, unsigned int len, ELF_Fail_Type type, const char *isa, bool cpu, bool elf) ++ { ++ bool code; ++ const char *NEC_MSG_ISA[2] = { "OFF", "ON" }; ++ if(!cpu && elf) ++ code = 1; ++ else ++ { ++ code = 0; ++ type = EFT_NONE; ++ } ++ NEC_print(buf, len, type, isa, NEC_MSG_ISA[cpu], NEC_MSG_ISA[elf], "Not supported by CPU"); ++ return code; ++ } ++ ++ static inline ELF_Fail_Type elf_ver_and_arch_ver_compatibility_check(unsigned int elf_ver, unsigned int arch_ver) ++ { ++ switch(elf_ver) ++ { ++ case EHFF_ELF_VER_1_3_0: ++ switch(arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ case EHFF_ELF_VER_1_3_1: ++ switch(arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ case EHFF_ARCH_VER_V2: ++ case EHFF_ARCH_VER_V3M: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ case EHFF_ELF_VER_1_4_0: ++ switch(arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ case EHFF_ARCH_VER_V2: ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ } ++ return EFT_ERROR; ++ } ++ ++ ++ static inline ELF_Fail_Type arch_ver_check(unsigned int CPU, unsigned int ELF) ++ { ++ switch(CPU) ++ { ++ case EHFF_ARCH_VER_V1: ++ switch(ELF) ++ { ++ case EHFF_ARCH_VER_V1: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ case EHFF_ARCH_VER_V2: ++ switch(ELF) ++ { ++ case EHFF_ARCH_VER_V1: ++ case EHFF_ARCH_VER_V2: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ case EHFF_ARCH_VER_V3: ++ switch(ELF) ++ { ++ case EHFF_ARCH_VER_V1: ++ case EHFF_ARCH_VER_V2: ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ case EHFF_ARCH_VER_V3M: ++ switch(ELF) ++ { ++ case EHFF_ARCH_VER_V3M: ++ return EFT_NONE; ++ default: ++ return EFT_ERROR; ++ } ++ } ++ return EFT_ERROR; ++ } ++ ++ // buf : buffer of char*, put Target Isa Info into *buf ++ // len : length of buffer (at least 300 chars in length) ++ // buf_status : status of buffer ++ // 0 : ok ++ // 1 : overflow ++#define TARGET_ISA_INFO_LEN 2000 ++ static inline unsigned int elf_check (unsigned char *ehdr, CALLBACK_FUNC reg_read_callback, char *buf, unsigned int len, unsigned int *buf_status) ++ { ++ unsigned int SR_msc_cfg, SR_msc_cfg2 = 0, SR_cpu_ver, SR_mmu_cfg, fpcfg, fucop_exist, fpu_mount; ++ unsigned int CPU_DIV_DX_ISA, CPU_MAC_DX_ISA; ++ unsigned int eflag, ELF_arch_ver, ELF_elf_ver, CPU_arch_ver; ++ unsigned short machine; ++ unsigned char big_endian_elf = 0, big_endian_cpu; ++ ++ char temp[100]; ++ char temp_cpu[10]; ++ char temp_elf[10]; ++ int n_error, n_warning; ++ int CPU_support; ++ unsigned char FPU_reg_elf, FPU_reg_cpu; ++ ELF_Fail_Type error_type; ++ ++ ++ ++ n_error = 0; ++ n_warning = 0; ++ ++ buf[0] = '\0'; ++ *buf_status = 0; ++ ++ SR_cpu_ver = reg_read_callback(CPU_SR_INDEX(0,0,0)); ++ SR_msc_cfg = reg_read_callback(CPU_SR_INDEX(0,4,0)); ++ SR_mmu_cfg = reg_read_callback(CPU_SR_INDEX(0,3,0)); ++ ++ if (SR_msc_cfg & MSC_CFG_MSC_EXT) ++ SR_msc_cfg2 = reg_read_callback(CPU_SR_INDEX(0,4,1)); ++ ++ switch(*((char*)(ehdr+5))) ++ { ++ case 1: ++ big_endian_elf = 0; ++ break; ++ case 2: ++ big_endian_elf = 1; ++ break; ++ } ++ ++ if(SR_mmu_cfg & MMU_CFG_DE) ++ big_endian_cpu = 1; ++ else ++ big_endian_cpu = 0; ++ ++ ++ /* 20091106 note : ++ * 1. In term of OS, elf_check() would be used in OS kernel and ld.so ++ * 2. Since OS is running on SID, eflag/machine did not need endian conversion for big endian format. ++ * 3. Later, elf_check interface is going to cover "OS" case by adding a new parameter. ++ * ++ */ ++#ifdef ELF_CHECKING_OS ++ eflag = *((unsigned int *)(ehdr+36)); ++ machine = *((unsigned short*)(ehdr+18)); ++#else // GDB loader / SID loader ++ eflag = (big_endian_elf == 0)? *((unsigned int *)(ehdr+36)) : elf_check_swap_4(*((unsigned int *)(ehdr+36))); ++ machine = (big_endian_elf == 0)? *((unsigned short*)(ehdr+18)) : elf_check_swap_2(*((unsigned short*)(ehdr+18))); ++#endif ++ ++ ELF_arch_ver = (eflag & EHFF_ARCH_VER) >> EHFF_ARCH_VER_SHIFT; ++ ELF_elf_ver = (eflag & EHFF_ELF_VER) >> EHFF_ELF_VER_SHIFT; ++ ++ CPU_arch_ver = ((SR_msc_cfg & MSC_CFG_BASEV) >> 13) + 1; ++ if(CPU_arch_ver == 3) ++ if(SR_msc_cfg & MSC_CFG_MCU) ++ CPU_arch_ver = 4; ++ ++ /*Basic version check ++ ++ 1.ELF version check ++ 2.Architecture version check ++ 3.Machine check ++ */ ++ if(ELF_elf_ver > EHFF_ELF_VER_1_4_0) ++ { ++ NEC_sprintf(temp, "Error: unsupport ELF version: 0x%x\n", ELF_elf_ver); ++ NEC_strcat_safety(buf, len, temp); ++ return 1; ++ } ++ NEC_sprintf(temp, "ELF version: %s\n", EHFF_ELF_VER_MSG[ELF_elf_ver]); ++ NEC_strcat_safety(buf, len, temp); ++ ++ ++ if(elf_ver_and_arch_ver_compatibility_check(ELF_elf_ver, ELF_arch_ver) == EFT_ERROR) ++ { ++ NEC_sprintf(temp, "Error: architecture version is not supported in this ELF version: %s\n", EHFF_ARCH_VER_MSG[ELF_arch_ver]); ++ NEC_strcat_safety(buf, len, temp); ++ return 1; ++ } ++ ++ NEC_sprintf(temp, "\t %9s %9s \n", "CPU", "ELF"); ++ NEC_strcat_safety(buf, len, temp); ++ if(big_endian_cpu != big_endian_elf) ++ { ++ error_type = EFT_ERROR; ++ n_error++; ++ } ++ else ++ error_type = EFT_NONE; ++ NEC_print(buf, len, error_type, "endianess", NEC_MSG_endian[big_endian_cpu], NEC_MSG_endian[big_endian_elf], "endianess mismatch"); ++ ++ ++ ++ ++ if (EM_NDS32 != machine) ++ { ++ error_type = EFT_ERROR; ++ n_error++; ++ } ++ else ++ error_type = EFT_NONE; ++ NEC_sprintf(temp_cpu, "%d", EM_NDS32); ++ NEC_sprintf(temp_elf, "%d", machine); ++ NEC_print(buf, len, error_type, "machine", temp_cpu, temp_elf, "wrong machine"); ++ ++ ++ error_type = arch_ver_check(CPU_arch_ver, ELF_arch_ver); ++ if(error_type == EFT_ERROR) ++ n_error++; ++ NEC_print(buf, len, error_type, "BASELINE ISA", EHFF_ARCH_VER_MSG[CPU_arch_ver], EHFF_ARCH_VER_MSG[ELF_arch_ver], "BASELINE ISA mismatch"); ++ ++ /*Prepare reference variables ++ ++ 1.DIV, MAC, DX ++ 2.FPU ++ */ ++ ++ CPU_MAC_DX_ISA = 0; ++ CPU_DIV_DX_ISA = 0; ++ switch(CPU_arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ if (SR_msc_cfg & MSC_CFG_MAC) ++ CPU_MAC_DX_ISA = 1; ++ if (SR_msc_cfg & MSC_CFG_DIV) ++ CPU_DIV_DX_ISA = 1; ++ break; ++ case EHFF_ARCH_VER_V2: ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ if (!(SR_msc_cfg & MSC_CFG_NOD)) ++ { ++ CPU_MAC_DX_ISA = 1; ++ CPU_DIV_DX_ISA = 1; ++ } ++ break; ++ } ++ fpu_mount = 0; ++ if (SR_cpu_ver & CPU_VER_FPU) ++ { ++ fucop_exist = reg_read_callback(CPU_SR_INDEX(0,5,0)); ++ if (fucop_exist & 0x80000000) ++ { ++ fpu_mount = 1; ++ fpcfg = reg_read_callback(FPU_SR_FPCFG()); ++ } ++ else ++ fpu_mount = 0; ++ } ++ ++ //Parse Configuration field (bit 27~8) ++ ++ //bit 27 Reserved ++ //bit 26 ZOL ++ CPU_support = 0; ++ if ((SR_msc_cfg & MSC_CFG_MSC_EXT) && (SR_msc_cfg2 & MSC_CFG2_ZOL)) ++ CPU_support = 1; ++ if (ELF_elf_ver == EHFF_ELF_VER_1_4_0) ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "ZOL", CPU_support, eflag & EHFF_HAS_ZOL); ++ ++ //bit 25 DSP ++ CPU_support = 0; ++ if ((SR_msc_cfg & MSC_CFG_MSC_EXT) && (SR_msc_cfg2 & MSC_CFG2_DSPPF)) ++ CPU_support = 1; ++ if (ELF_elf_ver == EHFF_ELF_VER_1_4_0) ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "DSP ISA", CPU_support, eflag & EHFF_ISA_DSP); ++ ++ //bit 24 ++ CPU_support = 0; ++ if(fpu_mount) ++ if(fpcfg & 0x00000010) ++ CPU_support = 1; ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU MAC ISA", CPU_support, eflag & EHFF_ISA_FPU_MAC); ++ ++ //bit 23~22 ++ if(fpu_mount) ++ FPU_reg_cpu = ((fpcfg >> 2) & 0x3) + 1; ++ else ++ FPU_reg_cpu = 0; ++ ++ if(eflag & (EHFF_ISA_FPU_SP | EHFF_ISA_FPU_DP | EHFF_ISA_FPU_MAC)) ++ FPU_reg_elf = ((eflag & EHFF_FPU_REG) >> EHFF_FPU_REG_SHIFT) + 1; ++ else ++ FPU_reg_elf = 0; ++ if(FPU_reg_elf > FPU_reg_cpu) ++ { ++ error_type = EFT_ERROR; ++ n_error++; ++ } ++ else ++ error_type = EFT_NONE; ++ NEC_print(buf, len, error_type, "FPU REGISTER", NEC_MSG_FPU_reg[FPU_reg_cpu], NEC_MSG_FPU_reg[FPU_reg_elf], ++ "FPU REGISTERS not supported by CPU"); ++ //bit 21 ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "L2C ISA", SR_msc_cfg & MSC_CFG_L2C, eflag & EHFF_ISA_L2C); ++ ++ //bit 20 ++ //MAC_DX check ++ // Target Machine certainly has MAC_DX under the following conditions: ++ // 1. Baseline V1 ISA && MSC_CFG.MAC (softcore version) ++ // 2. Baseline V2 ISA && D0/D1 support ++ // 3. Baseline V3 ISA && D0/D1 support ++ ++ switch(ELF_arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MAC/MAC DX ISA", CPU_MAC_DX_ISA, !(eflag & EHFF_ISA_NO_MAC)); ++ break; ++ case EHFF_ARCH_VER_V2: ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MAC DX ISA", CPU_MAC_DX_ISA, eflag & EHFF_ISA_MAC_DX); ++ break; ++ } ++ //bit 19 ++ CPU_support = 0; ++ if(fpu_mount) ++ if(fpcfg & 0x00000002) ++ CPU_support = 1; ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU DP ISA", CPU_support, eflag & EHFF_ISA_FPU_DP); ++ ++ ++ //bit 18 Reserved ++ //bit 17 ++ switch(ELF_elf_ver) ++ { ++ case EHFF_ELF_VER_1_3_0: ++ case EHFF_ELF_VER_1_3_1: ++ break; ++ case EHFF_ELF_VER_1_4_0: ++ switch(ELF_arch_ver) ++ { ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "SATURATION ISA", SR_cpu_ver & CPU_VER_SATURATION, eflag & EHFF_ISA_SATURATION); ++ break; ++ } ++ break; ++ } ++ //bit 16 ++ if(SR_msc_cfg & MSC_CFG_REDUCED_REG) ++ CPU_support = 0; ++ else ++ CPU_support = 1; ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "32 GPR", CPU_support, (eflag & EHFF_REDUCED_REGS) == 0); ++ ++ //bit 15 ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "STRING ISA", SR_cpu_ver & CPU_VER_STRING, eflag & EHFF_ISA_STRING); ++ ++ //bit 14 ++ switch(ELF_elf_ver) ++ { ++ case EHFF_ELF_VER_1_3_0: ++ case EHFF_ELF_VER_1_3_1: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "16-BIT ISA", SR_cpu_ver & CPU_VER_A16, eflag & EHFF_ISA_16BIT); ++ break; ++ case EHFF_ELF_VER_1_4_0: ++ switch(ELF_arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ case EHFF_ARCH_VER_V2: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "16-BIT ISA", SR_cpu_ver & CPU_VER_A16, eflag & EHFF_ISA_16BIT); ++ break; ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "IFC ISA", SR_msc_cfg & MSC_CFG_IFC, eflag & EHFF_ISA_IFC); ++ break; ++ } ++ break; ++ } ++ ++ //bit 13 ++ switch(ELF_arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "DIV DX ISA", CPU_DIV_DX_ISA, eflag & EHFF_ISA_DIV); ++ break; ++ case EHFF_ARCH_VER_V2: ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "DIV DX ISA", CPU_DIV_DX_ISA, eflag & EHFF_ISA_DIV_DX); ++ break; ++ } ++ //bit 12 ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "AUDIO/DSP ISA", SR_msc_cfg & MSC_CFG_AUDIO, eflag & EHFF_ISA_AUDIO); ++ //bit 11 ++ CPU_support = 0; ++ if(fpu_mount) ++ if(fpcfg & 0x00000001) ++ CPU_support = 1; ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU SP ISA", CPU_support, eflag & EHFF_ISA_FPU_SP); ++ ++ //bit 10 ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "PEX2 ISA", SR_cpu_ver & CPU_VER_EXT2, eflag & EHFF_ISA_EXT2); ++ ++ //bit 9 ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "PEX1 ISA", SR_cpu_ver & CPU_VER_EXT, eflag & EHFF_ISA_EXT); ++ ++ //bit 8 ++ CPU_support = 0; ++ if(CPU_arch_ver == EHFF_ARCH_VER_V3M) ++ CPU_support = 1; ++ switch(ELF_elf_ver) ++ { ++ case EHFF_ELF_VER_1_3_0: ++ case EHFF_ELF_VER_1_3_1: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MFUSR_PC ISA", CPU_support, eflag & EHFF_ISA_MFUSR_PC); ++ break; ++ case EHFF_ELF_VER_1_4_0: ++ switch(ELF_arch_ver) ++ { ++ case EHFF_ARCH_VER_V1: ++ case EHFF_ARCH_VER_V2: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MFUSR_PC ISA", CPU_support, eflag & EHFF_ISA_MFUSR_PC); ++ break; ++ case EHFF_ARCH_VER_V3: ++ case EHFF_ARCH_VER_V3M: ++ n_error += NEC_check_bool(buf, len, EFT_ERROR, "EIT ISA", SR_msc_cfg & MSC_CFG_EX9IT, eflag & EHFF_ISA_EIT); ++ break; ++ } ++ break; ++ } ++ ++ if(n_error) ++ { ++ NEC_strcat_safety(buf, len, (char*)"Error: ELF and CPU mismatch\n"); ++ NEC_sprintf(temp, "Total Error: %d\n", n_error); ++ NEC_strcat_safety(buf, len, temp); ++ ++ NEC_strcat_safety(buf, len, (char*)"Usage error, Consult Andes Toolchains and their compatible Andes cores for the Toolchain-CPU compatibility.\n"); ++ NEC_strcat_safety(buf, len, (char*)"The Loader Checking can be disabled under Debug Configuration.\n"); ++ } ++ else ++ NEC_strcat_safety(buf, len, (char*)"NDS32 ELF checking pass\n"); ++ ++ if(n_warning) ++ { ++ NEC_sprintf(temp, "Total Warning: %d\n", n_warning); ++ NEC_strcat_safety(buf, len, temp); ++ } ++ ++ ++ // checking buf overflow ++ if(strlen(buf) >= len) ++ *buf_status = 1; ++ ++ return n_error; ++ } //end of elf_check ++ ++#undef elf_check_swap_2 ++#undef elf_check_swap_4 ++ ++#undef MSC_CFG_BASEV ++ ++#undef CPU_VER_STRING ++#undef CPU_VER_EXT ++#undef CPU_VER_A16 ++#undef CPU_VER_EXT2 ++#undef CPU_VER_FPU ++#undef CPU_VER_SATURATION ++ ++#undef MSC_CFG_DIV ++#undef MSC_CFG_MAC ++#undef MSC_CFG_L2C ++#undef MSC_CFG_REDUCED_REG ++#undef MSC_CFG_NOD ++#undef MSC_CFG_AUDIO ++#undef MSC_CFG_AUDIO_NONE ++#undef MSC_CFG_IFC ++#undef MSC_CFG_MCU ++#undef MSC_CFG_EX9IT ++#undef MSC_CFG_MSC_EXT ++ ++#undef MSC_CFG2_DSPPF ++#undef MSC_CFG2_ZOL ++ ++#undef MMU_CFG_DE ++ ++#ifdef __cplusplus ++} ++#endif //#ifdef __cplusplus ++ ++#endif //end of _NDS32_ELF_CHECK ++ +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/nds32_ksyms.c linux-3.4.110/arch/nds32/kernel/nds32_ksyms.c +--- linux-3.4.110.orig/arch/nds32/kernel/nds32_ksyms.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/nds32_ksyms.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,103 @@ ++/* ++ * arch/nds32/kernel/nds32_ksyms.c ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * libgcc functions - functions that are used internally by the ++ * compiler... (prototypes are not correct though, but that ++ * doesn't really matter since they're not versioned). ++ */ ++extern void __ashldi3(void); ++extern void __ashrdi3(void); ++extern void __divsi3(void); ++extern void __lshrdi3(void); ++extern void __modsi3(void); ++extern void __muldi3(void); ++extern void __ucmpdi2(void); ++extern void __udivdi3(void); ++extern void __umoddi3(void); ++extern void __udivmoddi4(void); ++extern void __udivsi3(void); ++extern void __umodsi3(void); ++ ++/* ++ * This has a special calling convention; it doesn't ++ * modify any of the usual registers, except for LR. ++ */ ++#define EXPORT_SYMBOL_ALIAS(sym,orig) \ ++ const struct kernel_symbol __ksymtab_##sym \ ++ __attribute__((section("__ksymtab"))) = \ ++ { (unsigned long)&orig, #sym }; ++ ++/* ++ * floating point math emulator support. ++ * These symbols will never change their calling convention... ++ */ ++ ++/* networking */ ++EXPORT_SYMBOL(csum_partial); ++EXPORT_SYMBOL(csum_partial_copy_nocheck); ++ ++/* string / mem functions */ ++EXPORT_SYMBOL(strchr); ++EXPORT_SYMBOL(strrchr); ++EXPORT_SYMBOL(memset); ++EXPORT_SYMBOL(memcpy); ++EXPORT_SYMBOL(memmove); ++EXPORT_SYMBOL(__memzero); ++ ++/* user mem (segment) */ ++EXPORT_SYMBOL(__arch_copy_from_user); ++EXPORT_SYMBOL(__arch_copy_to_user); ++EXPORT_SYMBOL(__arch_clear_user); ++EXPORT_SYMBOL(__arch_strnlen_user); ++EXPORT_SYMBOL(__arch_strncpy_from_user); ++ ++EXPORT_SYMBOL(__get_user_1); ++EXPORT_SYMBOL(__get_user_2); ++EXPORT_SYMBOL(__get_user_4); ++EXPORT_SYMBOL(__get_user_8); ++ ++EXPORT_SYMBOL(__put_user_1); ++EXPORT_SYMBOL(__put_user_2); ++EXPORT_SYMBOL(__put_user_4); ++EXPORT_SYMBOL(__put_user_8); ++ ++/* gcc lib functions */ ++EXPORT_SYMBOL(__ashldi3); ++EXPORT_SYMBOL(__ashrdi3); ++EXPORT_SYMBOL(__divsi3); ++EXPORT_SYMBOL(__lshrdi3); ++EXPORT_SYMBOL(__modsi3); ++EXPORT_SYMBOL(__muldi3); ++EXPORT_SYMBOL(__ucmpdi2); ++EXPORT_SYMBOL(__udivdi3); ++EXPORT_SYMBOL(__umoddi3); ++EXPORT_SYMBOL(__udivmoddi4); ++EXPORT_SYMBOL(__udivsi3); ++EXPORT_SYMBOL(__umodsi3); ++ ++/* syscalls */ ++EXPORT_SYMBOL(sys_write); ++EXPORT_SYMBOL(sys_lseek); ++EXPORT_SYMBOL(sys_exit); ++EXPORT_SYMBOL(sys_wait4); ++ ++/* cache handling */ ++ ++EXPORT_SYMBOL(cpu_icache_inval_all); ++EXPORT_SYMBOL(cpu_dcache_wbinval_all); ++EXPORT_SYMBOL(cpu_dma_inval_range); ++EXPORT_SYMBOL(cpu_dma_wb_range); +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/proc.c linux-3.4.110/arch/nds32/kernel/proc.c +--- linux-3.4.110.orig/arch/nds32/kernel/proc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/proc.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,81 @@ ++/* ++ * linux/arch/nds32/kernel/setup.c ++ * ++ * Copyright (C) 1995-2001 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for Andes NDS32 architecture. ++ * ++ * Revision History: ++ * ++ * Jul.05.2007 Initial ported by Tom, revised and patched for KGDB ++ * by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++ ++#include ++ ++struct proc_info_item info_item = { ++ "AndesCore", ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ "I" ++#endif ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ "D" ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ "(wt)" ++#else ++ "(wb)" ++#endif ++#endif ++}; ++ ++struct proc_info_list n10_proc_info ++ __attribute__ ((section(".proc.info.init"))) = { ++.cpu_val = 0x0a000000,.cpu_mask = 0xff000000,.arch_name = ++ "NDS32 N10",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = ++ &info_item,}; ++ ++struct proc_info_list n12_proc_info ++ __attribute__ ((section(".proc.info.init"))) = { ++.cpu_val = 0x0c000000,.cpu_mask = 0xff000000,.arch_name = ++ "NDS32 N12",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = ++ &info_item,}; ++ ++struct proc_info_list n13_proc_info ++ __attribute__ ((section(".proc.info.init"))) = { ++.cpu_val = 0x0d000000,.cpu_mask = 0xff000000,.arch_name = ++ "NDS32 N13",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = ++ &info_item,}; ++ ++struct proc_info_list n968_proc_info ++ __attribute__ ((section(".proc.info.init"))) = { ++.cpu_val = 0x19000000,.cpu_mask = 0xff000000,.arch_name = ++ "NDS32 N968",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = ++ &info_item,}; ++ ++struct proc_info_list n1068_proc_info ++ __attribute__ ((section(".proc.info.init"))) = { ++.cpu_val = 0x1a000000,.cpu_mask = 0xff000000,.arch_name = ++ "NDS32 N1068",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = ++ &info_item,}; ++ ++// the last one (a roust way to do so) ++struct proc_info_list nXX_proc_info ++ __attribute__ ((section(".proc.info.init"))) = { ++.cpu_val = 0x00000000,.cpu_mask = 0x00000000,.arch_name = ++ "NDS32 N??",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = ++ &info_item,}; +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/process.c linux-3.4.110/arch/nds32/kernel/process.c +--- linux-3.4.110.orig/arch/nds32/kernel/process.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/process.c 2016-04-07 10:20:50.942081024 +0200 +@@ -0,0 +1,630 @@ ++/* ++ * linux/arch/nds32/kernel/process.c ++ */ ++/* Copyright (C) 1996-2000 Russell King - Converted to ARM. ++ * Original Copyright (C) 1995 Linus Torvalds ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is process implementation for NDS32 architecture, and it ++ * is original referred from ARM. ++ * ++ * Revision History: ++ * ++ * Oct.02.2007 Initial ported by Tom, Shawn, Steven, and Harry. ++ * Oct.03.2007 Updated get_wchan() for info under /proc. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern const char *processor_modes[]; ++extern void setup_mm_for_reboot(char mode); ++extern struct task_struct *_switch(struct task_struct *last, ++ struct thread_info *prev, ++ struct thread_info *next); ++ ++#ifndef CONFIG_UNLAZY_FPU ++struct task_struct *last_task_used_math = NULL; ++#endif ++#ifndef CONFIG_UNLAZY_AUDIO ++struct task_struct *last_task_used_audio = NULL; ++#endif ++static volatile int hlt_counter; ++ ++#ifdef CONFIG_PROC_FS ++struct proc_dir_entry *proc_dir_cpu; ++EXPORT_SYMBOL(proc_dir_cpu); ++#endif ++ ++extern inline void arch_reset(char mode) ++{ ++ if (mode == 's') { ++ /* Use cpu handler, jump to 0 */ ++ cpu_reset(0); ++ } else { ++ /* ++ * Suppose there should be HW function. ++ * Here we used one tick watchdog as a trick. ++ * It is not very good idea in the view of SoC ++ * design, but smart in firmware functionality. ++ * Harry@Jan,08.2008 ++ */ ++ REG32(WDT_FTWDT010_0_VA_BASE + 0x0C) = 0; // WdCR ++ REG32(WDT_FTWDT010_0_VA_BASE + 0x04) = 1; // WdLoad ++ REG32(WDT_FTWDT010_0_VA_BASE + 0x08) = 0x5AB9; // WdRestart ++ REG32(WDT_FTWDT010_0_VA_BASE + 0x0C) = 0x13; // Go... ++ } ++} ++ ++#ifndef arch_idle ++static inline void arch_idle(void) ++{ ++ cpu_do_idle(); ++} ++#endif ++ ++void disable_hlt(void) ++{ ++ hlt_counter++; ++} ++ ++EXPORT_SYMBOL(disable_hlt); ++ ++void enable_hlt(void) ++{ ++ hlt_counter--; ++} ++ ++EXPORT_SYMBOL(enable_hlt); ++ ++static int __init nohlt_setup(char *__unused) ++{ ++ hlt_counter = 1; ++ return 1; ++} ++ ++static int __init hlt_setup(char *__unused) ++{ ++ hlt_counter = 0; ++ return 1; ++} ++ ++__setup("nohlt", nohlt_setup); ++__setup("hlt", hlt_setup); ++ ++/* ++ * The following aren't currently used. ++ */ ++ ++void (*pm_idle) (void) = NULL; ++EXPORT_SYMBOL(pm_idle); ++ ++void (*pm_power_off) (void); ++EXPORT_SYMBOL(pm_power_off); ++ ++/* ++ * This is our default idle handler. We need to disable ++ * interrupts here to ensure we don't miss a wakeup call. ++ */ ++void default_idle(void) ++{ ++ local_irq_disable(); ++ if (!need_resched() && !hlt_counter) ++ arch_idle(); ++ local_irq_enable(); ++} ++ ++/* ++ * The idle thread. We try to conserve power, while trying to keep ++ * overall latency low. The architecture specific idle is passed ++ * a value to indicate the level of "idleness" of the system. ++ */ ++void cpu_idle(void) ++{ ++ ++ /* endless idle loop with no priority at all */ ++ while (1) { ++ void (*idle) (void) = pm_idle; ++ ++ if (!idle) ++ idle = default_idle; ++ tick_nohz_idle_enter(); ++ leds_event(led_idle_start); ++ while (!need_resched()) ++ idle(); ++ leds_event(led_idle_end); ++ tick_nohz_idle_exit(); ++ preempt_enable_no_resched(); ++ schedule(); ++ preempt_disable(); ++ } ++} ++ ++static char reboot_mode = 'h'; ++ ++int __init reboot_setup(char *str) ++{ ++ reboot_mode = str[0]; ++ return 1; ++} ++ ++#ifdef CONFIG_PLAT_AG102 ++static int cpub_pwroff(void) ++{ ++ //PCU_SET_REG(PCS9_PARA, ++ // PCU_PREPARE(PCS9_PARA, IE, 0x0) | ++ // PCU_PREPARE(PCS9_PARA, CMD, PCS_CMD_SCALING) | ++ // PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | ++ // PCU_PREPARE(PCS9_PARA, NXTPAR, 0x1b) // turn off cpub power ++ //); ++ //printk("cpub Power off: ok!!!OKOKOK\n"); ++ //REG32(PCU_VA_BASE + 0x1A4) = (0x0000001B & 0x00FFFFFF)| ((0x2 << 24) & 0x0F000000) | ((0x1 << 28) & 0x70000000) | 0x00000000; ++ //__asm__ volatile ("standby wait_done\n"); ++ //PCU_SET_REG(PCS9_ST1, 0x0); // clear status ++ //REG32(PCU_VA_BASE + 0x1A8) = 0x0; ++ ++ //par = PCS_POWER_CPUB; ++ //PCU_SET_REG(PCS9_PARA, ++ //PCU_PREPARE(PCS9_PARA, IE, 0x1) | ++ //PCU_PREPARE(PCS9_PARA, CMD, PCS_CMD_PW_DOWN) | ++ //PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | ++ //PCU_PREPARE(PCS9_PARA, NXTPAR, 0x6) // turn off all power ++ ++ //printk("cpua Power off: ok!!!YAYAYA\n"); ++ //printk("The value = 0x%08x\n", (0x00000006 & 0x00FFFFFF)| ((0x1 << 24) & 0x0F000000) | ((0x2 << 28) & 0x70000000) | 0x80000000); ++ REG32(PCU_VA_BASE + 0x1A4) = ++ (0x00000006 & 0x00FFFFFF) | ((0x1 << 24) & 0x0F000000) | ++ ((0x2 << 28) & 0x70000000) | 0x80000000; ++ __asm__ volatile ("standby wake_grant\n"); ++ return (0); ++} ++#else ++static int cpub_pwroff(void) ++{ ++ return 0; ++} ++ ++#endif ++ ++__setup("reboot=", reboot_setup); ++ ++void machine_halt(void) ++{ ++ //ADD by river 2011.04.14 ++ cpub_pwroff(); ++} ++ ++EXPORT_SYMBOL(machine_halt); ++ ++void machine_power_off(void) ++{ ++ if (pm_power_off) ++ pm_power_off(); ++} ++ ++EXPORT_SYMBOL(machine_power_off); ++ ++void machine_restart(char *__unused) ++{ ++ /* ++ * Clean and disable cache, and turn off interrupts ++ */ ++ cpu_proc_fin(); ++ ++ /* ++ * Tell the mm system that we are going to reboot - ++ * we may need it to insert some 1:1 mappings so that ++ * soft boot works. ++ */ ++ setup_mm_for_reboot(reboot_mode); ++ ++ /* ++ * Now call the architecture specific reboot code. ++ */ ++ arch_reset(reboot_mode); ++ ++ /* ++ * Whoops - the architecture was unable to reboot. ++ * Tell the user! ++ */ ++ mdelay(1000); ++ printk("Reboot failed -- System halted\n"); ++ while (1) ; ++} ++ ++EXPORT_SYMBOL(machine_restart); ++ ++void show_regs(struct pt_regs *regs) ++{ ++ print_symbol("PC is at %s\n", instruction_pointer(regs)); ++ print_symbol("LR is at %s\n", regs->NDS32_lp); ++ printk("pc : [<%08lx>] lp : [<%08lx>] %s\n" ++ "sp : %08lx fp : %08lx gp : %08lx\n", ++ instruction_pointer(regs), ++ regs->NDS32_lp, print_tainted(), regs->NDS32_sp, ++ regs->NDS32_fp, regs->NDS32_gp); ++ printk("r25: %08lx r24 : %08lx\n", regs->NDS32_r25, regs->NDS32_r24); ++ ++ printk("r23: %08lx r22: %08lx r21: %08lx r20: %08lx\n", ++ regs->NDS32_r23, regs->NDS32_r22, ++ regs->NDS32_r21, regs->NDS32_r20); ++ printk("r19: %08lx r18: %08lx r17: %08lx r16: %08lx\n", ++ regs->NDS32_r19, regs->NDS32_r18, ++ regs->NDS32_r17, regs->NDS32_r16); ++ printk("r15: %08lx r14: %08lx r13: %08lx r12: %08lx\n", ++ regs->NDS32_r15, regs->NDS32_r14, ++ regs->NDS32_r13, regs->NDS32_r12); ++ printk("r11: %08lx r10: %08lx r9 : %08lx r8 : %08lx\n", ++ regs->NDS32_r11, regs->NDS32_r10, ++ regs->NDS32_r9, regs->NDS32_r8); ++ printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", ++ regs->NDS32_r7, regs->NDS32_r6, regs->NDS32_r5, regs->NDS32_r4); ++ printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", ++ regs->NDS32_r3, regs->NDS32_r2, regs->NDS32_r1, regs->NDS32_r0); ++ printk(" IRQs o%s Segment %s\n", ++ interrupts_enabled(regs) ? "n" : "ff", ++ segment_eq(get_fs(), get_ds())? "kernel" : "user"); ++} ++ ++void show_fpregs(struct user_fp *regs) ++{ ++ int i; ++ ++ for (i = 0; i < 8; i++) { ++ unsigned long *p; ++ char type; ++ ++ p = (unsigned long *)(regs->fpregs + i); ++ ++ switch (regs->ftype[i]) { ++ case 1: ++ type = 'f'; ++ break; ++ case 2: ++ type = 'd'; ++ break; ++ case 3: ++ type = 'e'; ++ break; ++ default: ++ type = '?'; ++ break; ++ } ++ if (regs->init_flag) ++ type = '?'; ++ ++ printk(" f%d(%c): %08lx %08lx %08lx%c", ++ i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' '); ++ } ++ ++ printk("FPSR: %08lx FPCR: %08lx\n", ++ (unsigned long)regs->fpsr, (unsigned long)regs->fpcr); ++} ++ ++/* ++ * Task structure and kernel stack allocation. ++ */ ++static unsigned long *thread_info_head; ++static unsigned int nr_thread_info; ++ ++#define EXTRA_TASK_STRUCT 4 ++#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) ++#define ll_free_task_struct(p) free_pages((unsigned long)(p),1) ++ ++struct thread_info *alloc_thread_info(struct task_struct *task) ++{ ++ struct thread_info *thread = NULL; ++ ++ if (EXTRA_TASK_STRUCT) { ++ unsigned long *p = thread_info_head; ++ ++ if (p) { ++ thread_info_head = (unsigned long *)p[0]; ++ nr_thread_info -= 1; ++ } ++ thread = (struct thread_info *)p; ++ } ++ ++ if (!thread) ++ thread = ll_alloc_task_struct(); ++ ++#ifdef CONFIG_MAGIC_SYSRQ ++ /* ++ * The stack must be cleared if you want SYSRQ-T to ++ * give sensible stack usage information ++ */ ++ if (thread) { ++ char *p = (char *)thread; ++ memzero(p + KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); ++ } ++#endif ++ return thread; ++} ++ ++void free_thread_info(struct thread_info *thread) ++{ ++ if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { ++ unsigned long *p = (unsigned long *)thread; ++ p[0] = (unsigned long)thread_info_head; ++ thread_info_head = p; ++ nr_thread_info += 1; ++ } else ++ ll_free_task_struct(thread); ++} ++ ++/* ++ * Free current thread data structures etc.. ++ */ ++void exit_thread(void) ++{ ++#if defined(CONFIG_FPU) ++# ifndef CONFIG_UNLAZY_FPU ++ if (last_task_used_math == current) { ++ last_task_used_math = NULL; ++ } ++# endif ++#endif ++#if defined(CONFIG_AUDIO) ++# ifndef CONFIG_UNLAZY_AUDIO ++ if (last_task_used_audio == current) { ++ last_task_used_audio = NULL; ++ } ++# endif ++#endif ++} ++ ++void flush_thread(void) ++{ ++ struct task_struct *tsk = current; ++ ++ memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); ++#if defined(CONFIG_FPU) ++ clear_fpu(task_pt_regs(tsk)); ++ clear_used_math(); ++# ifndef CONFIG_UNLAZY_FPU ++ if (last_task_used_math == current) { ++ last_task_used_math = NULL; ++ } ++# endif ++#endif ++ ++#if defined(CONFIG_AUDIO) ++ clear_audio(task_pt_regs(tsk)); ++ clear_tsk_thread_flag(tsk, TIF_USEDAUDIO); ++# ifndef CONFIG_UNLAZY_AUDIO ++ if (last_task_used_audio == current) { ++ last_task_used_audio = NULL; ++ } ++# endif ++#endif ++ ++} ++ ++void release_thread(struct task_struct *dead_task) ++{ ++} ++ ++asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); ++ ++/* ++ * Shuffle the argument into the correct register before calling the ++ * thread function. $r1 is the thread argument, $r2 is the pointer to ++ * the thread function, and $r3 points to the exit function. ++ */ ++extern void kernel_thread_helper(void); ++asm(".section .text\n" ++ " .align\n" ++ " .type kernel_thread_helper, #function\n" ++ "kernel_thread_helper:\n" ++ " move $r2, $lp\n" ++ " move $r0, $r1\n" ++ " move $lp, $r3\n" ++ " jr $r2 \n" ++ " .size kernel_thread_helper, . - kernel_thread_helper\n" ++ " .previous"); ++ ++pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) ++{ ++ struct pt_regs regs; ++ ++ memset(®s, 0, sizeof(regs)); ++ ++ regs.NDS32_r1 = (unsigned long)arg; ++ regs.NDS32_r2 = (unsigned long)fn; ++ /* to apply right path */ ++ regs.NDS32_lp = regs.NDS32_r2; ++ regs.NDS32_r3 = (unsigned long)do_exit; ++ regs.NDS32_ipc = (unsigned long)kernel_thread_helper; ++ ++#ifdef __NDS32_EB__ ++#define PSW_DE PSW_mskBE ++#else ++#define PSW_DE 0x0 ++#endif ++ ++#ifdef CONFIG_WBNA ++#define PSW_valWBNA PSW_mskWBNA ++#else ++#define PSW_valWBNA 0x0 ++#endif ++ ++ regs.NDS32_ipsw = ++ (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | ++ PSW_SYSTEM | PSW_INTL_1 | PSW_mskGIE); ++ regs.NDS32_ir0 = ++ (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | ++ PSW_SYSTEM | PSW_INTL_1); ++ ++ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, ++ NULL); ++} ++ ++EXPORT_SYMBOL(kernel_thread); ++ ++int ++copy_thread(unsigned long clone_flags, unsigned long stack_start, ++ unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) ++{ ++ struct thread_info *thread = task_thread_info(p); ++ struct pt_regs *childregs; ++ ++ childregs = ++ ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; ++ ++ *childregs = *regs; ++ childregs->NDS32_r0 = 0; /* child get zero as ret. */ ++ childregs->NDS32_sp = stack_start; ++ childregs->NDS32_osp = 0; ++ ++ thread->sp_save = ((struct cpu_context_save *)(childregs)) - 1; ++ /* cpu context switching */ ++ thread->sp_save->pc = (unsigned long)ret_from_fork; ++ if (clone_flags & CLONE_SETTLS) ++ childregs->NDS32_r25 = regs->NDS32_r3; ++ ++#ifdef CONFIG_FPU ++ if (used_math()) { ++# ifdef CONFIG_UNLAZY_FPU ++ unlazy_fpu(current); ++# else ++ preempt_disable(); ++ if (last_task_used_math == current) ++ save_fpu(current); ++ preempt_enable(); ++# endif ++ p->thread.fpu = current->thread.fpu; ++ clear_fpu(task_pt_regs(p)); ++ set_stopped_child_used_math(p); ++ } ++#endif ++ ++#ifdef CONFIG_AUDIO ++ if (test_tsk_thread_flag(current, TIF_USEDAUDIO)) { ++# ifdef CONFIG_UNLAZY_AUDIO ++ unlazy_audio(current); ++# else ++ preempt_disable(); ++ if (last_task_used_audio == current) ++ save_audio(current); ++ preempt_enable(); ++# endif ++ p->thread.audio = current->thread.audio; ++ clear_audio(childregs); ++ set_tsk_thread_flag(p, TIF_USEDAUDIO); ++ } ++#endif ++ ++#ifdef CONFIG_HWZOL ++ childregs->NDS32_lb = 0; ++ childregs->NDS32_le = 0; ++ childregs->NDS32_lc = 0; ++#endif ++ ++ return 0; ++} ++ ++struct task_struct *__switch_to(struct task_struct *last, ++ struct thread_info *prev, ++ struct thread_info *next) ++{ ++#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO) ++# ifdef CONFIG_UNLAZY_FPU ++ unlazy_fpu(prev->task); ++# endif ++# ifdef CONFIG_UNLAZY_AUDIO ++ unlazy_audio(prev->task); ++# endif ++ if (!(next->task->flags & PF_KTHREAD)) { ++#ifdef CONFIG_FPU ++ clear_fpu(task_pt_regs(next->task)); ++#endif ++#ifdef CONFIG_AUDIO ++ clear_audio(task_pt_regs(next->task)); ++#endif ++ } ++#endif ++ return _switch(last, prev, next); ++} ++ ++/* ++ * fill in the fpe structure for a core dump... ++ */ ++int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu) ++{ ++ int fpvalid = 0; ++ ++#if 0 // XXX defined(CONFIG_FPU) ++ struct task_struct *tsk = current; ++ ++ fpvalid = !!tsk_used_math(tsk); ++ if (fpvalid) { ++ unlazy_fpu(tsk, regs); ++ memcpy(fpu, &tsk->thread.fpu, sizeof(*fpu)); ++ } ++#endif ++ ++ return fpvalid; ++} ++ ++EXPORT_SYMBOL(dump_fpu); ++ ++unsigned long get_wchan(struct task_struct *p) ++{ ++ unsigned long fp, lr; ++ unsigned long stack_start, stack_end; ++ int count = 0; ++ ++ if (!p || p == current || p->state == TASK_RUNNING) ++ return 0; ++ ++#ifdef CONFIG_FRAME_POINTER ++ stack_start = (unsigned long)end_of_stack(p); ++ stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; ++ ++ fp = thread_saved_fp(p); ++ do { ++ if (fp < stack_start || fp > stack_end) ++ return 0; ++ lr = ((unsigned long *)fp)[0]; ++ if (!in_sched_functions(lr)) ++ return lr; ++ fp = *(unsigned long *)(fp + 4); ++ } while (count++ < 16); ++ return 0; ++#else ++ return 0; ++#endif ++} ++ ++EXPORT_SYMBOL(get_wchan); ++ ++extern int do_elf_check_arch(const struct elf32_hdr *hdr); ++ ++int elf_check_arch(const struct elf32_hdr *hdr) ++{ ++ return do_elf_check_arch(hdr); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ptrace.c linux-3.4.110/arch/nds32/kernel/ptrace.c +--- linux-3.4.110.orig/arch/nds32/kernel/ptrace.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/ptrace.c 2016-04-07 10:22:02.056831821 +0200 +@@ -0,0 +1,919 @@ ++/* ++ * linux/arch/nds32/kernel/ptrace.c ++ */ ++/* By Ross Biro 1/23/92 ++ * edited by Linus Torvalds ++ * ARM modifications Copyright (C) 2000 Russell King ++ * NDS32 modifications Copyright (C) 2007 Harry Pan ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for Andes NDS32 architecture. ++ * ++ * Revision History: ++ * ++ * Jul.31.2007 Initial ported by Tom, Shawn, and Steven, ++ * revised by Harry. ++ * Current implmentation is based on Andes Instruction ++ * Set Architecture Specification (AS-0001-0001) ++ * version:3.7 date:7-20-2007. ++ * It is original taken from ARM, then fit to NDS32. ++ * Aug.15.2007 Mainly updated breakpoint handling base on NDS32 ISA. ++ * I also did code revise. ++ * Nov.14.2007 Fixed up ptrace_set_bpt() while handling 16-bit insn. ++ * Nov.27.2007 Added checking duplicate breakpoints in ++ * add_breakpoint(), based on Shawn's idea. ++ * Dec.06.2007 Added get_user_gpr(). ++ * Apr.17.2009 Added support for FPU and Audio regs. ++ * Added support for PTRACE_GETFPREGS, PTRACE_SETFPREGS, ++ * PTRACE_GETAUREGS, PTRACE_SETAUREGS ++ * ++ * Note: ++ * ++ * Current layout: 0-31 GR, 32-34 SPR, 35-... SR, index start from zero. ++ * ++ * +----------+-----+--------------+---+--------+ ++ * | GR | SPR | SR |...| Audio | ++ * +----------+-----+--------------+---+--------+ ++ * 0 32 35 ...500 531 ++ * ++ * ============================================================================ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ptrace.h" ++ ++#ifdef __NDS32_EL__ ++#define BREAKINST 0x01EA ++#else ++#define BREAKINST 0xEA01 ++#endif ++ ++/* get_user_reg() ++ * ++ * This routine will get a word off of the processes privileged stack. ++ * the offset is how far from the base addr as stored in the THREAD. ++ * this routine assumes that all the privileged stacks are in our ++ * data space. ++ */ ++static inline unsigned int get_user_reg(struct task_struct *task, int offset) ++{ ++ return task_pt_regs(task)->uregs[offset]; ++} ++ ++#if !defined(CONFIG_HSS) ++/* get_user_gpr() ++ * ++ */ ++static unsigned int get_user_gpr(struct task_struct *task, int idx) ++{ ++ unsigned int ret; ++ ++ if (idx < 26) // r0 to r25 ++ ret = get_user_reg(task, idx + 13); ++ else if (idx == 26 || idx == 27) // p0, p1 ++ ret = get_user_reg(task, idx - 26 + 7); ++ else if (idx > 27 && idx < 31) // fp, gp, lp ++ ret = get_user_reg(task, idx + 11); ++ else if (idx == 31) // sp ++ ret = get_user_reg(task, 3); ++ else ++ ret = 0; ++ ++ return ret; ++} ++#endif ++ ++/* put_user_reg() ++ * ++ * this routine will put a word on the processes privileged stack. ++ * the offset is how far from the base addr as stored in the THREAD. ++ * this routine assumes that all the privileged stacks are in our ++ * data space. ++ */ ++static inline int put_user_reg(struct task_struct *task, int offset, long data) ++{ ++ struct pt_regs newregs, *regs = task_pt_regs(task); ++ int ret = -EINVAL; ++ ++ newregs = *regs; ++ newregs.uregs[offset] = data; ++ ++ if (valid_user_regs(&newregs)) { ++ regs->uregs[offset] = data; ++ ret = 0; ++ } ++ ++ return ret; ++} ++ ++#if !defined(CONFIG_HSS) ++/* ++ * Read instruction. ++ */ ++static inline int ++read_insn(struct task_struct *task, unsigned long addr, u32 * res) ++{ ++ int ret; ++ *res = 0; ++ ret = access_process_vm(task, addr, res, 2, 0); ++ if (ret != 2) ++ return 0; ++#ifdef __NDS32_EL__ ++ *res = swab16(*res); ++#endif ++ if ((*res) & 0x8000) ++ return 2; ++ ++ ret = access_process_vm(task, addr, res, 4, 0); ++ if (ret != 4) ++ return 0; ++#ifdef __NDS32_EL__ ++ *res = swab32(*res); ++#endif ++ return 4; ++} ++ ++/* get_branch_address() ++ * ++ * Decode branch instructions and destination. ++ */ ++static unsigned long ++get_branch_address(struct task_struct *child, ++ unsigned long pc, unsigned long insn, unsigned int size) ++{ ++ unsigned int tpc = 0; ++ ++ /* ++ * TODO: COLE ++ * would it be simpler if we use two BREAKs, ++ * one for take, one for not ++ */ ++ ++ if (size == 4) { ++ /* 32-bit instruction */ ++ if ((insn & 0x7e000000) == 0x4c000000) // BR1 ++ { ++ int cond, imm14s; ++ unsigned int rt, ra; ++ ++ rt = (insn >> 20) & 0x1f; ++ ra = (insn >> 15) & 0x1f; ++ cond = (insn >> 14) & 0x01; ++ imm14s = insn & 0x00003fff; ++ ++ if (imm14s & 0x00002000) // sign extend ++ imm14s -= (0x00002000 << 1); ++ ++ rt = get_user_gpr(child, rt); ++ ra = get_user_gpr(child, ra); ++ ++ if (((cond == 1) && (rt != ra)) || // bne ++ ((cond == 0) && (rt == ra))) // beq ++ tpc = pc + (imm14s << 1); ++ } else if ((insn & 0x7e000000) == 0x4e000000) // BR2 ++ { ++ int cond, imm16s, taken = 0; ++ int rt; ++ ++ rt = (insn >> 20) & 0x1f; ++ cond = (insn >> 16) & 0x0f; ++ imm16s = insn & 0x0000ffff; ++ ++ if (imm16s & 0x00008000) // sign extend ++ imm16s -= (0x00008000 << 1); ++ ++ rt = get_user_gpr(child, rt); ++ ++ switch (cond) { ++ case 0x02: // beqz ++ if (rt == 0) ++ taken = 1; ++ break; ++ case 0x03: // bnez ++ if (rt != 0) ++ taken = 1; ++ break; ++ case 0x06: // bgtz ++ if (rt > 0) ++ taken = 1; ++ break; ++ case 0x07: // blez ++ if (rt <= 0) ++ taken = 1; ++ break; ++ case 0x04: // bgez ++ case 0x0c: // bgezal ++ if (rt >= 0) ++ taken = 1; ++ break; ++ case 0x05: // bltz ++ case 0x0d: // bltzal ++ if (rt < 0) ++ taken = 1; ++ break; ++ default: ++ printk(KERN_WARNING ++ "ptrace: unknown conditional branch.\n"); ++ break; ++ } ++ ++ if (taken) ++ tpc = pc + (imm16s << 1); ++ } else if ((insn & 0x7e000000) == 0x48000000) // JI ++ { ++ int imm24s; ++ ++ imm24s = insn & 0x00ffffff; ++ ++ if (imm24s & 0x00800000) // sign extend ++ imm24s -= (0x00800000 << 1); ++ ++ tpc = pc + (imm24s << 1); ++ } else if ((insn & 0x7e000000) == 0x4a000000) // JREG ++ { ++ unsigned int rb = (insn >> 10) & 0x1f; ++ ++ tpc = get_user_gpr(child, rb); ++ } ++ ++ } else { ++ /* 16-bit instruction */ ++ ++ if ((insn & 0xf800) == 0xc000) // beqz38 ++ { ++ unsigned int rt3; ++ ++ rt3 = (insn >> 8) & 0x07; ++ ++ rt3 = get_user_gpr(child, rt3); ++ ++ if (rt3 == 0) { ++ int imm8s; ++ ++ imm8s = insn & 0x00ff; ++ ++ if (imm8s & 0x0080) // sign extend ++ imm8s -= (0x0080 << 1); ++ ++ tpc = pc + (imm8s << 1); ++ } ++ } ++ ++ if ((insn & 0xf800) == 0xc800) // bnez38 ++ { ++ unsigned int rt3; ++ ++ rt3 = (insn >> 8) & 0x07; ++ ++ rt3 = get_user_gpr(child, rt3); ++ ++ if (rt3 != 0) { ++ int imm8s; ++ ++ imm8s = insn & 0x00ff; ++ ++ if (imm8s & 0x0080) // sign extend ++ imm8s -= (0x0080 << 1); ++ ++ tpc = pc + (imm8s << 1); ++ } ++ } ++ ++ if ((insn & 0xf800) == 0xd000) // beqs38, j8 ++ { ++ unsigned int rt3, r5; ++ ++ rt3 = (insn >> 8) & 0x07; ++ ++ rt3 = get_user_gpr(child, rt3); ++ r5 = get_user_gpr(child, 5); ++ ++ if (r5 == rt3) { ++ int imm8s; ++ imm8s = insn & 0x00ff; ++ ++ if (imm8s & 0x0080) // sign extend ++ imm8s -= (0x0080 << 1); ++ ++ tpc = pc + (imm8s << 1); ++ } ++ } ++ ++ if ((insn & 0xf800) == 0xd800) // bnes38 ++ { ++ unsigned int rt3, r5; ++ ++ rt3 = (insn >> 8) & 0x07; ++ ++ r5 = get_user_gpr(child, 5); ++ rt3 = get_user_gpr(child, rt3); ++ ++ if (r5 != rt3) { ++ int imm8s; ++ ++ imm8s = insn & 0x00ff; ++ ++ if (imm8s & 0x0080) // sign extend ++ imm8s -= (0x0080 << 1); ++ ++ tpc = pc + (imm8s << 1); ++ } ++ } ++ ++ if ((insn & 0xffe0) == 0xdd00 || // jr5 ++ (insn & 0xffe0) == 0xdd80 || // ret5 ++ (insn & 0xffe0) == 0xdd20) // jral5 ++ { ++ unsigned int rb5; ++ ++ rb5 = insn & 0x1f; ++ ++ tpc = get_user_gpr(child, rb5); ++ } ++ ++ if ((insn & 0xfe00) == 0xe800) { ++ int taken = 0; ++ unsigned int r15; ++ ++ r15 = get_user_gpr(child, 15); ++ ++ if (insn & 0x0100) // bnezs8 ++ { ++ if (r15 != 0) ++ taken = 1; ++ } else // beqzs8 ++ { ++ if (r15 == 0) ++ taken = 1; ++ } ++ ++ if (taken) { ++ int imm8s; ++ ++ imm8s = insn & 0x00ff; ++ ++ if (imm8s & 0x0080) // sign extend ++ imm8s -= (0x0080 << 1); ++ ++ tpc = pc + (imm8s << 1); ++ } ++ } ++ } ++ ++ return tpc; ++} ++ ++/* ++ * Swap instructions in the user program. ++ * swap in new_insn. save orignal value in old_insn ++ * assume new_insn is 2-bytes long ++ */ ++static int ++swap_insn(struct task_struct *task, unsigned long addr, ++ u16 * old_insn, u16 * new_insn) ++{ ++ int ret; ++ ++ ret = access_process_vm(task, addr, old_insn, 2, 0); ++ if (ret == 2) ++ ret = access_process_vm(task, addr, new_insn, 2, 1); ++ ++ return ret; ++} ++ ++/* ++ * Add one breakpoint in the user program. ++ */ ++static void ++add_breakpoint(struct task_struct *task, struct debug_info *dbg, ++ unsigned long addr) ++{ ++ u16 new_insn = BREAKINST; ++ int res; ++ ++ if (dbg->valid) { ++ printk(KERN_ERR "ptrace: too many breakpoints\n"); ++ return; ++ } ++ ++ dbg->address = addr; ++ res = swap_insn(task, addr, &dbg->insn, &new_insn); ++ if (res == 2) ++ dbg->valid = 1; ++ if (!dbg->valid) ++ printk(KERN_ERR "ptrace: fail to add breakpoint\n"); ++} ++ ++/* ++ * Clear one software breakpoint in the user program. ++ */ ++static void clear_breakpoint(struct task_struct *task, struct debug_info *dbg) ++{ ++ int ret; ++ unsigned int addr = dbg->address; ++ u16 old_insn; ++ ++ if (!dbg->valid) { ++ return; ++ } ++ dbg->valid = 0; ++ ++ ret = swap_insn(task, addr, &old_insn, &dbg->insn); ++ ++ if (ret != 2 || old_insn != BREAKINST) { ++ printk(KERN_ERR "ptrace: %s:%d: corrupted NDS16 breakpoint at " ++ "0x%08x (0x%04x)\n", task->comm, task->pid, ++ addr, old_insn); ++ } ++} ++ ++/* ++ * ptrace_set_swbk ++ * Set breakpoint in user program. ++ */ ++void ptrace_set_swbk(struct task_struct *child) ++{ ++ struct pt_regs *regs; ++ unsigned long pc; ++ unsigned int size; ++ u32 insn; ++ ++ /* ++ * always clear before set, ++ * since in some sepcial case, it may fail to hit ++ */ ++ ptrace_cancel_swbk(child); ++ regs = task_pt_regs(child); ++ pc = instruction_pointer(regs); ++ size = read_insn(child, pc, &insn); ++ ++ printk(KERN_DEBUG " STEP.size=%d\n", size); ++ ++ if (size > 0) { ++ struct debug_info *dbg = &child->thread.debug; ++ unsigned int tpc; ++ ++ /* Predict next PC. */ ++ tpc = get_branch_address(child, pc, insn, size); ++ ++ if (tpc) { ++ printk(KERN_DEBUG " STEP.addr=0x%x\n", tpc); ++ add_breakpoint(child, dbg, tpc); ++ } else { ++ if (size == 4) { ++ printk(KERN_DEBUG " STEP.addr=0x%x\n", ++ (unsigned int)(pc + 4)); ++ add_breakpoint(child, dbg, pc + 4); ++ } else if (size == 2) { ++ printk(KERN_DEBUG " STEP.addr=0x%x\n", ++ (unsigned int)(pc + 2)); ++ add_breakpoint(child, dbg, pc + 2); ++ } else { ++ printk(KERN_ERR ++ "ptrace: bad step address, pc + %d\n", ++ size); ++ } ++ } ++ } ++} ++ ++/* ++ * Ensure no single-step breakpoint is pending. Returns non-zero ++ * value if child was being single-stepped. ++ */ ++void ptrace_cancel_swbk(struct task_struct *child) ++{ ++ if (!child->thread.debug.valid) { ++ return; ++ } ++ ++ clear_breakpoint(child, &child->thread.debug); ++} ++#endif /* end of !defined (CONFIG_HSS) */ ++ ++/* ++ * Called by kernel/ptrace.c when detaching.. ++ * ++ * Make sure the single step bit is not set. ++ */ ++void ptrace_disable(struct task_struct *child) ++{ ++ user_disable_single_step(child); ++} ++ ++/* ++ * Handle hitting a breakpoint. ++ */ ++void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, ++ int error_code, int si_code) ++{ ++ struct siginfo info; ++ ++#if !defined (CONFIG_HSS) ++ /* clear the swbk; otherwise the user will see it */ ++ ptrace_cancel_swbk(tsk); ++#endif ++ ++ tsk->thread.trap_no = 1; ++ tsk->thread.error_code = error_code; ++ ++ memset(&info, 0, sizeof(info)); ++ info.si_signo = SIGTRAP; ++ info.si_code = si_code; ++ ++ info.si_addr = (void __user *)instruction_pointer(regs); ++ ++ /* Send us the fake SIGTRAP */ ++ force_sig_info(SIGTRAP, &info, tsk); ++} ++ ++/* ptrace_read_user() ++ * ++ * Read the word at offset "off" into the "struct user". We ++ * actually access the pt_regs stored on the kernel stack. ++ */ ++static int ++ptrace_read_user(struct task_struct *tsk, unsigned long off, ++ unsigned long __user * ret) ++{ ++ unsigned long tmp = 0; ++ ++ if (off < 500) { ++ if (off & 3 || off >= sizeof(struct user)) ++ return -EIO; ++ ++ if (off < sizeof(struct pt_regs)) ++ tmp = get_user_reg(tsk, off >> 2); ++ ++ return put_user(tmp, ret); ++ } else if (off < 532) { ++#ifdef CONFIG_AUDIO ++ off -= 500; ++ if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { ++#ifdef CONFIG_UNLAZY_AUDIO ++ unlazy_audio(tsk); ++#else ++ preempt_disable(); ++ if (last_task_used_audio == tsk) ++ save_audio(tsk); ++ preempt_enable(); ++#endif ++ tmp = tsk->thread.audio.auregs[off]; ++ } ++#endif ++ return put_user(tmp, ret); ++ } else ++ return -EIO; ++} ++ ++/* ptrace_write_user() ++ * ++ * Write the word at offset "off" into "struct user". We ++ * actually access the pt_regs stored on the kernel stack. ++ */ ++static int ++ptrace_write_user(struct task_struct *tsk, unsigned long off, unsigned long val) ++{ ++ if (off < 500) { ++ if (off & 3 || off >= sizeof(struct user)) ++ return -EIO; ++ ++ if (off >= sizeof(struct pt_regs)) ++ return 0; ++ ++ return put_user_reg(tsk, off >> 2, val); ++ } else if (off < 532) { ++#ifdef CONFIG_AUDIO ++ off -= 500; ++ if (!test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { ++ /* First time Audio user. */ ++ memset(&tsk->thread.audio, 0, ++ sizeof(struct audio_struct)); ++ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); ++ } else { ++#ifdef CONFIG_UNLAZY_AUDIO ++ unlazy_audio(tsk); ++#else ++ if (last_task_used_audio == tsk) { ++ preempt_disable(); ++ save_audio(tsk); ++ preempt_enable(); ++ } ++#endif ++ /* Let the lazy mechanism do the restore. */ ++ clear_audio(task_pt_regs(tsk)); ++ } ++ tsk->thread.audio.auregs[off] = val; ++#endif ++ return 0; ++ } else ++ return -EIO; ++} ++ ++/* ptrace_getregs() ++ * ++ * Get all user integer registers. ++ */ ++static int ptrace_getregs(struct task_struct *tsk, void __user * uregs) ++{ ++ struct pt_regs *regs = task_pt_regs(tsk); ++ ++ return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; ++} ++ ++/* ptrace_setregs() ++ * ++ * Set all user integer registers. ++ */ ++static int ptrace_setregs(struct task_struct *tsk, void __user * uregs) ++{ ++ struct pt_regs newregs; ++ int ret; ++ ++ ret = -EFAULT; ++ if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { ++ struct pt_regs *regs = task_pt_regs(tsk); ++ ++ ret = -EINVAL; ++ if (valid_user_regs(&newregs)) { ++ *regs = newregs; ++ ret = 0; ++ } ++ } ++ ++ return ret; ++} ++ ++/* ptrace_getfpregs() ++ * ++ * Get the child FPU state. ++ */ ++static int ptrace_getfpregs(struct task_struct *tsk, void __user * ufpregs) ++{ ++#ifdef CONFIG_FPU ++ if (used_math()) { ++# ifdef CONFIG_UNLAZY_FPU ++ unlazy_fpu(tsk); ++# else ++ preempt_disable(); ++ if (last_task_used_math == tsk) ++ save_fpu(tsk); ++ preempt_enable(); ++# endif ++ return copy_to_user(ufpregs, &tsk->thread.fpu, ++ sizeof(struct fpu_struct)) ? -EFAULT : 0; ++ } else { ++ /* First time FPU user. */ ++ memset(ufpregs, -1, sizeof(struct fpu_struct)); ++ return 0; ++ } ++ ++#else ++ return -EFAULT; ++#endif ++} ++ ++/* ++ * Set the child FPU state. ++ */ ++static int ptrace_setfpregs(struct task_struct *tsk, void __user * ufpregs) ++{ ++#ifdef CONFIG_FPU ++ int ret; ++ ++# ifndef CONFIG_UNLAZY_FPU ++ if (last_task_used_math == tsk) ++# endif ++ clear_fpu(task_pt_regs(tsk)); ++ ++ ret = ++ copy_from_user(&tsk->thread.fpu, ufpregs, ++ sizeof(struct fpu_struct)) ? -EFAULT : 0; ++ ++ if (!ret && !used_math()) { ++ /* First time Audio user. */ ++ set_used_math(); ++ } ++ ++ return ret; ++#else ++ return -EFAULT; ++#endif ++} ++ ++/* ptrace_getauregs() ++ * ++ * Get the child Audio state. ++ */ ++static int ptrace_getauregs(struct task_struct *tsk, void __user * uauregs) ++{ ++#ifdef CONFIG_AUDIO ++ if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { ++#ifdef CONFIG_UNLAZY_AUDIO ++ unlazy_audio(tsk); ++#else ++ preempt_disable(); ++ if (last_task_used_audio == tsk) ++ save_audio(tsk); ++ preempt_enable(); ++#endif ++ return copy_to_user(uauregs, &tsk->thread.audio, ++ sizeof(struct audio_struct)) ? -EFAULT : 0; ++ } else { ++ /* First time Audio user. */ ++ memset(uauregs, 0, sizeof(struct audio_struct)); ++ return 0; ++ } ++ ++#else ++ return -EFAULT; ++#endif ++} ++ ++/* ++ * Set the child Audio state. ++ */ ++static int ptrace_setauregs(struct task_struct *tsk, void __user * uauregs) ++{ ++#ifdef CONFIG_AUDIO ++ int ret; ++ ++#ifdef CONFIG_UNLAZY_AUDIO ++ clear_audio(task_pt_regs(tsk)); ++#else ++ if (last_task_used_audio == tsk) ++ clear_audio(task_pt_regs(tsk)); ++#endif ++ ret = ++ copy_from_user(&tsk->thread.audio, uauregs, ++ sizeof(struct audio_struct)) ? -EFAULT : 0; ++ ++ if (!ret && !test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { ++ /* First time Audio user. */ ++ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); ++ } ++ ++ return ret; ++#else ++ return -EFAULT; ++#endif ++} ++ ++/* do_ptrace() ++ * ++ * Provide ptrace defined service. ++ */ ++long arch_ptrace(struct task_struct *child, long request, unsigned long addr, ++ unsigned long data) ++{ ++ int ret; ++ ++ switch (request) { ++ case PTRACE_PEEKUSR: ++ ret = ++ ptrace_read_user(child, addr, (unsigned long __user *)data); ++ break; ++ ++ case PTRACE_POKEUSR: ++ ret = ptrace_write_user(child, addr, data); ++ break; ++ ++ case PTRACE_GETREGS: ++ ret = ptrace_getregs(child, (void __user *)data); ++ break; ++ ++ case PTRACE_SETREGS: ++ ret = ptrace_setregs(child, (void __user *)data); ++ break; ++ ++ case PTRACE_GETFPREGS: ++ ret = ptrace_getfpregs(child, (void __user *)data); ++ break; ++ ++ case PTRACE_SETAUREGS: ++ ret = ptrace_setauregs(child, (void __user *)data); ++ break; ++ ++ case PTRACE_GETAUREGS: ++ ret = ptrace_getauregs(child, (void __user *)data); ++ break; ++ ++ case PTRACE_SETFPREGS: ++ ret = ptrace_setfpregs(child, (void __user *)data); ++ break; ++/* ++ case PTRACE_GET_THREAD_AREA: ++ ret = put_user(task_thread_info(child)->tp_value, ++ (unsigned long __user *) data); ++ break; ++*/ ++ ++ default: ++ ret = ptrace_request(child, request, addr, data); ++ break; ++ } ++ ++ return ret; ++} ++ ++void user_enable_single_step(struct task_struct *child) ++{ ++ struct pt_regs *regs; ++ regs = task_pt_regs(child); ++#ifdef CONFIG_HSS ++ regs->NDS32_ipsw |= PSW_mskHSS; ++#else ++ ptrace_set_swbk(child); ++#endif ++ set_tsk_thread_flag(child, TIF_SINGLESTEP); ++} ++ ++void user_disable_single_step(struct task_struct *child) ++{ ++ struct pt_regs *regs; ++ regs = task_pt_regs(child); ++#ifdef CONFIG_HSS ++ regs->NDS32_ipsw &= ~PSW_mskHSS; ++#else ++ ptrace_cancel_swbk(child); ++#endif ++ clear_tsk_thread_flag(child, TIF_SINGLESTEP); ++} ++ ++/* sys_trace() ++ * ++ * syscall trace handler. ++ */ ++static inline void do_syscall_trace(void) ++{ ++ if (!test_thread_flag(TIF_SYSCALL_TRACE)) ++ return; ++ if (!(current->ptrace & PT_PTRACED)) ++ return; ++ ++ /* the 0x80 provides a way for the tracing parent to distinguish ++ between a syscall stop and SIGTRAP delivery */ ++ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ++ ? 0x80 : 0)); ++ /* ++ * this isn't the same as continuing with a signal, but it will do ++ * for normal use. strace only continues with a signal if the ++ * stopping signal is not SIGTRAP. -brl ++ */ ++ if (current->exit_code) { ++ send_sig(current->exit_code, current, 1); ++ current->exit_code = 0; ++ } ++} ++ ++asmlinkage int syscall_trace_enter(int syscall, struct pt_regs *regs) ++{ ++ int orig_r0; ++ ++ orig_r0 = regs->NDS32_ORIG_r0; ++ regs->NDS32_ORIG_r0 = syscall; ++ do_syscall_trace(); ++ syscall = regs->NDS32_ORIG_r0; ++ regs->NDS32_ORIG_r0 = orig_r0; ++ return syscall & 0xfff; ++} ++ ++asmlinkage void syscall_trace_leave(struct pt_regs *regs) ++{ ++ do_syscall_trace(); ++ ++ /* synthsize a single-step */ ++#if !defined(CONFIG_HSS) ++ /* for SWBK, break should be remove */ ++ ptrace_cancel_swbk(current); ++#endif ++ if (test_thread_flag(TIF_SINGLESTEP)) { ++ printk(KERN_INFO "synthsize trap (tf=0x%0x\n", ++ (unsigned int)current_thread_info()->flags); ++ send_sigtrap(current, regs, 0, TRAP_BRKPT); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/ptrace.h linux-3.4.110/arch/nds32/kernel/ptrace.h +--- linux-3.4.110.orig/arch/nds32/kernel/ptrace.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/ptrace.h 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * linux/arch/nds32/kernel/ptrace.h ++ */ ++/* Copyright (C) 2000-2003 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for Andes NDS32 architecture. ++ * ++ * Revision History: ++ * ++ * Jul.31.2007 Initial ported by Tom, Shawn, and Steven, ++ * revised by Harry. ++ * Current implmentation is based on Andes Instruction ++ * Set Architecture Specification (AS-0001-0001) ++ * version:3.7 date:7-20-2007. ++ * It is original taken from ARM, then fit to NDS32. ++ * ++ * Note: ++ * ++ * Current layout: 0-31 GR, 32-34 SPR, 35-... SR, index start from zero. ++ * ++ * +----------+-----+--------------+ ++ * | GR | SPR | SR | ++ * +-------------------------------+ ++ * 0 32 35 ... ++ * ++ * ============================================================================ ++ */ ++#ifndef __KERNEL_PTRACE_H__ ++#define __KERNEL_PTRACE_H__ ++ ++extern void ptrace_cancel_swbk(struct task_struct *); ++extern void ptrace_set_swbk(struct task_struct *); ++extern void ptrace_break(struct task_struct *, struct pt_regs *); ++extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, ++ int error_code, int si_code); ++ ++#endif // __KERNEL_PTRACE_H__ +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/relocate_kernel.S linux-3.4.110/arch/nds32/kernel/relocate_kernel.S +--- linux-3.4.110.orig/arch/nds32/kernel/relocate_kernel.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/relocate_kernel.S 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,89 @@ ++/* ++ * relocate_kernel.S - put the kernel image in place to boot ++ */ ++ ++#include ++ ++ .globl relocate_new_kernel ++relocate_new_kernel: ++ la $r0, kexec_indirection_page ++ slli $r0, $r0, 2 ++ srli $r0, $r0, 2 ++ lwi $r0, [$r0] ++ la $r1, kexec_start_address ++ slli $r1, $r1, 2 ++ srli $r1, $r1, 2 ++ lwi $r1, [$r1] ++ ++0: /* top, read another word for the indirection page */ ++ lwi.bi $r3, [$r0], #4 ++ ++ /* Is it a destination page. Put destination address to r4 */ ++ andi $p0, $r3, #1 ++ beqz $p0, 1f ++ li $p0, ~#1 ++ and $r4, $r3, $p0 ++ b 0b ++1: ++ /* Is it an indirection page */ ++ andi $p0, $r3, #2 ++ beqz $p0, 1f ++ li $p0, ~#2 ++ and $r0, $r3, $p0 ++ b 0b ++1: ++ /* are we done ? */ ++ andi $p0, $r3, #4 ++ beqz $p0, 1f ++ b 2f ++1: ++ /* is it source ? */ ++ andi $p0, $r3, #8 ++ beqz $p0, 0b ++ li $p0, ~#8 ++ and $r3, $r3, $p0 ++ li $r6, #(1024/16) /* 16 words per loop */ ++9: ++ lmw.bim $r7, [$r3], $r22 ++ smw.bim $r7, [$r4], $r22 ++ addi $r6, $r6, -1 ++ bnez $r6, 9b ++ b 0b ++2: ++ /* Jump to relocated kernel */ ++ move $lp, $r1 ++ li $r0, 0 ++ la $r1, kexec_mach_type ++ slli $r1, $r1, 2 ++ srli $r1, $r1, 2 ++ lwi $r1, [$r1] ++ la $r2, kexec_boot_atags ++ slli $r2, $r2, 2 ++ srli $r2, $r2, 2 ++ lwi $r2, [$r2] ++ ret ++ ++ .globl kexec_start_address ++kexec_start_address: ++ .long 0x0 ++ ++ .globl kexec_indirection_page ++kexec_indirection_page: ++ .long 0x0 ++ ++ .globl kexec_mach_type ++kexec_mach_type: ++ .long 0x0 ++ ++ /* phy addr of the atags for the new kernel */ ++ .globl kexec_boot_atags ++kexec_boot_atags: ++ .long 0x0 ++ ++relocate_new_kernel_end: ++ ++ .globl relocate_new_kernel_size ++relocate_new_kernel_size: ++ .long relocate_new_kernel_end - relocate_new_kernel ++ ++ +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/setup.c linux-3.4.110/arch/nds32/kernel/setup.c +--- linux-3.4.110.orig/arch/nds32/kernel/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/setup.c 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,1049 @@ ++/* ++ * linux/arch/nds32/kernel/setup.c ++ * ++ * Copyright (C) 1995-2001 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for Andes NDS32 architecture. ++ * ++ * Revision History: ++ * ++ * Jul.05.2007 Initial ported by Tom, revised and patched for KGDB ++ * by Harry. ++ * Aug.26.2008 Some reworks on CPU info output for SMP. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef MEM_SIZE ++#define MEM_SIZE CONFIG_SDRAM_SIZE ++#endif ++ ++#ifndef RAMDISK_SIZE ++#define RAMDISK_SIZE CONFIG_BLK_DEV_RAM_SIZE ++#endif ++ ++extern void (*init_arch_irq) (void); ++ ++extern void paging_init(struct machine_desc *desc); ++extern void reboot_setup(char *str); ++extern int root_mountflags; ++extern unsigned long _stext, _text, _etext, _sdata, _edata, _end; ++extern unsigned int ag101_cpufreq_get(unsigned int dummy); ++ ++unsigned long cpu_id, cpu_rev, cpu_cfgid; ++char *endianness = NULL; ++ ++unsigned int __machine_arch_type; ++EXPORT_SYMBOL(__machine_arch_type); ++ ++unsigned int elf_hwcap; ++EXPORT_SYMBOL(elf_hwcap); ++ ++unsigned char aux_device_present; ++ ++char elf_platform[ELF_PLATFORM_SIZE]; ++EXPORT_SYMBOL(elf_platform); ++ ++unsigned long phys_initrd_start __initdata = 0; ++unsigned long phys_initrd_size __initdata = 0; ++ ++static struct meminfo meminfo __initdata = { 0, }; ++ ++static const char *machine_name; ++static struct proc_info_item proc_info; ++static char command_line[COMMAND_LINE_SIZE]; ++ ++struct machine_desc *machine_desc __initdata; ++ ++static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; ++ ++DEFINE_PER_CPU(struct cpuinfo_nds32, cpu_data); ++ ++/* ++ * Standard memory resources ++ */ ++static struct resource mem_res[] = { ++ { ++ .name = "Video RAM", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_MEM}, ++ { ++ .name = "Kernel text", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_MEM}, ++ { ++ .name = "Kernel data", ++ .start = 0, ++ .end = 0, ++ .flags = IORESOURCE_MEM} ++}; ++ ++#define video_ram mem_res[0] ++#define kernel_code mem_res[1] ++#define kernel_data mem_res[2] ++ ++static struct resource io_res[] = { ++ { ++ .name = "reserved", ++ .start = 0x3bc, ++ .end = 0x3be, ++ .flags = IORESOURCE_IO | IORESOURCE_BUSY}, ++ { ++ .name = "reserved", ++ .start = 0x378, ++ .end = 0x37f, ++ .flags = IORESOURCE_IO | IORESOURCE_BUSY}, ++ { ++ .name = "reserved", ++ .start = 0x278, ++ .end = 0x27f, ++ .flags = IORESOURCE_IO | IORESOURCE_BUSY} ++}; ++ ++#define lp0 io_res[0] ++#define lp1 io_res[1] ++#define lp2 io_res[2] ++ ++/* ++ * The following string table, must sync with HWCAP_xx bitmask, ++ * which is defined in ++ */ ++static const char *hwcap_str[] = { ++ "mfusr_pc", ++ "perf1", ++ "perf2", ++ "fpu", ++ "audio", ++ "16b", ++ "string", ++ "reduced_regs", ++ "video", ++ "encrypt", ++ "edm", ++ "lmdma", ++ "pfm", ++ "hsmp", ++ "trace", ++ "div", ++ "mac", ++ "l2c", ++ "dx_regs", ++ "v2", ++ NULL, ++}; ++ ++static void __init squash_mem_tags(struct tag *tag) ++{ ++ for (; tag->hdr.size; tag = tag_next(tag)) ++ if (tag->hdr.tag == ATAG_MEM) ++ tag->hdr.tag = ATAG_NONE; ++} ++ ++struct cache_info L1_cache_info[2]; ++ ++static void __init dump_cpu_info(int cpu) ++{ ++ int i = 0, aliasing_num; ++#ifdef CONFIG_CACHE_L2 ++ unsigned long l2set, l2way, l2clsz; ++#endif ++ printk("CPU%d Features: ", cpu); ++ ++ for (i = 0; hwcap_str[i]; i++) { ++ if (elf_hwcap & (1 << i)) ++ printk("%s ", hwcap_str[i]); ++ } ++ ++ printk("\n"); ++ ++ L1_cache_info[ICACHE].cache_type = ICACHE; ++ L1_cache_info[ICACHE].ways = CACHE_WAY(ICACHE); ++ L1_cache_info[ICACHE].way_bits = ilog2(CACHE_WAY(ICACHE)); ++ L1_cache_info[ICACHE].line_size = CACHE_LINE_SIZE(ICACHE); ++ L1_cache_info[ICACHE].line_bits = ilog2(CACHE_LINE_SIZE(ICACHE)); ++ L1_cache_info[ICACHE].sets = CACHE_SET(ICACHE); ++ L1_cache_info[ICACHE].set_bits = ilog2(CACHE_SET(ICACHE)); ++ L1_cache_info[ICACHE].size = ++ CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) * CACHE_LINE_SIZE(ICACHE) / ++ 1024; ++ printk("L1I:%dKB/%dS/%dW/%dB\n", L1_cache_info[ICACHE].size, ++ L1_cache_info[ICACHE].sets, L1_cache_info[ICACHE].ways, ++ L1_cache_info[ICACHE].line_size); ++ aliasing_num = ++ L1_cache_info[ICACHE].size * 1024 / PAGE_SIZE / ++ L1_cache_info[ICACHE].ways; ++ if (aliasing_num & 1 && aliasing_num != 1) ++ printk ++ ("%s: not alising:%d, it should be multiple of 2 if it ia aliasing cache.\n", ++ __func__, aliasing_num); ++ L1_cache_info[ICACHE].aliasing_num = aliasing_num; ++ L1_cache_info[ICACHE].aliasing_mask = (aliasing_num - 1) << PAGE_SHIFT; ++ L1_cache_info[ICACHE].not_aliasing_mask = ++ ~L1_cache_info[ICACHE].aliasing_mask; ++ L1_cache_info[DCACHE].cache_type = DCACHE; ++ L1_cache_info[DCACHE].ways = CACHE_WAY(DCACHE); ++ L1_cache_info[DCACHE].way_bits = ilog2(CACHE_WAY(DCACHE)); ++ L1_cache_info[DCACHE].line_size = CACHE_LINE_SIZE(DCACHE); ++ L1_cache_info[DCACHE].line_bits = ilog2(CACHE_LINE_SIZE(DCACHE)); ++ L1_cache_info[DCACHE].sets = CACHE_SET(DCACHE); ++ L1_cache_info[DCACHE].set_bits = ilog2(CACHE_SET(DCACHE)); ++ L1_cache_info[DCACHE].size = ++ CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) * CACHE_LINE_SIZE(DCACHE) / ++ 1024; ++ printk("L1D:%dKB/%dS/%dW/%dB\n", L1_cache_info[DCACHE].size, ++ L1_cache_info[DCACHE].sets, L1_cache_info[DCACHE].ways, ++ L1_cache_info[DCACHE].line_size); ++ aliasing_num = ++ L1_cache_info[DCACHE].size * 1024 / PAGE_SIZE / ++ L1_cache_info[DCACHE].ways; ++#ifdef CONFIG_HIGHMEM ++ if (aliasing_num > 1 && CONFIG_HIGHMEM) ++ WARN(1, ++ "%s: HIGHMEM is not supported for alising VIPT cache. aliasing_num:%d\n", ++ __func__, aliasing_num); ++#else ++ if (aliasing_num & 1 && aliasing_num != 1) ++ printk ++ ("%s: not alising:%d, it should be multiple of 2 if it ia aliasing cache.\n", ++ __func__, aliasing_num); ++#endif ++ L1_cache_info[DCACHE].aliasing_num = aliasing_num; ++ L1_cache_info[DCACHE].aliasing_mask = (aliasing_num - 1) << PAGE_SHIFT; ++ L1_cache_info[DCACHE].not_aliasing_mask = ++ ~L1_cache_info[DCACHE].aliasing_mask; ++#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH ++ printk("L1 D-Cache is WRITE-THROUGH\n"); ++#else ++ printk("L1 D-Cache is WRITE-BACK\n"); ++#endif ++ ++ ++#ifdef CONFIG_CACHE_L2 ++ /* Here translation is on but I/O address is not mapped yet. */ ++ SET_PSW(GET_PSW() & ~PSW_mskDT); ++ DSB(); ++ l2set = ++ 64 << ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> ++ L2_CA_CONF_offL2SET); ++ l2way = ++ 1 + ++ ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> ++ L2_CA_CONF_offL2WAY); ++ l2clsz = ++ 4 << ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> ++ L2_CA_CONF_offL2CLSZ); ++ SET_PSW(GET_PSW() | PSW_mskDT); ++ DSB(); ++ ++ printk("L2:%luKB/%luS/%luW/%luB\n", ++ l2set * l2way * l2clsz / 1024, l2set, l2way, l2clsz); ++#endif ++#ifdef CONFIG_FPU ++ /* Disable fpu and enable when it is used. */ ++ disable_fpu(); ++ printk("FPU is able to use.\n"); ++#endif ++} ++ ++static void __init setup_processor(void) ++{ ++ unsigned long tmp = 0; ++ struct proc_info_list *list; ++ extern struct proc_info_list __proc_info_begin, __proc_info_end; ++ ++ register unsigned coreid = GET_CPU_VER(); ++ for (list = &__proc_info_begin; list < &__proc_info_end; list++) ++// if (list->cpu_val == (GET_CPU_VER() & CPU_VER_mskCPUID)) ++ if (list->cpu_val == (coreid & list->cpu_mask)) ++ break; ++ /* ++ * If the architecture type is not recognised, then we ++ * can co nothing... ++ */ ++ if (list >= &__proc_info_end) { ++ printk ++ ("Processor configuration botched (CPU_VER 0x%lx), unable to continue.\n", ++ GET_CPU_VER()); ++ while (1) ; ++ } ++ ++ proc_info = *list->info; ++ ++ cpu_dcache_inval_all(); // XXX head.S turn $$ on, need change. ++ cpu_icache_inval_all(); ++ DSB(); ++ ISB(); ++ ++ cpu_id = GET_CPU_ID(); ++ cpu_rev = GET_CPU_REV(); ++ cpu_cfgid = GET_CPU_CFGID(); ++ ++ printk("CPU: %s, %s %s, CPU_VER 0x%08lx(id %lu, rev %lu, cfg %lu)\n", ++ list->arch_name, ++ proc_info.manufacturer, proc_info.cpu_name, ++ GET_CPU_VER(), cpu_id, cpu_rev, cpu_cfgid); ++ ++ elf_hwcap |= HWCAP_MFUSR_PC; ++ ++ if (((GET_MSC_CFG() & MSC_CFG_mskBASEV) >> MSC_CFG_offBASEV) == 0) { ++ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) ++ elf_hwcap &= ~HWCAP_MFUSR_PC; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskDIV) ++ elf_hwcap |= HWCAP_DIV; ++ ++ if ((GET_MSC_CFG() & MSC_CFG_mskMAC) ++ || (cpu_id == 12 && cpu_rev < 4)) ++ elf_hwcap |= HWCAP_MAC; ++ } else { ++ elf_hwcap |= HWCAP_V2; ++ elf_hwcap |= HWCAP_DIV; ++ elf_hwcap |= HWCAP_MAC; ++ } ++ ++ if (cpu_cfgid & 0x0001) ++ elf_hwcap |= HWCAP_EXT; ++ ++ if (cpu_cfgid & 0x0002) ++ elf_hwcap |= HWCAP_BASE16; ++ ++ if (cpu_cfgid & 0x0004) ++ elf_hwcap |= HWCAP_EXT2; ++ ++ if (cpu_cfgid & 0x0008) ++ elf_hwcap |= HWCAP_FPU; ++ ++ if (cpu_cfgid & 0x0010) ++ elf_hwcap |= HWCAP_STRING; ++ ++ if (GET_MMU_CFG() & MMU_CFG_mskDE) ++ endianness = "MSB"; ++ else ++ endianness = "LSB"; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskEDM) ++ elf_hwcap |= HWCAP_EDM; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskLMDMA) ++ elf_hwcap |= HWCAP_LMDMA; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskPFM) ++ elf_hwcap |= HWCAP_PFM; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskHSMP) ++ elf_hwcap |= HWCAP_HSMP; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskTRACE) ++ elf_hwcap |= HWCAP_TRACE; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskAUDIO) ++ elf_hwcap |= HWCAP_AUDIO; ++ ++ if (GET_MSC_CFG() & MSC_CFG_mskL2C) ++ elf_hwcap |= HWCAP_L2C; ++ ++#ifdef CONFIG_ANDES_PAGE_SIZE_4KB ++ if (CPU_IS_N1213_43U1HA0()) { ++ /* ++ * Downsize dcache to bypass N1213-43u1h inconsistent ++ * use of PA and VA in fill-buffer logic issue. ++ */ ++ ++ if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096) ++ tmp |= 0x02 << SDZ_CTL_offDCDZ; ++ ++ if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096) ++ tmp |= 0x02 << SDZ_CTL_offICDZ; ++ ++ SET_SDZ_CTL(tmp); ++ ISB(); ++ printk("CPU%i enabled dcache downsizing to half set/4-way.\n", ++ smp_processor_id()); ++ } ++#endif /* CONFIG_ANDES_PAGE_SIZE_4KB */ ++ ++#ifdef CONFIG_CACHE_L2 ++#ifdef CONFIG_PLAT_AG102 ++ SET_HSMP_SADDR((CPU_MEM_PA_BASE & HSMP_SADDR_mskSADDR) | ++ (0xC00 << HSMP_SADDR_offRANGE) | HSMP_SADDR_mskEN); ++#endif ++ ++ /* Here translation is on but I/O address is not mapped yet. */ ++ SET_PSW(GET_PSW() & ~PSW_mskDT); ++ DSB(); ++ ++ /* This is the time when we enable L2$. */ ++ /* All masters can't write another master register */ ++ tmp = inl(L2CC_PA_BASE + L2CC_PROT_OFF); ++ tmp &= ~L2CC_PROT_mskMRWEN; ++ outl(tmp, L2CC_PA_BASE + L2CC_PROT_OFF); ++ ++ /* All masters share the whole cache memory space */ ++ tmp = inl(L2CC_PA_BASE + L2CC_SETUP_OFF); ++ tmp &= ~L2CC_SETUP_mskPART; ++ outl(tmp, L2CC_PA_BASE + L2CC_SETUP_OFF); ++ ++ /* each master access self master, does not add master base */ ++ tmp = inl(L2CC_PA_BASE + L2CC_CTRL_OFF); ++ tmp |= L2CC_CTRL_mskEN; ++ outl(tmp, L2CC_PA_BASE + L2CC_CTRL_OFF); ++ ++ SET_PSW(GET_PSW() | PSW_mskDT); ++ ISB(); ++#endif ++ tmp = GET_CACHE_CTL(); ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ tmp |= CACHE_CTL_mskDC_EN; ++#endif ++ ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ tmp |= CACHE_CTL_mskIC_EN; ++#endif ++ SET_CACHE_CTL(tmp); ++ DSB(); ++ ISB(); ++ ++ sprintf(elf_platform, "%s %s", list->elf_name, endianness); ++ ++ dump_cpu_info(smp_processor_id()); ++} ++ ++static struct machine_desc *__init setup_machine(unsigned int nr) ++{ ++ struct machine_desc *list; ++ ++ extern struct machine_desc __arch_info_begin, __arch_info_end; ++ /* ++ * locate machine in the list of supported machines. ++ */ ++ for (list = &__arch_info_begin; list < &__arch_info_end; list++) ++ if (list->nr == nr) ++ break; ++ /* ++ * If the architecture type is not recognised, then we ++ * can co nothing... ++ */ ++ if (list >= &__arch_info_end) { ++ printk("Architecture configuration botched (nr 0x%x), unable " ++ "to continue.\n", nr); ++ while (1) ; ++ } ++ ++ printk(KERN_INFO "Machine: %s\n", list->name); ++ ++ return list; ++} ++ ++static void __init early_initrd(char **p) ++{ ++ unsigned long start, size; ++ ++ start = memparse(*p, p); ++ if (**p == ',') { ++ size = memparse((*p) + 1, p); ++ ++ phys_initrd_start = start; //pa ++ phys_initrd_size = size; ++ } ++ printk(KERN_INFO ++ "phys_initrd_start at 0x%08lx, phys_initrd_size:0x%08lx\n", ++ phys_initrd_start, phys_initrd_size); ++ //memblock_reserve(phys_initrd_start, phys_initrd_size); ++} ++ ++__early_param("initrd=", early_initrd); ++ ++/* ++ * Pick out the memory size. We look for mem=size@start, ++ * where start and size are "size[KkMm]" ++ */ ++static void __init early_mem(char **p) ++{ ++ static int usermem __initdata = 0; ++ unsigned long size, start; ++ ++ /* ++ * If the user specifies memory size, we ++ * blow away any automatically generated ++ * size. ++ */ ++ if (usermem == 0) { ++ usermem = 1; ++ meminfo.nr_banks = 0; ++ } ++ ++ start = PHYS_OFFSET; //Tom 0x0 ++ size = memparse(*p, p); ++ if (**p == '@') ++ start = memparse(*p + 1, p); ++ ++ meminfo.bank[meminfo.nr_banks].start = start; ++ meminfo.bank[meminfo.nr_banks].size = size; ++ meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start); ++ memblock_add_node(meminfo.bank[meminfo.nr_banks].start, ++ meminfo.bank[meminfo.nr_banks].size, 0); ++ meminfo.nr_banks += 1; ++ ++} ++ ++__early_param("mem=", early_mem); ++ ++/* ++ * Initial parsing of the command line. ++ */ ++void __init parse_cmdline(char **cmdline_p, char *from) ++{ ++ char c = ' ', *to = command_line; ++ int len = 0; ++ ++ for (;;) { ++ if (c == ' ') { ++ extern struct early_params __early_begin, __early_end; ++ struct early_params *p; ++ ++ for (p = &__early_begin; p < &__early_end; p++) { ++ int len = strlen(p->arg); ++ ++ if (memcmp(from, p->arg, len) == 0) { ++ if (to != command_line) ++ to -= 1; ++ from += len; ++ p->fn(&from); ++ ++ while (*from != ' ' && *from != '\0') ++ from++; ++ break; ++ } ++ } ++ } ++ c = *from++; ++ if (!c) ++ break; ++ if (COMMAND_LINE_SIZE <= ++len) ++ break; ++ *to++ = c; ++ } ++ *to = '\0'; ++ *cmdline_p = command_line; ++} ++ ++static void __init ++setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) ++{ ++#ifdef CONFIG_BLK_DEV_RAM ++ extern int rd_size, rd_image_start, rd_prompt, rd_doload; ++ ++ rd_image_start = image_start; ++ rd_prompt = prompt; ++ rd_doload = doload; ++ ++ if (rd_sz) ++ rd_size = rd_sz; ++#endif ++} ++ ++static void __init ++request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) ++{ ++ struct resource *res; ++ int i; ++ ++ kernel_code.start = virt_to_phys(&_text); ++ kernel_code.end = virt_to_phys(&_etext - 1); ++ kernel_data.start = virt_to_phys(&_sdata); ++ kernel_data.end = virt_to_phys(&_end - 1); ++ ++ for (i = 0; i < mi->nr_banks; i++) { ++ unsigned long virt_start, virt_end; ++ ++ if (mi->bank[i].size == 0) ++ continue; ++ ++ virt_start = __phys_to_virt(mi->bank[i].start); ++ virt_end = virt_start + mi->bank[i].size - 1; ++ ++ res = alloc_bootmem_low(sizeof(*res)); ++ res->name = "System RAM"; ++ res->start = __virt_to_phys(virt_start); ++ res->end = __virt_to_phys(virt_end); ++ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; ++ ++ request_resource(&iomem_resource, res); ++ ++ if (kernel_code.start >= res->start && ++ kernel_code.end <= res->end) ++ request_resource(res, &kernel_code); ++ if (kernel_data.start >= res->start && ++ kernel_data.end <= res->end) ++ request_resource(res, &kernel_data); ++ } ++ ++ if (mdesc->video_start) { ++ video_ram.start = mdesc->video_start; ++ video_ram.end = mdesc->video_end; ++ request_resource(&iomem_resource, &video_ram); ++ } ++ ++ /* ++ * Some machines don't have the possibility of ever ++ * possessing lp0, lp1 or lp2 ++ */ ++ if (mdesc->reserve_lp0) ++ request_resource(&ioport_resource, &lp0); ++ if (mdesc->reserve_lp1) ++ request_resource(&ioport_resource, &lp1); ++ if (mdesc->reserve_lp2) ++ request_resource(&ioport_resource, &lp2); ++} ++ ++/* ++ * Tag parsing. ++ * ++ * This is the new way of passing data to the kernel at boot time. Rather ++ * than passing a fixed inflexible structure to the kernel, we pass a list ++ * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE ++ * tag for the list to be recognised (to distinguish the tagged list from ++ * a param_struct). The list is terminated with a zero-length tag (this tag ++ * is not parsed in any way). ++ */ ++//flag bit 0 = read-only ++static int __init parse_tag_core(const struct tag *tag) ++{ ++ if (tag->hdr.size > 2) { ++ if ((tag->u.core.flags & 1) == 0) ++ root_mountflags &= ~MS_RDONLY; ++ ROOT_DEV = old_decode_dev(tag->u.core.rootdev); ++ } ++ return 0; ++} ++ ++__tagtable(ATAG_CORE, parse_tag_core); ++ ++static int __init parse_tag_mem32(const struct tag *tag) ++{ ++ if (meminfo.nr_banks >= NR_BANKS) { ++ printk(KERN_WARNING ++ "Ignoring memory bank 0x%08x size %dKB\n", ++ tag->u.mem.start, tag->u.mem.size / 1024); ++ return -EINVAL; ++ } ++ meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start; ++ meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size; ++ memblock_add_node(meminfo.bank[meminfo.nr_banks].start, ++ meminfo.bank[meminfo.nr_banks].size, 0); ++ meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start); ++ meminfo.nr_banks += 1; ++ ++ return 0; ++} ++ ++__tagtable(ATAG_MEM, parse_tag_mem32); ++ ++#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) ++struct screen_info screen_info = { ++ .orig_video_lines = 30, ++ .orig_video_cols = 80, ++ .orig_video_mode = 0, ++ .orig_video_ega_bx = 0, ++ .orig_video_isVGA = 1, ++ .orig_video_points = 8 ++}; ++ ++static int __init parse_tag_videotext(const struct tag *tag) ++{ ++ screen_info.orig_x = tag->u.videotext.x; ++ screen_info.orig_y = tag->u.videotext.y; ++ screen_info.orig_video_page = tag->u.videotext.video_page; ++ screen_info.orig_video_mode = tag->u.videotext.video_mode; ++ screen_info.orig_video_cols = tag->u.videotext.video_cols; ++ screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; ++ screen_info.orig_video_lines = tag->u.videotext.video_lines; ++ screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; ++ screen_info.orig_video_points = tag->u.videotext.video_points; ++ return 0; ++} ++ ++__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); ++#endif ++ ++static int __init parse_tag_ramdisk(const struct tag *tag) ++{ ++ setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, ++ (tag->u.ramdisk.flags & 2) == 0, ++ tag->u.ramdisk.start, tag->u.ramdisk.size); ++ return 0; ++} ++ ++__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); ++ ++static int __init parse_tag_initrd(const struct tag *tag) ++{ ++ printk(KERN_WARNING "ATAG_INITRD is deprecated; " ++ "please update your bootloader.\n"); ++ phys_initrd_start = __virt_to_phys(tag->u.initrd.start); ++ phys_initrd_size = tag->u.initrd.size; ++ return 0; ++} ++ ++__tagtable(ATAG_INITRD, parse_tag_initrd); ++ ++static int __init parse_tag_initrd2(const struct tag *tag) ++{ ++ phys_initrd_start = tag->u.initrd.start; ++ phys_initrd_size = tag->u.initrd.size; ++ return 0; ++} ++ ++__tagtable(ATAG_INITRD2, parse_tag_initrd2); ++ ++static int __init parse_tag_revision(const struct tag *tag) ++{ ++ return 0; ++} ++ ++__tagtable(ATAG_REVISION, parse_tag_revision); ++ ++static int __init parse_tag_cmdline(const struct tag *tag) ++{ ++ strlcpy(default_command_line, tag->u.cmdline.cmdline, ++ COMMAND_LINE_SIZE); ++ return 0; ++} ++ ++__tagtable(ATAG_CMDLINE, parse_tag_cmdline); ++ ++/* ++ * Scan the tag table for this tag, and call its parse function. ++ * The tag table is built by the linker from all the __tagtable ++ * declarations. ++ */ ++static int __init parse_tag(const struct tag *tag) ++{ ++ extern struct tagtable __tagtable_begin, __tagtable_end; ++ struct tagtable *t; ++ ++ for (t = &__tagtable_begin; t < &__tagtable_end; t++) ++ if (tag->hdr.tag == t->tag) { ++ t->parse(tag); ++ break; ++ } ++ ++ return t < &__tagtable_end; ++} ++ ++/* ++ * Parse all tags in the list, checking both the global and architecture ++ * specific tag tables. ++ */ ++static void __init parse_tags(const struct tag *t) ++{ ++ for (; t->hdr.size; t = tag_next(t)) ++ if (!parse_tag(t)) ++ printk(KERN_WARNING ++ "Ignoring unrecognised tag 0x%08x\n", ++ t->hdr.tag); ++} ++ ++/* ++ * This holds our defaults. ++ */ ++static struct init_tags { ++ struct tag_header hdr1; ++ struct tag_core core; ++ struct tag_header hdr2; ++ struct tag_mem32 mem; ++ struct tag_header hdr3; ++} init_tags __initdata = { ++ {tag_size(tag_core), ATAG_CORE}, //hdr1 ++ {0, PAGE_SIZE, 0xff}, ++ {tag_size(tag_mem32), ATAG_MEM}, //hdr2 ++ {MEM_SIZE, PHYS_OFFSET}, ++ {0, ATAG_NONE} ++}; ++ ++static unsigned long __init setup_memory(void) ++{ ++ unsigned long bootmap_size; ++ unsigned long ram_start_pfn; ++ unsigned long free_ram_start_pfn; ++ phys_addr_t memory_start, memory_end; ++ struct memblock_region *region; ++ ++ memory_end = memory_start = 0; ++ ++ /* Find main memory where is the kernel */ ++ for_each_memblock(memory, region) { ++ memory_start = region->base; ++ memory_end = region->base + region->size; ++ printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__, ++ memory_start, memory_end); ++ } ++ ++ if (!memory_end) { ++ panic("No memory!"); ++ } ++ ++ ram_start_pfn = PFN_UP(memblock_start_of_DRAM()); ++ /* free_ram_start_pfn is first page after kernel */ ++ free_ram_start_pfn = PFN_UP(__pa(&_end)); ++ max_pfn = PFN_DOWN(memblock_end_of_DRAM()); ++ ++ /* it could update max_pfn */ ++ if (max_pfn - ram_start_pfn <= MAXMEM_PFN) ++ max_low_pfn = max_pfn; ++ else { ++ max_low_pfn = MAXMEM_PFN + ram_start_pfn; ++#ifndef CONFIG_HIGHMEM ++ max_pfn = MAXMEM_PFN + ram_start_pfn; ++#endif ++ } ++ /* high_memory is related with VMALLOC */ ++ high_memory = (void *)__va(max_low_pfn * PAGE_SIZE); ++ min_low_pfn = free_ram_start_pfn; ++ ++ /* ++ * initialize the boot-time allocator (with low memory only). ++ * ++ * This makes the memory from the end of the kernel to the end of ++ * RAM usable. ++ * init_bootmem sets the global values min_low_pfn, max_low_pfn. ++ */ ++ bootmap_size = init_bootmem_node(NODE_DATA(0), free_ram_start_pfn, ++ ram_start_pfn, max_low_pfn); ++ free_bootmem(PFN_PHYS(free_ram_start_pfn), ++ (max_low_pfn - free_ram_start_pfn) << PAGE_SHIFT); ++ reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size, ++ BOOTMEM_DEFAULT); ++ ++ for_each_memblock(reserved, region) { ++ if (region->size != 0) { ++ printk(KERN_INFO "Reserved - 0x%08x-0x%08x\n", ++ (u32) region->base, (u32) region->size); ++ reserve_bootmem(region->base, region->size, ++ BOOTMEM_DEFAULT); ++ } ++ } ++ return max_low_pfn; ++} ++ ++void __init setup_arch(char **cmdline_p) ++{ ++ struct tag *tags = (struct tag *)&init_tags; ++ struct machine_desc *mdesc; ++ char *from = default_command_line; ++ ++ setup_processor(); ++ mdesc = setup_machine(machine_arch_type); ++ machine_desc = mdesc; ++ machine_name = mdesc->name; ++ ++ if (mdesc->soft_reboot) ++ reboot_setup("s"); ++ ++ if (mdesc->param_offset) ++ tags = phys_to_virt(mdesc->param_offset); ++ ++ if (tags->hdr.tag != ATAG_CORE) ++ tags = (struct tag *)&init_tags; ++ ++ if (tags->hdr.tag == ATAG_CORE) { ++ if (meminfo.nr_banks != 0) ++ squash_mem_tags(tags); ++ parse_tags(tags); ++ } ++ ++ init_mm.start_code = (unsigned long)&_text; ++ init_mm.end_code = (unsigned long)&_etext; ++ init_mm.end_data = (unsigned long)&_edata; ++ init_mm.brk = (unsigned long)&_end; ++ ++ memcpy(boot_command_line, from, COMMAND_LINE_SIZE); ++ boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; ++ parse_cmdline(cmdline_p, from); ++ ++ /* use generic way to parse */ ++ parse_early_param(); ++ ++ /* setup bootmem allocator */ ++ setup_memory(); ++ ++ strlcpy(command_line, from, COMMAND_LINE_SIZE); ++ *cmdline_p = command_line; ++ ++ paging_init(mdesc); ++ request_standard_resources(&meminfo, mdesc); //- for test only ++ ++#ifdef CONFIG_SMP ++ smp_init_cpus(); ++#endif ++ ++ /* ++ * Set up various architecture-specific pointers ++ */ ++ init_arch_irq = mdesc->init_irq; ++ system_timer = mdesc->timer; ++ if (mdesc->init_machine) ++ mdesc->init_machine(); ++ ++#if defined(CONFIG_VT) ++#if defined(CONFIG_VGA_CONSOLE) ++ conswitchp = &vga_con; ++#elif defined(CONFIG_DUMMY_CONSOLE) ++ conswitchp = &dummy_con; //+ Tom: we will reach here ++#endif ++#endif ++ ++ early_trap_init(); ++} ++ ++/* ++ * cpu_init - initialise one CPU. ++ * ++ * cpu_init dumps the cache information, initialises SMP specific ++ * information. ++ */ ++ ++void __init cpu_init(void) ++{ ++ unsigned int cpu = smp_processor_id(), tmp = 0; ++ ++ if (cpu >= NR_CPUS) { ++ printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); ++ BUG(); ++ } ++ ++ if (system_state == SYSTEM_BOOTING) ++ dump_cpu_info(cpu); ++ ++ tmp = 1 << IVB_offESZ; ++#ifdef CONFIG_EVIC ++ tmp |= 1 << IVB_offEVIC; ++#endif ++ SET_IVB(tmp | IVB_BASE); ++ tmp = 0x10003; ++ SET_INT_MASK(tmp); ++ ISB(); ++} ++ ++static int __init topology_init(void) ++{ ++ int cpu; ++ ++ for_each_possible_cpu(cpu) ++ register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); ++ ++ return 0; ++} ++ ++subsys_initcall(topology_init); ++ ++static int c_show(struct seq_file *m, void *v) ++{ ++ int i; ++ ++ seq_printf(m, "Processor\t: %s %s (id %lu, rev %lu, cfg %lu)\n", ++ proc_info.manufacturer, proc_info.cpu_name, ++ cpu_id, cpu_rev, cpu_cfgid); ++#if defined(CONFIG_AG101_CPU_FREQ_SCALING_MODE) || defined(CONFIG_AG101_CPU_FREQ_FCS) ++ seq_printf(m, "MHz\t\t: %u\n", ag101_cpufreq_get(1) / 1000); ++#endif ++ ++ seq_printf(m, "L1I\t\t: %luKB/%luS/%luW/%luB\n", ++ CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) * ++ CACHE_LINE_SIZE(ICACHE) / 1024, CACHE_SET(ICACHE), ++ CACHE_WAY(ICACHE), CACHE_LINE_SIZE(ICACHE)); ++ ++ seq_printf(m, "L1D\t\t: %luKB/%luS/%luW/%luB\n", ++ CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) * ++ CACHE_LINE_SIZE(DCACHE) / 1024, CACHE_SET(DCACHE), ++ CACHE_WAY(DCACHE), CACHE_LINE_SIZE(DCACHE)); ++ ++#if defined(CONFIG_SMP) ++ for_each_online_cpu(i) { ++ seq_printf(m, "Processor\t: %d\n", i); ++ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", ++ per_cpu(cpu_data, ++ i).loops_per_jiffy / (500000UL / HZ), ++ (per_cpu(cpu_data, i).loops_per_jiffy / ++ (5000UL / HZ)) % 100); ++ } ++#else /* CONFIG_SMP */ ++ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", ++ loops_per_jiffy / (500000 / HZ), ++ (loops_per_jiffy / (5000 / HZ)) % 100); ++#endif ++ ++ /* dump out the processor features */ ++ seq_puts(m, "Features\t: "); ++ ++ for (i = 0; hwcap_str[i]; i++) ++ if (elf_hwcap & (1 << i)) ++ seq_printf(m, "%s ", hwcap_str[i]); ++ ++ seq_puts(m, "\n\n"); ++ seq_printf(m, "Hardware\t: %s\n", elf_platform); ++ ++ return 0; ++} ++ ++static void *c_start(struct seq_file *m, loff_t * pos) ++{ ++ return *pos < 1 ? (void *)1 : NULL; ++} ++ ++static void *c_next(struct seq_file *m, void *v, loff_t * pos) ++{ ++ ++*pos; ++ return NULL; ++} ++ ++static void c_stop(struct seq_file *m, void *v) ++{ ++} ++ ++struct seq_operations cpuinfo_op = { ++ .start = c_start, ++ .next = c_next, ++ .stop = c_stop, ++ .show = c_show ++}; +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/signal.c linux-3.4.110/arch/nds32/kernel/signal.c +--- linux-3.4.110.orig/arch/nds32/kernel/signal.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/signal.c 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,850 @@ ++/* ++ * linux/arch/nds32/kernel/signal.c ++ * ++ * Copyright (C) 1995-2002 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "ptrace.h" ++#include "signal.h" ++#include "fpu.h" ++#include "audio.h" ++ ++#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) ++ ++/* ++ * For NDS32 syscalls, we encode the syscall number into the instruction. ++ */ ++#if defined( __NDS32_EL__) ++#define SWI_SYS_SIGRETURN (0xeb0e0a64) ++#define SWI_SYS_RT_SIGRETURN (0xab150a64) ++#define SWI_SYS_RESTART (0x0b000a64) /* syscall __NR_restart_syscall */ ++#define SWI_SYS_RESTART_LWIBI (0x0180af0d) /* lwi.bi $p0, [$sp], 4 */ ++#define SWI_SYS_RESTART_JRP0 (0x0068004a) /* jr $p0 */ ++#elif defined(__NDS32_EB__) ++#define SWI_SYS_SIGRETURN (0x6400000b|(__NR_sigreturn<<5)) ++#define SWI_SYS_RT_SIGRETURN (0x6400000b|(__NR_rt_sigreturn<<5)) ++#define SWI_SYS_RESTART (0x640a000b) /* syscall __NR_restart_syscall */ ++#define SWI_SYS_RESTART_LWIBI (0x0daf8001) /* lwi.bi $p0, [$sp], 4 */ ++#define SWI_SYS_RESTART_JRP0 (0x4a006800) /* jr $p0 */ ++#else ++#error "NDS32, but neither __NDS32_EB__, nor __NDS32_EL__???" ++#endif ++ ++#ifdef CONFIG_FPU ++static struct fpu_struct init_fpuregs = { ++ .fs_regs = {[0 ... 31] = sNAN32}, ++ .fd_regs = {[0 ... 15] = sNAN64}, ++ .fpcsr = FPCSR_INIT ++}; ++#endif ++#ifdef CONFIG_AUDIO ++static struct audio_struct init_audioregs = { ++ .auregs = {[0...31] = NAN32} ++}; ++#endif ++const unsigned long retcodes[2] = { ++ SWI_SYS_SIGRETURN, ++ SWI_SYS_RT_SIGRETURN ++}; ++ ++const unsigned long syscall_restart_code[3] = { ++ SWI_SYS_RESTART, /* syscall __NR_restart_syscall */ ++ SWI_SYS_RESTART_LWIBI, /* lwi.bi $p0, [$sp], 4 */ ++ SWI_SYS_RESTART_JRP0 /* jr $p0 */ ++}; ++ ++static int do_signal(sigset_t * oldset, struct pt_regs *regs, int syscall); ++ ++/* ++ * atomically swap in the new signal mask, and wait for a signal. ++ */ ++asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, ++ old_sigset_t mask, struct pt_regs *regs) ++{ ++ sigset_t blocked; ++ ++ mask &= _BLOCKABLE; ++ current->saved_sigmask = current->blocked; ++ siginitset(&blocked, mask); ++ set_current_blocked(&blocked); ++ ++ current->state = TASK_INTERRUPTIBLE; ++ schedule(); ++ set_thread_flag(TIF_RESTORE_SIGMASK); ++ return -ERESTARTNOHAND; ++} ++ ++asmlinkage int sys_rt_sigsuspend(sigset_t __user * unewset, size_t sigsetsize, ++ struct pt_regs *regs) ++{ ++ sigset_t newset; ++ ++ /* XXX: Don't preclude handling different sized sigset_t's. */ ++ if (sigsetsize != sizeof(sigset_t)) ++ return -EINVAL; ++ ++ if (copy_from_user(&newset, unewset, sizeof(newset))) ++ return -EFAULT; ++ sigdelsetmask(&newset, ~_BLOCKABLE); ++ current->saved_sigmask = current->blocked; ++ set_current_blocked(&newset); ++ current->state = TASK_INTERRUPTIBLE; ++ schedule(); ++ set_thread_flag(TIF_RESTORE_SIGMASK); ++ return -ERESTARTNOHAND; ++} ++ ++asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user * act, ++ struct old_sigaction __user * oact) ++{ ++ struct k_sigaction new_ka, old_ka; ++ int ret; ++ ++ if (act) { ++ old_sigset_t mask; ++ if (!access_ok(VERIFY_READ, act, sizeof(*act)) || ++ __get_user(new_ka.sa.sa_handler, &act->sa_handler) || ++ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) { ++ ++ return -EFAULT; ++ } ++ __get_user(new_ka.sa.sa_flags, &act->sa_flags); ++ __get_user(mask, &act->sa_mask); ++ ++ siginitset(&new_ka.sa.sa_mask, mask); ++ } ++ ++ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); ++ ++ if (!ret && oact) { ++ ++ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || ++ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || ++ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) { ++ ++ return -EFAULT; ++ } ++ __put_user(old_ka.sa.sa_flags, &oact->sa_flags); ++ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); ++ } ++ ++ return ret; ++} ++ ++/* ++ * Auxiliary signal frame. This saves stuff like FP state. ++ * The layout of this structure is not part of the user ABI. ++ */ ++struct aux_sigframe { ++}; ++ ++/* ++ * Do a signal return; undo the signal stack. These are aligned to 64-bit. ++ */ ++struct sigframe { ++ struct sigcontext sc; ++ unsigned long extramask[_NSIG_WORDS - 1]; ++ unsigned long retcode; ++ struct aux_sigframe aux __attribute__ ((aligned(8))); ++}; ++ ++struct rt_sigframe { ++ struct siginfo __user *pinfo; ++ void __user *puc; ++ struct siginfo info; ++ struct ucontext uc; ++ unsigned long retcode; ++ struct aux_sigframe aux __attribute__ ((aligned(8))); ++}; ++ ++#ifdef CONFIG_FPU ++static inline int restore_sigcontext_fpu(struct pt_regs *regs, ++ struct sigcontext __user * sc) ++{ ++ struct task_struct *tsk = current; ++ unsigned long used_math_flag; ++ int ret = 0; ++ ++ if (!(GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) ++ return 0; ++ ++ __get_user_error(used_math_flag, &sc->used_math_flag, ret); ++ ++ if (!used_math_flag) ++ return 0; ++ ++ set_used_math(); ++ ++#ifdef CONFIG_UNLAZY_FPU ++ clear_fpu(regs); ++#else ++ preempt_disable(); ++ if (current == last_task_used_math) { ++ last_task_used_math = NULL; ++ release_fpu(regs); ++ } ++ preempt_enable(); ++#endif ++ ++ return __copy_from_user(&tsk->thread.fpu, &sc->fpu, ++ sizeof(struct fpu_struct)); ++} ++ ++static inline int setup_sigcontext_fpu(struct pt_regs *regs, ++ struct sigcontext __user * sc) ++{ ++ struct task_struct *tsk = current; ++ int ret = 0; ++ ++ if (!(GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) ++ return 0; ++ ++ __put_user_error(used_math(), &sc->used_math_flag, ret); ++ ++ if (!used_math()) ++ return ret; ++ ++ preempt_disable(); ++#ifdef CONFIG_UNLAZY_FPU ++ unlazy_fpu(tsk); ++#else ++ if (last_task_used_math != NULL) ++ save_fpu(last_task_used_math); ++#endif ++ ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu, ++ sizeof(struct fpu_struct)); ++ ++ grab_fpu(task_pt_regs(tsk)); ++ fpload(&init_fpuregs); ++#ifndef CONFIG_UNLAZY_FPU //Lazy FPU ++ last_task_used_math = current; ++#endif ++ preempt_enable(); ++ return ret; ++} ++#else ++static inline int ++restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user * sc) ++{ ++ return 0; ++} ++ ++static inline int ++setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user * sc) ++{ ++ return 0; ++} ++#endif /* CONFIG_FPU */ ++ ++#ifdef CONFIG_AUDIO ++static inline int restore_sigcontext_audio(struct pt_regs *regs, ++ struct sigcontext __user * sc) ++{ ++ struct task_struct *tsk = current; ++ unsigned long used_audio_flag; ++ int ret = 0; ++ ++ if (!(GET_MSC_CFG() & MSC_CFG_mskAUDIO)) ++ return 0; ++ ++ __get_user_error(used_audio_flag, &sc->used_audio_flag, ret); ++ ++ if (!used_audio_flag) ++ return 0; ++ ++ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); ++#ifdef CONFIG_UNLAZY_AUDIO ++ clear_audio(regs); ++#else ++ preempt_disable(); ++ if (current == last_task_used_audio) { ++ last_task_used_audio = NULL; ++ clear_audio(regs); ++ } ++ preempt_enable(); ++#endif ++ ++ return __copy_from_user(&tsk->thread.audio, &sc->audio, ++ sizeof(struct audio_struct)); ++} ++ ++static inline int setup_sigcontext_audio(struct pt_regs *regs, ++ struct sigcontext __user * sc) ++{ ++ struct task_struct *tsk = current; ++ int ret = 0; ++ ++ if (!(GET_MSC_CFG() & MSC_CFG_mskAUDIO)) ++ return 0; ++ ++ __put_user_error(test_tsk_thread_flag(tsk, TIF_USEDAUDIO), ++ &sc->used_audio_flag, ret); ++ ++ if (!test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) ++ return ret; ++ ++ preempt_disable(); ++#ifdef CONFIG_UNLAZY_AUDIO ++ unlazy_audio(tsk); ++#else ++ if (NULL != last_task_used_audio) { ++ save_audio(tsk); ++ } ++#endif ++ ret = __copy_to_user(&sc->audio, &tsk->thread.audio, ++ sizeof(struct audio_struct)); ++ ++ grab_audio(task_pt_regs(tsk)); ++ audioload(&init_audioregs); ++#ifndef CONFIG_UNLAZY_AUDIO //Lazy audio ++ last_task_used_audio = current; ++#endif ++ preempt_enable(); ++ return ret; ++} ++#else /*CONFIG_AUDIO */ ++static inline int ++restore_sigcontext_audio(struct pt_regs *regs, struct sigcontext __user * sc) ++{ ++ return 0; ++} ++ ++static inline int ++setup_sigcontext_audio(struct pt_regs *regs, struct sigcontext __user * sc) ++{ ++ return 0; ++} ++#endif ++ ++static int restore_sigcontext(struct pt_regs *regs, ++ struct sigcontext __user * sc, ++ struct aux_sigframe __user * aux) ++{ ++ int err = 0; ++ ++ __get_user_error(regs->NDS32_r0, &sc->nds32_r0, err); ++ __get_user_error(regs->NDS32_r1, &sc->nds32_r1, err); ++ __get_user_error(regs->NDS32_r2, &sc->nds32_r2, err); ++ __get_user_error(regs->NDS32_r3, &sc->nds32_r3, err); ++ __get_user_error(regs->NDS32_r4, &sc->nds32_r4, err); ++ __get_user_error(regs->NDS32_r5, &sc->nds32_r5, err); ++ __get_user_error(regs->NDS32_r6, &sc->nds32_r6, err); ++ __get_user_error(regs->NDS32_r7, &sc->nds32_r7, err); ++ __get_user_error(regs->NDS32_r8, &sc->nds32_r8, err); ++ __get_user_error(regs->NDS32_r9, &sc->nds32_r9, err); ++ __get_user_error(regs->NDS32_r10, &sc->nds32_r10, err); ++ __get_user_error(regs->NDS32_r11, &sc->nds32_r11, err); ++ __get_user_error(regs->NDS32_r12, &sc->nds32_r12, err); ++ __get_user_error(regs->NDS32_r13, &sc->nds32_r13, err); ++ __get_user_error(regs->NDS32_r14, &sc->nds32_r14, err); ++ __get_user_error(regs->NDS32_r15, &sc->nds32_r15, err); ++ __get_user_error(regs->NDS32_r16, &sc->nds32_r16, err); ++ __get_user_error(regs->NDS32_r17, &sc->nds32_r17, err); ++ __get_user_error(regs->NDS32_r18, &sc->nds32_r18, err); ++ __get_user_error(regs->NDS32_r19, &sc->nds32_r19, err); ++ __get_user_error(regs->NDS32_r20, &sc->nds32_r20, err); ++ ++ __get_user_error(regs->NDS32_r21, &sc->nds32_r21, err); ++ __get_user_error(regs->NDS32_r22, &sc->nds32_r22, err); ++ __get_user_error(regs->NDS32_r23, &sc->nds32_r23, err); ++ __get_user_error(regs->NDS32_r24, &sc->nds32_r24, err); ++ __get_user_error(regs->NDS32_r25, &sc->nds32_r25, err); ++ __get_user_error(regs->NDS32_fp, &sc->nds32_fp, err); ++ __get_user_error(regs->NDS32_gp, &sc->nds32_gp, err); ++ __get_user_error(regs->NDS32_lp, &sc->nds32_lr, err); ++ __get_user_error(regs->NDS32_sp, &sc->nds32_sp, err); ++ ++ __get_user_error(regs->NDS32_ipc, &sc->nds32_ipc, err); ++#if defined(CONFIG_HWZOL) ++ __get_user_error(regs->NDS32_lc, &sc->zol.nds32_lc, err); ++ __get_user_error(regs->NDS32_le, &sc->zol.nds32_le, err); ++ __get_user_error(regs->NDS32_lb, &sc->zol.nds32_lb, err); ++#endif ++ ++ err |= !valid_user_regs(regs); ++ err |= restore_sigcontext_audio(regs, sc); ++ err |= restore_sigcontext_fpu(regs, sc); ++ ++ return err; ++} ++ ++asmlinkage int sys_sigreturn(struct pt_regs *regs) ++{ ++ struct sigframe __user *frame; ++ sigset_t set; ++ ++ /* Always make any pending restarted system calls return -EINTR */ ++ current_thread_info()->restart_block.fn = do_no_restart_syscall; ++ ++ /* ++ * Since we stacked the signal on a 64-bit boundary, ++ * then 'sp' should be word aligned here. If it's ++ * not, then the user is trying to mess with us. ++ */ ++ if (regs->NDS32_sp & 7) ++ goto badframe; ++ ++ frame = (struct sigframe __user *)regs->NDS32_sp; ++ ++ if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) ++ goto badframe; ++ ++ if (__get_user(set.sig[0], &frame->sc.oldmask) ++ || (_NSIG_WORDS > 1 ++ && __copy_from_user(&set.sig[1], &frame->extramask, ++ sizeof(frame->extramask)))) ++ goto badframe; ++ ++ sigdelsetmask(&set, ~_BLOCKABLE); ++ spin_lock_irq(¤t->sighand->siglock); ++ current->blocked = set; ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->sighand->siglock); ++ ++ if (restore_sigcontext(regs, &frame->sc, &frame->aux)) ++ goto badframe; ++ ++ return regs->NDS32_r0; ++ ++badframe: ++ force_sig(SIGSEGV, current); ++ return 0; ++} ++ ++asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) ++{ ++ struct rt_sigframe __user *frame; ++ sigset_t set; ++ ++ /* Always make any pending restarted system calls return -EINTR */ ++ current_thread_info()->restart_block.fn = do_no_restart_syscall; ++ ++ /* ++ * Since we stacked the signal on a 64-bit boundary, ++ * then 'sp' should be word aligned here. If it's ++ * not, then the user is trying to mess with us. ++ */ ++ if (regs->NDS32_sp & 7) ++ goto badframe; ++ ++ frame = (struct rt_sigframe __user *)regs->NDS32_sp; ++ ++ if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) ++ goto badframe; ++ ++ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) ++ goto badframe; ++ ++ sigdelsetmask(&set, ~_BLOCKABLE); ++ spin_lock_irq(¤t->sighand->siglock); ++ current->blocked = set; ++ recalc_sigpending(); ++ spin_unlock_irq(¤t->sighand->siglock); ++ ++ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux)) ++ goto badframe; ++ ++ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->NDS32_sp) == ++ -EFAULT) ++ goto badframe; ++ ++ return regs->NDS32_r0; ++ ++badframe: ++ force_sig(SIGSEGV, current); ++ return 0; ++} ++ ++static int setup_sigcontext(struct sigcontext __user * sc, ++ struct aux_sigframe __user * aux, ++ struct pt_regs *regs, unsigned long mask) ++{ ++ int err = 0; ++ ++ err |= setup_sigcontext_fpu(regs, sc); ++ err |= setup_sigcontext_audio(regs, sc); ++ ++ __put_user_error(regs->NDS32_r0, &sc->nds32_r0, err); ++ __put_user_error(regs->NDS32_r1, &sc->nds32_r1, err); ++ __put_user_error(regs->NDS32_r2, &sc->nds32_r2, err); ++ __put_user_error(regs->NDS32_r3, &sc->nds32_r3, err); ++ __put_user_error(regs->NDS32_r4, &sc->nds32_r4, err); ++ __put_user_error(regs->NDS32_r5, &sc->nds32_r5, err); ++ __put_user_error(regs->NDS32_r6, &sc->nds32_r6, err); ++ __put_user_error(regs->NDS32_r7, &sc->nds32_r7, err); ++ __put_user_error(regs->NDS32_r8, &sc->nds32_r8, err); ++ __put_user_error(regs->NDS32_r9, &sc->nds32_r9, err); ++ __put_user_error(regs->NDS32_r10, &sc->nds32_r10, err); ++ __put_user_error(regs->NDS32_r11, &sc->nds32_r11, err); ++ __put_user_error(regs->NDS32_r12, &sc->nds32_r12, err); ++ __put_user_error(regs->NDS32_r13, &sc->nds32_r13, err); ++ __put_user_error(regs->NDS32_r14, &sc->nds32_r14, err); ++ __put_user_error(regs->NDS32_r15, &sc->nds32_r15, err); ++ __put_user_error(regs->NDS32_r16, &sc->nds32_r16, err); ++ __put_user_error(regs->NDS32_r17, &sc->nds32_r17, err); ++ __put_user_error(regs->NDS32_r18, &sc->nds32_r18, err); ++ __put_user_error(regs->NDS32_r19, &sc->nds32_r19, err); ++ __put_user_error(regs->NDS32_r20, &sc->nds32_r20, err); ++ ++ __put_user_error(regs->NDS32_r21, &sc->nds32_r21, err); ++ __put_user_error(regs->NDS32_r22, &sc->nds32_r22, err); ++ __put_user_error(regs->NDS32_r23, &sc->nds32_r23, err); ++ __put_user_error(regs->NDS32_r24, &sc->nds32_r24, err); ++ __put_user_error(regs->NDS32_r25, &sc->nds32_r25, err); ++ __put_user_error(regs->NDS32_fp, &sc->nds32_fp, err); ++ __put_user_error(regs->NDS32_gp, &sc->nds32_gp, err); ++ __put_user_error(regs->NDS32_lp, &sc->nds32_lr, err); ++ __put_user_error(regs->NDS32_sp, &sc->nds32_sp, err); ++ __put_user_error(regs->NDS32_ipc, &sc->nds32_ipc, err); ++#if defined(CONFIG_HWZOL) ++ __get_user_error(regs->NDS32_lc, &sc->zol.nds32_lc, err); ++ __get_user_error(regs->NDS32_le, &sc->zol.nds32_le, err); ++ __get_user_error(regs->NDS32_lb, &sc->zol.nds32_lb, err); ++#endif ++ ++ __put_user_error(current->thread.trap_no, &sc->trap_no, err); ++ __put_user_error(current->thread.error_code, &sc->error_code, err); ++ __put_user_error(current->thread.address, &sc->fault_address, err); ++ __put_user_error(mask, &sc->oldmask, err); ++ ++ return err; ++} ++ ++static inline void __user *get_sigframe(struct k_sigaction *ka, ++ struct pt_regs *regs, int framesize) ++{ ++ unsigned long sp = regs->NDS32_sp; ++ void __user *frame; ++ ++ /* ++ * This is the X/Open sanctioned signal stack switching. ++ */ ++ if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) ++ sp = current->sas_ss_sp + current->sas_ss_size; ++ ++ /* ++ * ATPCS B01 mandates 8-byte alignment ++ */ ++ frame = (void __user *)((sp - framesize) & ~7); ++ ++ /* ++ * Check that we can actually write to the signal frame. ++ */ ++ if (!access_ok(VERIFY_WRITE, frame, framesize)) ++ frame = NULL; ++ ++ return frame; ++} ++ ++static int setup_return(struct pt_regs *regs, struct k_sigaction *ka, ++ unsigned long __user * rc, void __user * frame, ++ int usig) ++{ ++ unsigned long handler = (unsigned long)ka->sa.sa_handler; ++ unsigned long retcode; ++ struct sigframe *sf = (struct sigframe *)frame; ++ ++ /* ++ * Maybe we need to deliver a 32-bit signal to a 26-bit task. ++ */ ++ if (ka->sa.sa_flags & SA_RESTORER) { ++ retcode = (unsigned long)ka->sa.sa_restorer; ++ } else { ++ ++ unsigned int idx = 0; //thumb; ++ unsigned long line_size = CACHE_LINE_SIZE(ICACHE); ++ unsigned long start, end; ++ ++ if (ka->sa.sa_flags & SA_SIGINFO) ++ idx++; ++ ++ if (__put_user(retcodes[idx], rc)) ++ return 1; ++ ++ /* ++ * Ensure that the instruction cache sees ++ * the return code written onto the stack. ++ */ ++ start = (unsigned long)rc & ~(line_size - 1); ++ end = start + line_size; ++ flush_icache_range(start, end); ++ ++ retcode = KERN_SIGRETURN_CODE + (idx << 2); ++ } ++ ++ regs->NDS32_r0 = usig; ++ regs->NDS32_r1 = 0; ++ regs->NDS32_r2 = (unsigned long)&sf->sc; ++ regs->NDS32_sp = (unsigned long)frame; ++ regs->NDS32_lp = retcode; ++ regs->NDS32_ipc = handler; ++ /* Also store handler address in r15 for updating GP in the handler. */ ++ regs->NDS32_r15 = handler; ++ ++ return 0; ++} ++ ++static int setup_frame(int usig, struct k_sigaction *ka, sigset_t * set, ++ struct pt_regs *regs) ++{ ++ struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); ++ int err = 0; ++ ++ if (!frame) ++ return 1; ++ ++ err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]); ++ ++ if (_NSIG_WORDS > 1) { ++ err |= __copy_to_user(frame->extramask, &set->sig[1], ++ sizeof(frame->extramask)); ++ } ++ ++ if (err == 0) ++ err = setup_return(regs, ka, &frame->retcode, frame, usig); ++ ++ return err; ++} ++ ++static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t * info, ++ sigset_t * set, struct pt_regs *regs) ++{ ++ struct rt_sigframe __user *frame = ++ get_sigframe(ka, regs, sizeof(*frame)); ++ stack_t stack; ++ int err = 0; ++ ++ if (!frame) ++ return 1; ++ ++ __put_user_error(&frame->info, &frame->pinfo, err); ++ __put_user_error(&frame->uc, &frame->puc, err); ++ err |= copy_siginfo_to_user(&frame->info, info); ++ ++ __put_user_error(0, &frame->uc.uc_flags, err); ++ __put_user_error(NULL, &frame->uc.uc_link, err); ++ ++ memset(&stack, 0, sizeof(stack)); ++ stack.ss_sp = (void __user *)current->sas_ss_sp; ++ stack.ss_flags = sas_ss_flags(regs->NDS32_sp); //NDS32_sp ++ stack.ss_size = current->sas_ss_size; ++ err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); ++ ++ err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux, ++ regs, set->sig[0]); ++ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); ++ ++ if (err == 0) ++ err = setup_return(regs, ka, &frame->retcode, frame, usig); ++ ++ if (err == 0) { ++ /* ++ * For realtime signals we must also set the second and third ++ * arguments for the signal handler. ++ * -- Peter Maydell 2000-12-06 ++ */ ++ regs->NDS32_r1 = (unsigned long)&frame->info; ++ regs->NDS32_r2 = (unsigned long)&frame->uc; ++ } ++ ++ return err; ++} ++ ++static inline void setup_restart_syscall(struct pt_regs *regs) ++{ ++ regs->NDS32_r0 = regs->NDS32_ORIG_r0; ++ regs->NDS32_ipc -= 4; ++} ++ ++/* ++ * OK, we're invoking a handler ++ */ ++static void handle_signal(unsigned long sig, struct k_sigaction *ka, ++ siginfo_t * info, sigset_t * oldset, ++ struct pt_regs *regs, int syscall) ++{ ++ struct thread_info *thread = current_thread_info(); ++ struct task_struct *tsk = current; ++ int usig = sig; ++ int ret; ++ ++ /* ++ * If we were from a system call, check for system call restarting... ++ */ ++ if (syscall) { ++ switch (regs->NDS32_r0) { ++ case -ERESTART_RESTARTBLOCK: ++ case -ERESTARTNOHAND: ++ regs->NDS32_r0 = -EINTR; ++ break; ++ case -ERESTARTSYS: ++ if (!(ka->sa.sa_flags & SA_RESTART)) { ++ regs->NDS32_r0 = -EINTR; ++ break; ++ } ++ /* fallthrough */ ++ case -ERESTARTNOINTR: ++ setup_restart_syscall(regs); ++ } ++ } ++ ++ /* ++ * translate the signal ++ */ ++ if (usig < 32 && thread->exec_domain ++ && thread->exec_domain->signal_invmap) ++ usig = thread->exec_domain->signal_invmap[usig]; ++ ++ /* ++ * Set up the stack frame ++ */ ++ if (ka->sa.sa_flags & SA_SIGINFO) ++ ret = setup_rt_frame(usig, ka, info, oldset, regs); ++ else ++ ret = setup_frame(usig, ka, oldset, regs); ++ ++ /* ++ * Check that the resulting registers are actually sane. ++ */ ++ ret |= !valid_user_regs(regs); ++ ++ /* ++ * Block the signal if we were unsuccessful. ++ */ ++ if (ret == 0) { ++ spin_lock_irq(&tsk->sighand->siglock); ++ sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); ++ if (!(ka->sa.sa_flags & SA_NODEFER)) ++ sigaddset(&tsk->blocked, sig); ++ recalc_sigpending(); ++ spin_unlock_irq(&tsk->sighand->siglock); ++#if 0 & defined(CONFIG_HSS) ++ /* COLE: i marked this tempory. ++ It doesn't behave the same as x86 */ ++ /* Clear HSS when entering the signal handler, ++ User should be step into signal handler */ ++ if (regs->NDS32_ipsw & PSW_mskHSS) { ++ regs->NDS32_ipsw &= ~PSW_mskHSS; ++ printk(KERN_INFO "clear for sig %d. pc=0x%08x\n", sig, ++ regs->NDS32_ipc); ++ } ++#endif ++ return; ++ } ++ ++ force_sigsegv(sig, tsk); ++} ++ ++/* ++ * Note that 'init' is a special process: it doesn't get signals it doesn't ++ * want to handle. Thus you cannot kill init even with a SIGKILL even by ++ * mistake. ++ * ++ * Note that we go through the signals twice: once to check the signals that ++ * the kernel can handle, and then we build all the user-level signal handling ++ * stack-frames in one go after that. ++ */ ++asmlinkage int do_signal(sigset_t * oldset, struct pt_regs *regs, int syscall) ++{ ++ struct k_sigaction ka; ++ siginfo_t info; ++ int signr; ++ ++ /* ++ * We want the common case to go fast, which ++ * is why we may in certain cases get here from ++ * kernel mode. Just return without doing anything ++ * if so. ++ */ ++ ++ if (!user_mode(regs)) ++ return 0; ++ ++ if (try_to_freeze()) ++ goto no_signal; ++ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) ++ oldset = ¤t->saved_sigmask; ++ ++ signr = get_signal_to_deliver(&info, &ka, regs, NULL); ++ ++ if (signr > 0) { ++ handle_signal(signr, &ka, &info, oldset, regs, syscall); ++ /* ++ * A signal was successfully delivered; the saved ++ * sigmask will have been stored in the signal frame, ++ * and will be restored by sigreturn, so we can simply ++ * clear the TIF_RESTORE_SIGMASK flag. ++ */ ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) ++ clear_thread_flag(TIF_RESTORE_SIGMASK); ++ return 1; ++ } ++ ++no_signal: ++ /* ++ * No signal to deliver to the process - restart the syscall. ++ */ ++ if (syscall) { ++ switch (regs->NDS32_r0) { ++ u32 __user *usp; ++ ++ case -ERESTART_RESTARTBLOCK: ++ regs->NDS32_sp -= 4; ++ usp = (u32 __user *) regs->NDS32_sp; ++ ++ if (put_user(regs->NDS32_ipc, usp) == 0) ++ regs->NDS32_ipc = KERN_RESTART_CODE; ++ else { ++ regs->NDS32_sp += 4; ++ force_sigsegv(0, current); ++ } ++ regs->NDS32_r0 = regs->NDS32_ORIG_r0; ++ break; ++ ++ case -ERESTARTNOHAND: ++ case -ERESTARTSYS: ++ case -ERESTARTNOINTR: ++ ++ setup_restart_syscall(regs); ++ break; ++ } ++ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { ++ clear_thread_flag(TIF_RESTORE_SIGMASK); ++ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); ++ } ++ } ++ ++ return 0; ++} ++ ++asmlinkage void do_notify_resume(struct pt_regs *regs, ++ unsigned int thread_flags, int syscall) ++{ ++ if (thread_flags & _TIF_SIGPENDING) ++ do_signal(¤t->blocked, regs, syscall); ++ if (thread_flags & _TIF_NOTIFY_RESUME) { ++ clear_thread_flag(TIF_NOTIFY_RESUME); ++ tracehook_notify_resume(regs); ++ if (current->replacement_session_keyring) ++ key_replace_session_keyring(); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/signal.h linux-3.4.110/arch/nds32/kernel/signal.h +--- linux-3.4.110.orig/arch/nds32/kernel/signal.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/signal.h 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * linux/arch/arm/kernel/signal.h ++ * ++ * Copyright (C) 2005-2009 Russell King. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++ ++#define RETURN_SYSCALL_BASE (0x2000) ++#define RETURN_SYSCALL_PA_BASE (PHYS_OFFSET | RETURN_SYSCALL_BASE) ++ ++#define KERN_SIGRETURN_CODE (fix_to_virt(FIX_RETURN_SYSCALL)) ++#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(retcodes)) ++ ++extern const unsigned long retcodes[2]; ++extern const unsigned long syscall_restart_code[3]; +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/smp.c linux-3.4.110/arch/nds32/kernel/smp.c +--- linux-3.4.110.orig/arch/nds32/kernel/smp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/smp.c 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,335 @@ ++/* ++ * linux/arch/nds32/kernel/smp.c ++ * ++ * Copyright (C) 2002 ARM Limited, All Rights Reserved. ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void smp_init_cpus(void) ++{ ++ int i; ++ for (i = 0; i < NR_CPUS; i++) ++ cpu_set(i, cpu_possible_map); ++} ++ ++int setup_profiling_timer(unsigned int multiplier) ++{ ++ return 0; ++} ++ ++struct tlb_data { ++ struct vm_area_struct *vma; ++ unsigned long start; ++ unsigned long end; ++}; ++ ++static void ipi_flush_tlb_all(void *data) ++{ ++ local_flush_tlb_all(); ++} ++ ++void flush_tlb_all(void) ++{ ++ on_each_cpu(ipi_flush_tlb_all, NULL, 1); ++} ++ ++static void ipi_flush_tlb_mm(void *data) ++{ ++ struct mm_struct *mm = (struct mm_struct *)data; ++ local_flush_tlb_mm(mm); ++} ++ ++void flush_tlb_mm(struct mm_struct *mm) ++{ ++ on_each_cpu(ipi_flush_tlb_mm, mm, 1); ++} ++ ++static void ipi_flush_tlb_page(void *data) ++{ ++ struct tlb_data *t = (struct tlb_data *)data; ++ local_flush_tlb_page(t->vma, t->start); ++} ++ ++void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) ++{ ++ struct tlb_data data; ++ ++ data.vma = vma; ++ data.start = addr; ++ on_each_cpu(ipi_flush_tlb_page, &data, 1); ++} ++ ++static void ipi_flush_tlb_range(void *data) ++{ ++ struct tlb_data *t = (struct tlb_data *)data; ++ local_flush_tlb_range(t->vma, t->start, t->end); ++} ++ ++void flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++ struct tlb_data data; ++ ++ data.vma = vma; ++ data.start = start; ++ data.end = end; ++ on_each_cpu(ipi_flush_tlb_range, &data, 1); ++} ++ ++static void ipi_flush_tlb_kernel_range(void *data) ++{ ++ struct tlb_data *t = (struct tlb_data *)data; ++ local_flush_tlb_kernel_range(t->start, t->end); ++} ++ ++void flush_tlb_kernel_range(unsigned long start, unsigned long end) ++{ ++ struct tlb_data data; ++ ++ data.start = start; ++ data.end = end; ++ on_each_cpu(ipi_flush_tlb_kernel_range, &data, 1); ++} ++ ++/* IPI implementation */ ++static inline unsigned long read_ipi_trigger(void) ++{ ++ /* AMIC IPI trigger register */ ++ return *(volatile unsigned long *)(AMIC_VA_BASE + 0x40); ++} ++ ++static inline void write_ipi_trigger(const struct cpumask *mask) ++{ ++ unsigned long data = *cpus_addr(*mask); ++ *(volatile unsigned long *)(AMIC_VA_BASE + 0x40) = data; ++} ++ ++static inline void clear_ipi_status(void) ++{ ++ *(volatile unsigned long *)(AMIC_VA_BASE + 0x44) = 0xf; ++ asm("msync store\nisb"); ++} ++ ++static void __init send_IPI_boot(int cpu, struct task_struct *tsk) ++{ ++ extern void secondary_startup(void); ++ unsigned long *ptr = (unsigned long *)(0xc0006000 + (cpu << 9)); ++ ptr[5] = virt_to_phys(secondary_startup); ++ ptr[6] = (unsigned long)task_stack_page(tsk) + THREAD_SIZE - 8; ++ asm("cctl %0, L1D_VA_WB, alevel\n"::"r"(ptr)); ++ asm("cctl %0, L1D_VA_INVAL, alevel\nmsync\ndsb\n"::"r"(ptr)); ++ write_ipi_trigger(get_cpu_mask(cpu)); ++} ++ ++static int __init wait_cpu_boot_done(int cpu) ++{ ++ int i, state; ++ for (i = 0; i < 10000; i++) { ++ state = read_ipi_trigger(); ++ if ((state & (1 << cpu)) == 0) ++ break; ++ udelay(100); ++ } ++ return (i == 10000) ? -1 : 0; ++} ++ ++void __init secondary_start_kernel(void) ++{ ++ unsigned long tmp; ++ unsigned int cpu = smp_processor_id(); ++ ++ atomic_inc(&init_mm.mm_count); ++ current->active_mm = &init_mm; ++ ++ /* ++ * enable cache. ++ */ ++ ++#ifdef CONFIG_ANDES_PAGE_SIZE_4KB ++ if (CPU_IS_N1213_43U1HA0()) { ++ /* Downsize cache to bypass cache aliasing issue */ ++ ++ if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096) ++ tmp = 0x02 << SDZ_CTL_offICDZ; ++ ++ if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096) ++ tmp |= 0x02 << SDZ_CTL_offDCDZ; ++ ++ SET_SDZ_CTL(tmp); ++ ISB(); ++// printk("CPU%d enabled cache downsizing.\n", cpu); ++ } ++#endif /* CONFIG_ANDES_PAGE_SIZE_4KB */ ++ ++ tmp = GET_CACHE_CTL(); ++#ifndef CONFIG_CPU_DCACHE_DISABLE ++ tmp |= CACHE_CTL_mskDC_EN; ++#endif ++ ++#ifndef CONFIG_CPU_ICACHE_DISABLE ++ tmp |= CACHE_CTL_mskIC_EN; ++#endif ++ SET_CACHE_CTL(tmp); ++ DSB(); ++ ISB(); ++ ++ preempt_disable(); ++ local_irq_enable(); ++ ++ //assume all of cores runs the same speed ++ //calibrate_delay(); ++ /* store cpu info ot the second cpu */ ++ smp_store_cpu_info(cpu); ++ ++ clear_ipi_status(); ++ cpu_idle(); ++} ++ ++/* ++ * Called by both boot and secondaries to move global data into ++ * per-processor storage. ++ */ ++void __init smp_store_cpu_info(unsigned int cpuid) ++{ ++ struct cpuinfo_nds32 *cpu_info = &per_cpu(cpu_data, cpuid); ++ ++ cpu_info->loops_per_jiffy = loops_per_jiffy; ++} ++ ++/* functions be used by generic layer */ ++void arch_send_call_function_single_ipi(int cpu) ++{ ++ write_ipi_trigger(get_cpu_mask(cpu)); ++} ++ ++void arch_send_call_function_ipi_mask(const struct cpumask *mask) ++{ ++ write_ipi_trigger(mask); ++} ++ ++static void __init smp_boot_one_cpu(int cpu) ++{ ++ struct task_struct *idle; ++ int ret; ++ ++ idle = fork_idle(cpu); ++ if (IS_ERR(idle)) ++ panic(KERN_ERR "Fork failed for CPU %d", cpu); ++ ++ send_IPI_boot(cpu, idle); ++ ret = wait_cpu_boot_done(cpu); ++ if (ret == 0) ++ cpu_set(cpu, cpu_online_map); ++ else ++ put_task_struct(idle); ++} ++ ++static void ipi_timer(void *data) ++{ ++ profile_tick(CPU_PROFILING); ++ update_process_times(user_mode(get_irq_regs())); ++} ++ ++void smp_send_timer(void) ++{ ++ smp_call_function(ipi_timer, NULL, 0); ++} ++ ++static void ipi_stop(void *data) ++{ ++ cpu_clear(smp_processor_id(), cpu_online_map); ++ local_irq_enable(); ++ for (;;) ; ++} ++ ++void smp_send_stop(void) ++{ ++ smp_call_function(ipi_stop, NULL, 0); ++} ++ ++void smp_send_reschedule(int cpu) ++{ ++ write_ipi_trigger(get_cpu_mask(cpu)); ++} ++ ++static void ipi_handler(unsigned int irq, struct irq_desc *desc) ++{ ++ clear_ipi_status(); ++ generic_smp_call_function_single_interrupt(); ++ generic_smp_call_function_interrupt(); ++} ++ ++void __init smp_prepare_cpus(unsigned int max_cpus) ++{ ++ /* ++ * XXX detect how many cores exist ++ */ ++ int i; ++ unsigned int cpu = smp_processor_id(); ++ ++ /* store master core cpu info */ ++ smp_store_cpu_info(cpu); ++ for (i = 0; i < max_cpus; i++) ++ cpu_set(i, cpu_present_map); ++ ++ /* setup IPI handler */ ++ set_irq_chip(32, &dummy_irq_chip); ++ set_irq_chained_handler(32, ipi_handler); ++} ++ ++int __cpuinit __cpu_up(unsigned int cpu) ++{ ++ smp_boot_one_cpu(cpu); ++ return cpu_online(cpu) ? 0 : -ENOSYS; ++} ++ ++void __init smp_cpus_done(unsigned int max_cpus) ++{ ++ int cpu; ++ unsigned long bogosum = 0; ++ ++ for_each_online_cpu(cpu) ++ bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; ++ ++ printk(KERN_INFO "SMP: Total of %d processors activated " ++ "(%lu.%02lu BogoMIPS).\n", ++ num_online_cpus(), ++ bogosum / (500000 / HZ), (bogosum / (5000 / HZ)) % 100); ++ ++ /* now we can set all interruption don't cared */ ++ *(volatile unsigned long *)(AMIC_VA_BASE + 0x4) = 0xffffffff; ++} ++ ++void __init smp_prepare_boot_cpu(void) ++{ ++ unsigned int cpu = smp_processor_id(); ++ unsigned long *ptr = (unsigned long *)(0xc0006000 + (cpu << 9)); ++ ptr[4] = 1; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/stacktrace.c linux-3.4.110/arch/nds32/kernel/stacktrace.c +--- linux-3.4.110.orig/arch/nds32/kernel/stacktrace.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/stacktrace.c 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,41 @@ ++#include ++#include ++void save_stack_trace(struct stack_trace *trace) ++{ ++ save_stack_trace_tsk(current, trace); ++} ++ ++void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) ++{ ++ unsigned long *fpn; ++ int skip = trace->skip; ++ int savesched; ++ ++ if (tsk == current) { ++ __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn)); ++ savesched = 1; ++ } else { ++ fpn = (unsigned long *)thread_saved_fp(tsk); ++ savesched = 0; ++ } ++ ++ while (!kstack_end(fpn) && !((unsigned long)fpn & 0x3) ++ && (fpn >= (unsigned long *)TASK_SIZE)) { ++ unsigned long lpp, fpp; ++ lpp = fpn[0]; ++ fpp = fpn[-1]; ++ if (!__kernel_text_address(lpp)) ++ break; ++ ++ if (savesched || !in_sched_functions(lpp)) { ++ if (skip) { ++ skip--; ++ } else { ++ trace->entries[trace->nr_entries++] = lpp; ++ if (trace->nr_entries >= trace->max_entries) ++ break; ++ } ++ } ++ fpn = (unsigned long *)fpp; ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/sys_nds32.c linux-3.4.110/arch/nds32/kernel/sys_nds32.c +--- linux-3.4.110.orig/arch/nds32/kernel/sys_nds32.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/sys_nds32.c 2016-04-07 10:20:50.946081179 +0200 +@@ -0,0 +1,331 @@ ++/* ++ * linux/arch/nds32/kernel/sys_nds32.c ++ * ++ * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c ++ * Copyright (C) 2007 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This file contains various random system calls that ++ * have a non-standard calling sequence on the Linux/nds32 ++ * platform. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, ++ unsigned long new_len, unsigned long flags, ++ unsigned long new_addr); ++ ++struct mmap_arg_struct { ++ unsigned long addr; ++ unsigned long len; ++ unsigned long prot; ++ unsigned long flags; ++ unsigned long fd; ++ unsigned long offset; ++}; ++ ++asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, ++ unsigned long prot, unsigned long flags, ++ unsigned long fd, unsigned long pgoff) ++{ ++ if (pgoff & (~PAGE_MASK >> 12)) ++ return -EINVAL; ++ ++ return sys_mmap_pgoff(addr, len, prot, flags, fd, ++ pgoff >> (PAGE_SHIFT - 12)); ++} ++ ++asmlinkage unsigned long ++sys_nds32_mremap(unsigned long addr, unsigned long old_len, ++ unsigned long new_len, unsigned long flags, ++ unsigned long new_addr) ++{ ++ unsigned long ret = -EINVAL; ++ ++ if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS) ++ goto out; ++ ++ down_write(¤t->mm->mmap_sem); ++ ret = do_mremap(addr, old_len, new_len, flags, new_addr); ++ up_write(¤t->mm->mmap_sem); ++ ++out: ++ return ret; ++} ++ ++/* ++ * Perform the select(nd, in, out, ex, tv) and mmap() system ++ * calls. ++ */ ++ ++struct sel_arg_struct { ++ unsigned long n; ++ fd_set __user *inp, *outp, *exp; ++ struct timeval __user *tvp; ++}; ++ ++asmlinkage int old_select(struct sel_arg_struct __user * arg) ++{ ++ struct sel_arg_struct a; ++ ++ if (copy_from_user(&a, arg, sizeof(a))) ++ return -EFAULT; ++ /* sys_select() does the appropriate kernel locking */ ++ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); ++} ++ ++/* ++ * sys_ipc() is the de-multiplexer for the SysV IPC calls.. ++ * ++ * This is really horribly ugly. ++ */ ++asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, ++ unsigned long third, void __user * ptr, long fifth) ++{ ++ int version, ret; ++ ++ version = call >> 16; /* hack for backward compatibility */ ++ call &= 0xffff; ++ ++ switch (call) { ++ case SEMOP: ++ return sys_semtimedop(first, (struct sembuf __user *)ptr, ++ second, NULL); ++ case SEMTIMEDOP: ++ return sys_semtimedop(first, (struct sembuf __user *)ptr, ++ second, ++ (const struct timespec __user *)fifth); ++ ++ case SEMGET: ++ return sys_semget(first, second, third); ++ case SEMCTL:{ ++ union semun fourth; ++ if (!ptr) ++ return -EINVAL; ++ if (get_user(fourth.__pad, (void __user * __user *)ptr)) ++ return -EFAULT; ++ return sys_semctl(first, second, third, fourth); ++ } ++ ++ case MSGSND: ++ return sys_msgsnd(first, (struct msgbuf __user *)ptr, ++ second, third); ++ case MSGRCV: ++ switch (version) { ++ case 0:{ ++ struct ipc_kludge tmp; ++ if (!ptr) ++ return -EINVAL; ++ if (copy_from_user ++ (&tmp, (struct ipc_kludge __user *)ptr, ++ sizeof(tmp))) ++ return -EFAULT; ++ return sys_msgrcv(first, tmp.msgp, second, ++ tmp.msgtyp, third); ++ } ++ default: ++ return sys_msgrcv(first, ++ (struct msgbuf __user *)ptr, ++ second, fifth, third); ++ } ++ case MSGGET: ++ return sys_msgget((key_t) first, second); ++ case MSGCTL: ++ return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); ++ ++ case SHMAT: ++ switch (version) { ++ default:{ ++ ulong raddr; ++ ret = ++ do_shmat(first, (char __user *)ptr, second, ++ &raddr); ++ if (ret) ++ return ret; ++ return put_user(raddr, (ulong __user *) third); ++ } ++ case 1: /* Of course, we don't support iBCS2! */ ++ return -EINVAL; ++ } ++ case SHMDT: ++ return sys_shmdt((char __user *)ptr); ++ case SHMGET: ++ return sys_shmget(first, second, third); ++ case SHMCTL: ++ return sys_shmctl(first, second, (struct shmid_ds __user *)ptr); ++ default: ++ return -ENOSYS; ++ } ++} ++ ++/* Fork a new task - this creates a new program thread. ++ * This is called indirectly via a small wrapper ++ */ ++asmlinkage int sys_fork(struct pt_regs *regs) ++{ ++ return do_fork(SIGCHLD, regs->NDS32_sp, regs, 0, NULL, NULL); ++} ++ ++/* Clone a task - this clones the calling program thread. ++ * This is called indirectly via a small wrapper ++ */ ++asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, ++ int __user * parent_tidptr, int tls_val, ++ int __user * child_tidptr, struct pt_regs *regs) ++{ ++ if (!newsp) ++ newsp = regs->NDS32_sp; ++ ++ return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, ++ child_tidptr); ++} ++ ++asmlinkage int sys_vfork(struct pt_regs *regs) ++{ ++ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->NDS32_sp, regs, ++ 0, NULL, NULL); ++} ++ ++/* sys_execve() executes a new program. ++ * This is called indirectly via a small wrapper ++ */ ++asmlinkage int sys_execve(const char __user * filenamei, ++ const char __user * const __user * argv, ++ const char __user * const __user * envp, ++ struct pt_regs *regs) ++{ ++ int error; ++ char *filename; ++ ++ filename = getname(filenamei); ++ error = PTR_ERR(filename); ++ if (IS_ERR(filename)) ++ goto out; ++ ++ error = do_execve(filename, argv, envp, regs); ++ putname(filename); ++ ++out: ++ return error; ++} ++ ++asmlinkage unsigned long sys_getpagesize(void) ++{ ++ return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ ++} ++ ++int kernel_execve(const char *filename, const char *const argv[], ++ const char *const envp[]) ++{ ++ struct pt_regs regs; ++ int ret; ++ ++ memset(®s, 0, sizeof(struct pt_regs)); ++ ret = do_execve(filename, argv, envp, ®s); ++ ++ if (ret < 0) { ++ goto out; ++ } ++ /* ++ * Save argc to the register structure for userspace. ++ */ ++ regs.NDS32_r0 = ret; ++ ++ /* ++ * We were successful. We won't be returning to our caller, but ++ * instead to user space by manipulating the kernel stack. ++ */ ++ asm("addi $r0, %0, %1\n\t" ++ "move $r1, %2\n\t" ++ "move $r2, %3\n\t" ++ "bal memmove\n\t" /* copy regs to top of stack */ ++ "move $r8, #0\n\t" /* not a syscall */ ++ "move $r9, %0\n\t" /* thread structure */ ++ "move $sp, $r0\n\t" /* reposition stack pointer */ ++"b resume_userspace": ++: "r"(current_thread_info()), ++ "ir"(THREAD_SIZE - 8 - sizeof(regs)), ++ "r"(®s), "ir"(sizeof(regs)) ++#ifdef _GCC444 ++: "$r0", "$r1", "$r2", "$r4", "$r5", "$r8", "$r9", "$p0", "$p1", ++ "memory"); ++#else ++: "$r0", "$r1", "$r2", "$r4", "$r5", "$r8", "$r9", "$r26", "$r27", ++ "memory"); ++#endif ++out: ++ return ret; ++} ++ ++EXPORT_SYMBOL(kernel_execve); ++ ++int sys_cacheflush(unsigned int start, unsigned int end) ++{ ++ struct vm_area_struct *vma; ++ ++ vma = find_vma(current->mm, start); ++ if (!vma) ++ return 0; ++ cpu_cache_wbinval_range_check(vma, start, end); ++ return 0; ++} ++ ++asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, ++ loff_t len) ++{ ++ return sys_fadvise64_64(fd, offset, len, advice); ++} ++ ++asmlinkage int nds32_syscall(int number, struct pt_regs *regs) ++{ ++ switch (number) { ++ case 0x7000: /* cacheflush */ ++ return sys_cacheflush(regs->NDS32_r1, regs->NDS32_r2); ++ ++#ifdef CONFIG_OPROFILE ++ case __NR_pfmctl: ++ sys_pfmctl(regs->NDS32_r1, regs->NDS32_r2, regs->NDS32_r3, ++ regs->NDS32_r4); ++ return 0; ++ ++ case __NR_getpfm: ++ return sys_getpfm((struct pcounter __user *)regs->NDS32_r1); ++ ++ case __NR_setpfm: ++ return sys_setpfm(regs->NDS32_r1, regs->NDS32_r2, ++ regs->NDS32_r3, ++ (struct pcounter __user *)regs->NDS32_r4); ++#endif ++ case __NR_wbna: ++ if (regs->NDS32_r1) ++ regs->NDS32_ipsw |= PSW_mskWBNA; ++ else ++ regs->NDS32_ipsw &= ~PSW_mskWBNA; ++ return 0; ++ ++ default: ++ return -ENOSYS; ++ } ++ return -ENOSYS; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/time.c linux-3.4.110/arch/nds32/kernel/time.c +--- linux-3.4.110.orig/arch/nds32/kernel/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/time.c 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,94 @@ ++/* ++ * linux/arch/nds32/kernel/time.c ++ * ++ * Copyright (C) 1991, 1992, 1995 Linus Torvalds ++ * Modifications for ARM (C) 1994-2001 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This file contains the ARM-specific time handling details: ++ * reading the RTC at bootup, etc... ++ * ++ * 1994-07-02 Alan Modra ++ * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime ++ * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 ++ * "A Kernel Model for Precision Timekeeping" by Dave Mills ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* ++ * Our system timer. ++ */ ++struct sys_timer *system_timer; ++ ++#ifdef CONFIG_SMP ++unsigned long profile_pc(struct pt_regs *regs) ++{ ++ unsigned long fp, pc = instruction_pointer(regs); ++ ++ if (in_lock_functions(pc)) { ++ fp = regs->NDS32_fp; ++ pc = ((unsigned long *)fp)[-1]; ++ } ++ ++ return pc; ++} ++ ++EXPORT_SYMBOL(profile_pc); ++#endif ++#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) ++static int timer_suspend(void) ++{ ++ if (system_timer->suspend) ++ system_timer->suspend(); ++ ++ return 0; ++} ++ ++static void timer_resume(void) ++{ ++ if (system_timer->resume) ++ system_timer->resume(); ++} ++#else ++#define timer_suspend NULL ++#define timer_resume NULL ++#endif ++#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET ++u32 arch_gettimeoffset(void) ++{ ++ if (system_timer->offset != NULL) ++ return system_timer->offset() * 1000; ++ ++ return 0; ++} ++#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */ ++static struct syscore_ops timer_syscore_ops = { ++ .suspend = timer_suspend, ++ .resume = timer_resume, ++}; ++ ++static int __init timer_init_syscore_ops(void) ++{ ++ register_syscore_ops(&timer_syscore_ops); ++ ++ return 0; ++} ++ ++device_initcall(timer_init_syscore_ops); ++ ++void __init time_init(void) ++{ ++ system_timer = machine_desc->timer; ++ system_timer->init(); // link to cpe_timer_init ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/traps.c linux-3.4.110/arch/nds32/kernel/traps.c +--- linux-3.4.110.orig/arch/nds32/kernel/traps.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/traps.c 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,733 @@ ++/* ++ * linux/arch/nds32/kernel/traps.c ++ * ++ * Copyright (C) 1995-2002 Russell King ++ * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * 'traps.c' handles hardware exceptions after we have saved some state in ++ * 'linux/arch/nds32/lib/traps.S'. Mostly a debugging aid, but will probably ++ * kill the offending process. ++ */ ++/* ============================================================================ ++ * ++ * linux/arch/nds32/kernel/traps.c ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is trap handling for NDS32 core, initial refer from ARM. ++ * ++ * Revision History: ++ * ++ * Jul.16.2007 Initial ported by Tom, revised for KGDB by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include "ptrace.h" ++#include "signal.h" ++ ++extern void show_pte(struct mm_struct *mm, unsigned long addr); ++ ++#ifdef CONFIG_DEBUG_USER ++unsigned int user_debug; ++ ++static int __init user_debug_setup(char *str) ++{ ++ get_option(&str, &user_debug); ++ return 1; ++} ++ ++__setup("user_debug=", user_debug_setup); ++#endif ++ ++/* ++ * Dump out the contents of some memory nicely... ++ */ ++void dump_mem(const char *str, unsigned long bottom, unsigned long top) ++{ ++ unsigned long p = bottom & ~31; ++ mm_segment_t fs; ++ int i; ++ ++ /* ++ * We need to switch to kernel mode so that we can use __get_user ++ * to safely read from kernel space. Note that we now dump the ++ * code first, just in case the backtrace kills us. ++ */ ++ fs = get_fs(); ++ set_fs(KERNEL_DS); ++ ++ printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); ++ ++ for (p = bottom & ~31; p < top;) { ++ printk("%04lx: ", p & 0xffff); ++ ++ for (i = 0; i < 8; i++, p += 4) { ++ unsigned int val; ++ ++ if (p < bottom || p >= top) ++ printk(" "); ++ else { ++ __get_user(val, (unsigned long *)p); ++ printk("%08x ", val); ++ } ++ } ++ printk("\n"); ++ } ++ ++ set_fs(fs); ++} ++ ++EXPORT_SYMBOL(dump_mem); ++ ++/* These intrinsic functions are not supported in V2 toolchains of BSP321. */ ++#ifndef __NDS32_BASELINE_V2__ ++#define DEBUG_TLB_CACHE ++#endif ++#ifdef DEBUG_TLB_CACHE ++/* This is the number of TLB entries. User should change it if necessary. */ ++#define TLB_NUM 128 ++unsigned int tlb_misc_new[TLB_NUM], tlb_vpn_new[TLB_NUM], tlb_data_new[TLB_NUM]; ++/* To get the whole TLB contents once it uses va=0x0 */ ++void dump_tlb(unsigned long va) ++{ ++ unsigned int rd_num, tlb_vpn, tlb_misc, tlb_data, mmu_cfg, tlb_num; ++ ++ /* save tlb system registers */ ++ tlb_vpn = __nds32__mfsr(NDS32_SR_TLB_VPN); ++ tlb_misc = __nds32__mfsr(NDS32_SR_TLB_MISC); ++ tlb_data = __nds32__mfsr(NDS32_SR_TLB_DATA); ++ mmu_cfg = __nds32__mfsr(NDS32_SR_MMU_CFG); ++ tlb_num = ++ (((mmu_cfg & MMU_CFG_mskTBW) >> MMU_CFG_offTBW) + ++ 1) * (1 << (((mmu_cfg & MMU_CFG_mskTBS) >> MMU_CFG_offTBS) + 2)); ++ ++ for (rd_num = 0; rd_num < tlb_num; rd_num++) { ++ /* read tlb entry with index */ ++ __nds32__tlbop_trd(rd_num); ++ __nds32__dsb(); ++ tlb_vpn_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_VPN); ++ tlb_misc_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_MISC); ++ tlb_data_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_DATA); ++ } ++ ++ /* restore tlb system registers */ ++ __nds32__mtsr(tlb_vpn, NDS32_SR_TLB_VPN); ++ __nds32__mtsr(tlb_misc, NDS32_SR_TLB_MISC); ++ __nds32__dsb(); ++ ++ printk("cur VPN:%08x, MISC:%08x, DATA:%08x\n", tlb_vpn, tlb_misc, ++ tlb_data); ++ /* to read out all the data */ ++ for (rd_num = 0; rd_num < tlb_num; rd_num++) { ++ /*unsigned int vpn = tlb_vpn_new[rd_num] & PAGE_MASK; */ ++ if (tlb_data_new[rd_num] & 0x1) ++ if (va == 0x0 ++ || (va != 0x0 ++ && (tlb_vpn_new[rd_num] == (va & PAGE_MASK)))) ++ printk ++ ("idx:0x%08x, VPN:%08x, MISC:%08x, DATA:%08x\n", ++ rd_num, tlb_vpn_new[rd_num], ++ tlb_misc_new[rd_num], ++ tlb_data_new[rd_num]); ++ } ++} ++ ++EXPORT_SYMBOL(dump_tlb); ++ ++struct cache_element { ++ unsigned int pa; ++ unsigned int wd; ++ unsigned int cacheline[8]; ++ unsigned char dirty; ++ unsigned char valid; ++ unsigned char lock; ++}; ++ ++/* This is the number of cache entries. User should change it if necessary. */ ++#define CACHE_SET_NUM 0x100 ++#define CACHE_WAY_NUM 0x4 ++volatile struct cache_element ce[CACHE_SET_NUM][CACHE_WAY_NUM]; ++#define CCTL_mskDIRTY 0x400000 ++#define CCTL_offDIRTY 22 ++#define CCTL_mskVALID 0x2 ++#define CCTL_offVALID 1 ++#define CCTL_mskLOCK 0x1 ++#define CCTL_offLOCK 0 ++#define CCTL_mskTAG 0x3ffffc ++#define CCTL_offTAG 0x2 ++extern unsigned long va2idx(unsigned long va, unsigned int cache_type, ++ unsigned long *way_offset); ++#include ++extern struct cache_info L1_cache_info[2]; ++void dump_cache(unsigned int cache_type) ++{ ++ volatile unsigned long idx, way, ra, tag, i; ++ unsigned long sets, ways, line_size, set_bits, way_bits, line_bits, ++ way_offset; ++ ++ ways = L1_cache_info[DCACHE].ways; ++ sets = L1_cache_info[DCACHE].sets; ++ set_bits = L1_cache_info[cache_type].set_bits; ++ way_bits = L1_cache_info[cache_type].way_bits; ++ line_bits = L1_cache_info[cache_type].line_bits; ++ line_size = L1_cache_info[cache_type].line_size; ++ way_offset = set_bits + line_bits; ++ ++ if (cache_type != ICACHE && cache_type != DCACHE) { ++ printk("%s not supported cache_type:%x\n", __func__, ++ cache_type); ++ return; ++ } ++ ++ /* NDS32_CCTL_L1I_IX_RTAG Read tag L1I cache */ ++ /* NDS32_CCTL_L1I_IX_RWD Read word data L1I cache */ ++ ++ for (idx = 0; idx < sets; idx++) { ++ for (way = 0; way < ways; way++) { ++ ra = (way << way_offset) | (idx << line_bits); ++ if (cache_type == ICACHE) ++ tag = ++ __nds32__cctlidx_read ++ (NDS32_CCTL_L1I_IX_RTAG, ra); ++ else ++ tag = ++ __nds32__cctlidx_read ++ (NDS32_CCTL_L1D_IX_RTAG, ra); ++ ce[idx][way].dirty = ++ (unsigned char)(tag & CCTL_mskDIRTY) >> ++ CCTL_offDIRTY; ++ ce[idx][way].valid = ++ (unsigned char)(tag & CCTL_mskVALID) >> ++ CCTL_offVALID; ++ ce[idx][way].lock = ++ (unsigned char)(tag & CCTL_mskLOCK) >> CCTL_offLOCK; ++ ce[idx][way].pa = ++ (tag & CCTL_mskTAG) >> CCTL_offTAG << PAGE_SHIFT; ++ for (i = 0; i < line_size / 4; i++) { ++ if (cache_type == ICACHE) ++ ce[idx][way].cacheline[i] = ++ __nds32__cctlidx_read ++ (NDS32_CCTL_L1I_IX_RWD, ++ (ra | i << 2)); ++ else ++ ce[idx][way].cacheline[i] = ++ __nds32__cctlidx_read ++ (NDS32_CCTL_L1D_IX_RWD, ++ (ra | i << 2)); ++ } ++ } ++ } ++ printk("dump %s\n", cache_type ? "DCACHE" : "ICACHE"); ++ printk("%8s %4s %4s %1s %1s %1s %8s %8s %8s %8s %8s %8s %8s %8s\n", ++ "ADDRESS", "SET", "WAY", "V", "D", "L", "00", "04", "08", "0C", ++ "10", "14", "18", "1C"); ++ for (idx = 0; idx < sets; idx++) { ++ for (way = 0; way < ways; way++) { ++ printk("%08lx %04lx %04lx %1u %1u %1u ", ++ ce[idx][way].pa + ++ ((idx * line_size) % PAGE_SIZE), idx, way, ++ ce[idx][way].valid, ce[idx][way].dirty, ++ ce[idx][way].lock); ++ for (i = 0; i < line_size / 4; i++) { ++ printk("%08x ", ce[idx][way].cacheline[i]); ++ } ++ printk("\n"); ++ } ++ } ++} ++ ++EXPORT_SYMBOL(dump_cache); ++ ++void dump_cache_va(unsigned int cache_type, unsigned int va) ++{ ++ volatile struct cache_element cache_entry[4]; ++ volatile unsigned long idx, way, tag, ra, i; ++ unsigned long ways, line_size, set_bits, line_bits, way_offset; ++ ++ ways = L1_cache_info[cache_type].ways; ++ line_size = CACHE_LINE_SIZE(cache_type); ++ set_bits = L1_cache_info[cache_type].set_bits; ++ line_bits = L1_cache_info[cache_type].line_bits; ++ ++ if (cache_type != ICACHE && cache_type != DCACHE) { ++ printk("%s not supported cache_type:%x\n", __func__, ++ cache_type); ++ return; ++ } ++ idx = va2idx(va, cache_type, &way_offset); ++ //idx = (va & (((1 << set_bits) - 1) << line_bits)) >> line_bits; ++ for (way = 0; way < ways; way++) { ++ ra = (way << way_offset) | idx; ++ if (cache_type == ICACHE) ++ tag = __nds32__cctlidx_read(NDS32_CCTL_L1I_IX_RTAG, ra); ++ else ++ tag = __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RTAG, ra); ++ cache_entry[way].dirty = ++ (unsigned char)(tag & CCTL_mskDIRTY) >> CCTL_offDIRTY; ++ cache_entry[way].valid = ++ (unsigned char)(tag & CCTL_mskVALID) >> CCTL_offVALID; ++ cache_entry[way].lock = ++ (unsigned char)(tag & CCTL_mskLOCK) >> CCTL_offLOCK; ++ cache_entry[way].pa = ++ (tag & CCTL_mskTAG) >> CCTL_offTAG << PAGE_SHIFT; ++ for (i = 0; i < line_size / 4; i++) { ++ if (cache_type == ICACHE) ++ cache_entry[way].cacheline[i] = ++ __nds32__cctlidx_read(NDS32_CCTL_L1I_IX_RWD, ++ (ra | i << 2)); ++ else ++ cache_entry[way].cacheline[i] = ++ __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD, ++ (ra | i << 2)); ++ } ++ } ++ printk("dump %s va:%x\n", cache_type ? "DCACHE" : "ICACHE", va); ++ ++ printk("%8s %4s %4s %1s %1s %1s %8s %8s %8s %8s %8s %8s %8s %8s\n", ++ "ADDRESS", "SET", "WAY", "V", "D", "L", "00", "04", "08", "0C", ++ "10", "14", "18", "1C"); ++ for (way = 0; way < ways; way++) { ++ printk("%08lx %04lx %04lx %1u %1u %1u ", ++ cache_entry[way].pa + ++ (((idx >> line_bits) * line_size) % PAGE_SIZE), ++ (idx >> line_bits), way, cache_entry[way].valid, ++ cache_entry[way].dirty, cache_entry[way].lock); ++ for (i = 0; i < 8; i++) { ++ printk("%08x ", cache_entry[way].cacheline[i]); ++ } ++ printk("\n"); ++ } ++} ++ ++EXPORT_SYMBOL(dump_cache_va); ++#endif ++ ++static void dump_instr(struct pt_regs *regs) ++{ ++ unsigned long addr = instruction_pointer(regs); ++ const int width = 8; ++ mm_segment_t fs; ++ int i; ++ ++ return; ++ /* ++ * We need to switch to kernel mode so that we can use __get_user ++ * to safely read from kernel space. Note that we now dump the ++ * code first, just in case the backtrace kills us. ++ */ ++ fs = get_fs(); ++ set_fs(KERNEL_DS); ++ ++ printk("Code: "); ++ for (i = -4; i < 1; i++) { ++ unsigned int val, bad; ++ ++ bad = __get_user(val, &((u32 *) addr)[i]); ++ ++ if (!bad) ++ printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); ++ else { ++ printk("bad PC value."); ++ break; ++ } ++ } ++ printk("\n"); ++ ++ set_fs(fs); ++} ++ ++#define LOOP_TIMES (100) ++void dump_stack(void) ++{ ++ int cnt = LOOP_TIMES; ++#ifndef CONFIG_FRAME_POINTER ++ unsigned long *stack; ++ unsigned long addr; ++ ++ __asm__ __volatile__("\tori\t%0, $sp, #0\n":"=r"(stack)); ++ printk("Call Trace:\n"); ++ while (!kstack_end(stack)) { ++ addr = *stack++; ++ if (__kernel_text_address(addr)) { ++ printk("[<%08lx>] ", addr); ++ print_symbol("%s\n", addr); ++ } ++ cnt--; ++ if (cnt < 0) ++ break; ++ } ++ printk("\n"); ++#else ++ unsigned long *fpn; ++ __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn)); ++ printk("Call Trace:\n"); ++ while (!kstack_end((void *)fpn) && !((unsigned long)fpn & 0x3) ++ && ((unsigned long)fpn >= TASK_SIZE)) { ++ unsigned long lpp, fpp; ++#if !defined(NDS32_ABI_2) ++ lpp = fpn[0]; ++ fpp = fpn[1]; ++#else ++ lpp = fpn[0]; ++ fpp = fpn[-1]; ++#endif ++ if (__kernel_text_address(lpp)) { ++ printk("[<%08lx>] ", lpp); ++ print_symbol("%s\n", lpp); ++ fpn = (unsigned long *)fpp; ++ } ++ cnt--; ++ if (cnt < 0) ++ break; ++ } ++ printk("\n"); ++#endif ++} ++ ++EXPORT_SYMBOL(dump_stack); ++ ++void show_stack(struct task_struct *tsk, unsigned long *sp) ++{ ++ unsigned long fp; ++ ++ if (!tsk) ++ tsk = current; ++ ++ if (tsk != current) ++ fp = thread_saved_fp(tsk); ++ else ++ asm("move %0, $fp":"=r"(fp)); ++ ++ dump_stack(); ++ barrier(); ++} ++ ++DEFINE_SPINLOCK(die_lock); ++ ++/* ++ * This function is protected against re-entrancy. ++ */ ++void die(const char *str, struct pt_regs *regs, int err) ++{ ++ struct task_struct *tsk = current; ++ static int die_counter; ++ ++ console_verbose(); ++ spin_lock_irq(&die_lock); ++ bust_spinlocks(1); ++ ++ printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter); ++ print_modules(); ++ printk("CPU: %i\n", smp_processor_id()); ++ show_regs(regs); ++ printk("Process %s (pid: %d, stack limit = 0x%p)\n", ++ tsk->comm, tsk->pid, task_thread_info(tsk) + 1); ++ ++ if (!user_mode(regs) || in_interrupt()) { ++ dump_mem("Stack: ", regs->NDS32_sp, ++ 8192 + (unsigned long)task_thread_info(tsk)); ++ dump_instr(regs); ++ dump_stack(); ++ } ++ ++ bust_spinlocks(0); ++ spin_unlock_irq(&die_lock); ++ do_exit(SIGSEGV); ++} ++ ++void die_if_kernel(const char *str, struct pt_regs *regs, int err) ++{ ++ if (user_mode(regs)) ++ return; ++ ++ die(str, regs, err); ++} ++ ++int bad_syscall(int n, struct pt_regs *regs) ++{ ++ struct thread_info *thread = current_thread_info(); ++ siginfo_t info; ++ ++ if (current->personality != PER_LINUX && thread->exec_domain->handler) { ++ thread->exec_domain->handler(n, regs); ++ return regs->NDS32_r0; ++ } ++#ifdef CONFIG_DEBUG_USER ++ if (user_debug & UDBG_SYSCALL) { ++ printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", ++ current->pid, current->comm, n); ++ dump_instr(regs); ++ } ++#endif ++ ++ info.si_signo = SIGILL; ++ info.si_errno = 0; ++ info.si_code = ILL_ILLTRP; ++ info.si_addr = (void __user *)instruction_pointer(regs) - 4; ++ ++ force_sig_info(SIGILL, &info, current); ++ die_if_kernel("Oops - bad syscall", regs, n); ++ return regs->NDS32_r0; ++} ++ ++void __pte_error(const char *file, int line, unsigned long val) ++{ ++ printk("%s:%d: bad pte %08lx.\n", file, line, val); ++} ++ ++void __pmd_error(const char *file, int line, unsigned long val) ++{ ++ printk("%s:%d: bad pmd %08lx.\n", file, line, val); ++} ++ ++void __pgd_error(const char *file, int line, unsigned long val) ++{ ++ printk("%s:%d: bad pgd %08lx.\n", file, line, val); ++} ++ ++extern char exception_vector[73][64]; ++void __init trap_init(void) ++{ ++ return; ++} ++ ++void __init early_trap_init(void) ++{ ++ unsigned long ivb = 0; ++ unsigned long base = 0xc0000000; ++ ++ memcpy((unsigned long *)base, (unsigned long *)exception_vector, ++ sizeof(exception_vector)); ++ ivb = __nds32__mfsr(NDS32_SR_IVB); ++#ifdef CONFIG_EVIC ++ __nds32__mtsr((ivb & ~IVB_mskESZ) | (2 << IVB_offESZ) | ++ (1 << IVB_offEVIC) | IVB_BASE, NDS32_SR_IVB); ++#else ++ /* Check platform support. */ ++# if defined (CONFIG_IVIC_INTC) ++ if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) >= 2) ++ panic ++ ("IVIC mode is not allowed on the platform with interrupt controller\n"); ++# elif defined(CONFIG_IVIC) ++ if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) < 2) ++ panic ++ ("IVIC mode is not allowed on the platform without interrupt controller\n"); ++# endif ++ __nds32__mtsr((ivb & ~IVB_mskESZ) | (2 << IVB_offESZ) | IVB_BASE, ++ NDS32_SR_IVB); ++#endif ++ __nds32__mtsr(0x10003, NDS32_SR_INT_MASK); ++ /* ++ * Copy signal return handlers into the vector page, and ++ * set sigreturn to be a pointer to these. ++ */ ++ memcpy((void *)KERN_SIGRETURN_CODE, retcodes, sizeof(retcodes)); ++ memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, ++ sizeof(syscall_restart_code)); ++ ++ /* ++ * 0x2000 is 8K-aligned of 0x1240 = 73 vectors * 64byte ++ * 0x1000 is page saving sigreturn & restart code ++ */ ++ flush_icache_range(base, base + 0x3000); ++} ++ ++#if 0 ++COLE:use send_sigtrap instread ++ static __inline__ void do_trap(int trapnr, int signr, const char *str, ++ struct pt_regs *regs, ++ unsigned long error_code, siginfo_t * info) ++{ ++ if (user_mode(regs)) { ++ /* trap_signal */ ++ struct task_struct *tsk = current; ++ tsk->thread.error_code = error_code; ++ tsk->thread.trap_no = trapnr; ++ if (info) ++ force_sig_info(signr, info, tsk); ++ else ++ force_sig(signr, tsk); ++ return; ++ } else { ++ /* kernel_trap */ ++ if (!fixup_exception(regs)) ++ die(str, regs, error_code); ++ return; ++ } ++} ++#endif ++ ++/* ++ * I modified original debug_trap to apply KGDB stuff, ++ * Harry@Jul.18.2007 ++ */ ++void do_debug_trap(unsigned long entry, unsigned long addr, ++ unsigned long type, struct pt_regs *regs) ++{ ++ if (notify_die(DIE_DEBUG, "debug", regs, addr, type, SIGTRAP) ++ == NOTIFY_STOP) ++ return; ++ ++#if !defined(CONFIG_HSS) ++ /* clear the swbk; otherwise the user will see it */ ++ if (test_tsk_thread_flag(current, TIF_SINGLESTEP)) ++ ptrace_cancel_swbk(current); ++#endif ++ ++ /* do_trap(1, SIGTRAP, 0, regs, 0, NULL); */ ++ if (user_mode(regs)) { ++ /* trap_signal */ ++ send_sigtrap(current, regs, 0, TRAP_BRKPT); ++ } else { ++ /* kernel_trap */ ++ if (!fixup_exception(regs)) ++ die("unexpected kernel_trap", regs, 0); ++ } ++} ++ ++void unhandled_interruption(struct pt_regs *regs) ++{ ++ siginfo_t si; ++ printk("unhandled_interruption\n"); ++ show_regs(regs); ++ if (!user_mode(regs)) ++ do_exit(SIGKILL); ++ si.si_signo = SIGKILL; ++ si.si_errno = 0; ++ force_sig_info(SIGKILL, &si, current); ++} ++ ++void unhandled_exceptions(unsigned long entry, unsigned long addr, ++ unsigned long type, struct pt_regs *regs) ++{ ++ siginfo_t si; ++ printk("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry, ++ addr, type); ++ show_regs(regs); ++ if (!user_mode(regs)) ++ do_exit(SIGKILL); ++ si.si_signo = SIGKILL; ++ si.si_errno = 0; ++ si.si_addr = (void *)addr; ++ force_sig_info(SIGKILL, &si, current); ++} ++ ++extern int do_page_fault(unsigned long entry, unsigned long addr, ++ unsigned int error_code, struct pt_regs *regs); ++ ++/* ++ * 2:DEF dispatch for TLB MISC exception handler ++*/ ++ ++void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr, ++ unsigned long type, struct pt_regs *regs) ++{ ++ type = type & (ITYPE_mskINST | ITYPE_mskETYPE); ++ if ((type & 0xf) < 5) ++ do_page_fault(entry, addr, type, regs); ++ else ++ unhandled_exceptions(entry, addr, type, regs); ++} ++ ++int (*do_unaligned_access) (unsigned long entry, unsigned long addr, ++ unsigned long type, struct pt_regs * regs) = NULL; ++ ++EXPORT_SYMBOL(do_unaligned_access); ++ ++void do_revinsn(struct pt_regs *regs) ++{ ++ siginfo_t si; ++ printk("Reserved Instruction\n"); ++ show_regs(regs); ++ if (!user_mode(regs)) ++ do_exit(SIGILL); ++ si.si_signo = SIGILL; ++ si.si_errno = 0; ++ force_sig_info(SIGILL, &si, current); ++} ++ ++/* ++ * 7:DEF dispatch for General exception handler ++ */ ++void do_dispatch_general(unsigned long entry, unsigned long addr, ++ unsigned long itype, struct pt_regs *regs, ++ unsigned long oipc) ++{ ++ unsigned int swid = itype >> ITYPE_offSWID; ++ unsigned long type = itype & (ITYPE_mskINST | ITYPE_mskETYPE); ++ if (type == 0) { /* Alignment check */ ++ ++ if (do_unaligned_access) { ++ ++ int ret = do_unaligned_access(entry, addr, type, regs); ++ ++ if (ret == 0) ++ return; ++ ++ if (ret == -EFAULT) ++ printk ++ ("Unhandled unaligned access exception\n"); ++ } ++ do_page_fault(entry, addr, type, regs); ++ } else if (type == 1) /* Reserved instruction */ ++ do_revinsn(regs); ++ else if (type == 6) { /* Coprocessor */ ++ if (((GET_ITYPE() & ITYPE_mskSTYPE) >> ITYPE_offSTYPE) == 3) { ++#ifdef CONFIG_AUDIO ++ preempt_disable(); ++ do_audio_context_switch(type, regs); ++ preempt_enable(); ++#else ++ unhandled_exceptions(entry, addr, type, regs); ++#endif ++ } else { ++#ifdef CONFIG_FPU ++ do_fpu_exception(type, regs); ++#else ++ unhandled_exceptions(entry, addr, type, regs); ++#endif ++ } ++ } else if (type == 2 && swid == 0x1a) { ++ /* trap, used on v3 EDM target debugging workaround */ ++ /* ++ * DIPC(OIPC) is passed as parameter before ++ * interrupt is enabled, so the DIPC will not be corrupted ++ * even though interrupts are coming in ++ */ ++ /* ++ * 1. update ipc ++ * 2. update pt_regs ipc with oipc ++ * 3. update pt_regs ipsw (clear DEX) ++ */ ++ __asm__ volatile ("mtsr %0, $IPC\n\t"::"r" (oipc)); ++ regs->NDS32_ipc = oipc; ++ regs->NDS32_ipsw &= ~0x400; ++ do_debug_trap(entry, addr, itype, regs); ++ } else ++ unhandled_exceptions(entry, addr, type, regs); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/kernel/vmlinux.lds.S linux-3.4.110/arch/nds32/kernel/vmlinux.lds.S +--- linux-3.4.110.orig/arch/nds32/kernel/vmlinux.lds.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/kernel/vmlinux.lds.S 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,74 @@ ++#include ++#include ++#include ++#include ++ ++#define LOAD_OFFSET (PAGE_OFFSET - PHYS_OFFSET) ++#include ++ ++OUTPUT_ARCH(nds32) ++ENTRY(_stext_lma) ++jiffies = jiffies_64; ++ ++SECTIONS ++{ ++ _stext_lma = TEXTADDR - LOAD_OFFSET; ++ . = TEXTADDR; ++ __init_begin = .; ++ HEAD_TEXT_SECTION ++ INIT_TEXT_SECTION(PAGE_SIZE) ++ /* These sections are arch specific. */ ++ .arch_info : AT(ADDR(.arch_info) - LOAD_OFFSET) { ++ . = ALIGN(4); ++ VMLINUX_SYMBOL(__proc_info_begin) = .; ++ *(.proc.info.init) ++ VMLINUX_SYMBOL(__proc_info_end) = .; ++ __arch_info_begin = .; ++ *(.arch.info) ++ __arch_info_end = .; ++ __tagtable_begin = .; ++ *(.taglist) ++ __tagtable_end = .; ++ . = ALIGN(16); ++ __pv_table_begin = .; ++ *(.pv_table) ++ __pv_table_end = .; ++ __early_begin = .; ++ *(__early_param) ++ __early_end = .; ++ } ++ ++ INIT_DATA_SECTION(16) ++ PERCPU_SECTION(L1_CACHE_BYTES) ++ __init_end = .; ++ ++ . = ALIGN(PAGE_SIZE); ++ _stext = .; ++ /* Real text segment */ ++ .text : AT(ADDR(.text) - LOAD_OFFSET) { ++ _text = .; /* Text and read-only data */ ++ TEXT_TEXT ++ SCHED_TEXT ++ LOCK_TEXT ++ KPROBES_TEXT ++ IRQENTRY_TEXT ++ *(.fixup) ++ } ++ ++ _etext = .; /* End of text and rodata section */ ++ ++ _sdata = .; ++ RO_DATA_SECTION(PAGE_SIZE) ++ RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) ++ _edata = .; ++ ++ EXCEPTION_TABLE(16) ++ NOTES ++ BSS_SECTION(4, 4, 4) ++ _end = .; ++ ++ STABS_DEBUG ++ DWARF_DEBUG ++ ++ DISCARDS ++} +diff -Nur linux-3.4.110.orig/arch/nds32/lib/copy_page.S linux-3.4.110/arch/nds32/lib/copy_page.S +--- linux-3.4.110.orig/arch/nds32/lib/copy_page.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/copy_page.S 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * linux/arch/nds32/lib/copypage.S ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++#include ++#include ++ ++ .text ++ENTRY(copy_page) ++ pushm $r2, $r10 ++ movi $r2, PAGE_SIZE >> 5 ++.Lcopy_loop: ++ lmw.bim $r3, [$r1], $r10 ++ smw.bim $r3, [$r0], $r10 ++ subi45 $r2, #1 ++ bnez38 $r2, .Lcopy_loop ++ popm $r2, $r10 ++ ret ++ ++ENTRY(clear_page) ++ pushm $r1, $r9 ++ movi $r1, PAGE_SIZE >> 5 ++ movi55 $r2, #0 ++ movi55 $r3, #0 ++ movi55 $r4, #0 ++ movi55 $r5, #0 ++ movi55 $r6, #0 ++ movi55 $r7, #0 ++ movi55 $r8, #0 ++ movi55 $r9, #0 ++.Lclear_loop: ++ smw.bim $r2, [$r0], $r9 ++ subi45 $r1, #1 ++ bnez38 $r1, .Lclear_loop ++ popm $r1, $r9 ++ ret +diff -Nur linux-3.4.110.orig/arch/nds32/lib/csum_partial.c linux-3.4.110/arch/nds32/lib/csum_partial.c +--- linux-3.4.110.orig/arch/nds32/lib/csum_partial.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/csum_partial.c 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,135 @@ ++/* ++ * INET An implementation of the TCP/IP protocol suite for the LINUX ++ * operating system. INET is implemented using the BSD Socket ++ * interface as the means of communication with the user level. ++ * ++ * MIPS specific IP/TCP/UDP checksumming routines ++ * ++ * Authors: Ralf Baechle, ++ * Lots of code moved from tcp.c and ip.c; see those files ++ * for more names. ++ * ++ * 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. ++ */ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define addc(_t,_r) \ ++ __asm__ __volatile__ ( \ ++ "add\t%0, %0, %1\n\t" \ ++ "slt\t$p1, %0, %1\n\t" \ ++ "add\r%0, %0, $p1\n\t" \ ++ : "=r"(_t) \ ++ : "r"(_r), "0"(_t)); ++ ++static inline unsigned short from32to16(unsigned int x) ++{ ++ /* 32 bits --> 16 bits + carry */ ++ x = (x & 0xffff) + (x >> 16); ++ /* 16 bits + carry --> 16 bits including carry */ ++ x = (x & 0xffff) + (x >> 16); ++ return (unsigned short)x; ++} ++ ++static inline unsigned int do_csum(const unsigned char *buff, int len) ++{ ++ int odd; ++ register unsigned int result = 0; ++ register unsigned int count; ++ if (len <= 0) ++ goto out; ++ odd = 1 & (unsigned long)buff; ++ if (odd) { ++ result = be16_to_cpu(*buff); ++ len--; ++ buff++; ++ } ++ count = len >> 1; /* nr of 16-bit words.. */ ++ if (count) { ++ if (2 & (unsigned long)buff) { ++ result += *(unsigned short *)buff; ++ count--; ++ len -= 2; ++ buff += 2; ++ } ++ count >>= 1; /* nr of 32-bit words.. */ ++ if (count) { ++ while (count >= 8) { ++ __asm__ ++ __volatile__("lmw.bi $r17, [%1], $r24\n\t" ++ "add\t%0, %0, $r17\n\t" ++ "slt\t$p1, %0, $r17\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r18\n\t" ++ "slt\t$p1, %0, $r18\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r19\n\t" ++ "slt\t$p1, %0, $r19\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r20\n\t" ++ "slt\t$p1, %0, $r20\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r21\n\t" ++ "slt\t$p1, %0, $r21\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r22\n\t" ++ "slt\t$p1, %0, $r22\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r23\n\t" ++ "slt\t$p1, %0, $r23\n\t" ++ "add\r%0, %0, $p1\n\t" ++ "add\t%0, %0, $r24\n\t" ++ "slt\t$p1, %0, $r24\n\t" ++ "add\r%0, %0, $p1\n\t":"=r" ++ (result) ++ :"r"(buff), "0"(result) ++ :"$r17", "$r18", "$r19", ++ "$r20", "$r21", "$r22", "$r23", ++ "$r24"); ++ count -= 8; ++ buff += 32; ++ } ++ while (count) { ++ unsigned int w = *(unsigned int *)buff; ++ count--; ++ buff += 4; ++ addc(result, w); ++ } ++ result = (result & 0xffff) + (result >> 16); ++ } ++ if (len & 2) { ++ result += *(unsigned short *)buff; ++ buff += 2; ++ } ++ } ++ if (len & 1) ++ result += le16_to_cpu(*buff); ++ result = from32to16(result); ++ if (odd) ++ result = swab16(result); ++out: ++ return result; ++} ++ ++/* ++ * computes a partial checksum, e.g. for TCP/UDP fragments ++ */ ++/* ++ * why bother folding? ++ */ ++unsigned int csum_partial(const void *buff, int len, unsigned int sum) ++{ ++ unsigned int result = 0; ++// printk("csum_partial %x %x %x\n", buff, len, sum); ++ result = do_csum(buff, len); ++ addc(result, sum); ++ return (unsigned short)from32to16(result); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/lib/csum_partial_copy.c linux-3.4.110/arch/nds32/lib/csum_partial_copy.c +--- linux-3.4.110.orig/arch/nds32/lib/csum_partial_copy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/csum_partial_copy.c 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,58 @@ ++/* ++ * INET An implementation of the TCP/IP protocol suite for the LINUX ++ * operating system. INET is implemented using the BSD Socket ++ * interface as the means of communication with the user level. ++ * ++ * MIPS specific IP/TCP/UDP checksumming routines ++ * ++ * Authors: Ralf Baechle, ++ * Lots of code moved from tcp.c and ip.c; see those files ++ * for more names. ++ * ++ * 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. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * copy while checksumming, otherwise like csum_partial ++ */ ++unsigned int csum_partial_copy_nocheck(const unsigned char *src, ++ unsigned char *dst, int len, ++ unsigned int sum) ++{ ++ /* ++ * It's 2:30 am and I don't feel like doing it real ... ++ * This is lots slower than the real thing (tm) ++ */ ++ sum = csum_partial(src, len, sum); ++ memcpy(dst, src, len); ++ ++ return sum; ++} ++ ++/* ++ * Copy from userspace and compute checksum. If we catch an exception ++ * then zero the rest of the buffer. ++ */ ++unsigned int csum_partial_copy_from_user(const unsigned char *src, ++ unsigned char *dst, int len, ++ unsigned int sum, int *err_ptr) ++{ ++ int missing; ++ ++ missing = copy_from_user(dst, src, len); ++ if (missing) { ++ memset(dst + len - missing, 0, missing); ++ *err_ptr = -EFAULT; ++ } ++ ++ return csum_partial(dst, len, sum); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/lib/divmod.c linux-3.4.110/arch/nds32/lib/divmod.c +--- linux-3.4.110.orig/arch/nds32/lib/divmod.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/divmod.c 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,46 @@ ++extern unsigned long udivmodsi4(unsigned long num, unsigned long den, ++ int modwanted); ++ ++long __divsi3(long a, long b) ++{ ++ int neg = 0; ++ long res; ++ ++ if (a < 0) { ++ a = -a; ++ neg = !neg; ++ } ++ ++ if (b < 0) { ++ b = -b; ++ neg = !neg; ++ } ++ ++ res = udivmodsi4(a, b, 0); ++ ++ if (neg) ++ res = -res; ++ ++ return res; ++} ++ ++long __modsi3(long a, long b) ++{ ++ int neg = 0; ++ long res; ++ ++ if (a < 0) { ++ a = -a; ++ neg = 1; ++ } ++ ++ if (b < 0) ++ b = -b; ++ ++ res = udivmodsi4(a, b, 1); ++ ++ if (neg) ++ res = -res; ++ ++ return res; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/lib/findbit.S linux-3.4.110/arch/nds32/lib/findbit.S +--- linux-3.4.110.orig/arch/nds32/lib/findbit.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/findbit.S 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,108 @@ ++/* ++ * linux/arch/nds32/lib/findbit.S ++ * ++ * Copyright (C) 1995-2000 Russell King ++ * Copyright (C) 2006 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++ ++ .text ++ ++/* ++ * Purpose : Find a 'zero' bit ++ * Prototype: int find_first_zero_bit(void *addr, int maxbit); ++ */ ++ENTRY(_find_first_zero_bit) ++ move $r2, #0 ++ move $p0, #0 ! Reset bit count ++next_word: ++ move $r4, #4 ++ lmw.bim $p1, [$r0], $p1 ++ li $r3, #0xffffffff ! Inversion mask ++ xor $p1, $p1, $r3 ! Inverted the word ++ addi $p0, $p0, #32 ++ beqz $p1, next_word ++ addi $p0, $p0, #-32 ++next_byte: ++ beqz $r4, next_word ++ andi $r3, $p1, #0xff ! Get the next byte ++ bnez $r3, found ! Found zero bit in this byte ++ addi $p0, $p0, #8 ! Update bit count ++ addi $r4, $r4, #-1 ++ srli $p1, $p1, #8 ++ bgt $r1, $p0, next_byte ++ addi $r0, $r1, #1 ! Return not found ++ ret ++ ++/* ++ * Purpose : Find next 'zero' bit ++ * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset) ++ */ ++ENTRY(_find_next_zero_bit) ++ beqz $r2, _find_first_zero_bit ! If offset=0, goto find_first_zero_bit ++ srli $p0, $r2, #5 ! Get offset byte count ++ slli $p0, $p0, #2 ++ add $r0, $r0, $p0 ! $r0 is the first word to load ++ lmw.bim $p1, [$r0], $p1 ++ li $p0, #0xffffffff ! Inversion mask ++ xor $p1, $p1, $p0 ! Inverted the word ++ andi $r4, $r2, #31 ! Left bits in offset ++ srl $p1, $p1, $r4 ! Shift out the left bits ++ xor $p0, $p0, $p0 ++ subri $r4, $r4, #31 ++loop: ++ andi $r3, $p1, #0xff ! The first byte to check ++ bnez $r3, found ! Found zero bit in this byte ++ addi $p0, $p0, #8 ++ addi $r4, $r4, #-8 ++ srli $p1, $p1, #8 ! Move on to the next byte ++ bgtz $r4, loop ++ b next_word ++ ++/* ++ * One or more bits in the LSB of $p1 are assumed to be set. ++ */ ++ ++found: ++ move $p1, $r3 ++ xor $r4, $r4, $r4 ++ andi $r5, $p1, #0x0f ! Get bits 0-3 ++ move $r3, #4 ! For 0 case (no set bit found) ++ cmovn $r3, $r4, $r5 ! Not 0 case (There's set bit in these 4 bits) ++ add $p0, $p0, $r3 ! Update bit count ++ slli $r3, $p1, #4 ! Not 0 case (Find set bit in these 4 bits) ++ cmovn $p1, $r3, $r5 ! For 0 case (Find set bit in the rest 4 bits) ++ andi $r5, $p1, #0x30 ! Get 4-5 ++ move $r3, #2 ! For 0 case (no set bit found) ++ cmovn $r3, $r4, $r5 ! Not 0 case (There's set bit in these 2 bits) ++ add $p0, $p0, $r3 ! Update bit count ++ slli $r3, $p1, #2 ! Not 0 case (Find set bit in these 2 bits) ++ cmovn $p1, $r3, $r5 ! For 0 case (Find set bit in the rest 2 bits) ++ andi $r5, $p1, #0x40 ! Get bit 6 ++ move $r3, #1 ! For 0 case (bit 6 is not set) ++ cmovn $r3, $r4, $r5 ! Not 0 case (bit 6 is set bit) ++ add $r5, $p0, $r3 ++ add $r0, $r5, $r2 ++ ret ++ ++ENTRY(_ext2_find_first_zero_bit) ++ pushm $r2, $r4 ++ move $r2, #0 ++ move $p0, #0 ! Reset bit count ++1: ++ lbi.bi $r3, [$r0], #1 ++ xori $r3, $r3, #0xff ++ addi $p0, $p0, #8 ++ beqz $r3, 1b ++ addi $p0, $p0, #-8 ++ ++2: ++ b found ! No return ++ popm $r2, $r4 ++ ret ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/getuser.S linux-3.4.110/arch/nds32/lib/getuser.S +--- linux-3.4.110.orig/arch/nds32/lib/getuser.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/getuser.S 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,79 @@ ++/* ++ * linux/arch/nds32/lib/getuser.S ++ * ++ * Copyright (C) 2001 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds ++ * ++ * These functions have a non-standard call interface to make them more ++ * efficient, especially as they return an error value in addition to ++ * the "real" return value. ++ * ++ * __get_user_X ++ * ++ * Inputs: $r0 contains the address ++ * Outputs: $r0 is the error code ++ * $r2, $r3 contains the zero-extended value ++ * lr corrupted ++ * ++ * No other registers must be altered. (see include/asm-nds32/uaccess.h ++ * for specific ASM register usage). ++ * ++ * Note that ADDR_LIMIT is either 0 or 0xc0000000. ++ * Note also that it is intended that __get_user_bad is not global. ++ */ ++#include ++#include ++#include ++#include ++ ++ ++ENTRY(__get_user_1) ++1: lbi $r2, [$r0] ++ move $r0, #0 ++ ret ++ ++ENTRY(__get_user_2) ++2: lbi.bi $r2, [$r0], #1 ++3: lbi $r3, [$r0] ++#ifndef __NDS32_EB__ ++ slli $p1, $r3, #8 ++ or $r2, $r2, $p1 ++#else ++ slli $p1, $r2, #8 ++ or $r2, $r3, $p1 ++#endif ++ move $r0, #0 ++ ret ++ ++ENTRY(__get_user_4) ++4: lwi $r2, [$r0] ++ move $r0, #0 ++ ret ++ ++ENTRY(__get_user_8) ++5: lwi.bi $r2, [$r0], #4 ++6: lwi $r3, [$r0] ++ move $r0, #0 ++ ret ++ ++__get_user_bad_8: ++ move $r3, #0 ++__get_user_bad: ++ move $r2, #0 ++ move $r0, #-EFAULT ++ ret ++ ++.section __ex_table, "a" ++ .long 1b, __get_user_bad ++ .long 2b, __get_user_bad ++ .long 3b, __get_user_bad ++ .long 4b, __get_user_bad ++ .long 5b, __get_user_bad_8 ++ .long 6b, __get_user_bad_8 ++.previous +diff -Nur linux-3.4.110.orig/arch/nds32/lib/libgcc2.c linux-3.4.110/arch/nds32/lib/libgcc2.c +--- linux-3.4.110.orig/arch/nds32/lib/libgcc2.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/libgcc2.c 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,351 @@ ++#define BITS_PER_UNIT 8 ++#include "longlong.h" ++typedef unsigned int UQItype __attribute__ ((mode(QI))); ++typedef int SItype __attribute__ ((mode(SI))); ++typedef unsigned int USItype __attribute__ ((mode(SI))); ++typedef int DItype __attribute__ ((mode(DI))); ++typedef unsigned int UDItype __attribute__ ((mode(DI))); ++ ++typedef int word_type __attribute__ ((mode(__word__))); ++ ++#define Wtype SItype ++#define UWtype USItype ++#define DWtype DItype ++#define UDWtype UDItype ++ ++#ifdef __NDS32_EB__ ++struct DWstruct { ++ Wtype high, low; ++}; ++#else ++struct DWstruct { ++ Wtype low, high; ++}; ++#endif ++ ++typedef union { ++ struct DWstruct s; ++ DWtype ll; ++} DWunion; ++DWtype __negdi2(DWtype u) ++{ ++ const DWunion uu = {.ll = u }; ++ const DWunion w = { {.low = -uu.s.low, ++ .high = -uu.s.high - ((UWtype) - uu.s.low > 0)} ++ }; ++ ++ return w.ll; ++} ++ ++DWtype __lshrdi3(DWtype u, word_type b) ++{ ++ const DWunion uu = {.ll = u }; ++ const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b; ++ DWunion w; ++ ++ if (b == 0) ++ return u; ++ ++ if (bm <= 0) { ++ w.s.high = 0; ++ w.s.low = (UWtype) uu.s.high >> -bm; ++ } else { ++ const UWtype carries = (UWtype) uu.s.high << bm; ++ ++ w.s.high = (UWtype) uu.s.high >> b; ++ w.s.low = ((UWtype) uu.s.low >> b) | carries; ++ } ++ ++ return w.ll; ++} ++ ++DWtype __ashldi3(DWtype u, word_type b) ++{ ++ const DWunion uu = {.ll = u }; ++ const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b; ++ DWunion w; ++ ++ if (b == 0) ++ return u; ++ ++ if (bm <= 0) { ++ w.s.low = 0; ++ w.s.high = (UWtype) uu.s.low << -bm; ++ } else { ++ const UWtype carries = (UWtype) uu.s.low >> bm; ++ ++ w.s.low = (UWtype) uu.s.low << b; ++ w.s.high = ((UWtype) uu.s.high << b) | carries; ++ } ++ ++ return w.ll; ++} ++ ++DWtype __ashrdi3(DWtype u, word_type b) ++{ ++ const DWunion uu = {.ll = u }; ++ const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b; ++ DWunion w; ++ ++ if (b == 0) ++ return u; ++ ++ if (bm <= 0) { ++ /* w.s.high = 1..1 or 0..0 */ ++ w.s.high = uu.s.high >> (sizeof(Wtype) * BITS_PER_UNIT - 1); ++ w.s.low = uu.s.high >> -bm; ++ } else { ++ const UWtype carries = (UWtype) uu.s.high << bm; ++ ++ w.s.high = uu.s.high >> b; ++ w.s.low = ((UWtype) uu.s.low >> b) | carries; ++ } ++ ++ return w.ll; ++} ++ ++DWtype __muldi3(DWtype u, DWtype v) ++{ ++ const DWunion uu = {.ll = u }; ++ const DWunion vv = {.ll = v }; ++ DWunion w = {.ll = __umulsidi3(uu.s.low, vv.s.low) }; ++ ++ w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high ++ + (UWtype) uu.s.high * (UWtype) vv.s.low); ++ ++ return w.ll; ++} ++ ++const UQItype __clz_tab[] = { ++ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, ++ 5, 5, 5, 5, 5, 5, 5, 5, ++ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, ++ 6, 6, 6, 6, 6, 6, 6, 6, ++ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, ++ 7, 7, 7, 7, 7, 7, 7, 7, ++ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, ++ 8, 8, 8, 8, 8, 8, 8, 8, ++}; ++ ++UDWtype __udivmoddi4(UDWtype n, UDWtype d, UDWtype * rp) ++{ ++ const DWunion nn = {.ll = n }; ++ const DWunion dd = {.ll = d }; ++ DWunion rr; ++ UWtype d0, d1, n0, n1, n2; ++ UWtype q0, q1; ++ UWtype b, bm; ++ DWunion ww; ++ ++ d0 = dd.s.low; ++ d1 = dd.s.high; ++ n0 = nn.s.low; ++ n1 = nn.s.high; ++ ++#if !UDIV_NEEDS_NORMALIZATION ++ if (d1 == 0) { ++ if (d0 > n1) { ++ /* 0q = nn / 0D */ ++ ++ udiv_qrnnd(q0, n0, n1, n0, d0); ++ q1 = 0; ++ ++ /* Remainder in n0. */ ++ } else { ++ /* qq = NN / 0d */ ++ ++ if (d0 == 0) ++ d0 = 1 / d0; /* Divide intentionally by zero. */ ++ ++ udiv_qrnnd(q1, n1, 0, n1, d0); ++ udiv_qrnnd(q0, n0, n1, n0, d0); ++ ++ /* Remainder in n0. */ ++ } ++ ++ if (rp != 0) { ++ rr.s.low = n0; ++ rr.s.high = 0; ++ *rp = rr.ll; ++ } ++ } ++#else /* UDIV_NEEDS_NORMALIZATION */ ++ ++ if (d1 == 0) { ++ if (d0 > n1) { ++ /* 0q = nn / 0D */ ++ ++ count_leading_zeros(bm, d0); ++ ++ if (bm != 0) { ++ /* Normalize, i.e. make the most significant bit of the ++ denominator set. */ ++ ++ d0 = d0 << bm; ++ n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); ++ n0 = n0 << bm; ++ } ++ ++ udiv_qrnnd(q0, n0, n1, n0, d0); ++ q1 = 0; ++ ++ /* Remainder in n0 >> bm. */ ++ } else { ++ /* qq = NN / 0d */ ++ ++ if (d0 == 0) ++ d0 = 1 / d0; /* Divide intentionally by zero. */ ++ ++ count_leading_zeros(bm, d0); ++ ++ if (bm == 0) { ++ /* From (n1 >= d0) /\ (the most significant bit of d0 is set), ++ conclude (the most significant bit of n1 is set) /\ (the ++ leading quotient digit q1 = 1). ++ ++ This special case is necessary, not an optimization. ++ (Shifts counts of W_TYPE_SIZE are undefined.) */ ++ ++ n1 -= d0; ++ q1 = 1; ++ } else { ++ /* Normalize. */ ++ ++ b = W_TYPE_SIZE - bm; ++ ++ d0 = d0 << bm; ++ n2 = n1 >> b; ++ n1 = (n1 << bm) | (n0 >> b); ++ n0 = n0 << bm; ++ ++ udiv_qrnnd(q1, n1, n2, n1, d0); ++ } ++ ++ /* n1 != d0... */ ++ ++ udiv_qrnnd(q0, n0, n1, n0, d0); ++ ++ /* Remainder in n0 >> bm. */ ++ } ++ ++ if (rp != 0) { ++ rr.s.low = n0 >> bm; ++ rr.s.high = 0; ++ *rp = rr.ll; ++ } ++ } ++#endif /* UDIV_NEEDS_NORMALIZATION */ ++ ++ else { ++ if (d1 > n1) { ++ /* 00 = nn / DD */ ++ ++ q0 = 0; ++ q1 = 0; ++ ++ /* Remainder in n1n0. */ ++ if (rp != 0) { ++ rr.s.low = n0; ++ rr.s.high = n1; ++ *rp = rr.ll; ++ } ++ } else { ++ /* 0q = NN / dd */ ++ ++ count_leading_zeros(bm, d1); ++ if (bm == 0) { ++ /* From (n1 >= d1) /\ (the most significant bit of d1 is set), ++ conclude (the most significant bit of n1 is set) /\ (the ++ quotient digit q0 = 0 or 1). ++ ++ This special case is necessary, not an optimization. */ ++ ++ /* The condition on the next line takes advantage of that ++ n1 >= d1 (true due to program flow). */ ++ if (n1 > d1 || n0 >= d0) { ++ q0 = 1; ++ sub_ddmmss(n1, n0, n1, n0, d1, d0); ++ } else ++ q0 = 0; ++ ++ q1 = 0; ++ ++ if (rp != 0) { ++ rr.s.low = n0; ++ rr.s.high = n1; ++ *rp = rr.ll; ++ } ++ } else { ++ UWtype m1, m0; ++ /* Normalize. */ ++ ++ b = W_TYPE_SIZE - bm; ++ ++ d1 = (d1 << bm) | (d0 >> b); ++ d0 = d0 << bm; ++ n2 = n1 >> b; ++ n1 = (n1 << bm) | (n0 >> b); ++ n0 = n0 << bm; ++ ++ udiv_qrnnd(q0, n1, n2, n1, d1); ++ umul_ppmm(m1, m0, q0, d0); ++ ++ if (m1 > n1 || (m1 == n1 && m0 > n0)) { ++ q0--; ++ sub_ddmmss(m1, m0, m1, m0, d1, d0); ++ } ++ ++ q1 = 0; ++ ++ /* Remainder in (n1n0 - m1m0) >> bm. */ ++ if (rp != 0) { ++ sub_ddmmss(n1, n0, n1, n0, m1, m0); ++ rr.s.low = (n1 << b) | (n0 >> bm); ++ rr.s.high = n1 >> bm; ++ *rp = rr.ll; ++ } ++ } ++ } ++ } ++ ++ ww.s.low = q0, ww.s.high = q1; ++ return ww.ll; ++} ++ ++UDWtype __umoddi3(UDWtype u, UDWtype v) ++{ ++ UDWtype w; ++ ++ (void)__udivmoddi4(u, v, &w); ++ ++ return w; ++} ++ ++UDWtype __udivdi3(UDWtype n, UDWtype d) ++{ ++ return __udivmoddi4(n, d, (UDWtype *) 0); ++} ++ ++word_type __ucmpdi2(DWtype a, DWtype b) ++{ ++ const DWunion au = {.ll = a }; ++ const DWunion bu = {.ll = b }; ++ ++ if ((UWtype) au.s.high < (UWtype) bu.s.high) ++ return 0; ++ else if ((UWtype) au.s.high > (UWtype) bu.s.high) ++ return 2; ++ if ((UWtype) au.s.low < (UWtype) bu.s.low) ++ return 0; ++ else if ((UWtype) au.s.low > (UWtype) bu.s.low) ++ return 2; ++ return 1; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/lib/longlong.h linux-3.4.110/arch/nds32/lib/longlong.h +--- linux-3.4.110.orig/arch/nds32/lib/longlong.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/longlong.h 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,105 @@ ++#define __BITS4 (W_TYPE_SIZE / 4) ++#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) ++#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) ++#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) ++ ++#define W_TYPE_SIZE (4 * 8) ++#define UHWtype USItype ++ ++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ ++ do { \ ++ UWtype __x; \ ++ __x = (al) - (bl); \ ++ (sh) = (ah) - (bh) - (__x > (al)); \ ++ (sl) = __x; \ ++ } while (0) ++ ++#define umul_ppmm(w1, w0, u, v) \ ++ do { \ ++ UWtype __x0, __x1, __x2, __x3; \ ++ UHWtype __ul, __vl, __uh, __vh; \ ++ \ ++ __ul = __ll_lowpart (u); \ ++ __uh = __ll_highpart (u); \ ++ __vl = __ll_lowpart (v); \ ++ __vh = __ll_highpart (v); \ ++ \ ++ __x0 = (UWtype) __ul * __vl; \ ++ __x1 = (UWtype) __ul * __vh; \ ++ __x2 = (UWtype) __uh * __vl; \ ++ __x3 = (UWtype) __uh * __vh; \ ++ \ ++ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ ++ __x1 += __x2; /* but this indeed can */ \ ++ if (__x1 < __x2) /* did we get it? */ \ ++ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ ++ \ ++ (w1) = __x3 + __ll_highpart (__x1); \ ++ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ ++ } while (0) ++ ++#define __umulsidi3(u, v) \ ++ ({DWunion __w; \ ++ umul_ppmm (__w.s.high, __w.s.low, u, v); \ ++ __w.ll; }) ++ ++#define __udiv_qrnnd_c(q, r, n1, n0, d) \ ++ do { \ ++ UWtype __d1, __d0, __q1, __q0; \ ++ UWtype __r1, __r0, __m; \ ++ __d1 = __ll_highpart (d); \ ++ __d0 = __ll_lowpart (d); \ ++ \ ++ __r1 = (n1) % __d1; \ ++ __q1 = (n1) / __d1; \ ++ __m = (UWtype) __q1 * __d0; \ ++ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ ++ if (__r1 < __m) \ ++ { \ ++ __q1--, __r1 += (d); \ ++ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ ++ if (__r1 < __m) \ ++ __q1--, __r1 += (d); \ ++ } \ ++ __r1 -= __m; \ ++ \ ++ __r0 = __r1 % __d1; \ ++ __q0 = __r1 / __d1; \ ++ __m = (UWtype) __q0 * __d0; \ ++ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ ++ if (__r0 < __m) \ ++ { \ ++ __q0--, __r0 += (d); \ ++ if (__r0 >= (d)) \ ++ if (__r0 < __m) \ ++ __q0--, __r0 += (d); \ ++ } \ ++ __r0 -= __m; \ ++ \ ++ (q) = (UWtype) __q1 * __ll_B | __q0; \ ++ (r) = __r0; \ ++ } while (0) ++ ++#define UDIV_NEEDS_NORMALIZATION 1 ++#define udiv_qrnnd __udiv_qrnnd_c ++ ++#define count_leading_zeros(count, x) \ ++ do { \ ++ UWtype __xr = (x); \ ++ UWtype __a; \ ++ \ ++ if (W_TYPE_SIZE <= 32) \ ++ { \ ++ __a = __xr < ((UWtype)1<<2*__BITS4) \ ++ ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ ++ : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ ++ } \ ++ else \ ++ { \ ++ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ ++ if (((__xr >> __a) & 0xff) != 0) \ ++ break; \ ++ } \ ++ \ ++ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ ++ } while (0) +diff -Nur linux-3.4.110.orig/arch/nds32/lib/Makefile linux-3.4.110/arch/nds32/lib/Makefile +--- linux-3.4.110.orig/arch/nds32/lib/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/Makefile 2016-04-07 10:20:50.950081334 +0200 +@@ -0,0 +1,19 @@ ++# ++# linux/arch/nds32/lib/Makefile ++# ++# Copyright (C) 2006 Andes Technology Corporation ++# ++ ++lib-y := csum_partial_copy.o csum_partial.o \ ++ copy_page.o memcpy.o memmove.o \ ++ memset.o memzero.o strncpy_from_user.o \ ++ strnlen_user.o strchr.o strrchr.o \ ++ uaccess.o getuser.o \ ++ putuser.o libgcc2.o divmod.o udivmod.o udivmodsi4.o ++ ++ifdef CONFIG_FUNCTION_TRACER ++CFLAGS_REMOVE_libgcc2.o = -pg ++CFLAGS_REMOVE_divmod.o = -pg ++CFLAGS_REMOVE_udivmod.o = -pg ++CFLAGS_REMOVE_udivmodsi4.o = -pg ++endif +diff -Nur linux-3.4.110.orig/arch/nds32/lib/memcpy.S linux-3.4.110/arch/nds32/lib/memcpy.S +--- linux-3.4.110.orig/arch/nds32/lib/memcpy.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/memcpy.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,101 @@ ++/* ++ * linux/arch/nds32/lib/memcpy.S -- Memory copy function. ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2001 Hiroyuki Kondo, and Hirokazu Takata ++ * Copyright (C) 2004 Hirokazu Takata ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ */ ++ ++#include ++ ++/* ++ void *memcpy(void *dst, const void *src, int n); ++ ++ dst: $r0 ++ src: $r1 ++ n : $r2 ++ ret: $r0 - pointer to the memory area dst. ++*/ ++ ++#include ++ ++ .text ++ ++ENTRY(memcpy) ++ move $r5, $r0 ++ beq $r0, $r1, quit_memcpy ++ beqz $r2, quit_memcpy ++ srli $r3, $r2, #5 ! check if len < cache-line size 32 ++ beqz $r3, word_copy_entry ++ andi $r4, $r0, #0x3 ! check byte-align ++ beqz $r4, unalign_word_copy_entry ++ ++ addi $r4, $r4,#-4 ++ abs $r4, $r4 ! check how many un-align byte to copy ++ sub $r2, $r2, $r4 ! update $R2 ++ ++unalign_byte_copy: ++ lbi.bi $r3, [$r1], #1 ++ addi $r4, $r4, #-1 ++ sbi.bi $r3, [$r0], #1 ++ bnez $r4, unalign_byte_copy ++ beqz $r2, quit_memcpy ++ ++unalign_word_copy_entry: ++ andi $r3, $r0, 0x1f ! check cache-line unaligncount ++ beqz $r3, cache_copy ++ ++ addi $r3, $r3, #-32 ++ abs $r3, $r3 ++ sub $r2, $r2, $r3 ! update $R2 ++ ++unalign_word_copy: ++ lmw.bim $r4, [$r1], $r4 ++ addi $r3, $r3, #-4 ++ smw.bim $r4, [$r0], $r4 ++ bnez $r3, unalign_word_copy ++ beqz $r2, quit_memcpy ++ ++ addi $r3, $r2, #-32 ! to check $r2< cache_line , than go to word_copy ++ bltz $r3, word_copy_entry ++cache_copy: ++ srli $r3, $r2, #5 ++ beqz $r3, word_copy_entry ++ pushm $r6, $r13 ++3: ++ lmw.bim $r6, [$r1], $r13 ++ addi $r3, $r3, #-1 ++ smw.bim $r6, [$r0], $r13 ++ bnez $r3, 3b ++ popm $r6, $r13 ++ ++word_copy_entry: ++ andi $r2, $r2, #31 ++ ++ beqz $r2, quit_memcpy ++5: ++ srli $r3, $r2, #2 ++ beqz $r3, byte_copy ++word_copy: ++ lmw.bim $r4, [$r1], $r4 ++ addi $r3, $r3, #-1 ++ smw.bim $r4, [$r0], $r4 ++ bnez $r3, word_copy ++ andi $r2, $r2, #3 ++ beqz $r2, quit_memcpy ++byte_copy: ++ lbi.bi $r3, [$r1], #1 ++ addi $r2, $r2, #-1 ++ ++ sbi.bi $r3, [$r0], #1 ++ bnez $r2, byte_copy ++quit_memcpy: ++ move $r0, $r5 ++ ret ++ ++ .end +diff -Nur linux-3.4.110.orig/arch/nds32/lib/memmove.S linux-3.4.110/arch/nds32/lib/memmove.S +--- linux-3.4.110.orig/arch/nds32/lib/memmove.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/memmove.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,80 @@ ++/* ++ * linux/arch/nds32/lib/memmove.S -- Memory move function. ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2001 Hiroyuki Kondo, and Hirokazu Takata ++ * Copyright (C) 2004 Hirokazu Takata ++ * Copyright (C) 2006 Andes Technology Corporation ++ * ++ */ ++ ++#include ++ ++/* ++ void *memmove(void *dst, const void *src, int n); ++ ++ dst: $r0 ++ src: $r1 ++ n : $r2 ++ ret: $r0 - pointer to the memory area dst. ++*/ ++ .text ++ ++ENTRY(memmove) ++ move $r5, $r0 ! Set return value = det ++ beq $r0, $r1, exit_memcpy ! Exit when det = src ++ beqz $r2, exit_memcpy ! Exit when n = 0 ++ pushm $t0, $t1 ! Save reg ++ srli $p1, $r2, #2 ! $p1 is how many words to copy ++ ++ ! Avoid data lost when memory overlap ++ ! Copy data reversely when src < dst ++ slt $p0, $r0, $r1 ! check if $r0 < $r1 ++ beqz $p0, do_reverse ! branch if dst > src ++ ++ ! No reverse, dst < src ++ andi $r2, $r2, #3 ! How many bytes are less than a word ++ li $t0, #1 ! Determining copy direction in byte_cpy ++ beqz $p1, byte_cpy ! When n is less than a word ++ ++word_cpy: ++ lmw.bim $p0, [$r1], $p0 ! Read a word from src ++ addi $p1, $p1, #-1 ! How many words left to copy ++ smw.bim $p0, [$r0], $p0 ! Copy the word to det ++ bnez $p1, word_cpy ! If remained words > 0 ++ beqz $r2, end_memcpy ! No left bytes to copy ++ b byte_cpy ++ ++do_reverse: ++ add $r0, $r0, $r2 ! Start with the end of $r0 ++ add $r1, $r1, $r2 ! Start with the end of $r1 ++ andi $r2, $r2, #3 ! How many bytes are less than a word ++ li $t0, #-1 ! Determining copy direction in byte_cpy ++ beqz $p1, reverse_byte_cpy ! When n is less than a word ++ ++reverse_word_cpy: ++ lmw.adm $p0, [$r1], $p0 ! Read a word from src ++ addi $p1, $p1, #-1 ! How many words left to copy ++ smw.adm $p0, [$r0], $p0 ! Copy the word to det ++ bnez $p1, reverse_word_cpy ! If remained words > 0 ++ beqz $r2, end_memcpy ! No left bytes to copy ++ ++reverse_byte_cpy: ++ addi $r0, $r0, #-1 ++ addi $r1, $r1, #-1 ++byte_cpy: ! Less than 4 bytes to copy now ++ lb.bi $p0, [$r1], $t0 ! Read a byte from src ++ addi $r2, $r2, #-1 ! How many bytes left to copy ++ sb.bi $p0, [$r0], $t0 ! copy the byte to det ++ bnez $r2, byte_cpy ! If remained bytes > 0 ++ ++end_memcpy: ++ popm $t0, $t1 ++exit_memcpy: ++ move $r0, $r5 ++ ret ++ ++ .end +diff -Nur linux-3.4.110.orig/arch/nds32/lib/memset.S linux-3.4.110/arch/nds32/lib/memset.S +--- linux-3.4.110.orig/arch/nds32/lib/memset.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/memset.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,51 @@ ++ ++/* ++ * linux/arch/nds32/lib/memset.S -- memset function. ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2001,2002 Hiroyuki Kondo, and Hirokazu Takata ++ * Copyright (C) 2004 Hirokazu Takata ++ * Copyright (C) 2006 Andes Technology Corporation ++ * ++ */ ++#include ++#include ++ ++/* ++ void *memset(void *dst, int val, int len); ++ ++ dst: $r0 ++ val: $r1 ++ len: $r2 ++ ret: $r0 - pointer to the memory area dst. ++*/ ++ .text ++ENTRY(memset) ++ move $r5, $r0 ! Return value ++ beqz $r2, end_memset ! Exit when len = 0 ++ srli $p1, $r2, 2 ! $p1 is how many words to copy ++ andi $r2, $r2, 3 ! How many bytes are less than a word ++ beqz $p1, byte_set ! When n is less than a word ++ ++ ! set $r1 from ??????ab to abababab ++ andi $r1, $r1, #0x00ff ! $r1 = 000000ab ++ slli $p0, $r1, #8 ! $p0 = 0000ab00 ++ or $r1, $r1, $p0 ! $r1 = 0000abab ++ slli $p0, $r1, #16 ! $p0 = abab0000 ++ or $r1, $r1, $p0 ! $r1 = abababab ++word_set: ++ addi $p1, $p1, #-1 ! How many words left to copy ++ smw.bim $r1, [$r0], $r1 ! Copy the word to det ++ bnez $p1, word_set ! Still words to set, continue looping ++ beqz $r2, end_memset ! No left byte to set ++byte_set: ! Less than 4 bytes left to set ++ addi $r2, $r2, #-1 ! Decrease len by 1 ++ sbi.bi $r1, [$r0], #1 ! Set data of the next byte to $r1 ++ bnez $r2, byte_set ! Still bytes left to set ++end_memset: ++ move $r0, $r5 ++ ret ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/memzero.S linux-3.4.110/arch/nds32/lib/memzero.S +--- linux-3.4.110.orig/arch/nds32/lib/memzero.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/memzero.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * linux/arch/nds32/lib/memzero.S ++ * ++ * Copyright (C) 1995-2000 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++ ++ .text ++/* ++ * void *__memzero(void *dst, int len); ++ * ++ * dst: $r0 ++ * len: $r1 ++ * ret: $r0 - pointer to the memory area dst. ++ * ++ * Call memset(dst, 0, len) to perform memzero. ++ * Currently no optimization because only being referenced in 31 files ++ * (For comparison, memset being referenced in 2527 files) ++ */ ++ENTRY(__memzero) ++ beqz $r1, 1f ++ push $lp ++ move $r2, $r1 ++ move $r1, #0 ++ push $r0 ++ bal memset ++ pop $r0 ++ pop $lp ++1: ++ ret +diff -Nur linux-3.4.110.orig/arch/nds32/lib/putuser.S linux-3.4.110/arch/nds32/lib/putuser.S +--- linux-3.4.110.orig/arch/nds32/lib/putuser.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/putuser.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,68 @@ ++/* ++ * linux/arch/nds32/lib/putuser.S ++ * ++ * Copyright (C) 2001 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds ++ * ++ * These functions have a non-standard call interface to make ++ * them more efficient, especially as they return an error ++ * value in addition to the "real" return value. ++ * ++ * __put_user_X ++ * ++ * Inputs: $r0 contains the address ++ * $r2, $r3 contains the value ++ * Outputs: $r0 is the error code ++ * lr corrupted ++ * ++ * No other registers must be altered. (see include/asm-arm/uaccess.h ++ * for specific ASM register usage). ++ * ++ * Note that ADDR_LIMIT is either 0 or 0xc0000000 ++ * Note also that it is intended that __put_user_bad is not global. ++ */ ++#include ++#include ++#include ++#include ++ ++ .text ++ ++ENTRY(__put_user_1) ++1: sb $r2, [$r0] ++ move $r0, #0 ++ ret ++ ++ENTRY(__put_user_2) ++2: shi $r2, [$r0] ! Store input halfword ++ move $r0, #0 ++ ret ++ ++ENTRY(__put_user_4) ++3: sw $r2, [$r0] ++ move $r0, #0 ++ ret ++ ++ENTRY(__put_user_8) ++5: swi.bi $r2, [$r0], #4 ++6: sw $r3, [$r0] ++ move $r0, #0 ++ ret ++ ++__put_user_bad: ++ move $r0, #-EFAULT ++ ret ++ ++.section __ex_table, "a" ++ .long 1b, __put_user_bad ++ .long 2b, __put_user_bad ++ .long 3b, __put_user_bad ++ .long 5b, __put_user_bad ++ .long 6b, __put_user_bad ++.previous +diff -Nur linux-3.4.110.orig/arch/nds32/lib/strchr.S linux-3.4.110/arch/nds32/lib/strchr.S +--- linux-3.4.110.orig/arch/nds32/lib/strchr.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/strchr.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,37 @@ ++/* ++ * linux/arch/nds32/lib/strchr.S ++ * ++ * Copyright (C) 1995-2000 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ASM optimised string functions ++ */ ++#include ++#include ++ ++/* ++ * Prototype: char *strrchr(const char *s, int c); ++ * Purpose : Returns a pointer to the first occurrence of the character c ++ * in the string s. Here "character" means "byte" - these functions ++ * do not work with wide or multi-byte characters. ++ */ ++ ++ .text ++ ++ENTRY(strchr) ++ move $r5, $r0 ! Setup return value ++ andi $r1, $r1, #0xff ! Wipe out useless bits ++loop: ++ lbi.bi $p0, [$r5], #1 ! Load the next byte ++ beqz $p0, exit ! Reach EOS (NULL), return NULL ++ bne $p0, $r1, loop ! Continue if != c ++ addi $r5, $r5, #-1 ! Found ++exit: ++ cmovz $r5, $p0, $p0 ! Return NULL if EOS (NULL) ++ move $r0, $r5 ++ ret ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/strncpy_from_user.S linux-3.4.110/arch/nds32/lib/strncpy_from_user.S +--- linux-3.4.110.orig/arch/nds32/lib/strncpy_from_user.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/strncpy_from_user.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * linux/arch/nds32/lib/strncpy_from_user.S ++ * ++ * Copyright (C) 1995-2000 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++ ++ ++/* ++ * Copy a string from user space to kernel space. ++ * $r0 = dst, $r1 = src, $r2 = n (byte length) ++ * returns the number of characters copied (strlen of copied string), ++ * -EFAULT on exception, or "len" if we fill the whole buffer ++ */ ++ ++ .text ++ .align 4 ++ENTRY(__arch_strncpy_from_user) ++ move $p1, $r1 ! Record the start src addr ++loop: ++ addi $r2, $r2, #-1 ! Decrease n by 1 ++ bltz $r2, exit ! Exit if n < 0 ++USER( lbi.bi, $p0, [$r1], #1) ! Load the byte from src ++ sbi.bi $p0, [$r0], #1 ! Store the byte to dst ++ bnez $p0, loop ! Continue looping if terminator is not reached ++ addi $r1, $r1, #-1 ! Don't count the terminator ++exit: ++ sub $r0, $r1, $p1 ! Get copied count ++ ret ++ ++ .section .fixup,"ax" ++ .align 0 ++9001: xor $p0, $p0, $p0 ++ sb $p0, [$r0] ! Zero the buffer ++ move $r0, -EFAULT ! Return -EFAULT ++ ret ++ .previous ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/strnlen_user.S linux-3.4.110/arch/nds32/lib/strnlen_user.S +--- linux-3.4.110.orig/arch/nds32/lib/strnlen_user.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/strnlen_user.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,43 @@ ++/* ++ * linux/arch/nds32/lib/strnlen_user.S ++ * ++ * Copyright (C) 1995-2000 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++ ++ .text ++ ++/* Prototype: unsigned long ___arch_strnlen_user(const char *str, long n) ++ * Purpose : get length of a string in user memory ++ * Params : str - address of string in user memory ++ * Returns : length of string *including terminator* ++ * or zero on exception, or n + 1 if too long ++ */ ++ .align 4 ++ENTRY(__arch_strnlen_user) ++ move $p0, $r0 ! Record the start addr ++ ! beqz $r0, exit ! Exit when Null address ++ beqz $r1, exit ! Exit when n = 0 ++loop: ++USER( lbi.bi, $p1, [$r0], #1) ! Load the next byte ++ beqz $p1, exit ! Exit when terminator is reached ++ addi $r1, $r1, #-1 ! Decrease n by 1 ++ bnez $r1, loop ! Continue looping if n != 0 ++ addi $r0, $r0, #1 ! Return n+1 if too long ++exit: ++ sub $r0, $r0, $p0 ! Get the counted length ++ ret ++ ++ .section .fixup,"ax" ++ .align 0 ++9001: move $r0, #0 ! Return 0 on exception ++ ret ++ .previous ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/strrchr.S linux-3.4.110/arch/nds32/lib/strrchr.S +--- linux-3.4.110.orig/arch/nds32/lib/strrchr.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/strrchr.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,37 @@ ++/* ++ * linux/arch/nds32/lib/strrchr.S ++ * ++ * Copyright (C) 1995-2000 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ASM optimised string functions ++ */ ++#include ++#include ++ ++ .text ++/* ++ * Prototype: char *strrchr(const char *s, int c); ++ * Purpose : Returns a pointer to the last occurrence of the character c ++ * in the string s. Here "character" means "byte" - these functions ++ * do not work with wide or multi-byte characters. ++ */ ++ .align 4 ++ENTRY(strrchr) ++ move $r5, #0 ++ beqz $r0, exit ++ andi $r1, $r1, #0xff ! Wipe out useless bits ++loop: ++ lbi $p0, [$r0] ! Load the next byte ++ xor $p1, $p0, $r1 ! Test if the byte == c ++ cmovz $r5, $r0, $p1 ! Save the current position ++ addi $r0, $r0, #1 ! Move on to the next byte ++ bnez $p0, loop ! Continue if not NULL (EOS) ++exit: ++ move $r0, $r5 ++ ret ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/uaccess.S linux-3.4.110/arch/nds32/lib/uaccess.S +--- linux-3.4.110.orig/arch/nds32/lib/uaccess.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/uaccess.S 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,159 @@ ++/* ++ * linux/arch/nds32/lib/uaccess.S ++ * ++ * Copyright (C) 1995, 1996,1997,1998 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Routines to block copy data to/from user memory ++ * These are highly optimised both for the 4k page size ++ * and for various alignments. ++ */ ++#include ++#include ++#include ++ ++ .text ++ ++//#define PAGE_SHIFT 12 ++ ++/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) ++ * Purpose : copy a block to user memory from kernel memory ++ * Params : to - user memory ++ * : from - kernel memory ++ * : n - number of bytes to copy ++ * Returns : Number of bytes NOT copied. ++ */ ++ ++ENTRY(__arch_copy_to_user) ++ push $r0 ++ push $r2 ++ beqz $r2, ctu_exit ++ srli $p0, $r2, #2 ! $p0 = number of word to clear ++ andi $r2, $r2, #3 ! Bytes less than a word to copy ++ beqz $p0, byte_ctu ! Only less than a word to copy ++word_ctu: ++ lmw.bim $p1, [$r1], $p1 ! Load the next word ++USER( smw.bim,$p1, [$r0], $p1) ! Store the next word ++ addi $p0, $p0, #-1 ! Decrease word count ++ bnez $p0, word_ctu ! Continue looping to copy all words ++ beqz $r2, ctu_exit ! No left bytes to copy ++byte_ctu: ++ lbi.bi $p1, [$r1], #1 ! Load the next byte ++USER( sbi.bi, $p1, [$r0], #1) ! Store the next byte ++ addi $r2, $r2, #-1 ! Decrease byte count ++ bnez $r2, byte_ctu ! Continue looping to clear all left bytes ++ctu_exit: ++ move $r0, $r2 ! Set return value ++ pop $r2 ++ pop $r2 ! Pop saved $r0 to $r2 to not corrupt return value ++ ret ++ ++ .section .fixup,"ax" ++ .align 0 ++9001: ++ pop $p1 ! Original $r2, n ++ pop $p0 ! Original $r0, void *to ++ sub $r1, $r0, $p0 ! Bytes copied ++ sub $r2, $p1, $r1 ! Bytes left to copy ++ push $lp ++ move $r0, $p0 ++ bal __memzero ! Clean up the memory ++ pop $lp ++ move $r0, $r2 ++ ret ++ ++ .previous ++ ++/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); ++ * Purpose : copy a block from user memory to kernel memory ++ * Params : to - kernel memory ++ * : from - user memory ++ * : n - number of bytes to copy ++ * Returns : Number of bytes NOT copied. ++ */ ++ ++ ++ENTRY(__arch_copy_from_user) ++ push $r1 ++ push $r2 ++ beqz $r2, cfu_exit ++ srli $p0, $r2, #2 ! $p0 = number of word to clear ++ andi $r2, $r2, #3 ! Bytes less than a word to copy ++ beqz $p0, byte_cfu ! Only less than a word to copy ++word_cfu: ++USER( lmw.bim,$p1, [$r1], $p1) ! Load the next word ++ smw.bim $p1, [$r0], $p1 ! Store the next word ++ addi $p0, $p0, #-1 ! Decrease word count ++ bnez $p0, word_cfu ! Continue looping to copy all words ++ beqz $r2, cfu_exit ! No left bytes to copy ++byte_cfu: ++USER( lbi.bi, $p1, [$r1], #1) ! Load the next byte ++ sbi.bi $p1, [$r0], #1 ! Store the next byte ++ addi $r2, $r2, #-1 ! Decrease byte count ++ bnez $r2, byte_cfu ! Continue looping to clear all left bytes ++cfu_exit: ++ move $r0, $r2 ! Set return value ++ pop $r2 ++ pop $r1 ++ ret ++ ++ .section .fixup,"ax" ++ .align 0 ++ /* ++ * We took an exception. $r0 contains a pointer to ++ * the byte not copied. ++ */ ++9001: ++ pop $p1 ! Original $r2, n ++ pop $p0 ! Original $r0, void *to ++ sub $r1, $r1, $p0 ! Bytes copied ++ sub $r2, $p1, $r1 ! Bytes left to copy ++ push $lp ++ bal __memzero ! Clean up the memory ++ pop $lp ++ move $r0, $r2 ++ ret ++ .previous ++ ++/* Prototype: int __arch_clear_user(void *addr, size_t sz) ++ * Purpose : clear some user memory ++ * Params : addr - user memory address to clear ++ * : sz - number of bytes to clear ++ * Returns : number of bytes NOT cleared ++ */ ++ .align 5 ++ENTRY(__arch_clear_user) ++ pushm $r0, $r1 ++ beqz $r1, clear_exit ++ xor $p1, $p1, $p1 ! Use $p1=0 to clear mem ++ srli $p0, $r1, #2 ! $p0 = number of word to clear ++ andi $r1, $r1, #3 ! Bytes less than a word to copy ++ beqz $p0, byte_clear ! Only less than a word to clear ++word_clear: ++USER( smw.bim,$p1, [$r0], $p1) ! Clear the word ++ addi $p0, $p0, #-1 ! Decrease word count ++ bnez $p0, word_clear ! Continue looping to clear all words ++ beqz $r1, clear_exit ! No left bytes to copy ++byte_clear: ++USER( sbi.bi, $p1, [$r0], #1) ! Clear the byte ++ addi $r1, $r1, #-1 ! Decrease byte count ++ bnez $r1, byte_clear ! Continue looping to clear all left bytes ++clear_exit: ++ move $r0, $r1 ! Set return value ++ pop $r1 ++ pop $r1 ! Pop saved $r0 to $r1 to not corrupt return value ++ ret ++ ++ .section .fixup,"ax" ++ .align 0 ++9001: ++ popm $p0, $p1 ! $p0 = original $r0, *addr, $p1 = original $r1, n ++ sub $p0, $r0, $p0 ! Bytes copied ++ sub $r0, $p1, $p0 ! Bytes left to copy ++ ret ++ .previous ++ +diff -Nur linux-3.4.110.orig/arch/nds32/lib/udivmod.c linux-3.4.110/arch/nds32/lib/udivmod.c +--- linux-3.4.110.orig/arch/nds32/lib/udivmod.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/udivmod.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,12 @@ ++extern unsigned long udivmodsi4(unsigned long num, unsigned long den, ++ int modwanted); ++ ++long __udivsi3(long a, long b) ++{ ++ return udivmodsi4(a, b, 0); ++} ++ ++long __umodsi3(long a, long b) ++{ ++ return udivmodsi4(a, b, 1); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/lib/udivmodsi4.c linux-3.4.110/arch/nds32/lib/udivmodsi4.c +--- linux-3.4.110.orig/arch/nds32/lib/udivmodsi4.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/lib/udivmodsi4.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,21 @@ ++unsigned long udivmodsi4(unsigned long num, unsigned long den, int modwanted) ++{ ++ unsigned long bit = 1; ++ unsigned long res = 0; ++ ++ while (den < num && bit && !(den & (1L << 31))) { ++ den <<= 1; ++ bit <<= 1; ++ } ++ while (bit) { ++ if (num >= den) { ++ num -= den; ++ res |= bit; ++ } ++ bit >>= 1; ++ den >>= 1; ++ } ++ if (modwanted) ++ return num; ++ return res; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/Makefile linux-3.4.110/arch/nds32/Makefile +--- linux-3.4.110.orig/arch/nds32/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/Makefile 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,100 @@ ++# ++# arch/nds32/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Copyright (C) 1995-2001 by Russell King ++ ++LDFLAGS_vmlinux :=-nostdlib --no-undefined -X ++OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S ++GZFLAGS :=-9 ++KBUILD_CFLAGS +=-pipe -mno-sched-prolog-epilog ++ ++# Do not use arch/nds32/defconfig - it's always outdated. ++# Select a platform tht is kept up-to-date ++KBUILD_DEFCONFIG := orca_defconfig ++ ++ifeq ($(CONFIG_FRAME_POINTER),y) ++KBUILD_CFLAGS +=-fno-omit-frame-pointer ++endif ++ ++comma = , ++ ++# This selects which instruction set is used. ++# Note that GCC does not numerically define an architecture version ++# macro, but instead defines a whole series of macros which makes ++# testing for a specific architecture or later rather impossible. ++arch-y +=-D__nds32__ ++gcc_ver :=$(shell $(CC) -E -dM -xc /dev/null | grep __VERSION__ | sed 's/\#define __VERSION__ //') ++ifeq ($(shell expr `echo $(gcc_ver)` \>= 4.9.2 ), 1) ++arch-y += \ ++ $(shell $(CC) -E -dM -xc /dev/null | \ ++ grep -o -m1 NDS32_EXT_FPU_SP | \ ++ sed -e 's/NDS32_EXT_FPU_SP/-mno-ext-fpu-sp -mfloat-abi=soft/') \ ++ $(shell $(CC) -E -dM -xc /dev/null | \ ++ grep -o -m1 NDS32_EXT_FPU_DP | \ ++ sed -e 's/NDS32_EXT_FPU_DP/-mno-ext-fpu-dp -mfloat-abi=soft/') ++tune-y =-D__OPTIMIZE__ -mcmodel=large -D__ARCH_WANT_SYS_WAITPID ++else ++$(shell echo $(__VERSION__)) ++arch-y += $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | \ ++ sed -e 's/NDS32_EXT_FPU_SP/-mno-ext-fpu-sp/') \ ++ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | \ ++ sed -e 's/NDS32_EXT_FPU_DP/-mno-ext-fpu-dp/') \ ++ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_ABI | \ ++ sed -e 's/NDS32_ABI/-mabi=2/') ++tune-y =-D__OPTIMIZE__ -G0 -D__ARCH_WANT_SYS_WAITPID -D_GCC444 ++endif ++ ++# This is a workaround for FUNCTION_TRACER because v3push will push $fp, $gp and $lp. ++ifdef CONFIG_FUNCTION_TRACER ++arch-y += -mno-v3push ++endif ++# This selects how we optimise for the processor. ++# Need -Unds32 for gcc < 3.x ++CHECKFLAGS += -D__nds32__ ++ ++KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -Unds32 -DSTRICT_MM_TYPECHECKS # for c-style checking for page.h ++KBUILD_AFLAGS +=$(AFLAGS_ABI) $(arch-y) $(tune-y) ++ ++#Default value ++head-y := arch/nds32/kernel/head.o arch/nds32/kernel/init_task.o ++textaddr-y := 0xC000C000 ++ ++TEXTADDR := $(textaddr-y) ++ ++export TEXTADDR DATAADDR GZFLAGS ++ ++ ++# If we have a machine-specific directory, then include it in the build. ++core-y += arch/nds32/kernel/ arch/nds32/mm/ ++core-y += arch/nds32/platforms/ ++core-$(CONFIG_FPU) += arch/nds32/math-emu/ ++ ++drivers-$(CONFIG_OPROFILE) += arch/nds32/oprofile/ ++ ++libs-y += arch/nds32/lib/ ++ ++boot := arch/nds32/boot ++ ++.PHONY: FORCE ++ ++Image: vmlinux ++ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ ++ ++CLEAN_FILES += include/asm-nds32/constants.h* ++ ++# We use MRPROPER_FILES and CLEAN_FILES now ++archclean: ++ $(Q)$(MAKE) $(clean)=$(boot) ++ ++.PHONY: arch/nds32/kernel/asm-offsets.s ++arch/nds32/kernel/asm-offsets.s: arch/nds32/kernel/asm-offsets.c ++ $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) ++ ++ ++define archhelp ++ echo ' Image - kernel image (arch/$(ARCH)/boot/Image)' ++endef +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_add.c linux-3.4.110/arch/nds32/math-emu/dp_add.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_add.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_add.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,179 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ * ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) ++{ ++ COMPXDP; ++ COMPYDP; ++ ++ EXPLODEXDP; ++ EXPLODEYDP; ++ ++ CLEARCX; ++ ++ FLUSHXDP; ++ FLUSHYDP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ if (xs == ys) ++ return x; ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ return x; ++ ++ /* Zero handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ if (xs == ys) ++ return x; ++ else ++ return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ return x; ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ DPDNORMX; ++ ++ /* FALL THROUGH */ ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ DPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ DPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ assert(xm & DP_HIDDEN_BIT); ++ assert(ym & DP_HIDDEN_BIT); ++ ++ /* provide guard,round and stick bit space */ ++ xm <<= 3; ++ ym <<= 3; ++ ++ if (xe > ye) { ++ /* have to shift y fraction right to align ++ */ ++ int s = xe - ye; ++ ym = XDPSRS(ym, s); ++ ye += s; ++ } else if (ye > xe) { ++ /* have to shift x fraction right to align ++ */ ++ int s = ye - xe; ++ xm = XDPSRS(xm, s); ++ xe += s; ++ } ++ assert(xe == ye); ++ assert(xe <= DP_EMAX); ++ ++ if (xs == ys) { ++ /* generate 28 bit result of adding two 27 bit numbers ++ * leaving result in xm,xs,xe ++ */ ++ xm = xm + ym; ++ xe = xe; ++ xs = xs; ++ ++ if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */ ++ xm = XDPSRS1(xm); ++ xe++; ++ } ++ } else { ++ if (xm >= ym) { ++ xm = xm - ym; ++ xe = xe; ++ xs = xs; ++ } else { ++ xm = ym - xm; ++ xe = xe; ++ xs = ys; ++ } ++ if (xm == 0) ++ return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD); ++ ++ /* normalize to rounding precision */ ++ while ((xm >> (DP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ ++ } ++ DPNORMRET2(xs, xe, xm, "add", x, y); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_cmp.c linux-3.4.110/arch/nds32/math-emu/dp_cmp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_cmp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_cmp.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,66 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig) ++{ ++ COMPXDP; ++ COMPYDP; ++ ++ EXPLODEXDP; ++ EXPLODEYDP; ++ FLUSHXDP; ++ FLUSHYDP; ++ CLEARCX; /* Even clear inexact flag here */ ++ ++ if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) { ++ if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN) ++ SETCX(IEEE754_INVALID_OPERATION); ++ if (cmp & IEEE754_CUN) ++ return 1; ++ if (cmp & (IEEE754_CLT | IEEE754_CGT)) { ++ if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) ++ return ieee754si_xcpt(0, "fcmpf", x); ++ } ++ return 0; ++ } else { ++ s64 vx = x.bits; ++ s64 vy = y.bits; ++ ++ if (vx < 0) ++ vx = -vx ^ DP_SIGN_BIT; ++ if (vy < 0) ++ vy = -vy ^ DP_SIGN_BIT; ++ ++ if (vx < vy) ++ return (cmp & IEEE754_CLT) != 0; ++ else if (vx == vy) ++ return (cmp & IEEE754_CEQ) != 0; ++ else ++ return (cmp & IEEE754_CGT) != 0; ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_div.c linux-3.4.110/arch/nds32/math-emu/dp_div.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_div.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_div.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,155 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) ++{ ++ COMPXDP; ++ COMPYDP; ++ ++ EXPLODEXDP; ++ EXPLODEYDP; ++ ++ CLEARCX; ++ ++ FLUSHXDP; ++ FLUSHYDP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ return ieee754dp_zero(xs ^ ys); ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ return ieee754dp_inf(xs ^ ys); ++ ++ /* Zero handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ SETCX(IEEE754_ZERO_DIVIDE); ++ return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ return ieee754dp_zero(xs == ys ? 0 : 1); ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ DPDNORMX; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ DPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ DPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ assert(xm & DP_HIDDEN_BIT); ++ assert(ym & DP_HIDDEN_BIT); ++ ++ /* provide rounding space */ ++ xm <<= 3; ++ ym <<= 3; ++ ++ { ++ /* now the dirty work */ ++ ++ u64 rm = 0; ++ int re = xe - ye; ++ u64 bm; ++ ++ for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) { ++ if (xm >= ym) { ++ xm -= ym; ++ rm |= bm; ++ if (xm == 0) ++ break; ++ } ++ xm <<= 1; ++ } ++ rm <<= 1; ++ if (xm) ++ rm |= 1; /* have remainder, set sticky */ ++ ++ assert(rm); ++ ++ /* normalise rm to rounding precision ? ++ */ ++ while ((rm >> (DP_MBITS + 3)) == 0) { ++ rm <<= 1; ++ re--; ++ } ++ ++ DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_fint.c linux-3.4.110/arch/nds32/math-emu/dp_fint.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_fint.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_fint.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,79 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_fint(int x) ++{ ++ u64 xm; ++ int xe; ++ int xs; ++ ++ CLEARCX; ++ ++ if (x == 0) ++ return ieee754dp_zero(0); ++ if (x == 1 || x == -1) ++ return ieee754dp_one(x < 0); ++ if (x == 10 || x == -10) ++ return ieee754dp_ten(x < 0); ++ ++ xs = (x < 0); ++ if (xs) { ++ if (x == (1 << 31)) ++ xm = ((unsigned)1 << 31); /* max neg can't be safely negated */ ++ else ++ xm = -x; ++ } else { ++ xm = x; ++ } ++ ++#if 1 ++ /* normalize - result can never be inexact or overflow */ ++ xe = DP_MBITS; ++ while ((xm >> DP_MBITS) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); ++#else ++ /* normalize */ ++ xe = DP_MBITS + 3; ++ while ((xm >> (DP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ DPNORMRET1(xs, xe, xm, "fint", x); ++#endif ++} ++ ++ieee754dp ieee754dp_funs(unsigned int u) ++{ ++ if ((int)u < 0) ++ return ieee754dp_add(ieee754dp_1e31(), ++ ieee754dp_fint(u & ~(1 << 31))); ++ return ieee754dp_fint(u); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_flong.c linux-3.4.110/arch/nds32/math-emu/dp_flong.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_flong.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_flong.c 2016-04-07 10:20:50.958081643 +0200 +@@ -0,0 +1,77 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_flong(s64 x) ++{ ++ u64 xm; ++ int xe; ++ int xs; ++ ++ CLEARCX; ++ ++ if (x == 0) ++ return ieee754dp_zero(0); ++ if (x == 1 || x == -1) ++ return ieee754dp_one(x < 0); ++ if (x == 10 || x == -10) ++ return ieee754dp_ten(x < 0); ++ ++ xs = (x < 0); ++ if (xs) { ++ if (x == (1ULL << 63)) ++ xm = (1ULL << 63); /* max neg can't be safely negated */ ++ else ++ xm = -x; ++ } else { ++ xm = x; ++ } ++ ++ /* normalize */ ++ xe = DP_MBITS + 3; ++ if (xm >> (DP_MBITS + 1 + 3)) { ++ /* shunt out overflow bits */ ++ while (xm >> (DP_MBITS + 1 + 3)) { ++ XDPSRSX1(); ++ } ++ } else { ++ /* normalize in grs extended double precision */ ++ while ((xm >> (DP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ } ++ DPNORMRET1(xs, xe, xm, "dp_flong", x); ++} ++ ++ieee754dp ieee754dp_fulong(u64 u) ++{ ++ if ((s64) u < 0) ++ return ieee754dp_add(ieee754dp_1e63(), ++ ieee754dp_flong(u & ~(1ULL << 63))); ++ return ieee754dp_flong(u); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_frexp.c linux-3.4.110/arch/nds32/math-emu/dp_frexp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_frexp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_frexp.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,52 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++/* close to ieeep754dp_logb ++*/ ++ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr) ++{ ++ COMPXDP; ++ CLEARCX; ++ EXPLODEXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ case IEEE754_CLASS_ZERO: ++ *eptr = 0; ++ return x; ++ case IEEE754_CLASS_DNORM: ++ DPDNORMX; ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ *eptr = xe + 1; ++ return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_fsp.c linux-3.4.110/arch/nds32/math-emu/dp_fsp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_fsp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_fsp.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,71 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_fsp(ieee754sp x) ++{ ++ COMPXSP; ++ ++ EXPLODEXSP; ++ ++ CLEARCX; ++ ++ FLUSHXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp"); ++ case IEEE754_CLASS_QNAN: ++ return ieee754dp_nanxcpt(builddp(xs, ++ DP_EMAX + 1 + DP_EBIAS, ++ ((u64) xm ++ << (DP_MBITS - ++ SP_MBITS))), "fsp", x); ++ case IEEE754_CLASS_INF: ++ return ieee754dp_inf(xs); ++ case IEEE754_CLASS_ZERO: ++ return ieee754dp_zero(xs); ++ case IEEE754_CLASS_DNORM: ++ /* normalize */ ++ while ((xm >> SP_MBITS) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ ++ /* CANT possibly overflow,underflow, or need rounding ++ */ ++ ++ /* drop the hidden bit */ ++ xm &= ~SP_HIDDEN_BIT; ++ ++ return builddp(xs, xe + DP_EBIAS, (u64) xm << (DP_MBITS - SP_MBITS)); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_logb.c linux-3.4.110/arch/nds32/math-emu/dp_logb.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_logb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_logb.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,53 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_logb(ieee754dp x) ++{ ++ COMPXDP; ++ ++ CLEARCX; ++ ++ EXPLODEXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ return ieee754dp_nanxcpt(x, "logb", x); ++ case IEEE754_CLASS_QNAN: ++ return x; ++ case IEEE754_CLASS_INF: ++ return ieee754dp_inf(0); ++ case IEEE754_CLASS_ZERO: ++ return ieee754dp_inf(1); ++ case IEEE754_CLASS_DNORM: ++ DPDNORMX; ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ return ieee754dp_fint(xe); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_modf.c linux-3.4.110/arch/nds32/math-emu/dp_modf.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_modf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_modf.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,79 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++/* modf function is always exact for a finite number ++*/ ++ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip) ++{ ++ COMPXDP; ++ ++ CLEARCX; ++ ++ EXPLODEXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ case IEEE754_CLASS_ZERO: ++ *ip = x; ++ return x; ++ case IEEE754_CLASS_DNORM: ++ /* far to small */ ++ *ip = ieee754dp_zero(xs); ++ return x; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ if (xe < 0) { ++ *ip = ieee754dp_zero(xs); ++ return x; ++ } ++ if (xe >= DP_MBITS) { ++ *ip = x; ++ return ieee754dp_zero(xs); ++ } ++ /* generate ipart mantissa by clearing bottom bits ++ */ ++ *ip = builddp(xs, xe + DP_EBIAS, ++ ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) & ++ ~DP_HIDDEN_BIT); ++ ++ /* generate fpart mantissa by clearing top bits ++ * and normalizing (must be able to normalize) ++ */ ++ xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe)); ++ if (xm == 0) ++ return ieee754dp_zero(xs); ++ ++ while ((xm >> DP_MBITS) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_mul.c linux-3.4.110/arch/nds32/math-emu/dp_mul.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_mul.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_mul.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,170 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) ++{ ++ COMPXDP; ++ COMPYDP; ++ ++ EXPLODEXDP; ++ EXPLODEYDP; ++ ++ CLEARCX; ++ ++ FLUSHXDP; ++ FLUSHYDP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754dp_inf(xs ^ ys); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ return ieee754dp_zero(xs ^ ys); ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ DPDNORMX; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ DPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ DPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ /* rm = xm * ym, re = xe+ye basicly */ ++ assert(xm & DP_HIDDEN_BIT); ++ assert(ym & DP_HIDDEN_BIT); ++ { ++ int re = xe + ye; ++ int rs = xs ^ ys; ++ u64 rm; ++ ++ /* shunt to top of word */ ++ xm <<= 64 - (DP_MBITS + 1); ++ ym <<= 64 - (DP_MBITS + 1); ++ ++ /* multiply 32bits xm,ym to give high 32bits rm with stickness ++ */ ++ ++ /* 32 * 32 => 64 */ ++#define DPXMULT(x, y) ((u64)(x) * (u64)y) ++ ++ { ++ unsigned lxm = xm; ++ unsigned hxm = xm >> 32; ++ unsigned lym = ym; ++ unsigned hym = ym >> 32; ++ u64 lrm; ++ u64 hrm; ++ ++ lrm = DPXMULT(lxm, lym); ++ hrm = DPXMULT(hxm, hym); ++ ++ { ++ u64 t = DPXMULT(lxm, hym); ++ { ++ u64 at = lrm + (t << 32); ++ hrm += at < lrm; ++ lrm = at; ++ } ++ hrm = hrm + (t >> 32); ++ } ++ ++ { ++ u64 t = DPXMULT(hxm, lym); ++ { ++ u64 at = lrm + (t << 32); ++ hrm += at < lrm; ++ lrm = at; ++ } ++ hrm = hrm + (t >> 32); ++ } ++ rm = hrm | (lrm != 0); ++ } ++ ++ /* ++ * sticky shift down to normal rounding precision ++ */ ++ if ((s64) rm < 0) { ++ rm = (rm >> (64 - (DP_MBITS + 1 + 3))) | ++ ((rm << (DP_MBITS + 1 + 3)) != 0); ++ re++; ++ } else { ++ rm = (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) | ++ ((rm << (DP_MBITS + 1 + 3 + 1)) != 0); ++ } ++ assert(rm & (DP_HIDDEN_BIT << 3)); ++ DPNORMRET2(rs, re, rm, "mul", x, y); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_scalb.c linux-3.4.110/arch/nds32/math-emu/dp_scalb.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_scalb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_scalb.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,56 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_scalb(ieee754dp x, int n) ++{ ++ COMPXDP; ++ ++ CLEARCX; ++ ++ EXPLODEXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ return ieee754dp_nanxcpt(x, "scalb", x, n); ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ case IEEE754_CLASS_ZERO: ++ return x; ++ case IEEE754_CLASS_DNORM: ++ DPDNORMX; ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n); ++} ++ ++ieee754dp ieee754dp_ldexp(ieee754dp x, int n) ++{ ++ return ieee754dp_scalb(x, n); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_simple.c linux-3.4.110/arch/nds32/math-emu/dp_simple.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_simple.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_simple.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,87 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++int ieee754dp_finite(ieee754dp x) ++{ ++ return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS; ++} ++ ++ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y) ++{ ++ CLEARCX; ++ DPSIGN(x) = DPSIGN(y); ++ return x; ++} ++ ++ieee754dp ieee754dp_neg(ieee754dp x) ++{ ++ COMPXDP; ++ ++ EXPLODEXDP; ++ CLEARCX; ++ FLUSHXDP; ++ ++ /* ++ * Invert the sign ALWAYS to prevent an endless recursion on ++ * pow() in libc. ++ */ ++ /* quick fix up */ ++ DPSIGN(x) ^= 1; ++ ++ if (xc == IEEE754_CLASS_SNAN) { ++ ieee754dp y = ieee754dp_indef(); ++ SETCX(IEEE754_INVALID_OPERATION); ++ DPSIGN(y) = DPSIGN(x); ++ return ieee754dp_nanxcpt(y, "neg"); ++ } ++ ++ if (ieee754dp_isnan(x)) /* but not infinity */ ++ return ieee754dp_nanxcpt(x, "neg", x); ++ return x; ++} ++ ++ieee754dp ieee754dp_abs(ieee754dp x) ++{ ++ COMPXDP; ++ ++ EXPLODEXDP; ++ CLEARCX; ++ FLUSHXDP; ++ ++ if (xc == IEEE754_CLASS_SNAN) { ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); ++ } ++ ++ if (ieee754dp_isnan(x)) /* but not infinity */ ++ return ieee754dp_nanxcpt(x, "abs", x); ++ ++ /* quick fix up */ ++ DPSIGN(x) = 0; ++ return x; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_sqrt.c linux-3.4.110/arch/nds32/math-emu/dp_sqrt.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_sqrt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_sqrt.c 2016-04-07 10:20:50.974082262 +0200 +@@ -0,0 +1,164 @@ ++/* IEEE754 floating point arithmetic ++ * double precision square root ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++static const unsigned table[] = { ++ 0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, ++ 29598, 36145, 43202, 50740, 58733, 67158, 75992, ++ 85215, 83599, 71378, 60428, 50647, 41945, 34246, ++ 27478, 21581, 16499, 12183, 8588, 5674, 3403, ++ 1742, 661, 130 ++}; ++ ++ieee754dp ieee754dp_sqrt(ieee754dp x) ++{ ++ struct _ieee754_csr oldcsr; ++ ieee754dp y, z, t; ++ unsigned scalx, yh; ++ COMPXDP; ++ ++ EXPLODEXDP; ++ CLEARCX; ++ FLUSHXDP; ++ ++ /* x == INF or NAN? */ ++ switch (xc) { ++ case IEEE754_CLASS_QNAN: ++ /* sqrt(Nan) = Nan */ ++ return ieee754dp_nanxcpt(x, "sqrt"); ++ case IEEE754_CLASS_SNAN: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); ++ case IEEE754_CLASS_ZERO: ++ /* sqrt(0) = 0 */ ++ return x; ++ case IEEE754_CLASS_INF: ++ if (xs) { ++ /* sqrt(-Inf) = Nan */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); ++ } ++ /* sqrt(+Inf) = Inf */ ++ return x; ++ case IEEE754_CLASS_DNORM: ++ DPDNORMX; ++ /* fall through */ ++ case IEEE754_CLASS_NORM: ++ if (xs) { ++ /* sqrt(-x) = Nan */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); ++ } ++ break; ++ } ++ ++ /* save old csr; switch off INX enable & flag; set RN rounding */ ++ oldcsr = ieee754_csr; ++ ieee754_csr.mx &= ~IEEE754_INEXACT; ++ ieee754_csr.sx &= ~IEEE754_INEXACT; ++ ieee754_csr.rm = IEEE754_RN; ++ ++ /* adjust exponent to prevent overflow */ ++ scalx = 0; ++ if (xe > 512) { /* x > 2**-512? */ ++ xe -= 512; /* x = x / 2**512 */ ++ scalx += 256; ++ } else if (xe < -512) { /* x < 2**-512? */ ++ xe += 512; /* x = x * 2**512 */ ++ scalx -= 256; ++ } ++ ++ y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); ++ ++ /* magic initial approximation to almost 8 sig. bits */ ++ yh = y.bits >> 32; ++ yh = (yh >> 1) + 0x1ff80000; ++ yh = yh - table[(yh >> 15) & 31]; ++ y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff); ++ ++ /* Heron's rule once with correction to improve to ~18 sig. bits */ ++ /* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */ ++ t = ieee754dp_div(x, y); ++ y = ieee754dp_add(y, t); ++ y.bits -= 0x0010000600000000LL; ++ y.bits &= 0xffffffff00000000LL; ++ ++ /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */ ++ /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */ ++ z = t = ieee754dp_mul(y, y); ++ t.parts.bexp += 0x001; ++ t = ieee754dp_add(t, z); ++ z = ieee754dp_mul(ieee754dp_sub(x, z), y); ++ ++ /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */ ++ t = ieee754dp_div(z, ieee754dp_add(t, x)); ++ t.parts.bexp += 0x001; ++ y = ieee754dp_add(y, t); ++ ++ /* twiddle last bit to force y correctly rounded */ ++ ++ /* set RZ, clear INEX flag */ ++ ieee754_csr.rm = IEEE754_RZ; ++ ieee754_csr.sx &= ~IEEE754_INEXACT; ++ ++ /* t=x/y; ...chopped quotient, possibly inexact */ ++ t = ieee754dp_div(x, y); ++ ++ if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) { ++ ++ if (!(ieee754_csr.sx & IEEE754_INEXACT)) ++ /* t = t-ulp */ ++ t.bits -= 1; ++ ++ /* add inexact to result status */ ++ oldcsr.cx |= IEEE754_INEXACT; ++ oldcsr.sx |= IEEE754_INEXACT; ++ ++ switch (oldcsr.rm) { ++ case IEEE754_RP: ++ y.bits += 1; ++ /* drop through */ ++ case IEEE754_RN: ++ t.bits += 1; ++ break; ++ } ++ ++ /* y=y+t; ...chopped sum */ ++ y = ieee754dp_add(y, t); ++ ++ /* adjust scalx for correctly rounded sqrt(x) */ ++ scalx -= 1; ++ } ++ ++ /* py[n0]=py[n0]+scalx; ...scale back y */ ++ y.parts.bexp += scalx; ++ ++ /* restore rounding mode, possibly set inexact */ ++ ieee754_csr = oldcsr; ++ ++ return y; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_sub.c linux-3.4.110/arch/nds32/math-emu/dp_sub.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_sub.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_sub.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,187 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) ++{ ++ COMPXDP; ++ COMPYDP; ++ ++ EXPLODEXDP; ++ EXPLODEYDP; ++ ++ CLEARCX; ++ ++ FLUSHXDP; ++ FLUSHYDP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ if (xs != ys) ++ return x; ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ return ieee754dp_inf(ys ^ 1); ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ return x; ++ ++ /* Zero handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ if (xs != ys) ++ return x; ++ else ++ return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ return x; ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ /* quick fix up */ ++ DPSIGN(y) ^= 1; ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ DPDNORMX; ++ /* FAAL THOROUGH */ ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ /* normalize ym,ye */ ++ DPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ /* normalize xm,xe */ ++ DPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ /* flip sign of y and handle as add */ ++ ys ^= 1; ++ ++ assert(xm & DP_HIDDEN_BIT); ++ assert(ym & DP_HIDDEN_BIT); ++ ++ /* provide guard,round and stick bit dpace */ ++ xm <<= 3; ++ ym <<= 3; ++ ++ if (xe > ye) { ++ /* have to shift y fraction right to align ++ */ ++ int s = xe - ye; ++ ym = XDPSRS(ym, s); ++ ye += s; ++ } else if (ye > xe) { ++ /* have to shift x fraction right to align ++ */ ++ int s = ye - xe; ++ xm = XDPSRS(xm, s); ++ xe += s; ++ } ++ assert(xe == ye); ++ assert(xe <= DP_EMAX); ++ ++ if (xs == ys) { ++ /* generate 28 bit result of adding two 27 bit numbers ++ */ ++ xm = xm + ym; ++ xe = xe; ++ xs = xs; ++ ++ if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */ ++ xm = XDPSRS1(xm); /* shift preserving sticky */ ++ xe++; ++ } ++ } else { ++ if (xm >= ym) { ++ xm = xm - ym; ++ xe = xe; ++ xs = xs; ++ } else { ++ xm = ym - xm; ++ xe = xe; ++ xs = ys; ++ } ++ if (xm == 0) { ++ if (ieee754_csr.rm == IEEE754_RD) ++ return ieee754dp_zero(1); /* round negative inf. => sign = -1 */ ++ else ++ return ieee754dp_zero(0); /* other round modes => sign = 1 */ ++ } ++ ++ /* normalize to rounding precision ++ */ ++ while ((xm >> (DP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ } ++ DPNORMRET2(xs, xe, xm, "sub", x, y); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_tint.c linux-3.4.110/arch/nds32/math-emu/dp_tint.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_tint.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_tint.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,121 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include ++#include "ieee754dp.h" ++ ++int ieee754dp_tint(ieee754dp x) ++{ ++ COMPXDP; ++ ++ CLEARCX; ++ ++ EXPLODEXDP; ++ FLUSHXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); ++ case IEEE754_CLASS_ZERO: ++ return 0; ++ case IEEE754_CLASS_DNORM: ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ if (xe > 31) { ++ /* Set invalid. We will only use overflow for floating ++ point overflow */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); ++ } ++ /* oh gawd */ ++ if (xe > DP_MBITS) { ++ xm <<= xe - DP_MBITS; ++ } else if (xe < DP_MBITS) { ++ u64 residue; ++ int round; ++ int sticky; ++ int odd; ++ ++ if (xe < -1) { ++ residue = xm; ++ round = 0; ++ sticky = residue != 0; ++ xm = 0; ++ } else { ++ residue = xm << (64 - DP_MBITS + xe); ++ round = (residue >> 63) != 0; ++ sticky = (residue << 1) != 0; ++ xm >>= DP_MBITS - xe; ++ } ++ /* Note: At this point upper 32 bits of xm are guaranteed ++ to be zero */ ++ odd = (xm & 0x1) != 0x0; ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ if (round && (sticky || odd)) ++ xm++; ++ break; ++ case IEEE754_RZ: ++ break; ++ case IEEE754_RU: /* toward +Infinity */ ++ if ((round || sticky) && !xs) ++ xm++; ++ break; ++ case IEEE754_RD: /* toward -Infinity */ ++ if ((round || sticky) && xs) ++ xm++; ++ break; ++ } ++ /* look for valid corner case 0x80000000 */ ++ if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) { ++ /* This can happen after rounding */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); ++ } ++ if (round || sticky) ++ SETCX(IEEE754_INEXACT); ++ } ++ if (xs) ++ return -xm; ++ else ++ return xm; ++} ++ ++unsigned int ieee754dp_tuns(ieee754dp x) ++{ ++ ieee754dp hb = ieee754dp_1e31(); ++ ++ /* what if x < 0 ?? */ ++ if (ieee754dp_lt(x, hb)) ++ return (unsigned)ieee754dp_tint(x); ++ ++ return (unsigned)ieee754dp_tint(ieee754dp_sub(x, hb)) | ++ ((unsigned)1 << 31); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/dp_tlong.c linux-3.4.110/arch/nds32/math-emu/dp_tlong.c +--- linux-3.4.110.orig/arch/nds32/math-emu/dp_tlong.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/dp_tlong.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,123 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++s64 ieee754dp_tlong(ieee754dp x) ++{ ++ COMPXDP; ++ ++ CLEARCX; ++ ++ EXPLODEXDP; ++ FLUSHXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); ++ case IEEE754_CLASS_ZERO: ++ return 0; ++ case IEEE754_CLASS_DNORM: ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ if (xe >= 63) { ++ /* look for valid corner case */ ++ if (xe == 63 && xs && xm == DP_HIDDEN_BIT) ++ return -0x8000000000000000LL; ++ /* Set invalid. We will only use overflow for floating ++ point overflow */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); ++ } ++ /* oh gawd */ ++ if (xe > DP_MBITS) { ++ xm <<= xe - DP_MBITS; ++ } else if (xe < DP_MBITS) { ++ u64 residue; ++ int round; ++ int sticky; ++ int odd; ++ ++ if (xe < -1) { ++ residue = xm; ++ round = 0; ++ sticky = residue != 0; ++ xm = 0; ++ } else { ++ /* Shifting a u64 64 times does not work, ++ * so we do it in two steps. Be aware that xe ++ * may be -1 */ ++ residue = xm << (xe + 1); ++ residue <<= 63 - DP_MBITS; ++ round = (residue >> 63) != 0; ++ sticky = (residue << 1) != 0; ++ xm >>= DP_MBITS - xe; ++ } ++ odd = (xm & 0x1) != 0x0; ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ if (round && (sticky || odd)) ++ xm++; ++ break; ++ case IEEE754_RZ: ++ break; ++ case IEEE754_RU: /* toward +Infinity */ ++ if ((round || sticky) && !xs) ++ xm++; ++ break; ++ case IEEE754_RD: /* toward -Infinity */ ++ if ((round || sticky) && xs) ++ xm++; ++ break; ++ } ++ if ((xm >> 63) != 0) { ++ /* This can happen after rounding */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); ++ } ++ if (round || sticky) ++ SETCX(IEEE754_INEXACT); ++ } ++ if (xs) ++ return -xm; ++ else ++ return xm; ++} ++ ++u64 ieee754dp_tulong(ieee754dp x) ++{ ++ ieee754dp hb = ieee754dp_1e63(); ++ ++ /* what if x < 0 ?? */ ++ if (ieee754dp_lt(x, hb)) ++ return (u64) ieee754dp_tlong(x); ++ ++ return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) | (1ULL << 63); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/fpuemu.c linux-3.4.110/arch/nds32/math-emu/fpuemu.c +--- linux-3.4.110.orig/arch/nds32/math-emu/fpuemu.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/fpuemu.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,565 @@ ++/* ++ * linux/arch/nds32/math-emu/fpuemu.c: a nds32 coprocessor (fpu) instruction emulator ++ * ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * A complete emulator for MIPS coprocessor 1 instructions. This is ++ * required for #float(switch) or #float(trap), where it catches all ++ * COP1 instructions via the "CoProcessor Unusable" exception. ++ * ++ * More surprisingly it is also required for #float(ieee), to help out ++ * the hardware fpu at the boundaries of the IEEE-754 representation ++ * (denormalised values, infinities, underflow, etc). It is made ++ * quite nasty because emulation of some non-COP1 instructions is ++ * required, e.g. in branch delay slots. ++ * ++ * Note if you know that you won't have an fpu, then you'll get much ++ * better performance by compiling with -msoft-float! ++ */ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "ieee754.h" ++#include "insn.h" ++#include "fpu_emulator.h" ++ ++/* Function which emulates a floating point instruction. */ ++ ++static int fpu_emu(struct pt_regs *, struct fpu_struct *, unsigned long); ++ ++/* Further private data for which no space exists in fpu_struct */ ++ ++struct fpu_emulator_stats fpuemustats; ++ ++/* rounding mode */ ++#define FPU_FPCSR_RN 0x0 /* nearest */ ++#define FPU_FPCSR_RU 0x1 /* towards +Infinity */ ++#define FPU_FPCSR_RD 0x2 /* towards -Infinity */ ++#define FPU_FPCSR_RZ 0x3 /* towards zero */ ++ ++/* Convert Mips rounding mode (0..3) to IEEE library modes. */ ++static const unsigned char ieee_rm[4] = { ++ [FPU_FPCSR_RN] = IEEE754_RN, ++ [FPU_FPCSR_RU] = IEEE754_RU, ++ [FPU_FPCSR_RD] = IEEE754_RD, ++ [FPU_FPCSR_RZ] = IEEE754_RZ, ++}; ++ ++/* Convert IEEE library modes to NDS32 rounding mode (0..3). */ ++static const unsigned char nds32_rm[4] = { ++ [IEEE754_RN] = FPU_FPCSR_RN, ++ [IEEE754_RZ] = FPU_FPCSR_RZ, ++ [IEEE754_RD] = FPU_FPCSR_RD, ++ [IEEE754_RU] = FPU_FPCSR_RU, ++}; ++ ++/* ++ * In the Linux kernel, we support selection of FPR format on the ++ * basis of the Status.FR bit. This does imply that, if a full 32 ++ * FPRs are desired, there needs to be a flip-flop that can be written ++ * to one at that bit position. In any case, O32 MIPS ABI uses ++ * only the even FPRs (Status.FR = 0). ++ */ ++ ++#define CP0_STATUS_FR_SUPPORT ++ ++#ifdef CP0_STATUS_FR_SUPPORT ++#define FR_BIT ST0_FR ++#else ++#define FR_BIT 0 ++#endif ++ ++#define SIFROMREG(si, x) ((si) = *((unsigned long *)ctx + x)) ++#define SITOREG(si, x) (*((unsigned long *)ctx + x)= (si)) ++ ++#ifdef __NDS32_EL__ ++#define DIFROMREG(di, x) ((di) = (unsigned long long)ptr[2*x] << 32 | (unsigned long long)ptr[2*x+1]) ++#define DITOREG(di, x) ptr[2*x] = (di) >> 32; ptr[2*x+1] = (unsigned long)(di) ++#else ++#define DIFROMREG(di, x) ((di) = (unsigned long long)ptr[2*x+1] << 32 | (unsigned long long)ptr[2*x]) ++#define DITOREG(di, x) ptr[2*x+1] = (di) >> 32; ptr[2*x] = (unsigned long)(di) ++#endif ++ ++#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x) ++#define SPTOREG(sp, x) SITOREG((sp).bits, x) ++#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x) ++#define DPTOREG(dp, x) DITOREG((dp).bits, x) ++ ++#define DEF3OP(name, p, f1, f2, f3) \ ++static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \ ++ ieee754##p t) \ ++{ \ ++ struct _ieee754_csr ieee754_csr_save; \ ++ s = f1(s, t); \ ++ ieee754_csr_save = ieee754_csr; \ ++ s = f2(s, r); \ ++ ieee754_csr_save.cx |= ieee754_csr.cx; \ ++ ieee754_csr_save.sx |= ieee754_csr.sx; \ ++ s = f3(s); \ ++ ieee754_csr.cx |= ieee754_csr_save.cx; \ ++ ieee754_csr.sx |= ieee754_csr_save.sx; \ ++ return s; \ ++} ++ ++DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add,); ++DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub,); ++DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg); ++DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg); ++DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add,); ++DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub,); ++DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); ++DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); ++ ++/* ++ * Emulate the floating point instruction w/ denorm input pointed at by IPC. ++ * According to spec, only FPU arithmetic, data format conversion, and compare instructions. ++ */ ++ ++static int fpuEmulate(struct pt_regs *regs, struct fpu_struct *fpu) ++{ ++ unsigned long insn = 0, addr = regs->NDS32_ipc; ++ unsigned long emulpc, contpc; ++ unsigned char *pc = (void *)&insn; ++ char c; ++ int i = 0; ++ ++ for (i = 0; i < 4; i++) { ++ if (__get_user(c, (unsigned char *)addr++)) ++ return SIGBUS; ++ *pc++ = c; ++ } ++ ++ insn = be32_to_cpu(insn); ++ ++ emulpc = regs->NDS32_ipc; ++ contpc = regs->NDS32_ipc + 4; ++ ++ fpuemustats.emulated++; ++ switch (NDS32Insn_OPCODE(insn)) { ++ case cop0_op: ++ switch (NDS32Insn_OPCODE_COP0(insn)) { ++ ++ case fs1_op: ++ case fs2_op: ++ case fd1_op: ++ case fd2_op: ++ { ++ int sig; ++ ++ /* a real fpu computation instruction */ ++ if ((sig = fpu_emu(regs, fpu, insn))) ++ return sig; ++ } ++ break; ++ ++ default: ++ return SIGILL; ++ } ++ break; ++ default: ++ return SIGILL; ++ } ++ ++ /* we did it !! */ ++ regs->NDS32_ipc = contpc; ++ ++ return 0; ++} ++ ++/* ++ * Conversion table from NDS32 fcmp TYP ++ * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig); ++ */ ++static const unsigned char cmptab[8] = { ++ IEEE754_CEQ, ++ IEEE754_CLT, ++ IEEE754_CLT | IEEE754_CEQ, ++ IEEE754_CUN, ++ 0, ++ 0, ++ 0, ++ 0, ++}; ++ ++/* ++ * Emulate a single FPU arithmetic instruction. ++ */ ++static int fpu_emu(struct pt_regs *xcp, struct fpu_struct *ctx, ++ unsigned long insn) ++{ ++ int rfmt; /* resulting format */ ++ unsigned rfpcsr = 0; /* resulting csr */ ++ unsigned long *ptr = (unsigned long *)ctx; ++ union { ++ ieee754dp d; ++ ieee754sp s; ++ int w; ++ } rv; /* resulting value */ ++ ++ fpuemustats.fpuops++; ++ switch (rfmt = NDS32Insn_OPCODE_COP0(insn)) { ++ case fs1_op:{ ++ union { ++ ieee754sp(*t) (ieee754sp, ieee754sp, ieee754sp); ++ ieee754sp(*b) (ieee754sp, ieee754sp); ++ ieee754sp(*u) (ieee754sp); ++ } handler; ++ ++ switch (NDS32Insn_OPCODE_BIT69(insn)) { ++ case fadds_op: ++ handler.b = ieee754sp_add; ++ goto scopbop; ++ case fsubs_op: ++ handler.b = ieee754sp_sub; ++ goto scopbop; ++ case fmadds_op: ++ handler.t = fpemu_sp_madd; ++ goto scoptop; ++ case fmsubs_op: ++ handler.t = fpemu_sp_msub; ++ goto scoptop; ++ case fnmadds_op: ++ handler.t = fpemu_sp_nmadd; ++ goto scoptop; ++ case fnmsubs_op: ++ handler.t = fpemu_sp_nmsub; ++ goto scoptop; ++ case fmuls_op: ++ handler.b = ieee754sp_mul; ++ goto scopbop; ++ case fdivs_op: ++ handler.b = ieee754sp_div; ++ goto scopbop; ++ ++ /* binary op on handler */ ++scoptop: ++ { ++ ieee754sp fd, fr, fs, ft; ++ ++ SPFROMREG(fr, ++ NDS32Insn_OPCODE_Rt(insn)); ++ SPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ SPFROMREG(ft, ++ NDS32Insn_OPCODE_Rb(insn)); ++ fd = (*handler.t) (fr, fs, ft); ++ SPTOREG(fd, NDS32Insn_OPCODE_Rt(insn)); ++ } ++scopbop: ++ { ++ ieee754sp fs, ft; ++ ++ SPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ SPFROMREG(ft, ++ NDS32Insn_OPCODE_Rb(insn)); ++ ++ rv.s = (*handler.b) (fs, ft); ++ goto copcsr; ++ } ++scopuop: ++ { ++ ieee754sp fs; ++ ++ SPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ rv.s = (*handler.u) (fs); ++ goto copcsr; ++ } ++copcsr: ++ if (ieee754_cxtest(IEEE754_INEXACT)) ++ rfpcsr |= FPCSR_mskIEX; ++ if (ieee754_cxtest(IEEE754_UNDERFLOW)) ++ rfpcsr |= FPCSR_mskUDF; ++ if (ieee754_cxtest(IEEE754_OVERFLOW)) ++ rfpcsr |= FPCSR_mskOVF; ++ if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) ++ rfpcsr |= FPCSR_mskDBZ; ++ if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) ++ rfpcsr |= FPCSR_mskIVO; ++ break; ++ ++ case fs1_f2op_op: ++ switch (NDS32Insn_OPCODE_BIT1014(insn)) { ++ case fs2d_op:{ ++ ieee754sp fs; ++ SPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra ++ (insn)); ++ rv.d = ieee754dp_fsp(fs); ++ rfmt = fd1_op; ++ goto copcsr; ++ } ++ case fsqrts_op: ++ handler.u = ieee754sp_sqrt; ++ goto scopuop; ++ case fabss_op: ++ handler.u = ieee754sp_abs; ++ goto scopuop; ++ default: ++ return SIGILL; ++ } ++ default: ++ return SIGILL; ++ } ++ break; ++ } ++ ++ case fs2_op: ++ switch (NDS32Insn_OPCODE_BIT69(insn)) { ++ case fcmpeqs_op: ++ case fcmpeqs_e_op: ++ case fcmplts_op: ++ case fcmplts_e_op: ++ case fcmples_op: ++ case fcmples_e_op: ++ case fcmpuns_op: ++ case fcmpuns_e_op: ++ { ++ unsigned int cmpop = ++ NDS32Insn_OPCODE_BIT69(insn); ++ if (cmpop < 0x8) { ++ ieee754sp fs, ft; ++ ++ SPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ SPFROMREG(ft, ++ NDS32Insn_OPCODE_Rb(insn)); ++ rv.w = ++ ieee754sp_cmp(fs, ft, ++ cmptab[(cmpop >> 1) & ++ 0x7], ++ cmpop & 0x1); ++ if ((cmpop & 0x1) ++ && ++ ieee754_cxtest ++ (IEEE754_INVALID_OPERATION)) ++ rfpcsr = FPCSR_mskIVO; ++ else ++ goto copcsr; ++ } else ++ return SIGILL; ++ } ++ break; ++ ++ default: ++ return SIGILL; ++ } ++ break; ++ ++ case fd1_op: ++ { ++ union { ++ ieee754dp(*t) (ieee754dp, ieee754dp, ieee754dp); ++ ieee754dp(*b) (ieee754dp, ieee754dp); ++ ieee754dp(*u) (ieee754dp); ++ } handler; ++ ++ switch (NDS32Insn_OPCODE_BIT69(insn)) { ++ case faddd_op: ++ handler.b = ieee754dp_add; ++ goto dcopbop; ++ case fsubd_op: ++ handler.b = ieee754dp_sub; ++ goto dcopbop; ++ case fmaddd_op: ++ handler.t = fpemu_dp_madd; ++ goto tdcoptop; ++ case fmsubd_op: ++ handler.t = fpemu_dp_msub; ++ goto tdcoptop; ++ case fnmaddd_op: ++ handler.t = fpemu_dp_nmadd; ++ goto tdcoptop; ++ case fnmsubd_op: ++ handler.t = fpemu_dp_nmsub; ++ goto tdcoptop; ++ ++tdcoptop: ++ { ++ ieee754dp fd, fr, fs, ft; ++ ++ DPFROMREG(fr, ++ NDS32Insn_OPCODE_Rt(insn)); ++ DPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ DPFROMREG(ft, ++ NDS32Insn_OPCODE_Rb(insn)); ++ fd = (*handler.t) (fr, fs, ft); ++ DPTOREG(fd, NDS32Insn_OPCODE_Rt(insn)); ++ goto copcsr; ++ } ++ ++ case fmuld_op: ++ handler.b = ieee754dp_mul; ++ goto dcopbop; ++ case fdivd_op: ++ handler.b = ieee754dp_div; ++ goto dcopbop; ++ ++ /* binary op on handler */ ++dcopbop: { ++ ieee754dp fs, ft; ++ ++ DPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ DPFROMREG(ft, ++ NDS32Insn_OPCODE_Rb(insn)); ++ ++ rv.d = (*handler.b) (fs, ft); ++ goto copcsr; ++ } ++dcopuop: { ++ ieee754dp fs; ++ ++ DPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ rv.d = (*handler.u) (fs); ++ goto copcsr; ++ } ++ ++ case fd1_f2op_op: ++ switch (NDS32Insn_OPCODE_BIT1014(insn)) { ++ case fd2s_op:{ ++ ieee754dp fs; ++ ++ DPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra ++ (insn)); ++ rv.s = ieee754sp_fdp(fs); ++ rfmt = fd1_op; ++ goto copcsr; ++ } ++ case fsqrtd_op: ++ handler.u = ieee754dp_sqrt; ++ goto dcopuop; ++ case fabsd_op: ++ handler.u = ieee754dp_abs; ++ goto dcopuop; ++ default: ++ return SIGILL; ++ } ++ default: ++ return SIGILL; ++ } ++ break; ++ } ++ ++ case fd2_op: ++ switch (NDS32Insn_OPCODE_BIT69(insn)) { ++ case fcmpeqd_op: ++ case fcmpeqd_e_op: ++ case fcmpltd_op: ++ case fcmpltd_e_op: ++ case fcmpled_op: ++ case fcmpled_e_op: ++ case fcmpund_op: ++ case fcmpund_e_op: ++ { ++ unsigned cmpop = NDS32Insn_OPCODE_BIT69(insn); ++ if (cmpop < 0x8) { ++ ieee754dp fs, ft; ++ ++ DPFROMREG(fs, ++ NDS32Insn_OPCODE_Ra(insn)); ++ DPFROMREG(ft, ++ NDS32Insn_OPCODE_Rb(insn)); ++ rv.w = ++ ieee754dp_cmp(fs, ft, ++ cmptab[(cmpop >> 1) & ++ 0x7], ++ cmpop & 0x1); ++ rfmt = fs2_op; ++ if ((cmpop & 0x1) ++ && ++ ieee754_cxtest ++ (IEEE754_INVALID_OPERATION)) ++ rfpcsr = FPCSR_mskIVO; ++ else ++ goto copcsr; ++ } else ++ return SIGILL; ++ } ++ break; ++ default: ++ return SIGILL; ++ } ++ break; ++ ++ default: ++ return SIGILL; ++ } ++ ++ /* ++ * Now we can safely write the result back to the register file. ++ */ ++ switch (rfmt) { ++ case fd1_op: ++ case fd2_op: ++ DPTOREG(rv.d, NDS32Insn_OPCODE_Rt(insn)); ++ break; ++ case fs1_op: ++ case fs2_op: ++ SPTOREG(rv.s, NDS32Insn_OPCODE_Rt(insn)); ++ break; ++ default: ++ return SIGILL; ++ } ++ ++ /* ++ * Update the fpu CSR register for this operation. ++ * If an exception is required, generate a tidy SIGFPE exception, ++ * without updating the result register. ++ * Note: cause exception bits do not accumulate, they are rewritten ++ * for each op; only the flag/sticky bits accumulate. ++ */ ++ ctx->fpcsr = (ctx->fpcsr & ~FPCSR_mskALL) | rfpcsr; ++ if ((ctx->fpcsr << 5) & ctx->fpcsr & FPCSR_mskALLE) { ++ return SIGFPE; ++ } ++ ++ return 0; ++} ++ ++int do_fpu_denorm(struct pt_regs *regs, struct fpu_struct *fpu) ++{ ++ int sig = 0; ++ ++ /* ++ * The 'ieee754_csr' is an alias of ++ * fpcsr->RM. No need to copy fpcsr->RM to ++ * ieee754_csr. But ieee754_csr.rm is ieee ++ * library modes. (not NDS32 rounding mode) ++ */ ++ /* convert to ieee library modes */ ++ ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; ++ sig = fpuEmulate(regs, fpu); ++ /* revert to NDS32 rounding mode */ ++ ieee754_csr.rm = nds32_rm[ieee754_csr.rm]; ++ ++ return sig; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/fpu_emulator.h linux-3.4.110/arch/nds32/math-emu/fpu_emulator.h +--- linux-3.4.110.orig/arch/nds32/math-emu/fpu_emulator.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/fpu_emulator.h 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,36 @@ ++/* ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * Further private data for which no space exists in mips_fpu_struct. ++ * This should be subsumed into the mips_fpu_struct structure as ++ * defined in processor.h as soon as the absurd wired absolute assembler ++ * offsets become dynamic at compile time. ++ * ++ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ */ ++#ifndef _ASM_FPU_EMULATOR_H ++#define _ASM_FPU_EMULATOR_H ++ ++struct fpu_emulator_stats { ++ unsigned int emulated; ++ unsigned int loads; ++ unsigned int stores; ++ unsigned int fpuops; ++ unsigned int errors; ++}; ++ ++extern struct fpu_emulator_stats fpuemustats; ++ ++#endif /* _ASM_FPU_EMULATOR_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754.c linux-3.4.110/arch/nds32/math-emu/ieee754.c +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,125 @@ ++/* ieee754 floating point arithmetic ++ * single and double precision ++ * ++ * BUGS ++ * not much dp done ++ * doesn't generate IEEE754_INEXACT ++ * ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754int.h" ++#include "ieee754sp.h" ++#include "ieee754dp.h" ++ ++#define DP_EBIAS 1023 ++#define DP_EMIN (-1022) ++#define DP_EMAX 1023 ++ ++#define SP_EBIAS 127 ++#define SP_EMIN (-126) ++#define SP_EMAX 127 ++ ++/* special constants ++*/ ++ ++#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__NDS32_EL__) ++#define SPSTR(s, b, m) {m, b, s} ++#define DPSTR(s, b, mh, ml) {ml, mh, b, s} ++#endif ++ ++#ifdef __NDS32_EB__ ++#define SPSTR(s, b, m) {s, b, m} ++#define DPSTR(s, b, mh, ml) {s, b, mh, ml} ++#endif ++ ++const struct ieee754dp_konst __ieee754dp_spcvals[] = { ++ DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* + zero */ ++ DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* - zero */ ++ DPSTR(0, DP_EBIAS, 0, 0), /* + 1.0 */ ++ DPSTR(1, DP_EBIAS, 0, 0), /* - 1.0 */ ++ DPSTR(0, 3 + DP_EBIAS, 0x40000, 0), /* + 10.0 */ ++ DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */ ++ DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */ ++ DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */ ++ DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x7FFFF, 0xFFFFFFFF), /* + indef quiet Nan */ ++ DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */ ++ DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */ ++ DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */ ++ DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0), /* - min normal */ ++ DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* + min denormal */ ++ DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* - min denormal */ ++ DPSTR(0, 31 + DP_EBIAS, 0, 0), /* + 1.0e31 */ ++ DPSTR(0, 63 + DP_EBIAS, 0, 0), /* + 1.0e63 */ ++}; ++ ++const struct ieee754sp_konst __ieee754sp_spcvals[] = { ++ SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0), /* + zero */ ++ SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0), /* - zero */ ++ SPSTR(0, SP_EBIAS, 0), /* + 1.0 */ ++ SPSTR(1, SP_EBIAS, 0), /* - 1.0 */ ++ SPSTR(0, 3 + SP_EBIAS, 0x200000), /* + 10.0 */ ++ SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */ ++ SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */ ++ SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */ ++ SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x3FFFFF), /* + indef quiet Nan */ ++ SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */ ++ SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */ ++ SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */ ++ SPSTR(1, SP_EMIN + SP_EBIAS, 0), /* - min normal */ ++ SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1), /* + min denormal */ ++ SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1), /* - min denormal */ ++ SPSTR(0, 31 + SP_EBIAS, 0), /* + 1.0e31 */ ++ SPSTR(0, 63 + SP_EBIAS, 0), /* + 1.0e63 */ ++}; ++ ++int ieee754si_xcpt(int r, const char *op, ...) ++{ ++ struct ieee754xctx ax; ++ ++ if (!TSTX()) ++ return r; ++ ax.op = op; ++ ax.rt = IEEE754_RT_SI; ++ ax.rv.si = r; ++ va_start(ax.ap, op); ++ ieee754_xcpt(&ax); ++ va_end(ax.ap); ++ return ax.rv.si; ++} ++ ++s64 ieee754di_xcpt(s64 r, const char *op, ...) ++{ ++ struct ieee754xctx ax; ++ ++ if (!TSTX()) ++ return r; ++ ax.op = op; ++ ax.rt = IEEE754_RT_DI; ++ ax.rv.di = r; ++ va_start(ax.ap, op); ++ ieee754_xcpt(&ax); ++ va_end(ax.ap); ++ return ax.rv.di; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754d.c linux-3.4.110/arch/nds32/math-emu/ieee754d.c +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754d.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754d.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,134 @@ ++/* ++ * Some debug functions ++ * ++ * MIPS floating point support ++ * ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * Nov 7, 2000 ++ * Modified to build and operate in Linux kernel environment. ++ * ++ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ */ ++ ++#include ++#include "ieee754.h" ++ ++#define DP_EBIAS 1023 ++#define DP_EMIN (-1022) ++#define DP_EMAX 1023 ++#define DP_FBITS 52 ++ ++#define SP_EBIAS 127 ++#define SP_EMIN (-126) ++#define SP_EMAX 127 ++#define SP_FBITS 23 ++ ++#define DP_MBIT(x) ((u64)1 << (x)) ++#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS) ++#define DP_SIGN_BIT DP_MBIT(63) ++ ++#define SP_MBIT(x) ((u32)1 << (x)) ++#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS) ++#define SP_SIGN_BIT SP_MBIT(31) ++ ++#define SPSIGN(sp) (sp.parts.sign) ++#define SPBEXP(sp) (sp.parts.bexp) ++#define SPMANT(sp) (sp.parts.mant) ++ ++#define DPSIGN(dp) (dp.parts.sign) ++#define DPBEXP(dp) (dp.parts.bexp) ++#define DPMANT(dp) (dp.parts.mant) ++ ++ieee754dp ieee754dp_dump(char *m, ieee754dp x) ++{ ++ int i; ++ ++ printk("%s", m); ++ printk("<%08x,%08x>\n", (unsigned)(x.bits >> 32), (unsigned)x.bits); ++ printk("\t="); ++ switch (ieee754dp_class(x)) { ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_SNAN: ++ printk("Nan %c", DPSIGN(x) ? '-' : '+'); ++ for (i = DP_FBITS - 1; i >= 0; i--) ++ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); ++ break; ++ case IEEE754_CLASS_INF: ++ printk("%cInfinity", DPSIGN(x) ? '-' : '+'); ++ break; ++ case IEEE754_CLASS_ZERO: ++ printk("%cZero", DPSIGN(x) ? '-' : '+'); ++ break; ++ case IEEE754_CLASS_DNORM: ++ printk("%c0.", DPSIGN(x) ? '-' : '+'); ++ for (i = DP_FBITS - 1; i >= 0; i--) ++ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); ++ printk("e%d", DPBEXP(x) - DP_EBIAS); ++ break; ++ case IEEE754_CLASS_NORM: ++ printk("%c1.", DPSIGN(x) ? '-' : '+'); ++ for (i = DP_FBITS - 1; i >= 0; i--) ++ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); ++ printk("e%d", DPBEXP(x) - DP_EBIAS); ++ break; ++ default: ++ printk("Illegal/Unknown IEEE754 value class"); ++ } ++ printk("\n"); ++ return x; ++} ++ ++ieee754sp ieee754sp_dump(char *m, ieee754sp x) ++{ ++ int i; ++ ++ printk("%s=", m); ++ printk("<%08x>\n", (unsigned)x.bits); ++ printk("\t="); ++ switch (ieee754sp_class(x)) { ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_SNAN: ++ printk("Nan %c", SPSIGN(x) ? '-' : '+'); ++ for (i = SP_FBITS - 1; i >= 0; i--) ++ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); ++ break; ++ case IEEE754_CLASS_INF: ++ printk("%cInfinity", SPSIGN(x) ? '-' : '+'); ++ break; ++ case IEEE754_CLASS_ZERO: ++ printk("%cZero", SPSIGN(x) ? '-' : '+'); ++ break; ++ case IEEE754_CLASS_DNORM: ++ printk("%c0.", SPSIGN(x) ? '-' : '+'); ++ for (i = SP_FBITS - 1; i >= 0; i--) ++ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); ++ printk("e%d", SPBEXP(x) - SP_EBIAS); ++ break; ++ case IEEE754_CLASS_NORM: ++ printk("%c1.", SPSIGN(x) ? '-' : '+'); ++ for (i = SP_FBITS - 1; i >= 0; i--) ++ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); ++ printk("e%d", SPBEXP(x) - SP_EBIAS); ++ break; ++ default: ++ printk("Illegal/Unknown IEEE754 value class"); ++ } ++ printk("\n"); ++ return x; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.c linux-3.4.110/arch/nds32/math-emu/ieee754dp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754dp.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,239 @@ ++/* IEEE754 floating point arithmetic ++ * double precision: common utilities ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754dp.h" ++ ++int ieee754dp_class(ieee754dp x) ++{ ++ COMPXDP; ++ EXPLODEXDP; ++ return xc; ++} ++ ++int ieee754dp_isnan(ieee754dp x) ++{ ++ return ieee754dp_class(x) >= IEEE754_CLASS_SNAN; ++} ++ ++int ieee754dp_issnan(ieee754dp x) ++{ ++ assert(ieee754dp_isnan(x)); ++ return ((DPMANT(x) & DP_MBIT(DP_MBITS - 1)) == DP_MBIT(DP_MBITS - 1)); ++} ++ ++ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...) ++{ ++ struct ieee754xctx ax; ++ if (!TSTX()) ++ return r; ++ ++ ax.op = op; ++ ax.rt = IEEE754_RT_DP; ++ ax.rv.dp = r; ++ va_start(ax.ap, op); ++ ieee754_xcpt(&ax); ++ va_end(ax.ap); ++ return ax.rv.dp; ++} ++ ++ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...) ++{ ++ struct ieee754xctx ax; ++ ++ assert(ieee754dp_isnan(r)); ++ ++ if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ ++ return r; ++ ++ if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { ++ /* not enabled convert to a quiet NaN */ ++ DPMANT(r) &= (~DP_MBIT(DP_MBITS - 1)); ++ if (ieee754dp_isnan(r)) ++ return r; ++ else ++ return ieee754dp_indef(); ++ } ++ ++ ax.op = op; ++ ax.rt = 0; ++ ax.rv.dp = r; ++ va_start(ax.ap, op); ++ ieee754_xcpt(&ax); ++ va_end(ax.ap); ++ return ax.rv.dp; ++} ++ ++ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y) ++{ ++ assert(ieee754dp_isnan(x)); ++ assert(ieee754dp_isnan(y)); ++ ++ if (DPMANT(x) > DPMANT(y)) ++ return x; ++ else ++ return y; ++} ++ ++static u64 get_rounding(int sn, u64 xm) ++{ ++ /* inexact must round of 3 bits ++ */ ++ if (xm & (DP_MBIT(3) - 1)) { ++ switch (ieee754_csr.rm) { ++ case IEEE754_RZ: ++ break; ++ case IEEE754_RN: ++ xm += 0x3 + ((xm >> 3) & 1); ++ /* xm += (xm&0x8)?0x4:0x3 */ ++ break; ++ case IEEE754_RU: /* toward +Infinity */ ++ if (!sn) /* ?? */ ++ xm += 0x8; ++ break; ++ case IEEE754_RD: /* toward -Infinity */ ++ if (sn) /* ?? */ ++ xm += 0x8; ++ break; ++ } ++ } ++ return xm; ++} ++ ++/* generate a normal/denormal number with over,under handling ++ * sn is sign ++ * xe is an unbiased exponent ++ * xm is 3bit extended precision value. ++ */ ++ieee754dp ieee754dp_format(int sn, int xe, u64 xm) ++{ ++ assert(xm); /* we don't gen exact zeros (probably should) */ ++ ++ assert((xm >> (DP_MBITS + 1 + 3)) == 0); /* no execess */ ++ assert(xm & (DP_HIDDEN_BIT << 3)); ++ ++ if (xe < DP_EMIN) { ++ /* strip lower bits */ ++ int es = DP_EMIN - xe; ++ ++ if (ieee754_csr.nod) { ++ SETCX(IEEE754_UNDERFLOW); ++ SETCX(IEEE754_INEXACT); ++ ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ return ieee754dp_zero(sn); ++ case IEEE754_RZ: ++ return ieee754dp_zero(sn); ++ case IEEE754_RU: /* toward +Infinity */ ++ if (sn == 0) ++ return ieee754dp_min(0); ++ else ++ return ieee754dp_zero(1); ++ case IEEE754_RD: /* toward -Infinity */ ++ if (sn == 0) ++ return ieee754dp_zero(0); ++ else ++ return ieee754dp_min(1); ++ } ++ } ++ ++ if (xe == DP_EMIN - 1 ++ && get_rounding(sn, xm) >> (DP_MBITS + 1 + 3)) { ++ /* Not tiny after rounding */ ++ SETCX(IEEE754_INEXACT); ++ xm = get_rounding(sn, xm); ++ xm >>= 1; ++ /* Clear grs bits */ ++ xm &= ~(DP_MBIT(3) - 1); ++ xe++; ++ } else { ++ /* sticky right shift es bits ++ */ ++ xm = XDPSRS(xm, es); ++ xe += es; ++ assert((xm & (DP_HIDDEN_BIT << 3)) == 0); ++ assert(xe == DP_EMIN); ++ } ++ } ++ if (xm & (DP_MBIT(3) - 1)) { ++ SETCX(IEEE754_INEXACT); ++ if ((xm & (DP_HIDDEN_BIT << 3)) == 0) { ++ SETCX(IEEE754_UNDERFLOW); ++ } ++ ++ /* inexact must round of 3 bits ++ */ ++ xm = get_rounding(sn, xm); ++ /* adjust exponent for rounding add overflowing ++ */ ++ if (xm >> (DP_MBITS + 3 + 1)) { ++ /* add causes mantissa overflow */ ++ xm >>= 1; ++ xe++; ++ } ++ } ++ /* strip grs bits */ ++ xm >>= 3; ++ ++ assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ ++ assert(xe >= DP_EMIN); ++ ++ if (xe > DP_EMAX) { ++ SETCX(IEEE754_OVERFLOW); ++ SETCX(IEEE754_INEXACT); ++ /* -O can be table indexed by (rm,sn) */ ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ return ieee754dp_inf(sn); ++ case IEEE754_RZ: ++ return ieee754dp_max(sn); ++ case IEEE754_RU: /* toward +Infinity */ ++ if (sn == 0) ++ return ieee754dp_inf(0); ++ else ++ return ieee754dp_max(1); ++ case IEEE754_RD: /* toward -Infinity */ ++ if (sn == 0) ++ return ieee754dp_max(0); ++ else ++ return ieee754dp_inf(1); ++ } ++ } ++ /* gen norm/denorm/zero */ ++ ++ if ((xm & DP_HIDDEN_BIT) == 0) { ++ /* we underflow (tiny/zero) */ ++ assert(xe == DP_EMIN); ++ if (ieee754_csr.mx & IEEE754_UNDERFLOW) ++ SETCX(IEEE754_UNDERFLOW); ++ return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm); ++ } else { ++ assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ ++ assert(xm & DP_HIDDEN_BIT); ++ ++ return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.h linux-3.4.110/arch/nds32/math-emu/ieee754dp.h +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754dp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754dp.h 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,83 @@ ++/* ++ * IEEE754 floating point ++ * double precision internal header file ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++ ++#include "ieee754int.h" ++ ++#define assert(expr) ((void)0) ++ ++/* 3bit extended double precision sticky right shift */ ++#define XDPSRS(v,rs) \ ++ ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0)) ++ ++#define XDPSRSX1() \ ++ (xe++, (xm = (xm >> 1) | (xm & 1))) ++ ++#define XDPSRS1(v) \ ++ (((v) >> 1) | ((v) & 1)) ++ ++/* convert denormal to normalized with extended exponent */ ++#define DPDNORMx(m,e) \ ++ while( (m >> DP_MBITS) == 0) { m <<= 1; e--; } ++#define DPDNORMX DPDNORMx(xm, xe) ++#define DPDNORMY DPDNORMx(ym, ye) ++ ++static inline ieee754dp builddp(int s, int bx, u64 m) ++{ ++ ieee754dp r; ++ ++ assert((s) == 0 || (s) == 1); ++ assert((bx) >= DP_EMIN - 1 + DP_EBIAS ++ && (bx) <= DP_EMAX + 1 + DP_EBIAS); ++ assert(((m) >> DP_MBITS) == 0); ++ ++ r.parts.sign = s; ++ r.parts.bexp = bx; ++ r.parts.mant = m; ++ return r; ++} ++ ++extern int ieee754dp_isnan(ieee754dp); ++extern int ieee754dp_issnan(ieee754dp); ++extern int ieee754si_xcpt(int, const char *, ...); ++extern s64 ieee754di_xcpt(s64, const char *, ...); ++extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...); ++extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...); ++extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp); ++extern ieee754dp ieee754dp_format(int, int, u64); ++ ++ ++#define DPNORMRET2(s, e, m, name, a0, a1) \ ++{ \ ++ ieee754dp V = ieee754dp_format(s, e, m); \ ++ if(TSTX()) \ ++ return ieee754dp_xcpt(V, name, a0, a1); \ ++ else \ ++ return V; \ ++} ++ ++#define DPNORMRET1(s, e, m, name, a0) DPNORMRET2(s, e, m, name, a0, a0) +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754.h linux-3.4.110/arch/nds32/math-emu/ieee754.h +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754.h 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,467 @@ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * Nov 7, 2000 ++ * Modification to allow integration with Linux kernel ++ * ++ * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ */ ++#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H ++#define __ARCH_MIPS_MATH_EMU_IEEE754_H ++ ++#include ++#include ++#include ++ ++/* ++ * Not very pretty, but the Linux kernel's normal va_list definition ++ * does not allow it to be used as a structure element, as it is here. ++ */ ++#ifndef _STDARG_H ++#include ++#endif ++ ++#ifdef __LITTLE_ENDIAN ++struct ieee754dp_konst { ++ unsigned mantlo:32; ++ unsigned manthi:20; ++ unsigned bexp:11; ++ unsigned sign:1; ++}; ++struct ieee754sp_konst { ++ unsigned mant:23; ++ unsigned bexp:8; ++ unsigned sign:1; ++}; ++ ++typedef union _ieee754dp { ++ struct ieee754dp_konst oparts; ++ struct { ++ u64 mant:52; ++ unsigned int bexp:11; ++ unsigned int sign:1; ++ } parts; ++ u64 bits; ++ double d; ++} ieee754dp; ++ ++typedef union _ieee754sp { ++ struct ieee754sp_konst parts; ++ float f; ++ u32 bits; ++} ieee754sp; ++#endif ++ ++#ifdef __BIG_ENDIAN ++struct ieee754dp_konst { ++ unsigned sign:1; ++ unsigned bexp:11; ++ unsigned manthi:20; ++ unsigned mantlo:32; ++}; ++ ++typedef union _ieee754dp { ++ struct ieee754dp_konst oparts; ++ struct { ++ unsigned int sign:1; ++ unsigned int bexp:11; ++ u64 mant:52; ++ } parts; ++ double d; ++ u64 bits; ++} ieee754dp; ++ ++struct ieee754sp_konst { ++ unsigned sign:1; ++ unsigned bexp:8; ++ unsigned mant:23; ++}; ++ ++typedef union _ieee754sp { ++ struct ieee754sp_konst parts; ++ float f; ++ u32 bits; ++} ieee754sp; ++#endif ++ ++/* ++ * single precision (often aka float) ++*/ ++int ieee754sp_finite(ieee754sp x); ++int ieee754sp_class(ieee754sp x); ++ ++ieee754sp ieee754sp_abs(ieee754sp x); ++ieee754sp ieee754sp_neg(ieee754sp x); ++ieee754sp ieee754sp_scalb(ieee754sp x, int); ++ieee754sp ieee754sp_logb(ieee754sp x); ++ ++/* x with sign of y */ ++ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y); ++ ++ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y); ++ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y); ++ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y); ++ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y); ++ ++ieee754sp ieee754sp_fint(int x); ++ieee754sp ieee754sp_funs(unsigned x); ++ieee754sp ieee754sp_flong(s64 x); ++ieee754sp ieee754sp_fulong(u64 x); ++ieee754sp ieee754sp_fdp(ieee754dp x); ++ ++int ieee754sp_tint(ieee754sp x); ++unsigned int ieee754sp_tuns(ieee754sp x); ++s64 ieee754sp_tlong(ieee754sp x); ++u64 ieee754sp_tulong(ieee754sp x); ++ ++int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig); ++/* ++ * basic sp math ++ */ ++ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip); ++ieee754sp ieee754sp_frexp(ieee754sp x, int *exp); ++ieee754sp ieee754sp_ldexp(ieee754sp x, int exp); ++ ++ieee754sp ieee754sp_ceil(ieee754sp x); ++ieee754sp ieee754sp_floor(ieee754sp x); ++ieee754sp ieee754sp_trunc(ieee754sp x); ++ ++ieee754sp ieee754sp_sqrt(ieee754sp x); ++ ++/* ++ * double precision (often aka double) ++*/ ++int ieee754dp_finite(ieee754dp x); ++int ieee754dp_class(ieee754dp x); ++ ++/* x with sign of y */ ++ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y); ++ ++ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y); ++ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y); ++ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y); ++ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y); ++ ++ieee754dp ieee754dp_abs(ieee754dp x); ++ieee754dp ieee754dp_neg(ieee754dp x); ++ieee754dp ieee754dp_scalb(ieee754dp x, int); ++ ++/* return exponent as integer in floating point format ++ */ ++ieee754dp ieee754dp_logb(ieee754dp x); ++ ++ieee754dp ieee754dp_fint(int x); ++ieee754dp ieee754dp_funs(unsigned x); ++ieee754dp ieee754dp_flong(s64 x); ++ieee754dp ieee754dp_fulong(u64 x); ++ieee754dp ieee754dp_fsp(ieee754sp x); ++ ++ieee754dp ieee754dp_ceil(ieee754dp x); ++ieee754dp ieee754dp_floor(ieee754dp x); ++ieee754dp ieee754dp_trunc(ieee754dp x); ++ ++int ieee754dp_tint(ieee754dp x); ++unsigned int ieee754dp_tuns(ieee754dp x); ++s64 ieee754dp_tlong(ieee754dp x); ++u64 ieee754dp_tulong(ieee754dp x); ++ ++int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig); ++/* ++ * basic sp math ++ */ ++ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip); ++ieee754dp ieee754dp_frexp(ieee754dp x, int *exp); ++ieee754dp ieee754dp_ldexp(ieee754dp x, int exp); ++ ++ieee754dp ieee754dp_ceil(ieee754dp x); ++ieee754dp ieee754dp_floor(ieee754dp x); ++ieee754dp ieee754dp_trunc(ieee754dp x); ++ ++ieee754dp ieee754dp_sqrt(ieee754dp x); ++ ++ ++ ++/* 5 types of floating point number ++*/ ++#define IEEE754_CLASS_NORM 0x00 ++#define IEEE754_CLASS_ZERO 0x01 ++#define IEEE754_CLASS_DNORM 0x02 ++#define IEEE754_CLASS_INF 0x03 ++#define IEEE754_CLASS_SNAN 0x04 ++#define IEEE754_CLASS_QNAN 0x05 ++ ++/* exception numbers */ ++#define IEEE754_INVALID_OPERATION 0x01 ++#define IEEE754_ZERO_DIVIDE 0x02 ++#define IEEE754_OVERFLOW 0x04 ++#define IEEE754_UNDERFLOW 0x08 ++#define IEEE754_INEXACT 0x10 ++ ++/* cmp operators ++*/ ++#define IEEE754_CLT 0x01 ++#define IEEE754_CEQ 0x02 ++#define IEEE754_CGT 0x04 ++#define IEEE754_CUN 0x08 ++ ++/* rounding mode ++*/ ++#define IEEE754_RN 0 /* round to nearest */ ++#define IEEE754_RZ 1 /* round toward zero */ ++#define IEEE754_RD 2 /* round toward -Infinity */ ++#define IEEE754_RU 3 /* round toward +Infinity */ ++ ++/* other naming */ ++#define IEEE754_RM IEEE754_RD ++#define IEEE754_RP IEEE754_RU ++ ++/* "normal" comparisons ++*/ ++static inline int ieee754sp_eq(ieee754sp x, ieee754sp y) ++{ ++ return ieee754sp_cmp(x, y, IEEE754_CEQ, 0); ++} ++ ++static inline int ieee754sp_ne(ieee754sp x, ieee754sp y) ++{ ++ return ieee754sp_cmp(x, y, ++ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0); ++} ++ ++static inline int ieee754sp_lt(ieee754sp x, ieee754sp y) ++{ ++ return ieee754sp_cmp(x, y, IEEE754_CLT, 0); ++} ++ ++static inline int ieee754sp_le(ieee754sp x, ieee754sp y) ++{ ++ return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0); ++} ++ ++static inline int ieee754sp_gt(ieee754sp x, ieee754sp y) ++{ ++ return ieee754sp_cmp(x, y, IEEE754_CGT, 0); ++} ++ ++ ++static inline int ieee754sp_ge(ieee754sp x, ieee754sp y) ++{ ++ return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0); ++} ++ ++static inline int ieee754dp_eq(ieee754dp x, ieee754dp y) ++{ ++ return ieee754dp_cmp(x, y, IEEE754_CEQ, 0); ++} ++ ++static inline int ieee754dp_ne(ieee754dp x, ieee754dp y) ++{ ++ return ieee754dp_cmp(x, y, ++ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0); ++} ++ ++static inline int ieee754dp_lt(ieee754dp x, ieee754dp y) ++{ ++ return ieee754dp_cmp(x, y, IEEE754_CLT, 0); ++} ++ ++static inline int ieee754dp_le(ieee754dp x, ieee754dp y) ++{ ++ return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0); ++} ++ ++static inline int ieee754dp_gt(ieee754dp x, ieee754dp y) ++{ ++ return ieee754dp_cmp(x, y, IEEE754_CGT, 0); ++} ++ ++static inline int ieee754dp_ge(ieee754dp x, ieee754dp y) ++{ ++ return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0); ++} ++ ++ ++/* ++ * Like strtod ++ */ ++ieee754dp ieee754dp_fstr(const char *s, char **endp); ++char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af); ++ ++ ++/* ++ * The control status register ++ */ ++struct _ieee754_csr { ++#ifdef __BIG_ENDIAN ++ unsigned pad0:12; ++ unsigned cx:7; /* exceptions this operation */ ++ unsigned nod:1; /* set 1 for no denormalised numbers */ ++ unsigned mx:5; /* exception enable mask */ ++ unsigned sx:5; /* exceptions total */ ++ unsigned rm:2; /* current rounding mode */ ++#endif ++#ifdef __LITTLE_ENDIAN ++ unsigned rm:2; /* current rounding mode */ ++ unsigned sx:5; /* exceptions total */ ++ unsigned mx:5; /* exception enable mask */ ++ unsigned nod:1; /* set 1 for no denormalised numbers */ ++ unsigned cx:7; /* exceptions this operation */ ++ unsigned pad0:12; ++#endif ++}; ++#define ieee754_csr (*(struct _ieee754_csr *)(¤t->thread.fpu.fpcsr)) ++ ++static inline unsigned ieee754_getrm(void) ++{ ++ return (ieee754_csr.rm); ++} ++static inline unsigned ieee754_setrm(unsigned rm) ++{ ++ return (ieee754_csr.rm = rm); ++} ++ ++/* ++ * get current exceptions ++ */ ++static inline unsigned ieee754_getcx(void) ++{ ++ return (ieee754_csr.cx); ++} ++ ++/* test for current exception condition ++ */ ++static inline int ieee754_cxtest(unsigned n) ++{ ++ return (ieee754_csr.cx & n); ++} ++ ++/* ++ * get sticky exceptions ++ */ ++static inline unsigned ieee754_getsx(void) ++{ ++ return (ieee754_csr.sx); ++} ++ ++/* clear sticky conditions ++*/ ++static inline unsigned ieee754_clrsx(void) ++{ ++ return (ieee754_csr.sx = 0); ++} ++ ++/* test for sticky exception condition ++ */ ++static inline int ieee754_sxtest(unsigned n) ++{ ++ return (ieee754_csr.sx & n); ++} ++ ++/* debugging */ ++ieee754sp ieee754sp_dump(char *s, ieee754sp x); ++ieee754dp ieee754dp_dump(char *s, ieee754dp x); ++ ++#define IEEE754_SPCVAL_PZERO 0 ++#define IEEE754_SPCVAL_NZERO 1 ++#define IEEE754_SPCVAL_PONE 2 ++#define IEEE754_SPCVAL_NONE 3 ++#define IEEE754_SPCVAL_PTEN 4 ++#define IEEE754_SPCVAL_NTEN 5 ++#define IEEE754_SPCVAL_PINFINITY 6 ++#define IEEE754_SPCVAL_NINFINITY 7 ++#define IEEE754_SPCVAL_INDEF 8 ++#define IEEE754_SPCVAL_PMAX 9 /* +max norm */ ++#define IEEE754_SPCVAL_NMAX 10 /* -max norm */ ++#define IEEE754_SPCVAL_PMIN 11 /* +min norm */ ++#define IEEE754_SPCVAL_NMIN 12 /* +min norm */ ++#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */ ++#define IEEE754_SPCVAL_NMIND 14 /* +min denorm */ ++#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */ ++#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */ ++ ++extern const struct ieee754dp_konst __ieee754dp_spcvals[]; ++extern const struct ieee754sp_konst __ieee754sp_spcvals[]; ++#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals) ++#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals) ++ ++/* ++ * Return infinity with given sign ++ */ ++#define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) ++#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) ++#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) ++#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) ++#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF]) ++#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) ++#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) ++#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) ++#define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31]) ++#define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63]) ++ ++#define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) ++#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) ++#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) ++#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) ++#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF]) ++#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) ++#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) ++#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) ++#define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31]) ++#define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63]) ++ ++/* ++ * Indefinite integer value ++ */ ++#define ieee754si_indef() INT_MAX ++#ifdef LONG_LONG_MAX ++#define ieee754di_indef() LONG_LONG_MAX ++#else ++#define ieee754di_indef() ((s64)(~0ULL>>1)) ++#endif ++ ++/* IEEE exception context, passed to handler */ ++struct ieee754xctx { ++ const char *op; /* operation name */ ++ int rt; /* result type */ ++ union { ++ ieee754sp sp; /* single precision */ ++ ieee754dp dp; /* double precision */ ++#ifdef IEEE854_XP ++ ieee754xp xp; /* extended precision */ ++#endif ++ int si; /* standard signed integer (32bits) */ ++ s64 di; /* extended signed integer (64bits) */ ++ } rv; /* default result format implied by op */ ++ va_list ap; ++}; ++ ++/* result types for xctx.rt */ ++#define IEEE754_RT_SP 0 ++#define IEEE754_RT_DP 1 ++#define IEEE754_RT_XP 2 ++#define IEEE754_RT_SI 3 ++#define IEEE754_RT_DI 4 ++ ++extern void ieee754_xcpt(struct ieee754xctx *xcp); ++ ++/* compat */ ++#define ieee754dp_fix(x) ieee754dp_tint(x) ++#define ieee754sp_fix(x) ieee754sp_tint(x) ++ ++#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754int.h linux-3.4.110/arch/nds32/math-emu/ieee754int.h +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754int.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754int.h 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,165 @@ ++/* ++ * IEEE754 floating point ++ * common internal header file ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++ ++#include "ieee754.h" ++ ++#define DP_EBIAS 1023 ++#define DP_EMIN (-1022) ++#define DP_EMAX 1023 ++#define DP_MBITS 52 ++ ++#define SP_EBIAS 127 ++#define SP_EMIN (-126) ++#define SP_EMAX 127 ++#define SP_MBITS 23 ++ ++#define DP_MBIT(x) ((u64)1 << (x)) ++#define DP_HIDDEN_BIT DP_MBIT(DP_MBITS) ++#define DP_SIGN_BIT DP_MBIT(63) ++ ++#define SP_MBIT(x) ((u32)1 << (x)) ++#define SP_HIDDEN_BIT SP_MBIT(SP_MBITS) ++#define SP_SIGN_BIT SP_MBIT(31) ++ ++ ++#define SPSIGN(sp) (sp.parts.sign) ++#define SPBEXP(sp) (sp.parts.bexp) ++#define SPMANT(sp) (sp.parts.mant) ++ ++#define DPSIGN(dp) (dp.parts.sign) ++#define DPBEXP(dp) (dp.parts.bexp) ++#define DPMANT(dp) (dp.parts.mant) ++ ++#define CLPAIR(x, y) ((x)*6+(y)) ++ ++#define CLEARCX \ ++ (ieee754_csr.cx = 0) ++ ++#define SETCX(x) \ ++ (ieee754_csr.cx |= (x), ieee754_csr.sx |= (x)) ++ ++#define SETANDTESTCX(x) \ ++ (SETCX(x), ieee754_csr.mx & (x)) ++ ++#define TSTX() \ ++ (ieee754_csr.cx & ieee754_csr.mx) ++ ++ ++#define COMPXSP \ ++ unsigned xm; int xe; int xs; int xc ++ ++#define COMPYSP \ ++ unsigned ym; int ye; int ys; int yc ++ ++#define EXPLODESP(v, vc, vs, ve, vm) \ ++{\ ++ vs = SPSIGN(v);\ ++ ve = SPBEXP(v);\ ++ vm = SPMANT(v);\ ++ if(ve == SP_EMAX+1+SP_EBIAS){\ ++ if(vm == 0)\ ++ vc = IEEE754_CLASS_INF;\ ++ else if(vm & SP_MBIT(SP_MBITS-1)) \ ++ vc = IEEE754_CLASS_SNAN;\ ++ else \ ++ vc = IEEE754_CLASS_QNAN;\ ++ } else if(ve == SP_EMIN-1+SP_EBIAS) {\ ++ if(vm) {\ ++ ve = SP_EMIN;\ ++ vc = IEEE754_CLASS_DNORM;\ ++ } else\ ++ vc = IEEE754_CLASS_ZERO;\ ++ } else {\ ++ ve -= SP_EBIAS;\ ++ vm |= SP_HIDDEN_BIT;\ ++ vc = IEEE754_CLASS_NORM;\ ++ }\ ++} ++#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm) ++#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym) ++ ++ ++#define COMPXDP \ ++u64 xm; int xe; int xs; int xc ++ ++#define COMPYDP \ ++u64 ym; int ye; int ys; int yc ++ ++#define EXPLODEDP(v, vc, vs, ve, vm) \ ++{\ ++ vm = DPMANT(v);\ ++ vs = DPSIGN(v);\ ++ ve = DPBEXP(v);\ ++ if(ve == DP_EMAX+1+DP_EBIAS){\ ++ if(vm == 0)\ ++ vc = IEEE754_CLASS_INF;\ ++ else if(vm & DP_MBIT(DP_MBITS-1)) \ ++ vc = IEEE754_CLASS_SNAN;\ ++ else \ ++ vc = IEEE754_CLASS_QNAN;\ ++ } else if(ve == DP_EMIN-1+DP_EBIAS) {\ ++ if(vm) {\ ++ ve = DP_EMIN;\ ++ vc = IEEE754_CLASS_DNORM;\ ++ } else\ ++ vc = IEEE754_CLASS_ZERO;\ ++ } else {\ ++ ve -= DP_EBIAS;\ ++ vm |= DP_HIDDEN_BIT;\ ++ vc = IEEE754_CLASS_NORM;\ ++ }\ ++} ++#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm) ++#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym) ++ ++#define FLUSHDP(v, vc, vs, ve, vm) \ ++ if(vc==IEEE754_CLASS_DNORM) {\ ++ if(ieee754_csr.nod) {\ ++ SETCX(IEEE754_INEXACT);\ ++ vc = IEEE754_CLASS_ZERO;\ ++ ve = DP_EMIN-1+DP_EBIAS;\ ++ vm = 0;\ ++ v = ieee754dp_zero(vs);\ ++ }\ ++ } ++ ++#define FLUSHSP(v, vc, vs, ve, vm) \ ++ if(vc==IEEE754_CLASS_DNORM) {\ ++ if(ieee754_csr.nod) {\ ++ SETCX(IEEE754_INEXACT);\ ++ vc = IEEE754_CLASS_ZERO;\ ++ ve = SP_EMIN-1+SP_EBIAS;\ ++ vm = 0;\ ++ v = ieee754sp_zero(vs);\ ++ }\ ++ } ++ ++#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm) ++#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym) ++#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm) ++#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym) +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754m.c linux-3.4.110/arch/nds32/math-emu/ieee754m.c +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754m.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754m.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,55 @@ ++/* ++ * floor, trunc, ceil ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754.h" ++ ++ieee754dp ieee754dp_floor(ieee754dp x) ++{ ++ ieee754dp i; ++ ++ if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0))) ++ return ieee754dp_sub(i, ieee754dp_one(0)); ++ else ++ return i; ++} ++ ++ieee754dp ieee754dp_ceil(ieee754dp x) ++{ ++ ieee754dp i; ++ ++ if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0))) ++ return ieee754dp_add(i, ieee754dp_one(0)); ++ else ++ return i; ++} ++ ++ieee754dp ieee754dp_trunc(ieee754dp x) ++{ ++ ieee754dp i; ++ ++ (void)ieee754dp_modf(x, &i); ++ return i; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.c linux-3.4.110/arch/nds32/math-emu/ieee754sp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754sp.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,239 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++int ieee754sp_class(ieee754sp x) ++{ ++ COMPXSP; ++ EXPLODEXSP; ++ return xc; ++} ++ ++int ieee754sp_isnan(ieee754sp x) ++{ ++ return ieee754sp_class(x) >= IEEE754_CLASS_SNAN; ++} ++ ++int ieee754sp_issnan(ieee754sp x) ++{ ++ assert(ieee754sp_isnan(x)); ++ return (SPMANT(x) & SP_MBIT(SP_MBITS - 1)); ++} ++ ++ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...) ++{ ++ struct ieee754xctx ax; ++ ++ if (!TSTX()) ++ return r; ++ ++ ax.op = op; ++ ax.rt = IEEE754_RT_SP; ++ ax.rv.sp = r; ++ va_start(ax.ap, op); ++ ieee754_xcpt(&ax); ++ va_end(ax.ap); ++ return ax.rv.sp; ++} ++ ++ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...) ++{ ++ struct ieee754xctx ax; ++ ++ assert(ieee754sp_isnan(r)); ++ ++ if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ ++ return r; ++ ++ if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { ++ /* not enabled convert to a quiet NaN */ ++ SPMANT(r) &= (~SP_MBIT(SP_MBITS - 1)); ++ if (ieee754sp_isnan(r)) ++ return r; ++ else ++ return ieee754sp_indef(); ++ } ++ ++ ax.op = op; ++ ax.rt = 0; ++ ax.rv.sp = r; ++ va_start(ax.ap, op); ++ ieee754_xcpt(&ax); ++ va_end(ax.ap); ++ return ax.rv.sp; ++} ++ ++ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y) ++{ ++ assert(ieee754sp_isnan(x)); ++ assert(ieee754sp_isnan(y)); ++ ++ if (SPMANT(x) > SPMANT(y)) ++ return x; ++ else ++ return y; ++} ++ ++static unsigned get_rounding(int sn, unsigned xm) ++{ ++ /* inexact must round of 3 bits ++ */ ++ if (xm & (SP_MBIT(3) - 1)) { ++ switch (ieee754_csr.rm) { ++ case IEEE754_RZ: ++ break; ++ case IEEE754_RN: ++ xm += 0x3 + ((xm >> 3) & 1); ++ /* xm += (xm&0x8)?0x4:0x3 */ ++ break; ++ case IEEE754_RU: /* toward +Infinity */ ++ if (!sn) /* ?? */ ++ xm += 0x8; ++ break; ++ case IEEE754_RD: /* toward -Infinity */ ++ if (sn) /* ?? */ ++ xm += 0x8; ++ break; ++ } ++ } ++ return xm; ++} ++ ++/* generate a normal/denormal number with over,under handling ++ * sn is sign ++ * xe is an unbiased exponent ++ * xm is 3bit extended precision value. ++ */ ++ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) ++{ ++ assert(xm); /* we don't gen exact zeros (probably should) */ ++ ++ assert((xm >> (SP_MBITS + 1 + 3)) == 0); /* no execess */ ++ assert(xm & (SP_HIDDEN_BIT << 3)); ++ ++ if (xe < SP_EMIN) { ++ /* strip lower bits */ ++ int es = SP_EMIN - xe; ++ ++ if (ieee754_csr.nod) { ++ SETCX(IEEE754_UNDERFLOW); ++ SETCX(IEEE754_INEXACT); ++ ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ return ieee754sp_zero(sn); ++ case IEEE754_RZ: ++ return ieee754sp_zero(sn); ++ case IEEE754_RU: /* toward +Infinity */ ++ if (sn == 0) ++ return ieee754sp_min(0); ++ else ++ return ieee754sp_zero(1); ++ case IEEE754_RD: /* toward -Infinity */ ++ if (sn == 0) ++ return ieee754sp_zero(0); ++ else ++ return ieee754sp_min(1); ++ } ++ } ++ ++ if (xe == SP_EMIN - 1 ++ && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3)) { ++ /* Not tiny after rounding */ ++ SETCX(IEEE754_INEXACT); ++ xm = get_rounding(sn, xm); ++ xm >>= 1; ++ /* Clear grs bits */ ++ xm &= ~(SP_MBIT(3) - 1); ++ xe++; ++ } else { ++ /* sticky right shift es bits ++ */ ++ SPXSRSXn(es); ++ assert((xm & (SP_HIDDEN_BIT << 3)) == 0); ++ assert(xe == SP_EMIN); ++ } ++ } ++ if (xm & (SP_MBIT(3) - 1)) { ++ SETCX(IEEE754_INEXACT); ++ if ((xm & (SP_HIDDEN_BIT << 3)) == 0) { ++ SETCX(IEEE754_UNDERFLOW); ++ } ++ ++ /* inexact must round of 3 bits ++ */ ++ xm = get_rounding(sn, xm); ++ /* adjust exponent for rounding add overflowing ++ */ ++ if (xm >> (SP_MBITS + 1 + 3)) { ++ /* add causes mantissa overflow */ ++ xm >>= 1; ++ xe++; ++ } ++ } ++ /* strip grs bits */ ++ xm >>= 3; ++ ++ assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ ++ assert(xe >= SP_EMIN); ++ ++ if (xe > SP_EMAX) { ++ SETCX(IEEE754_OVERFLOW); ++ SETCX(IEEE754_INEXACT); ++ /* -O can be table indexed by (rm,sn) */ ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ return ieee754sp_inf(sn); ++ case IEEE754_RZ: ++ return ieee754sp_max(sn); ++ case IEEE754_RU: /* toward +Infinity */ ++ if (sn == 0) ++ return ieee754sp_inf(0); ++ else ++ return ieee754sp_max(1); ++ case IEEE754_RD: /* toward -Infinity */ ++ if (sn == 0) ++ return ieee754sp_max(0); ++ else ++ return ieee754sp_inf(1); ++ } ++ } ++ /* gen norm/denorm/zero */ ++ ++ if ((xm & SP_HIDDEN_BIT) == 0) { ++ /* we underflow (tiny/zero) */ ++ assert(xe == SP_EMIN); ++ if (ieee754_csr.mx & IEEE754_UNDERFLOW) ++ SETCX(IEEE754_UNDERFLOW); ++ return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm); ++ } else { ++ assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ ++ assert(xm & SP_HIDDEN_BIT); ++ ++ return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.h linux-3.4.110/arch/nds32/math-emu/ieee754sp.h +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754sp.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754sp.h 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,89 @@ ++/* ++ * IEEE754 floating point ++ * double precision internal header file ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++ ++#include "ieee754int.h" ++ ++#define assert(expr) ((void)0) ++ ++/* 3bit extended single precision sticky right shift */ ++#define SPXSRSXn(rs) \ ++ (xe += rs, \ ++ xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0)) ++ ++#define SPXSRSX1() \ ++ (xe++, (xm = (xm >> 1) | (xm & 1))) ++ ++#define SPXSRSYn(rs) \ ++ (ye+=rs, \ ++ ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0)) ++ ++#define SPXSRSY1() \ ++ (ye++, (ym = (ym >> 1) | (ym & 1))) ++ ++/* convert denormal to normalized with extended exponent */ ++#define SPDNORMx(m,e) \ ++ while( (m >> SP_MBITS) == 0) { m <<= 1; e--; } ++#define SPDNORMX SPDNORMx(xm, xe) ++#define SPDNORMY SPDNORMx(ym, ye) ++ ++static inline ieee754sp buildsp(int s, int bx, unsigned m) ++{ ++ ieee754sp r; ++ ++ assert((s) == 0 || (s) == 1); ++ assert((bx) >= SP_EMIN - 1 + SP_EBIAS ++ && (bx) <= SP_EMAX + 1 + SP_EBIAS); ++ assert(((m) >> SP_MBITS) == 0); ++ ++ r.parts.sign = s; ++ r.parts.bexp = bx; ++ r.parts.mant = m; ++ ++ return r; ++} ++ ++extern int ieee754sp_isnan(ieee754sp); ++extern int ieee754sp_issnan(ieee754sp); ++extern int ieee754si_xcpt(int, const char *, ...); ++extern s64 ieee754di_xcpt(s64, const char *, ...); ++extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...); ++extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...); ++extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp); ++extern ieee754sp ieee754sp_format(int, int, unsigned); ++ ++ ++#define SPNORMRET2(s, e, m, name, a0, a1) \ ++{ \ ++ ieee754sp V = ieee754sp_format(s, e, m); \ ++ if(TSTX()) \ ++ return ieee754sp_xcpt(V, name, a0, a1); \ ++ else \ ++ return V; \ ++} ++ ++#define SPNORMRET1(s, e, m, name, a0) SPNORMRET2(s, e, m, name, a0, a0) +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/ieee754xcpt.c linux-3.4.110/arch/nds32/math-emu/ieee754xcpt.c +--- linux-3.4.110.orig/arch/nds32/math-emu/ieee754xcpt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/ieee754xcpt.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,48 @@ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++/************************************************************************** ++ * Nov 7, 2000 ++ * Added preprocessor hacks to map to Linux kernel diagnostics. ++ * ++ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ *************************************************************************/ ++ ++#include ++#include "ieee754.h" ++ ++/* ++ * Very naff exception handler (you can plug in your own and ++ * override this). ++ */ ++ ++static const char *const rtnames[] = { ++ "sp", "dp", "xp", "si", "di" ++}; ++ ++void ieee754_xcpt(struct ieee754xctx *xcp) ++{ ++ printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n", ++ xcp->op, rtnames[xcp->rt]); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/insn.h linux-3.4.110/arch/nds32/math-emu/insn.h +--- linux-3.4.110.orig/arch/nds32/math-emu/insn.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/insn.h 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,101 @@ ++#ifndef _ASM_INST_H ++#define _ASM_INST_H ++ ++#define cop0_op 0x35 ++ ++/* ++ * COP0 field of opcodes. ++ */ ++#define fs1_op 0x0 ++#define fs2_op 0x4 ++#define fd1_op 0x8 ++#define fd2_op 0xc ++ ++/* ++ * FS1 opcode. ++ */ ++enum fs1 { ++ fadds_op, fsubs_op, fcpynss_op, fcpyss_op, ++ fmadds_op, fmsubs_op, fcmovns_op, fcmovzs_op, ++ fnmadds_op, fnmsubs_op, ++ fmuls_op = 0xc, fdivs_op, ++ fs1_f2op_op = 0xf ++}; ++ ++/* ++ * FS1/F2OP opcode. ++ */ ++enum fs1_f2 { ++ fs2d_op, fsqrts_op, fabss_op = 0x5, ++ fui2s_op = 0x8, fsi2s_op = 0xc, ++ fs2ui_op = 0x10, fs2ui_z_op = 0x14, ++ fs2si_op = 0x18, fs2si_z_op = 0x1c ++}; ++ ++/* ++ * FS2 opcode. ++ */ ++enum fs2 { ++ fcmpeqs_op, fcmpeqs_e_op, fcmplts_op, fcmplts_e_op, ++ fcmples_op, fcmples_e_op, fcmpuns_op, fcmpuns_e_op ++}; ++ ++/* ++ * FD1 opcode. ++ */ ++enum fd1 { ++ faddd_op, fsubd_op, fcpynsd_op, fcpysd_op, ++ fmaddd_op, fmsubd_op, fcmovnd_op, fcmovzd_op, ++ fnmaddd_op, fnmsubd_op, ++ fmuld_op = 0xc, fdivd_op, fd1_f2op_op = 0xf ++}; ++ ++/* ++ * FD1/F2OP opcode. ++ */ ++enum fd1_f2 { ++ fd2s_op, fsqrtd_op, fabsd_op = 0x5, ++ fui2d_op = 0x8, fsi2d_op = 0xc, ++ fd2ui_op = 0x10, fd2ui_z_op = 0x14, ++ fd2si_op = 0x18, fd2si_z_op = 0x1c ++}; ++ ++/* ++ * FD2 opcode. ++ */ ++enum fd2 { ++ fcmpeqd_op, fcmpeqd_e_op, fcmpltd_op, fcmpltd_e_op, ++ fcmpled_op, fcmpled_e_op, fcmpund_op, fcmpund_e_op ++}; ++ ++ ++#define NDS32Insn(x) x ++ ++#define I_OPCODE_off 25 ++#define NDS32Insn_OPCODE(x) (NDS32Insn(x) >> I_OPCODE_off) ++ ++#define I_OPCODE_offRt 20 ++#define I_OPCODE_mskRt (0x1fUL << I_OPCODE_offRt) ++#define NDS32Insn_OPCODE_Rt(x) ((NDS32Insn(x) & I_OPCODE_mskRt) >> I_OPCODE_offRt) ++ ++#define I_OPCODE_offRa 15 ++#define I_OPCODE_mskRa (0x1fUL << I_OPCODE_offRa) ++#define NDS32Insn_OPCODE_Ra(x) ((NDS32Insn(x) & I_OPCODE_mskRa) >> I_OPCODE_offRa) ++ ++#define I_OPCODE_offRb 10 ++#define I_OPCODE_mskRb (0x1fUL << I_OPCODE_offRb) ++#define NDS32Insn_OPCODE_Rb(x) ((NDS32Insn(x) & I_OPCODE_mskRb) >> I_OPCODE_offRb) ++ ++#define I_OPCODE_offbit1014 10 ++#define I_OPCODE_mskbit1014 (0x1fUL << I_OPCODE_offbit1014) ++#define NDS32Insn_OPCODE_BIT1014(x) ((NDS32Insn(x) & I_OPCODE_mskbit1014) >> I_OPCODE_offbit1014) ++ ++#define I_OPCODE_offbit69 6 ++#define I_OPCODE_mskbit69 (0xfUL << I_OPCODE_offbit69) ++#define NDS32Insn_OPCODE_BIT69(x) ((NDS32Insn(x) & I_OPCODE_mskbit69) >> I_OPCODE_offbit69) ++ ++#define I_OPCODE_offCOP0 0 ++#define I_OPCODE_mskCOP0 (0x3fUL << I_OPCODE_offCOP0) ++#define NDS32Insn_OPCODE_COP0(x) ((NDS32Insn(x) & I_OPCODE_mskCOP0) >> I_OPCODE_offCOP0) ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/Makefile linux-3.4.110/arch/nds32/math-emu/Makefile +--- linux-3.4.110.orig/arch/nds32/math-emu/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/Makefile 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,13 @@ ++# ++# Makefile for the Linux/nds32 kernel FPU emulation. ++# ++ ++obj-y := fpuemu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ ++ ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \ ++ dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \ ++ dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \ ++ sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \ ++ sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ ++ dp_sqrt.o sp_sqrt.o ++ ++EXTRA_CFLAGS += -Werror +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_add.c linux-3.4.110/arch/nds32/math-emu/sp_add.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_add.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_add.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,173 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) ++{ ++ COMPXSP; ++ COMPYSP; ++ ++ EXPLODEXSP; ++ EXPLODEYSP; ++ ++ CLEARCX; ++ ++ FLUSHXSP; ++ FLUSHYSP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ if (xs == ys) ++ return x; ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ return x; ++ ++ /* Zero handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ if (xs == ys) ++ return x; ++ else ++ return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ return x; ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ SPDNORMX; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ SPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ SPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ assert(xm & SP_HIDDEN_BIT); ++ assert(ym & SP_HIDDEN_BIT); ++ ++ /* provide guard,round and stick bit space */ ++ xm <<= 3; ++ ym <<= 3; ++ ++ if (xe > ye) { ++ /* have to shift y fraction right to align ++ */ ++ int s = xe - ye; ++ SPXSRSYn(s); ++ } else if (ye > xe) { ++ /* have to shift x fraction right to align ++ */ ++ int s = ye - xe; ++ SPXSRSXn(s); ++ } ++ assert(xe == ye); ++ assert(xe <= SP_EMAX); ++ ++ if (xs == ys) { ++ /* generate 28 bit result of adding two 27 bit numbers ++ * leaving result in xm,xs,xe ++ */ ++ xm = xm + ym; ++ xe = xe; ++ xs = xs; ++ ++ if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */ ++ SPXSRSX1(); ++ } ++ } else { ++ if (xm >= ym) { ++ xm = xm - ym; ++ xe = xe; ++ xs = xs; ++ } else { ++ xm = ym - xm; ++ xe = xe; ++ xs = ys; ++ } ++ if (xm == 0) ++ return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD); ++ ++ /* normalize in extended single precision */ ++ while ((xm >> (SP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ ++ } ++ SPNORMRET2(xs, xe, xm, "add", x, y); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_cmp.c linux-3.4.110/arch/nds32/math-emu/sp_cmp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_cmp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_cmp.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,66 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig) ++{ ++ COMPXSP; ++ COMPYSP; ++ ++ EXPLODEXSP; ++ EXPLODEYSP; ++ FLUSHXSP; ++ FLUSHYSP; ++ CLEARCX; /* Even clear inexact flag here */ ++ ++ if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) { ++ if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN) ++ SETCX(IEEE754_INVALID_OPERATION); ++ if (cmp & IEEE754_CUN) ++ return 1; ++ if (cmp & (IEEE754_CLT | IEEE754_CGT)) { ++ if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) ++ return ieee754si_xcpt(0, "fcmpf", x); ++ } ++ return 0; ++ } else { ++ int vx = x.bits; ++ int vy = y.bits; ++ ++ if (vx < 0) ++ vx = -vx ^ SP_SIGN_BIT; ++ if (vy < 0) ++ vy = -vy ^ SP_SIGN_BIT; ++ ++ if (vx < vy) ++ return (cmp & IEEE754_CLT) != 0; ++ else if (vx == vy) ++ return (cmp & IEEE754_CEQ) != 0; ++ else ++ return (cmp & IEEE754_CGT) != 0; ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_div.c linux-3.4.110/arch/nds32/math-emu/sp_div.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_div.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_div.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,155 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) ++{ ++ COMPXSP; ++ COMPYSP; ++ ++ EXPLODEXSP; ++ EXPLODEYSP; ++ ++ CLEARCX; ++ ++ FLUSHXSP; ++ FLUSHYSP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ return ieee754sp_zero(xs ^ ys); ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ return ieee754sp_inf(xs ^ ys); ++ ++ /* Zero handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ SETCX(IEEE754_ZERO_DIVIDE); ++ return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ return ieee754sp_zero(xs == ys ? 0 : 1); ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ SPDNORMX; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ SPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ SPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ assert(xm & SP_HIDDEN_BIT); ++ assert(ym & SP_HIDDEN_BIT); ++ ++ /* provide rounding space */ ++ xm <<= 3; ++ ym <<= 3; ++ ++ { ++ /* now the dirty work */ ++ ++ unsigned rm = 0; ++ int re = xe - ye; ++ unsigned bm; ++ ++ for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) { ++ if (xm >= ym) { ++ xm -= ym; ++ rm |= bm; ++ if (xm == 0) ++ break; ++ } ++ xm <<= 1; ++ } ++ rm <<= 1; ++ if (xm) ++ rm |= 1; /* have remainder, set sticky */ ++ ++ assert(rm); ++ ++ /* normalise rm to rounding precision ? ++ */ ++ while ((rm >> (SP_MBITS + 3)) == 0) { ++ rm <<= 1; ++ re--; ++ } ++ ++ SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_fdp.c linux-3.4.110/arch/nds32/math-emu/sp_fdp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_fdp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_fdp.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,76 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_fdp(ieee754dp x) ++{ ++ COMPXDP; ++ ieee754sp nan; ++ ++ EXPLODEXDP; ++ ++ CLEARCX; ++ ++ FLUSHXDP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp"); ++ case IEEE754_CLASS_QNAN: ++ nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32) ++ (xm >> (DP_MBITS - SP_MBITS))); ++ if (!ieee754sp_isnan(nan)) ++ nan = ieee754sp_indef(); ++ return ieee754sp_nanxcpt(nan, "fdp", x); ++ case IEEE754_CLASS_INF: ++ return ieee754sp_inf(xs); ++ case IEEE754_CLASS_ZERO: ++ return ieee754sp_zero(xs); ++ case IEEE754_CLASS_DNORM: ++ /* can't possibly be sp representable */ ++ SETCX(IEEE754_UNDERFLOW); ++ SETCX(IEEE754_INEXACT); ++ if ((ieee754_csr.rm == IEEE754_RU && !xs) || ++ (ieee754_csr.rm == IEEE754_RD && xs)) ++ return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x); ++ return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x); ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ ++ { ++ u32 rm; ++ ++ /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift ++ */ ++ rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) | ++ ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0); ++ ++ SPNORMRET1(xs, xe, rm, "fdp", x); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_fint.c linux-3.4.110/arch/nds32/math-emu/sp_fint.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_fint.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_fint.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,78 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_fint(int x) ++{ ++ unsigned xm; ++ int xe; ++ int xs; ++ ++ CLEARCX; ++ ++ if (x == 0) ++ return ieee754sp_zero(0); ++ if (x == 1 || x == -1) ++ return ieee754sp_one(x < 0); ++ if (x == 10 || x == -10) ++ return ieee754sp_ten(x < 0); ++ ++ xs = (x < 0); ++ if (xs) { ++ if (x == (1 << 31)) ++ xm = ((unsigned)1 << 31); /* max neg can't be safely negated */ ++ else ++ xm = -x; ++ } else { ++ xm = x; ++ } ++ xe = SP_MBITS + 3; ++ ++ if (xm >> (SP_MBITS + 1 + 3)) { ++ /* shunt out overflow bits ++ */ ++ while (xm >> (SP_MBITS + 1 + 3)) { ++ SPXSRSX1(); ++ } ++ } else { ++ /* normalize in grs extended single precision ++ */ ++ while ((xm >> (SP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ } ++ SPNORMRET1(xs, xe, xm, "fint", x); ++} ++ ++ieee754sp ieee754sp_funs(unsigned int u) ++{ ++ if ((int)u < 0) ++ return ieee754sp_add(ieee754sp_1e31(), ++ ieee754sp_fint(u & ~(1 << 31))); ++ return ieee754sp_fint(u); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_flong.c linux-3.4.110/arch/nds32/math-emu/sp_flong.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_flong.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_flong.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,77 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_flong(s64 x) ++{ ++ u64 xm; /* <--- need 64-bit mantissa temp */ ++ int xe; ++ int xs; ++ ++ CLEARCX; ++ ++ if (x == 0) ++ return ieee754sp_zero(0); ++ if (x == 1 || x == -1) ++ return ieee754sp_one(x < 0); ++ if (x == 10 || x == -10) ++ return ieee754sp_ten(x < 0); ++ ++ xs = (x < 0); ++ if (xs) { ++ if (x == (1ULL << 63)) ++ xm = (1ULL << 63); /* max neg can't be safely negated */ ++ else ++ xm = -x; ++ } else { ++ xm = x; ++ } ++ xe = SP_MBITS + 3; ++ ++ if (xm >> (SP_MBITS + 1 + 3)) { ++ /* shunt out overflow bits ++ */ ++ while (xm >> (SP_MBITS + 1 + 3)) { ++ SPXSRSX1(); ++ } ++ } else { ++ /* normalize in grs extended single precision */ ++ while ((xm >> (SP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ } ++ SPNORMRET1(xs, xe, xm, "sp_flong", x); ++} ++ ++ieee754sp ieee754sp_fulong(u64 u) ++{ ++ if ((s64) u < 0) ++ return ieee754sp_add(ieee754sp_1e63(), ++ ieee754sp_flong(u & ~(1ULL << 63))); ++ return ieee754sp_flong(u); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_frexp.c linux-3.4.110/arch/nds32/math-emu/sp_frexp.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_frexp.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_frexp.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,52 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++/* close to ieeep754sp_logb ++*/ ++ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr) ++{ ++ COMPXSP; ++ CLEARCX; ++ EXPLODEXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ case IEEE754_CLASS_ZERO: ++ *eptr = 0; ++ return x; ++ case IEEE754_CLASS_DNORM: ++ SPDNORMX; ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ *eptr = xe + 1; ++ return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_logb.c linux-3.4.110/arch/nds32/math-emu/sp_logb.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_logb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_logb.c 2016-04-07 10:20:50.978082417 +0200 +@@ -0,0 +1,53 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_logb(ieee754sp x) ++{ ++ COMPXSP; ++ ++ CLEARCX; ++ ++ EXPLODEXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ return ieee754sp_nanxcpt(x, "logb", x); ++ case IEEE754_CLASS_QNAN: ++ return x; ++ case IEEE754_CLASS_INF: ++ return ieee754sp_inf(0); ++ case IEEE754_CLASS_ZERO: ++ return ieee754sp_inf(1); ++ case IEEE754_CLASS_DNORM: ++ SPDNORMX; ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ return ieee754sp_fint(xe); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_modf.c linux-3.4.110/arch/nds32/math-emu/sp_modf.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_modf.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_modf.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,79 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++/* modf function is always exact for a finite number ++*/ ++ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip) ++{ ++ COMPXSP; ++ ++ CLEARCX; ++ ++ EXPLODEXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ case IEEE754_CLASS_ZERO: ++ *ip = x; ++ return x; ++ case IEEE754_CLASS_DNORM: ++ /* far to small */ ++ *ip = ieee754sp_zero(xs); ++ return x; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ if (xe < 0) { ++ *ip = ieee754sp_zero(xs); ++ return x; ++ } ++ if (xe >= SP_MBITS) { ++ *ip = x; ++ return ieee754sp_zero(xs); ++ } ++ /* generate ipart mantissa by clearing bottom bits ++ */ ++ *ip = buildsp(xs, xe + SP_EBIAS, ++ ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) & ++ ~SP_HIDDEN_BIT); ++ ++ /* generate fpart mantissa by clearing top bits ++ * and normalizing (must be able to normalize) ++ */ ++ xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe)); ++ if (xm == 0) ++ return ieee754sp_zero(xs); ++ ++ while ((xm >> SP_MBITS) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_mul.c linux-3.4.110/arch/nds32/math-emu/sp_mul.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_mul.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_mul.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,168 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) ++{ ++ COMPXSP; ++ COMPYSP; ++ ++ EXPLODEXSP; ++ EXPLODEYSP; ++ ++ CLEARCX; ++ ++ FLUSHXSP; ++ FLUSHYSP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754sp_inf(xs ^ ys); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ return ieee754sp_zero(xs ^ ys); ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ SPDNORMX; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ SPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ SPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ /* rm = xm * ym, re = xe+ye basicly */ ++ assert(xm & SP_HIDDEN_BIT); ++ assert(ym & SP_HIDDEN_BIT); ++ ++ { ++ int re = xe + ye; ++ int rs = xs ^ ys; ++ unsigned rm; ++ ++ /* shunt to top of word */ ++ xm <<= 32 - (SP_MBITS + 1); ++ ym <<= 32 - (SP_MBITS + 1); ++ ++ /* multiply 32bits xm,ym to give high 32bits rm with stickness ++ */ ++ { ++ unsigned short lxm = xm & 0xffff; ++ unsigned short hxm = xm >> 16; ++ unsigned short lym = ym & 0xffff; ++ unsigned short hym = ym >> 16; ++ unsigned lrm; ++ unsigned hrm; ++ ++ lrm = lxm * lym; /* 16 * 16 => 32 */ ++ hrm = hxm * hym; /* 16 * 16 => 32 */ ++ ++ { ++ unsigned t = lxm * hym; /* 16 * 16 => 32 */ ++ { ++ unsigned at = lrm + (t << 16); ++ hrm += at < lrm; ++ lrm = at; ++ } ++ hrm = hrm + (t >> 16); ++ } ++ ++ { ++ unsigned t = hxm * lym; /* 16 * 16 => 32 */ ++ { ++ unsigned at = lrm + (t << 16); ++ hrm += at < lrm; ++ lrm = at; ++ } ++ hrm = hrm + (t >> 16); ++ } ++ rm = hrm | (lrm != 0); ++ } ++ ++ /* ++ * sticky shift down to normal rounding precision ++ */ ++ if ((int)rm < 0) { ++ rm = (rm >> (32 - (SP_MBITS + 1 + 3))) | ++ ((rm << (SP_MBITS + 1 + 3)) != 0); ++ re++; ++ } else { ++ rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) | ++ ((rm << (SP_MBITS + 1 + 3 + 1)) != 0); ++ } ++ assert(rm & (SP_HIDDEN_BIT << 3)); ++ ++ SPNORMRET2(rs, re, rm, "mul", x, y); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_scalb.c linux-3.4.110/arch/nds32/math-emu/sp_scalb.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_scalb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_scalb.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,56 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_scalb(ieee754sp x, int n) ++{ ++ COMPXSP; ++ ++ CLEARCX; ++ ++ EXPLODEXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ return ieee754sp_nanxcpt(x, "scalb", x, n); ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ case IEEE754_CLASS_ZERO: ++ return x; ++ case IEEE754_CLASS_DNORM: ++ SPDNORMX; ++ break; ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n); ++} ++ ++ieee754sp ieee754sp_ldexp(ieee754sp x, int n) ++{ ++ return ieee754sp_scalb(x, n); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_simple.c linux-3.4.110/arch/nds32/math-emu/sp_simple.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_simple.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_simple.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,87 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++int ieee754sp_finite(ieee754sp x) ++{ ++ return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; ++} ++ ++ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y) ++{ ++ CLEARCX; ++ SPSIGN(x) = SPSIGN(y); ++ return x; ++} ++ ++ieee754sp ieee754sp_neg(ieee754sp x) ++{ ++ COMPXSP; ++ ++ EXPLODEXSP; ++ CLEARCX; ++ FLUSHXSP; ++ ++ /* ++ * Invert the sign ALWAYS to prevent an endless recursion on ++ * pow() in libc. ++ */ ++ /* quick fix up */ ++ SPSIGN(x) ^= 1; ++ ++ if (xc == IEEE754_CLASS_SNAN) { ++ ieee754sp y = ieee754sp_indef(); ++ SETCX(IEEE754_INVALID_OPERATION); ++ SPSIGN(y) = SPSIGN(x); ++ return ieee754sp_nanxcpt(y, "neg"); ++ } ++ ++ if (ieee754sp_isnan(x)) /* but not infinity */ ++ return ieee754sp_nanxcpt(x, "neg", x); ++ return x; ++} ++ ++ieee754sp ieee754sp_abs(ieee754sp x) ++{ ++ COMPXSP; ++ ++ EXPLODEXSP; ++ CLEARCX; ++ FLUSHXSP; ++ ++ if (xc == IEEE754_CLASS_SNAN) { ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "abs"); ++ } ++ ++ if (ieee754sp_isnan(x)) /* but not infinity */ ++ return ieee754sp_nanxcpt(x, "abs", x); ++ ++ /* quick fix up */ ++ SPSIGN(x) = 0; ++ return x; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_sqrt.c linux-3.4.110/arch/nds32/math-emu/sp_sqrt.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_sqrt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_sqrt.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,116 @@ ++/* IEEE754 floating point arithmetic ++ * single precision square root ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_sqrt(ieee754sp x) ++{ ++ int ix, s, q, m, t, i; ++ unsigned int r; ++ COMPXSP; ++ ++ /* take care of Inf and NaN */ ++ ++ EXPLODEXSP; ++ CLEARCX; ++ FLUSHXSP; ++ ++ /* x == INF or NAN? */ ++ switch (xc) { ++ case IEEE754_CLASS_QNAN: ++ /* sqrt(Nan) = Nan */ ++ return ieee754sp_nanxcpt(x, "sqrt"); ++ case IEEE754_CLASS_SNAN: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); ++ case IEEE754_CLASS_ZERO: ++ /* sqrt(0) = 0 */ ++ return x; ++ case IEEE754_CLASS_INF: ++ if (xs) { ++ /* sqrt(-Inf) = Nan */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); ++ } ++ /* sqrt(+Inf) = Inf */ ++ return x; ++ case IEEE754_CLASS_DNORM: ++ case IEEE754_CLASS_NORM: ++ if (xs) { ++ /* sqrt(-x) = Nan */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); ++ } ++ break; ++ } ++ ++ ix = x.bits; ++ ++ /* normalize x */ ++ m = (ix >> 23); ++ if (m == 0) { /* subnormal x */ ++ for (i = 0; (ix & 0x00800000) == 0; i++) ++ ix <<= 1; ++ m -= i - 1; ++ } ++ m -= 127; /* unbias exponent */ ++ ix = (ix & 0x007fffff) | 0x00800000; ++ if (m & 1) /* odd m, double x to make it even */ ++ ix += ix; ++ m >>= 1; /* m = [m/2] */ ++ ++ /* generate sqrt(x) bit by bit */ ++ ix += ix; ++ q = s = 0; /* q = sqrt(x) */ ++ r = 0x01000000; /* r = moving bit from right to left */ ++ ++ while (r != 0) { ++ t = s + r; ++ if (t <= ix) { ++ s = t + r; ++ ix -= t; ++ q += r; ++ } ++ ix += ix; ++ r >>= 1; ++ } ++ ++ if (ix != 0) { ++ SETCX(IEEE754_INEXACT); ++ switch (ieee754_csr.rm) { ++ case IEEE754_RP: ++ q += 2; ++ break; ++ case IEEE754_RN: ++ q += (q & 1); ++ break; ++ } ++ } ++ ix = (q >> 1) + 0x3f000000; ++ ix += (m << 23); ++ x.bits = ix; ++ return x; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_sub.c linux-3.4.110/arch/nds32/math-emu/sp_sub.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_sub.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_sub.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,180 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) ++{ ++ COMPXSP; ++ COMPYSP; ++ ++ EXPLODEXSP; ++ EXPLODEYSP; ++ ++ CLEARCX; ++ ++ FLUSHXSP; ++ FLUSHYSP; ++ ++ switch (CLPAIR(xc, yc)) { ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): ++ return x; ++ ++ /* Infinity handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ if (xs != ys) ++ return x; ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y); ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): ++ return ieee754sp_inf(ys ^ 1); ++ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): ++ return x; ++ ++ /* Zero handling ++ */ ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): ++ if (xs != ys) ++ return x; ++ else ++ return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD); ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): ++ return x; ++ ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): ++ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): ++ /* quick fix up */ ++ DPSIGN(y) ^= 1; ++ return y; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): ++ SPDNORMX; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): ++ SPDNORMY; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): ++ SPDNORMX; ++ break; ++ ++ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): ++ break; ++ } ++ /* flip sign of y and handle as add */ ++ ys ^= 1; ++ ++ assert(xm & SP_HIDDEN_BIT); ++ assert(ym & SP_HIDDEN_BIT); ++ ++ /* provide guard,round and stick bit space */ ++ xm <<= 3; ++ ym <<= 3; ++ ++ if (xe > ye) { ++ /* have to shift y fraction right to align ++ */ ++ int s = xe - ye; ++ SPXSRSYn(s); ++ } else if (ye > xe) { ++ /* have to shift x fraction right to align ++ */ ++ int s = ye - xe; ++ SPXSRSXn(s); ++ } ++ assert(xe == ye); ++ assert(xe <= SP_EMAX); ++ ++ if (xs == ys) { ++ /* generate 28 bit result of adding two 27 bit numbers ++ */ ++ xm = xm + ym; ++ xe = xe; ++ xs = xs; ++ ++ if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */ ++ SPXSRSX1(); /* shift preserving sticky */ ++ } ++ } else { ++ if (xm >= ym) { ++ xm = xm - ym; ++ xe = xe; ++ xs = xs; ++ } else { ++ xm = ym - xm; ++ xe = xe; ++ xs = ys; ++ } ++ if (xm == 0) { ++ if (ieee754_csr.rm == IEEE754_RD) ++ return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ ++ else ++ return ieee754sp_zero(0); /* other round modes => sign = 1 */ ++ } ++ /* normalize to rounding precision ++ */ ++ while ((xm >> (SP_MBITS + 3)) == 0) { ++ xm <<= 1; ++ xe--; ++ } ++ } ++ SPNORMRET2(xs, xe, xm, "sub", x, y); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_tint.c linux-3.4.110/arch/nds32/math-emu/sp_tint.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_tint.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_tint.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,125 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include ++#include "ieee754sp.h" ++ ++int ieee754sp_tint(ieee754sp x) ++{ ++ COMPXSP; ++ ++ CLEARCX; ++ ++ EXPLODEXSP; ++ FLUSHXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); ++ case IEEE754_CLASS_ZERO: ++ return 0; ++ case IEEE754_CLASS_DNORM: ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ if (xe >= 31) { ++ /* look for valid corner case */ ++ if (xe == 31 && xs && xm == SP_HIDDEN_BIT) ++ return -0x80000000; ++ /* Set invalid. We will only use overflow for floating ++ point overflow */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); ++ } ++ /* oh gawd */ ++ if (xe > SP_MBITS) { ++ xm <<= xe - SP_MBITS; ++ } else { ++ u32 residue; ++ int round; ++ int sticky; ++ int odd; ++ ++ if (xe < -1) { ++ residue = xm; ++ round = 0; ++ sticky = residue != 0; ++ xm = 0; ++ } else { ++ /* Shifting a u32 32 times does not work, ++ * so we do it in two steps. Be aware that xe ++ * may be -1 */ ++ residue = xm << (xe + 1); ++ residue <<= 31 - SP_MBITS; ++ round = (residue >> 31) != 0; ++ sticky = (residue << 1) != 0; ++ xm >>= SP_MBITS - xe; ++ } ++ odd = (xm & 0x1) != 0x0; ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ if (round && (sticky || odd)) ++ xm++; ++ break; ++ case IEEE754_RZ: ++ break; ++ case IEEE754_RU: /* toward +Infinity */ ++ if ((round || sticky) && !xs) ++ xm++; ++ break; ++ case IEEE754_RD: /* toward -Infinity */ ++ if ((round || sticky) && xs) ++ xm++; ++ break; ++ } ++ if ((xm >> 31) != 0) { ++ /* This can happen after rounding */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); ++ } ++ if (round || sticky) ++ SETCX(IEEE754_INEXACT); ++ } ++ if (xs) ++ return -xm; ++ else ++ return xm; ++} ++ ++unsigned int ieee754sp_tuns(ieee754sp x) ++{ ++ ieee754sp hb = ieee754sp_1e31(); ++ ++ /* what if x < 0 ?? */ ++ if (ieee754sp_lt(x, hb)) ++ return (unsigned)ieee754sp_tint(x); ++ ++ return (unsigned)ieee754sp_tint(ieee754sp_sub(x, hb)) | ++ ((unsigned)1 << 31); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/math-emu/sp_tlong.c linux-3.4.110/arch/nds32/math-emu/sp_tlong.c +--- linux-3.4.110.orig/arch/nds32/math-emu/sp_tlong.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/math-emu/sp_tlong.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,119 @@ ++/* IEEE754 floating point arithmetic ++ * single precision ++ */ ++/* ++ * MIPS floating point support ++ * Copyright (C) 1994-2000 Algorithmics Ltd. ++ * http://www.algor.co.uk ++ * ++ * ######################################################################## ++ * ++ * This program is free software; you can distribute it and/or modify it ++ * under the terms of the GNU General Public License (Version 2) as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope 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., ++ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. ++ * ++ * ######################################################################## ++ */ ++ ++#include "ieee754sp.h" ++ ++s64 ieee754sp_tlong(ieee754sp x) ++{ ++ COMPXDP; /* <-- need 64-bit mantissa tmp */ ++ ++ CLEARCX; ++ ++ EXPLODEXSP; ++ FLUSHXSP; ++ ++ switch (xc) { ++ case IEEE754_CLASS_SNAN: ++ case IEEE754_CLASS_QNAN: ++ case IEEE754_CLASS_INF: ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); ++ case IEEE754_CLASS_ZERO: ++ return 0; ++ case IEEE754_CLASS_DNORM: ++ case IEEE754_CLASS_NORM: ++ break; ++ } ++ if (xe >= 63) { ++ /* look for valid corner case */ ++ if (xe == 63 && xs && xm == SP_HIDDEN_BIT) ++ return -0x8000000000000000LL; ++ /* Set invalid. We will only use overflow for floating ++ point overflow */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); ++ } ++ /* oh gawd */ ++ if (xe > SP_MBITS) { ++ xm <<= xe - SP_MBITS; ++ } else if (xe < SP_MBITS) { ++ u32 residue; ++ int round; ++ int sticky; ++ int odd; ++ ++ if (xe < -1) { ++ residue = xm; ++ round = 0; ++ sticky = residue != 0; ++ xm = 0; ++ } else { ++ residue = xm << (32 - SP_MBITS + xe); ++ round = (residue >> 31) != 0; ++ sticky = (residue << 1) != 0; ++ xm >>= SP_MBITS - xe; ++ } ++ odd = (xm & 0x1) != 0x0; ++ switch (ieee754_csr.rm) { ++ case IEEE754_RN: ++ if (round && (sticky || odd)) ++ xm++; ++ break; ++ case IEEE754_RZ: ++ break; ++ case IEEE754_RU: /* toward +Infinity */ ++ if ((round || sticky) && !xs) ++ xm++; ++ break; ++ case IEEE754_RD: /* toward -Infinity */ ++ if ((round || sticky) && xs) ++ xm++; ++ break; ++ } ++ if ((xm >> 63) != 0) { ++ /* This can happen after rounding */ ++ SETCX(IEEE754_INVALID_OPERATION); ++ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); ++ } ++ if (round || sticky) ++ SETCX(IEEE754_INEXACT); ++ } ++ if (xs) ++ return -xm; ++ else ++ return xm; ++} ++ ++u64 ieee754sp_tulong(ieee754sp x) ++{ ++ ieee754sp hb = ieee754sp_1e63(); ++ ++ /* what if x < 0 ?? */ ++ if (ieee754sp_lt(x, hb)) ++ return (u64) ieee754sp_tlong(x); ++ ++ return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) | (1ULL << 63); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/mm/alignment.c linux-3.4.110/arch/nds32/mm/alignment.c +--- linux-3.4.110.orig/arch/nds32/mm/alignment.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/alignment.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,560 @@ ++/* ++ * linux/arch/nds32/mm/alignment.c ++ * ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#ifdef CONFIG_PROC_FS ++extern struct proc_dir_entry *proc_dir_cpu; ++#endif ++ ++#define DEBUG(enable, tagged, ...) \ ++ do{ \ ++ if (enable) { \ ++ if (tagged) \ ++ printk(KERN_WARNING "[ %30s() ] ", __func__); \ ++ printk(KERN_WARNING __VA_ARGS__); \ ++ } \ ++ } while (0) ++ ++#define RT(inst) (((inst) >> 20) & 0x1FUL) ++#define RA(inst) (((inst) >> 15) & 0x1FUL) ++#define RB(inst) (((inst) >> 10) & 0x1FUL) ++#define SV(inst) (((inst) >> 8) & 0x3UL) ++#define IMM(inst) (((inst) >> 0) & 0x3FFFUL) ++ ++#define RA3(inst) (((inst) >> 3) & 0x7UL) ++#define RT3(inst) (((inst) >> 6) & 0x7UL) ++#define IMM3U(inst) (((inst) >> 0) & 0x7UL) ++ ++#define RA5(inst) (((inst) >> 0) & 0x1FUL) ++#define RT4(inst) (((inst) >> 5) & 0xFUL) ++ ++extern int (*do_unaligned_access) ++ (unsigned long entry, unsigned long addr, ++ unsigned long type, struct pt_regs * regs); ++extern int va_present(struct mm_struct *mm, unsigned long addr); ++extern int va_kernel_present(unsigned long addr); ++extern int va_readable(struct pt_regs *regs, unsigned long addr); ++extern int va_writable(struct pt_regs *regs, unsigned long addr); ++ ++static int mode = 0x3; ++module_param(mode, int, 1); ++ ++static inline unsigned long *idx_to_addr(struct pt_regs *regs, int idx) ++{ ++ /* this should be consistent with ptrace.h */ ++ if (idx >= 0 && idx <= 25) /* R0-R25 */ ++ return ®s->NDS32_r0 + idx; ++ else if (idx >= 28 && idx <= 30) /* FP, GP, LP */ ++ return ®s->NDS32_fp + (idx - 28); ++ else if (idx == 31) /* SP */ ++ return ®s->NDS32_sp; ++ else ++ return NULL; /* cause a segfault */ ++} ++ ++static inline unsigned long get_inst(unsigned long addr) ++{ ++ /* FIXME: consider 16-bit inst. */ ++ return be32_to_cpu(get_unaligned((u32 *) addr)); ++} ++ ++static inline unsigned long get_data(unsigned long addr, int len) ++{ ++ if (len == 4) ++ return get_unaligned((u32 *) addr); ++ else ++ return get_unaligned((u16 *) addr); ++} ++ ++static inline void set_data(unsigned long addr, unsigned long val, int len) ++{ ++ if (len == 4) ++ put_unaligned(val, (u32 *) addr); ++ else ++ put_unaligned(val, (u16 *) addr); ++} ++ ++static inline unsigned long sign_extend(unsigned long val, int len) ++{ ++ unsigned long ret = 0; ++ unsigned char *s, *t; ++ int i = 0; ++ ++ val = cpu_to_le32(val); ++ ++ s = (void *)&val; ++ t = (void *)&ret; ++ ++ while (i++ < len) ++ *t++ = *s++; ++ ++ if (((*(t - 1)) & 0x80) && (i < 4)) { ++ ++ while (i++ <= 4) ++ *t++ = 0xff; ++ } ++ ++ return le32_to_cpu(ret); ++} ++ ++static inline int do_16(unsigned long inst, struct pt_regs *regs) ++{ ++ int imm, regular, load, len, addr_mode, idx_mode; ++ unsigned long unaligned_addr, target_val, source_idx, target_idx, ++ shift = 0; ++ switch ((inst >> 9) & 0x3F) { ++ ++ case 0x12: /* LHI333 */ ++ imm = 1; ++ regular = 1; ++ load = 1; ++ len = 2; ++ addr_mode = 3; ++ idx_mode = 3; ++ break; ++ case 0x10: /* LWI333 */ ++ imm = 1; ++ regular = 1; ++ load = 1; ++ len = 4; ++ addr_mode = 3; ++ idx_mode = 3; ++ break; ++ case 0x11: /* LWI333.bi */ ++ imm = 1; ++ regular = 0; ++ load = 1; ++ len = 4; ++ addr_mode = 3; ++ idx_mode = 3; ++ break; ++ case 0x1A: /* LWI450 */ ++ imm = 0; ++ regular = 1; ++ load = 1; ++ len = 4; ++ addr_mode = 5; ++ idx_mode = 4; ++ break; ++ case 0x16: /* SHI333 */ ++ imm = 1; ++ regular = 1; ++ load = 0; ++ len = 2; ++ addr_mode = 3; ++ idx_mode = 3; ++ break; ++ case 0x14: /* SWI333 */ ++ imm = 1; ++ regular = 1; ++ load = 0; ++ len = 4; ++ addr_mode = 3; ++ idx_mode = 3; ++ break; ++ case 0x15: /* SWI333.bi */ ++ imm = 1; ++ regular = 0; ++ load = 0; ++ len = 4; ++ addr_mode = 3; ++ idx_mode = 3; ++ break; ++ case 0x1B: /* SWI450 */ ++ imm = 0; ++ regular = 1; ++ load = 0; ++ len = 4; ++ addr_mode = 5; ++ idx_mode = 4; ++ break; ++ ++ default: ++ return -EFAULT; ++ } ++ ++ if (addr_mode == 3) { ++ unaligned_addr = *idx_to_addr(regs, RA3(inst)); ++ source_idx = RA3(inst); ++ } else { ++ unaligned_addr = *idx_to_addr(regs, RA5(inst)); ++ source_idx = RA5(inst); ++ } ++ ++ if (idx_mode == 3) ++ target_idx = RT3(inst); ++ else ++ target_idx = RT4(inst); ++ ++ if (imm) ++ shift = IMM3U(inst) * len; ++ ++ if (regular) ++ unaligned_addr += shift; ++ else ++ *idx_to_addr(regs, source_idx) = unaligned_addr + shift; ++ ++ if (load) { ++ ++ if (!va_readable(regs, unaligned_addr)) ++ return -EACCES; ++ ++ if (!access_ok(VERIFY_READ, (void *)unaligned_addr, len)) ++ return -EACCES; ++ ++ *idx_to_addr(regs, target_idx) = get_data(unaligned_addr, len); ++ } else { ++ ++ if (!va_writable(regs, unaligned_addr)) ++ return -EACCES; ++ ++ if (!access_ok(VERIFY_WRITE, (void *)unaligned_addr, len)) ++ return -EACCES; ++ ++ target_val = *idx_to_addr(regs, target_idx); ++ set_data(unaligned_addr, target_val, len); ++ } ++ ++ regs->NDS32_ipc += 2; ++ ++ return 0; ++} ++ ++static inline int do_32(unsigned long inst, struct pt_regs *regs) ++{ ++ int imm, regular, load, len, sign_ext; ++ unsigned long unsligned_addr, target_val, shift; ++ ++ unsligned_addr = *idx_to_addr(regs, RA(inst)); ++ ++ switch ((inst >> 25) << 1) { ++ ++ case 0x02: /* LHI */ ++ imm = 1; ++ regular = 1; ++ load = 1; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x0A: /* LHI.bi */ ++ imm = 1; ++ regular = 0; ++ load = 1; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x22: /* LHSI */ ++ imm = 1; ++ regular = 1; ++ load = 1; ++ len = 2; ++ sign_ext = 1; ++ break; ++ case 0x2A: /* LHSI.bi */ ++ imm = 1; ++ regular = 0; ++ load = 1; ++ len = 2; ++ sign_ext = 1; ++ break; ++ case 0x04: /* LWI */ ++ imm = 1; ++ regular = 1; ++ load = 1; ++ len = 4; ++ sign_ext = 0; ++ break; ++ case 0x0C: /* LWI.bi */ ++ imm = 1; ++ regular = 0; ++ load = 1; ++ len = 4; ++ sign_ext = 0; ++ break; ++ case 0x12: /* SHI */ ++ imm = 1; ++ regular = 1; ++ load = 0; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x1A: /* SHI.bi */ ++ imm = 1; ++ regular = 0; ++ load = 0; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x14: /* SWI */ ++ imm = 1; ++ regular = 1; ++ load = 0; ++ len = 4; ++ sign_ext = 0; ++ break; ++ case 0x1C: /* SWI.bi */ ++ imm = 1; ++ regular = 0; ++ load = 0; ++ len = 4; ++ sign_ext = 0; ++ break; ++ ++ default: ++ switch (inst & 0xff) { ++ ++ case 0x01: /* LH */ ++ imm = 0; ++ regular = 1; ++ load = 1; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x05: /* LH.bi */ ++ imm = 0; ++ regular = 0; ++ load = 1; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x11: /* LHS */ ++ imm = 0; ++ regular = 1; ++ load = 1; ++ len = 2; ++ sign_ext = 1; ++ break; ++ case 0x15: /* LHS.bi */ ++ imm = 0; ++ regular = 0; ++ load = 1; ++ len = 2; ++ sign_ext = 1; ++ break; ++ case 0x02: /* LW */ ++ imm = 0; ++ regular = 1; ++ load = 1; ++ len = 4; ++ sign_ext = 0; ++ break; ++ case 0x06: /* LW.bi */ ++ imm = 0; ++ regular = 0; ++ load = 1; ++ len = 4; ++ sign_ext = 0; ++ break; ++ case 0x09: /* SH */ ++ imm = 0; ++ regular = 1; ++ load = 0; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x0D: /* SH.bi */ ++ imm = 0; ++ regular = 0; ++ load = 0; ++ len = 2; ++ sign_ext = 0; ++ break; ++ case 0x0A: /* SW */ ++ imm = 0; ++ regular = 1; ++ load = 0; ++ len = 4; ++ sign_ext = 0; ++ break; ++ case 0x0E: /* SW.bi */ ++ imm = 0; ++ regular = 0; ++ load = 0; ++ len = 4; ++ sign_ext = 0; ++ break; ++ ++ default: ++ return -EFAULT; ++ } ++ } ++ ++ if (imm) ++ shift = IMM(inst) * len; ++ else ++ shift = *idx_to_addr(regs, RB(inst)) << SV(inst); ++ ++ if (regular) ++ unsligned_addr += shift; ++ else ++ *idx_to_addr(regs, RA(inst)) = unsligned_addr + shift; ++ ++ if (load) { ++ ++ if (!va_readable(regs, unsligned_addr)) ++ return -EACCES; ++ ++ if (!access_ok(VERIFY_READ, (void *)unsligned_addr, len)) ++ return -EACCES; ++ ++ if (sign_ext) ++ *idx_to_addr(regs, RT(inst)) = ++ sign_extend(get_data(unsligned_addr, len), len); ++ else ++ *idx_to_addr(regs, RT(inst)) = ++ get_data(unsligned_addr, len); ++ } else { ++ ++ if (!va_writable(regs, unsligned_addr)) ++ return -EACCES; ++ ++ if (!access_ok(VERIFY_WRITE, (void *)unsligned_addr, len)) ++ return -EACCES; ++ ++ target_val = *idx_to_addr(regs, RT(inst)); ++ set_data(unsligned_addr, target_val, len); ++ } ++ ++ regs->NDS32_ipc += 4; ++ ++ return 0; ++} ++ ++static int _do_unaligned_access(unsigned long entry, unsigned long addr, ++ unsigned long type, struct pt_regs *regs) ++{ ++ unsigned long inst; ++ int ret = -EFAULT; ++ ++ if (user_mode(regs)) { ++ /* user mode */ ++ if (!va_present(current->mm, addr)) ++ return ret; ++ } else { ++ /* kernel mode */ ++ if (!va_kernel_present(addr)) ++ return ret; ++ } ++ ++ inst = get_inst(regs->NDS32_ipc); ++ ++ DEBUG(mode & 0x04, 1, ++ "Faulting Addr: 0x%08lx, PC: 0x%08lx [ 0x%08lx ]\n", addr, ++ regs->NDS32_ipc, inst); ++ ++ if ((user_mode(regs) && (mode & 0x01)) ++ || (!user_mode(regs) && (mode & 0x02))) { ++ ++ mm_segment_t seg = get_fs(); ++ ++ set_fs(KERNEL_DS); ++ ++ if (inst & 0x80000000) ++ ret = do_16((inst >> 16) & 0xffff, regs); ++ else ++ ret = do_32(inst, regs); ++ ++ set_fs(seg); ++ } ++ ++ return ret; ++} ++ ++#ifdef CONFIG_PROC_FS ++ ++static int proc_alignment_read(char *page, char **start, off_t off, int count, ++ int *eof, void *data) ++{ ++ char *p = page; ++ int len; ++ ++ p += sprintf(p, "(0x01) User Mode: %s\n", mode & 0x01 ? "on" : "off"); ++ p += sprintf(p, "(0x02) Kernel Mode: %s\n", mode & 0x02 ? "on" : "off"); ++ p += sprintf(p, "(0x04) Warning: %s\n", mode & 0x04 ? "on" : "off"); ++ ++ len = (p - page) - off; ++ if (len < 0) ++ len = 0; ++ ++ *eof = (len <= count) ? 1 : 0; ++ *start = page + off; ++ ++ return len; ++} ++ ++#define INPUTLEN 12 /* '0' + 'x' + 8digit + '\n' + '\0' */ ++ ++static int proc_alignment_write(struct file *file, const char __user * buffer, ++ unsigned long count, void *data) ++{ ++ unsigned long en; ++ char *endp; ++ char inbuf[INPUTLEN]; ++ ++ if (count > INPUTLEN - 1) ++ return -EFAULT; ++ ++ if (copy_from_user(inbuf, buffer, count)) ++ return -EFAULT; ++ ++ inbuf[count - 1] = '\0'; ++ ++ en = simple_strtoul(inbuf, &endp, 0); ++ if (en > 0x07) ++ return -EFAULT; ++ ++ mode = en & 0x7; ++ ++ return count; ++} ++ ++#endif /* CONFIG_PROC_FS */ ++ ++static int __init unaligned_access_init(void) ++{ ++#ifdef CONFIG_PROC_FS ++ static struct proc_dir_entry *res_alignment; ++ ++ if (!proc_dir_cpu) ++ if (!(proc_dir_cpu = proc_mkdir("cpu", NULL))) ++ return -ENOMEM; ++ ++ if (! ++ (res_alignment = ++ create_proc_entry("alignment", S_IWUSR | S_IRUGO, proc_dir_cpu))) ++ return -ENOMEM; ++ ++ res_alignment->read_proc = proc_alignment_read; ++ res_alignment->write_proc = proc_alignment_write; ++#endif ++ do_unaligned_access = _do_unaligned_access; ++ ++ return 0; ++} ++ ++static void __exit unaligned_access_exit(void) ++{ ++#ifdef CONFIG_PROC_FS ++ remove_proc_entry("alignment", proc_dir_cpu); ++#endif ++ do_unaligned_access = NULL; ++} ++ ++MODULE_AUTHOR("Roy Lee"); ++MODULE_DESCRIPTION("Unaligned Access Handler"); ++MODULE_LICENSE("GPL"); ++ ++module_init(unaligned_access_init); ++module_exit(unaligned_access_exit); +diff -Nur linux-3.4.110.orig/arch/nds32/mm/cacheflush.c linux-3.4.110/arch/nds32/mm/cacheflush.c +--- linux-3.4.110.orig/arch/nds32/mm/cacheflush.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/cacheflush.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,355 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct cache_info L1_cache_info[2]; ++ ++#ifdef CONFIG_CPU_CACHE_NONALIASING ++void flush_cache_mm(struct mm_struct *mm) ++{ ++} ++ ++void flush_cache_dup_mm(struct mm_struct *mm) ++{ ++} ++ ++void flush_cache_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++} ++ ++void flush_cache_page(struct vm_area_struct *vma, ++ unsigned long addr, unsigned long pfn) ++{ ++} ++ ++void flush_cache_vmap(unsigned long start, unsigned long end) ++{ ++} ++ ++void flush_cache_vunmap(unsigned long start, unsigned long end) ++{ ++} ++ ++void flush_dcache_page(struct page *page) ++{ ++ struct address_space *mapping; ++ ++ if (!PageHighMem(page)) { ++ mapping = page_mapping(page); ++ if (mapping && !mapping_mapped(mapping)) ++ set_bit(PG_dcache_dirty, &page->flags); ++ else ++ cpu_dcache_wbinval_page((unsigned long) ++ page_address(page)); ++ } else { ++ unsigned long kaddr = (unsigned long)kmap_atomic(page); ++ cpu_dcache_wbinval_page(kaddr); ++ kunmap_atomic((void *)kaddr); ++ } ++} ++ ++void copy_to_user_page(struct vm_area_struct *vma, struct page *page, ++ unsigned long vaddr, void *dst, void *src, int len) ++{ ++ unsigned long line_size, start, end; ++ ++ memcpy(dst, src, len); ++ if (vma->vm_flags & VM_EXEC) { ++ line_size = L1_cache_info[DCACHE].line_size; ++ start = (unsigned long)dst & ~(line_size - 1); ++ end = ++ ((unsigned long)dst + len + line_size - 1) & ~(line_size - ++ 1); ++ cpu_cache_wbinval_range(start, end, 1); ++ } ++} ++ ++void copy_from_user_page(struct vm_area_struct *vma, struct page *page, ++ unsigned long vaddr, void *dst, void *src, int len) ++{ ++ memcpy(dst, src, len); ++} ++ ++void flush_icache_range(unsigned long start, unsigned long end) ++{ ++ cpu_cache_wbinval_range(start, end, 1); ++} ++ ++void flush_icache_page(struct vm_area_struct *vma, struct page *page) ++{ ++} ++ ++void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, ++ pte_t * pte) ++{ ++ struct page *page; ++ unsigned long pfn = pte_pfn(*pte); ++ ++ if (!pfn_valid(pfn)) ++ return; ++ ++ if (vma->vm_mm == current->active_mm) ++ asm("mtsr %1, $mr2\ndsb\n" ++ "tlbop %0, RWR\nisb\n" ++ ::"r"(*pte), "r"(addr)); ++ ++ page = pfn_to_page(pfn); ++ ++ if ((test_and_clear_bit(PG_dcache_dirty, &page->flags)) || ++ (vma->vm_flags & VM_EXEC)) { ++ ++ if (!PageHighMem(page)) { ++ cpu_cache_wbinval_page((unsigned long) ++ page_address(page), ++ vma->vm_flags & VM_EXEC); ++ } else { ++ unsigned long kaddr = (unsigned long)kmap_atomic(page); ++ cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); ++ kunmap_atomic((void *)kaddr); ++ } ++ } ++} ++#else ++int va_present(struct mm_struct *mm, unsigned long addr); ++ ++static inline unsigned long aliasing(unsigned long addr, unsigned long page) ++{ ++ return ((addr & PAGE_MASK) ^ page) & (REALSHMLBA - 1); ++} ++ ++static inline unsigned long kremap0(unsigned long uaddr, unsigned long pa) ++{ ++ unsigned long kaddr, pte; ++ ++#define BASE_ADDR0 0xffffc000 ++ kaddr = BASE_ADDR0 | (uaddr & L1_cache_info[DCACHE].aliasing_mask); ++ pte = (pa | PAGE_KERNEL); ++ asm("mtsr %1, $mr2\ndsb\n" ++ "tlbop %0, RWLK\nisb\n" ++ ::"r"(pte), "r"(kaddr)); ++ return kaddr; ++} ++ ++static inline void kunmap01(unsigned long kaddr) ++{ ++ asm volatile ("tlbop %0, UNLK\n\t" ++ "tlbop %0, INV\n\t" ++ ::"r" (kaddr)); ++} ++ ++static inline unsigned long kremap1(unsigned long uaddr, unsigned long pa) ++{ ++ unsigned long kaddr, pte; ++ ++#define BASE_ADDR1 0xffff8000 ++ kaddr = BASE_ADDR1 | (uaddr & L1_cache_info[DCACHE].aliasing_mask); ++ pte = (pa | PAGE_KERNEL); ++ asm("mtsr %1, $mr2\ndsb\n" ++ "tlbop %0, RWLK\nisb\n" ++ ::"r"(pte), "r"(kaddr)); ++ return kaddr; ++} ++ ++void flush_cache_mm(struct mm_struct *mm) ++{ ++ cpu_dcache_wbinval_all(); ++ cpu_icache_inval_all(); ++} ++ ++void flush_cache_dup_mm(struct mm_struct *mm) ++{ ++} ++ ++void flush_cache_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++ if ((end - start) > 8 * PAGE_SIZE) { ++ cpu_dcache_wbinval_all(); ++ if (vma->vm_flags & VM_EXEC) ++ cpu_icache_inval_all(); ++ return; ++ } ++ ++ while (start < end) { ++ if (va_present(vma->vm_mm, start)) ++ cpu_cache_wbinval_page(start, vma->vm_flags & VM_EXEC); ++ start += PAGE_SIZE; ++ } ++} ++ ++void flush_cache_page(struct vm_area_struct *vma, ++ unsigned long addr, unsigned long pfn) ++{ ++ unsigned long vto, flags; ++ ++ local_irq_save(flags); ++ vto = kremap0(addr, pfn << PAGE_SHIFT); ++ cpu_cache_wbinval_page(vto, vma->vm_flags & VM_EXEC); ++ kunmap01(vto); ++ local_irq_restore(flags); ++} ++ ++void flush_cache_vmap(unsigned long start, unsigned long end) ++{ ++ cpu_dcache_wbinval_all(); ++} ++ ++void flush_cache_vunmap(unsigned long start, unsigned long end) ++{ ++ cpu_dcache_wbinval_all(); ++} ++ ++void copy_user_highpage(struct page *to, struct page *from, ++ unsigned long vaddr, struct vm_area_struct *vma) ++{ ++ unsigned long vto, vfrom, flags, kto, kfrom, pfrom, pto; ++ kto = ((unsigned long)page_address(to) & PAGE_MASK); ++ kfrom = ((unsigned long)page_address(from) & PAGE_MASK); ++ pto = page_to_phys(to); ++ pfrom = page_to_phys(from); ++ ++ if (aliasing(vaddr, (unsigned long)kfrom)) ++ cpu_dcache_wb_page((unsigned long)kfrom); ++ if (aliasing(vaddr, (unsigned long)kto)) ++ cpu_dcache_inval_page((unsigned long)kto); ++ local_irq_save(flags); ++ vto = kremap0(vaddr, pto); ++ vfrom = kremap1(vaddr, pfrom); ++ copy_page((void *)vto, (void *)vfrom); ++ kunmap01(vfrom); ++ kunmap01(vto); ++ local_irq_restore(flags); ++} ++ ++EXPORT_SYMBOL(copy_user_highpage); ++ ++void clear_user_highpage(struct page *page, unsigned long vaddr) ++{ ++ unsigned long vto, flags, kto; ++ ++ kto = ((unsigned long)page_address(page) & PAGE_MASK); ++ ++ local_irq_save(flags); ++ if (aliasing(kto, vaddr) && kto != 0) { ++ cpu_dcache_inval_page(kto); ++ cpu_icache_inval_page(kto); ++ } ++ vto = kremap0(vaddr, page_to_phys(page)); ++ clear_page((void *)vto); ++ kunmap01(vto); ++ local_irq_restore(flags); ++} ++ ++EXPORT_SYMBOL(clear_user_highpage); ++ ++void flush_dcache_page(struct page *page) ++{ ++ struct address_space *mapping; ++ ++ mapping = page_mapping(page); ++ if (mapping && !mapping_mapped(mapping)) ++ set_bit(PG_dcache_dirty, &page->flags); ++ else { ++ int i, pc; ++ unsigned long vto, kaddr, flags; ++ cpu_dcache_wbinval_page((unsigned long)page_address(page)); ++ kaddr = (unsigned long)page_address(page); ++ pc = CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE) / PAGE_SIZE; ++ for (i = 0; i < pc; i++) { ++ local_irq_save(flags); ++ vto = kremap0(kaddr + i * PAGE_SIZE, __pa(kaddr)); ++ cpu_dcache_wbinval_page(vto); ++ kunmap01(vto); ++ local_irq_restore(flags); ++ } ++ } ++} ++ ++void copy_to_user_page(struct vm_area_struct *vma, struct page *page, ++ unsigned long vaddr, void *dst, void *src, int len) ++{ ++ unsigned long line_size, start, end, vto, flags; ++ ++ local_irq_save(flags); ++ vto = kremap0(vaddr, page_to_phys(page)); ++ dst = (void *)(vto | (vaddr & (PAGE_SIZE - 1))); ++ memcpy(dst, src, len); ++ if (vma->vm_flags & VM_EXEC) { ++ line_size = L1_cache_info[DCACHE].line_size; ++ start = (unsigned long)dst & ~(line_size - 1); ++ end = ++ ((unsigned long)dst + len + line_size - 1) & ~(line_size - ++ 1); ++ cpu_cache_wbinval_range(start, end, 1); ++ } ++ kunmap01(vto); ++ local_irq_restore(flags); ++} ++ ++void copy_from_user_page(struct vm_area_struct *vma, struct page *page, ++ unsigned long vaddr, void *dst, void *src, int len) ++{ ++ unsigned long vto, flags; ++ ++ local_irq_save(flags); ++ vto = kremap0(vaddr, page_to_phys(page)); ++ src = (void *)(vto | (vaddr & (PAGE_SIZE - 1))); ++ memcpy(dst, src, len); ++ kunmap01(vto); ++ local_irq_restore(flags); ++} ++ ++void flush_anon_page(struct vm_area_struct *vma, ++ struct page *page, unsigned long vaddr) ++{ ++ if (!PageAnon(page)) ++ return; ++ ++ if (vma->vm_mm != current->active_mm) ++ return; ++ ++ cpu_cache_wbinval_page(vaddr & PAGE_MASK, vma->vm_flags & VM_EXEC); ++} ++ ++void flush_kernel_dcache_page(struct page *page) ++{ ++ cpu_dcache_wbinval_page((unsigned long)page_address(page)); ++} ++ ++void flush_icache_range(unsigned long start, unsigned long end) ++{ ++ cpu_cache_wbinval_range(start, end, 1); ++} ++ ++void flush_icache_page(struct vm_area_struct *vma, struct page *page) ++{ ++} ++ ++void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, ++ pte_t * pte) ++{ ++ struct page *page; ++ unsigned long pfn = pte_pfn(*pte); ++ ++ if (!pfn_valid(pfn)) ++ return; ++ ++ if (vma->vm_mm == current->active_mm) { ++ asm("mtsr %1, $mr2\ndsb\n" ++ "tlbop %0, RWR\nisb\n" ++ ::"r"(*pte), "r"(addr)); ++ } ++ ++ page = pfn_to_page(pfn); ++ if (test_and_clear_bit(PG_dcache_dirty, &page->flags) || ++ (vma->vm_flags & VM_EXEC)) ++ cpu_dcache_wbinval_page((unsigned long)page_address(page)); ++} ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/mm/cctl.c linux-3.4.110/arch/nds32/mm/cctl.c +--- linux-3.4.110.orig/arch/nds32/mm/cctl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/cctl.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,284 @@ ++/* ++ * linux/arch/nds32/mm/cctl.c ++ * ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include "cctl.h" ++ ++#define DEBUG( enable, tagged, ...) \ ++ do{ \ ++ if( enable){ \ ++ if( tagged) \ ++ printk( "[ %30s() ] ", __func__); \ ++ printk( __VA_ARGS__); \ ++ } \ ++ } while( 0) ++ ++static int debug = 1; ++module_param(debug, int, 0); ++ ++static int proc_read_cache_en(char *page, char **start, off_t off, ++ int count, int *eof, void *data) ++{ ++ ++ if (!strncmp(data, "ic_en", 7)) ++ return sprintf(page, "I-cache: %s\n", ++ (GET_CACHE_CTL() & CACHE_CTL_mskIC_EN) ? ++ "Enabled" : "Disabled"); ++ else ++ return sprintf(page, "D-cache: %s\n", ++ (GET_CACHE_CTL() & CACHE_CTL_mskDC_EN) ? ++ "Enabled" : "Disabled"); ++} ++ ++static int proc_write_cache_en(struct file *file, const char *buffer, ++ unsigned long count, void *data) ++{ ++ ++ unsigned long en, saved_gie; ++ char inbuf[INPUTLEN]; ++ ++ if (count > INPUTLEN - 1) ++ count = INPUTLEN - 1; ++ ++ if (copy_from_user(inbuf, buffer, count)) ++ return -EFAULT; ++ ++ inbuf[count] = '\0'; ++ ++ if (!sscanf(inbuf, "%lu", &en) || en > 1) ++ return -EFAULT; ++ ++ GIE_SAVE(&saved_gie); ++ ++ if (!strncmp(data, "ic_en", 7)) { ++ ++ if (en && !(GET_CACHE_CTL() & CACHE_CTL_mskIC_EN)) { ++ ++ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskIC_EN); ++ DEBUG(debug, 1, "I-cache: Enabled\n"); ++ } else if (!en && (GET_CACHE_CTL() & CACHE_CTL_mskIC_EN)) { ++ ++ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskIC_EN); ++ cpu_icache_inval_all(); ++ DEBUG(debug, 1, "I-cache: Disabled\n"); ++ } ++ } else { ++ if (en && !(GET_CACHE_CTL() & CACHE_CTL_mskDC_EN)) { ++ ++ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN); ++ DEBUG(debug, 1, "D-cache: Enabled\n"); ++ } else if (!en && (GET_CACHE_CTL() & CACHE_CTL_mskDC_EN)) { ++ ++ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN); ++ cpu_dcache_wbinval_all(); ++ DEBUG(debug, 1, "D-cache: Disabled\n"); ++ } ++ } ++ ++ GIE_RESTORE(saved_gie); ++ ++ return count; ++} ++ ++struct entry_struct proc_table_cache_en[] = { ++ ++ {"ic_en", 0644, proc_read_cache_en, proc_write_cache_en}, ++ {"dc_en", 0644, proc_read_cache_en, proc_write_cache_en}, ++ {NULL, 0, NULL, NULL} ++}; ++ ++static int sprint_cache_sdz(char *buf, unsigned long size, unsigned long way, ++ unsigned sdz) ++{ ++ ++ return sprintf(buf, "[%c] %luK x %lu\n[%c] %luK x %lu\n" ++ "[%c] %luK x %lu\n[%c] %luK x %lu\n", ++ (sdz == 0) ? '*' : ' ', (size / 1024), way, ++ (sdz == 1) ? '*' : ' ', (size / 1024), way / 2, ++ (sdz == 2) ? '*' : ' ', (size / 1024) / 2, way, ++ (sdz == 3) ? '*' : ' ', (size / 1024) / 2, way / 2); ++} ++ ++static int proc_read_cache_sdz(char *page, char **start, off_t off, ++ int count, int *eof, void *data) ++{ ++ ++ if (!strncmp(data, "ic_sdz", 7)) { ++ ++ return sprint_cache_sdz(page, ++ CACHE_LINE_SIZE(ICACHE) * ++ CACHE_SET(ICACHE), CACHE_WAY(ICACHE), ++ (GET_SDZ_CTL() & SDZ_CTL_mskICDZ) >> ++ SDZ_CTL_offICDZ); ++ } else { ++ return sprint_cache_sdz(page, ++ CACHE_LINE_SIZE(DCACHE) * ++ CACHE_SET(DCACHE), CACHE_WAY(DCACHE), ++ (GET_SDZ_CTL() & SDZ_CTL_mskDCDZ) >> ++ SDZ_CTL_offDCDZ); ++ } ++} ++ ++static int proc_write_cache_sdz(struct file *file, const char *buffer, ++ unsigned long count, void *data) ++{ ++ ++ unsigned long mode, saved_gie, saved_cctl; ++ char inbuf[INPUTLEN]; ++ ++ if (count > INPUTLEN - 1) ++ count = INPUTLEN - 1; ++ ++ if (copy_from_user(inbuf, buffer, count)) ++ return -EFAULT; ++ ++ inbuf[count] = '\0'; ++ ++ if (!sscanf(inbuf, "%lu", &mode) || mode > 3) ++ return -EFAULT; ++ ++ GIE_SAVE(&saved_gie); ++ ++ saved_cctl = GET_CACHE_CTL(); ++ DEBUG(debug, 1, "saved_gie: %ld, saved_cctl: 0x%08lx\n", saved_gie, ++ saved_cctl); ++ ++ if (!strncmp(data, "ic_sdz", 7)) { ++ ++ DEBUG(debug, 1, "IC_SDZ: mode %ld\n", mode); ++ ++ if (mode == 2 || mode == 3) { ++ ++ if (CACHE_LINE_SIZE(ICACHE) * CACHE_SET(ICACHE) / 2 < ++ 4096) { ++ ++ GIE_RESTORE(saved_gie); ++ DEBUG(debug, 1, "Error: way size < 4096\n"); ++ return -1; ++ } ++ } ++ ++ /* turn off and flush cache */ ++ DEBUG(debug, 1, "turning off cache\n"); ++ SET_CACHE_CTL(saved_cctl & ~CACHE_CTL_mskIC_EN); ++ DEBUG(debug, 1, "flushing cache\n"); ++ cpu_icache_inval_all(); ++ ++ /* perform down size operation */ ++ DEBUG(debug, 1, "downsizing cache\n"); ++ SET_SDZ_CTL((GET_SDZ_CTL() & ~SDZ_CTL_mskICDZ) | ++ (mode << SDZ_CTL_offICDZ)); ++ } else { ++ ++ DEBUG(debug, 1, "DC_SDZ: mode %ld\n", mode); ++ ++ if (mode == 2 || mode == 3) { ++ ++ if (CACHE_LINE_SIZE(DCACHE) * CACHE_SET(DCACHE) / 2 < ++ 4096) { ++ ++ GIE_RESTORE(saved_gie); ++ DEBUG(debug, 1, "Error: way size < 4096\n"); ++ return -1; ++ } ++ } ++ ++ /* turn off and flush cache */ ++ DEBUG(debug, 1, "turning off cache\n"); ++ SET_CACHE_CTL(saved_cctl & ~CACHE_CTL_mskDC_EN); ++ DEBUG(debug, 1, "flushing cache\n"); ++ cpu_dcache_wbinval_all(); ++ ++ /* perform down size operation */ ++ DEBUG(debug, 1, "downsizing cache\n"); ++ SET_SDZ_CTL((GET_SDZ_CTL() & ~SDZ_CTL_mskDCDZ) | ++ (mode << SDZ_CTL_offDCDZ)); ++ } ++ ++ /* turn on cache ( if it was enabled) */ ++ DEBUG(debug, 1, "restoring saved_cctl : 0x%08lx\n", saved_cctl); ++ SET_CACHE_CTL(saved_cctl); ++ ++ DEBUG(debug, 1, "restoring saved_git: %ld\n", saved_gie); ++ GIE_RESTORE(saved_gie); ++ ++ return count; ++} ++ ++struct entry_struct proc_table_cache_sdz[] = { ++ ++ {"ic_sdz", 0644, proc_read_cache_sdz, proc_write_cache_sdz}, ++ {"dc_sdz", 0644, proc_read_cache_sdz, proc_write_cache_sdz}, ++ {NULL, 0, NULL, NULL} ++}; ++ ++static struct proc_dir_entry *proc_cctl; ++ ++static void create_seq_entry(struct entry_struct *e, mode_t mode, ++ struct proc_dir_entry *parent) ++{ ++ ++ struct proc_dir_entry *entry = create_proc_entry(e->name, mode, parent); ++ ++ if (entry) { ++ ++ entry->read_proc = e->readop; ++ entry->write_proc = e->writeop; ++ entry->data = e->name; ++ } ++} ++ ++static void install_proc_table(struct entry_struct *table) ++{ ++ ++ while (table->name) { ++ ++ create_seq_entry(table, table->perm, proc_cctl); ++ table++; ++ } ++} ++ ++static void remove_proc_table(struct entry_struct *table) ++{ ++ ++ while (table->name) { ++ ++ remove_proc_entry(table->name, proc_cctl); ++ table++; ++ } ++} ++ ++static int __init init_cctl(void) ++{ ++ ++ DEBUG(debug, 1, "CCTL module registered\n"); ++ ++ proc_cctl = proc_mkdir("cctl", NULL); ++ ++ install_proc_table(proc_table_cache_en); ++ install_proc_table(proc_table_cache_sdz); ++ ++ return 0; ++} ++ ++static void __exit cleanup_cctl(void) ++{ ++ ++ remove_proc_table(proc_table_cache_sdz); ++ remove_proc_table(proc_table_cache_en); ++ remove_proc_entry("cctl", NULL); ++ ++ DEBUG(debug, 1, "CCTL module unregistered\n"); ++} ++ ++module_init(init_cctl); ++module_exit(cleanup_cctl); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Userspace Cache Control Module"); +diff -Nur linux-3.4.110.orig/arch/nds32/mm/cctl.h linux-3.4.110/arch/nds32/mm/cctl.h +--- linux-3.4.110.orig/arch/nds32/mm/cctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/cctl.h 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,22 @@ ++#ifndef CCTL_H ++#define CCTL_H ++ ++#include ++#include ++#include ++#include ++ ++#define INPUTLEN 32 ++ ++extern void cpu_icache_flush(void); ++extern void cpu_dcache_flush(void); ++ ++struct entry_struct{ ++ ++ char *name; ++ int perm; ++ read_proc_t *readop; ++ write_proc_t *writeop; ++}; ++ ++#endif /* CCTL_H */ +diff -Nur linux-3.4.110.orig/arch/nds32/mm/consistent.c linux-3.4.110/arch/nds32/mm/consistent.c +--- linux-3.4.110.orig/arch/nds32/mm/consistent.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/consistent.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,448 @@ ++/* ++ * linux/arch/nds32/mm/consistent.c ++ * ++ * Copyright (C) 2000-2004 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * DMA uncached mapping support. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * This is the page table (2MB) covering uncached, DMA consistent allocations ++ */ ++static pte_t *consistent_pte; ++static DEFINE_RAW_SPINLOCK(consistent_lock); ++ ++/* ++ * VM region handling support. ++ * ++ * This should become something generic, handling VM region allocations for ++ * vmalloc and similar (ioremap, module space, etc). ++ * ++ * I envisage vmalloc()'s supporting vm_struct becoming: ++ * ++ * struct vm_struct { ++ * struct vm_region region; ++ * unsigned long flags; ++ * struct page **pages; ++ * unsigned int nr_pages; ++ * unsigned long phys_addr; ++ * }; ++ * ++ * get_vm_area() would then call vm_region_alloc with an appropriate ++ * struct vm_region head (eg): ++ * ++ * struct vm_region vmalloc_head = { ++ * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), ++ * .vm_start = VMALLOC_START, ++ * .vm_end = VMALLOC_END, ++ * }; ++ * ++ * However, vmalloc_head.vm_start is variable (typically, it is dependent on ++ * the amount of RAM found at boot time.) I would imagine that get_vm_area() ++ * would have to initialise this each time prior to calling vm_region_alloc(). ++ */ ++struct arch_vm_region { ++ struct list_head vm_list; ++ unsigned long vm_start; ++ unsigned long vm_end; ++ struct page *vm_pages; ++}; ++ ++static struct arch_vm_region consistent_head = { ++ .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), ++ .vm_start = CONSISTENT_BASE, ++ .vm_end = CONSISTENT_END, ++}; ++ ++static struct arch_vm_region *vm_region_alloc(struct arch_vm_region *head, ++ size_t size, int gfp) ++{ ++ unsigned long addr = head->vm_start, end = head->vm_end - size; ++ unsigned long flags; ++ struct arch_vm_region *c, *new; ++ ++ new = kmalloc(sizeof(struct arch_vm_region), gfp); ++ if (!new) ++ goto out; ++ ++ raw_spin_lock_irqsave(&consistent_lock, flags); ++ ++ list_for_each_entry(c, &head->vm_list, vm_list) { ++ if ((addr + size) < addr) ++ goto nospc; ++ if ((addr + size) <= c->vm_start) ++ goto found; ++ addr = c->vm_end; ++ if (addr > end) ++ goto nospc; ++ } ++ ++found: ++ /* ++ * Insert this entry _before_ the one we found. ++ */ ++ list_add_tail(&new->vm_list, &c->vm_list); ++ new->vm_start = addr; ++ new->vm_end = addr + size; ++ ++ raw_spin_unlock_irqrestore(&consistent_lock, flags); ++ return new; ++ ++nospc: ++ raw_spin_unlock_irqrestore(&consistent_lock, flags); ++ kfree(new); ++out: ++ return NULL; ++} ++ ++static struct arch_vm_region *vm_region_find(struct arch_vm_region *head, ++ unsigned long addr) ++{ ++ struct arch_vm_region *c; ++ ++ list_for_each_entry(c, &head->vm_list, vm_list) { ++ if (c->vm_start == addr) ++ goto out; ++ } ++ c = NULL; ++out: ++ return c; ++} ++ ++#ifdef CONFIG_HUGETLB_PAGE ++#error ARM Coherent DMA allocator does not (yet) support huge TLB ++#endif ++ ++static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t * handle, ++ int gfp, pgprot_t prot) ++{ ++ struct page *page; ++ struct arch_vm_region *c; ++ unsigned long order; ++ unsigned int i; ++ u64 mask = ISA_DMA_THRESHOLD, limit; ++ ++ if (!consistent_pte) { ++ printk(KERN_ERR "%s: not initialised\n", __func__); ++ dump_stack(); ++ return NULL; ++ } ++ ++ if (dev) { ++ mask = dev->coherent_dma_mask; ++ ++ /* ++ * Sanity check the DMA mask - it must be non-zero, and ++ * must be able to be satisfied by a DMA allocation. ++ */ ++ if (mask == 0) { ++ dev_warn(dev, "coherent DMA mask is unset\n"); ++ goto no_page; ++ } ++ ++ if ((~mask) & ISA_DMA_THRESHOLD) { ++ dev_warn(dev, "coherent DMA mask %#llx is smaller " ++ "than system GFP_DMA mask %#llx\n", ++ mask, (unsigned long long)ISA_DMA_THRESHOLD); ++ goto no_page; ++ } ++ } ++ ++ /* ++ * Sanity check the allocation size. ++ */ ++ size = PAGE_ALIGN(size); ++ limit = (mask + 1) & ~mask; ++ if ((limit && size >= limit) || ++ size >= (CONSISTENT_END - CONSISTENT_BASE)) { ++ printk(KERN_WARNING "coherent allocation too big " ++ "(requested %#x mask %#llx)\n", size, mask); ++ goto no_page; ++ } ++ ++ order = get_order(size); ++ ++ if (mask != 0xffffffff) ++ gfp |= GFP_DMA; ++ ++ page = alloc_pages(gfp, order); ++ if (!page) ++ goto no_page; ++ ++ for (i = 1; i < (1 << order); i++) ++ atomic_set(&(page + i)->_count, 1); ++ ++ /* ++ * Invalidate any data that might be lurking in the ++ * kernel direct-mapped region for device DMA. ++ */ ++ { ++ unsigned long kaddr = (unsigned long)page_address(page); ++ memset(page_address(page), 0, size); ++ cpu_dma_wbinval_range(kaddr, kaddr + size); ++ } ++ ++ /* ++ * Allocate a virtual address in the consistent mapping region. ++ */ ++ c = vm_region_alloc(&consistent_head, size, ++ gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); ++ if (c) { ++ pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start); ++ struct page *end = page + (1 << order); ++ ++ c->vm_pages = page; ++ ++ /* ++ * Set the "dma handle" ++ */ ++ *handle = page_to_dma(dev, page); ++ ++ do { ++ BUG_ON(!pte_none(*pte)); ++ ++ /* ++ * x86 does not mark the pages reserved... ++ */ ++ SetPageReserved(page); ++ set_pte(pte, mk_pte(page, prot)); ++ page++; ++ pte++; ++ } while (size -= PAGE_SIZE); ++ ++ /* ++ * Free the otherwise unused pages. ++ */ ++ while (page < end) { ++ __free_page(page); ++ page++; ++ } ++ ++ return (void *)c->vm_start; ++ } ++ ++ if (page) ++ __free_pages(page, order); ++no_page: ++ *handle = ~0; ++ return NULL; ++} ++ ++/* ++ * Allocate DMA-coherent memory space and return both the kernel remapped ++ * virtual and bus address for that space. ++ */ ++void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t * handle, ++ gfp_t gfp) ++{ ++ return __dma_alloc(dev, size, handle, gfp, ++ pgprot_noncached(PAGE_KERNEL)); ++} ++ ++EXPORT_SYMBOL(dma_alloc_coherent); ++ ++/* ++ * Allocate a writecombining region, in much the same way as ++ * dma_alloc_coherent above. ++ */ ++void *dma_alloc_writecombine(struct device *dev, size_t size, ++ dma_addr_t * handle, gfp_t gfp) ++{ ++ return __dma_alloc(dev, size, handle, gfp, ++ pgprot_writecombine(PAGE_KERNEL)); ++} ++ ++EXPORT_SYMBOL(dma_alloc_writecombine); ++ ++static int dma_mmap(struct device *dev, struct vm_area_struct *vma, ++ void *cpu_addr, dma_addr_t dma_addr, size_t size) ++{ ++ unsigned long flags, user_size, kern_size; ++ struct arch_vm_region *c; ++ int ret = -ENXIO; ++ ++ user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; ++ ++ raw_spin_lock_irqsave(&consistent_lock, flags); ++ c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); ++ raw_spin_unlock_irqrestore(&consistent_lock, flags); ++ ++ if (c) { ++ unsigned long off = vma->vm_pgoff; ++ ++ kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT; ++ ++ if (off < kern_size && user_size <= (kern_size - off)) { ++ vma->vm_flags |= VM_RESERVED; ++ ret = remap_pfn_range(vma, vma->vm_start, ++ page_to_pfn(c->vm_pages) + off, ++ user_size << PAGE_SHIFT, ++ vma->vm_page_prot); ++ } ++ } ++ ++ return ret; ++} ++ ++int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, ++ void *cpu_addr, dma_addr_t dma_addr, size_t size) ++{ ++ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); ++ return dma_mmap(dev, vma, cpu_addr, dma_addr, size); ++} ++ ++EXPORT_SYMBOL(dma_mmap_coherent); ++ ++int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, ++ void *cpu_addr, dma_addr_t dma_addr, size_t size) ++{ ++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ++ return dma_mmap(dev, vma, cpu_addr, dma_addr, size); ++} ++ ++EXPORT_SYMBOL(dma_mmap_writecombine); ++ ++/* ++ * free a page as defined by the above mapping. ++ */ ++void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, ++ dma_addr_t handle) ++{ ++ struct arch_vm_region *c; ++ unsigned long flags, addr; ++ pte_t *ptep; ++ ++ size = PAGE_ALIGN(size); ++ ++ raw_spin_lock_irqsave(&consistent_lock, flags); ++ ++ c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); ++ if (!c) ++ goto no_area; ++ ++ if ((c->vm_end - c->vm_start) != size) { ++ printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", ++ __func__, c->vm_end - c->vm_start, size); ++ dump_stack(); ++ size = c->vm_end - c->vm_start; ++ } ++ ++ ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start); ++ addr = c->vm_start; ++ do { ++ pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); ++ unsigned long pfn; ++ ++ ptep++; ++ addr += PAGE_SIZE; ++ ++ if (!pte_none(pte) && pte_present(pte)) { ++ pfn = pte_pfn(pte); ++ ++ if (pfn_valid(pfn)) { ++ struct page *page = pfn_to_page(pfn); ++ ++ /* ++ * x86 does not mark the pages reserved... ++ */ ++ ClearPageReserved(page); ++ ++ __free_page(page); ++ continue; ++ } ++ } ++ ++ printk(KERN_CRIT "%s: bad page in kernel page table\n", ++ __func__); ++ } while (size -= PAGE_SIZE); ++ ++ flush_tlb_kernel_range(c->vm_start, c->vm_end); ++ ++ list_del(&c->vm_list); ++ ++ raw_spin_unlock_irqrestore(&consistent_lock, flags); ++ ++ kfree(c); ++ return; ++ ++no_area: ++ raw_spin_unlock_irqrestore(&consistent_lock, flags); ++ printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", ++ __func__, cpu_addr); ++ dump_stack(); ++} ++ ++EXPORT_SYMBOL(dma_free_coherent); ++ ++/* ++ * Initialise the consistent memory allocation. ++ */ ++static int __init consistent_init(void) ++{ ++ pgd_t *pgd; ++ pmd_t *pmd; ++ pte_t *pte; ++ int ret = 0; ++ ++ do { ++ pgd = pgd_offset(&init_mm, CONSISTENT_BASE); ++ pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); ++ if (!pmd) { ++ printk(KERN_ERR "%s: no pmd tables\n", __func__); ++ ret = -ENOMEM; ++ break; ++ } ++ /* The first level mapping may be created in somewhere. ++ * It's not necessary to warn here. */ ++ /* WARN_ON(!pmd_none(*pmd)); */ ++ ++ pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); ++ if (!pte) { ++ ret = -ENOMEM; ++ break; ++ } ++ ++ consistent_pte = pte; ++ } while (0); ++ ++ return ret; ++} ++ ++core_initcall(consistent_init); ++ ++/* ++ * Make an area consistent for devices. ++ */ ++void consistent_sync(void *vaddr, size_t size, int direction) ++{ ++ unsigned long start = (unsigned long)vaddr; ++ unsigned long end = start + size; ++ ++ switch (direction) { ++ case DMA_FROM_DEVICE: /* invalidate only */ ++ cpu_dma_inval_range(start, end); ++ break; ++ case DMA_TO_DEVICE: /* writeback only */ ++ cpu_dma_wb_range(start, end); ++ break; ++ case DMA_BIDIRECTIONAL: /* writeback and invalidate */ ++ cpu_dma_wbinval_range(start, end); ++ break; ++ default: ++ BUG(); ++ } ++} ++ ++EXPORT_SYMBOL(consistent_sync); +diff -Nur linux-3.4.110.orig/arch/nds32/mm/extable.c linux-3.4.110/arch/nds32/mm/extable.c +--- linux-3.4.110.orig/arch/nds32/mm/extable.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/extable.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * linux/arch/nds32/mm/extable.c ++ * ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++#include ++#include ++ ++int fixup_exception(struct pt_regs *regs) ++{ ++ const struct exception_table_entry *fixup; ++ ++ fixup = search_exception_tables(instruction_pointer(regs)); ++ if (fixup) ++ regs->NDS32_ipc = fixup->fixup; ++ ++ return fixup != NULL; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/mm/fault.c linux-3.4.110/arch/nds32/mm/fault.c +--- linux-3.4.110.orig/arch/nds32/mm/fault.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/fault.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,507 @@ ++/* ++ * linux/arch/arm/mm/fault.c ++ * ++ * Copyright (C) 1995 Linus Torvalds ++ * Modifications for ARM processor (c) 1995-2004 Russell King ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++/* ============================================================================ ++ * ++ * linux/arch/nds32/mm/fault.c ++ * ++ * Copyright (C) 2007 Andes Technology Corporation ++ * This file is part of Linux and should be licensed under the GPL. ++ * See the file COPYING for conditions for redistribution. ++ * ++ * Abstract: ++ * ++ * This program is for NDS32 architecture, referred from ARM's ++ * implementation. ++ * ++ * Revision History: ++ * ++ * Nov.26.2007 Initial ported by Tom, Shawn, and Steven, ++ * patched for KGDB and refined code by Harry. ++ * ++ * Note: ++ * ++ * ============================================================================ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "fault.h" ++ ++/* ++ * This is useful to dump out the page tables associated with ++ * 'addr' in mm 'mm'. ++ */ ++void show_pte(struct mm_struct *mm, unsigned long addr) ++{ ++ pgd_t *pgd; ++ if (!mm) ++ mm = &init_mm; ++ ++ printk(KERN_ALERT "pgd = %p\n", mm->pgd); ++ pgd = pgd_offset(mm, addr); ++ printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); ++ ++ do { ++ pmd_t *pmd; ++ ++ if (pgd_none(*pgd)) ++ break; ++ ++ if (pgd_bad(*pgd)) { ++ printk("(bad)"); ++ break; ++ } ++ ++ pmd = pmd_offset(pgd, addr); ++#if PTRS_PER_PMD != 1 ++ printk(", *pmd=%08lx", pmd_val(*pmd)); ++#endif ++ ++ if (pmd_none(*pmd)) ++ break; ++ ++ if (pmd_bad(*pmd)) { ++ printk("(bad)"); ++ break; ++ } ++#ifndef CONFIG_HIGHMEM ++ { ++ pte_t *pte; ++ /* We must not map this if we have highmem enabled */ ++ pte = pte_offset_map(pmd, addr); ++ printk(", *pte=%08lx", pte_val(*pte)); ++ pte_unmap(pte); ++ } ++#endif ++ } while (0); ++ ++ printk("\n"); ++} ++ ++/* ++ * Oops. The kernel tried to access some page that wasn't present. ++ */ ++static void ++__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, ++ struct pt_regs *regs) ++{ ++ /* ++ * Are we prepared to handle this kernel fault? ++ */ ++ if (fixup_exception(regs)) ++ return; ++ ++ /* ++ * No handler, we'll have to terminate things with extreme prejudice. ++ */ ++ bust_spinlocks(1); ++ printk(KERN_ALERT ++ "__do_kernel_fault: Unable to handle kernel %s at virtual address %08lx\n", ++ (addr < PAGE_SIZE) ? "NULL pointer dereference" : ++ "paging request", addr); ++ ++ show_pte(mm, addr); ++ die("Oops", regs, fsr); ++ bust_spinlocks(0); ++ do_exit(SIGKILL); ++} ++ ++/* ++ * Something tried to access memory that isn't in our memory map.. ++ * User mode accesses just cause a SIGSEGV ++ */ ++static void ++__do_user_fault(struct task_struct *tsk, unsigned long addr, ++ unsigned int fsr, int code, struct pt_regs *regs) ++{ ++ struct siginfo si; ++ ++#ifdef CONFIG_DEBUG_USER ++ if (user_debug & UDBG_SEGV) { ++ printk(KERN_DEBUG ++ "%s: unhandled page fault at 0x%08lx, code 0x%03x\n", ++ tsk->comm, addr, fsr); ++ show_pte(tsk->mm, addr); ++ show_regs(regs); ++ } ++#endif ++ ++ tsk->thread.address = addr; ++ tsk->thread.error_code = fsr; ++ tsk->thread.trap_no = 14; ++ si.si_signo = SIGSEGV; ++ si.si_errno = 0; ++ si.si_code = code; ++ si.si_addr = (void __user *)addr; ++ force_sig_info(SIGSEGV, &si, tsk); ++} ++ ++void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) ++{ ++ struct task_struct *tsk = current; ++ struct mm_struct *mm = tsk->active_mm; ++ ++ /* ++ * If we are in kernel mode at this point, we ++ * have no context to handle this fault with. ++ */ ++ if (user_mode(regs)) { ++ __do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs); ++ } else { ++ __do_kernel_fault(mm, addr, fsr, regs); ++ } ++} ++ ++#define VM_FAULT_BADMAP 0x010000 ++#define VM_FAULT_BADACCESS 0x020000 ++ ++void do_page_fault(unsigned long entry, unsigned long addr, ++ unsigned int error_code, struct pt_regs *regs) ++{ ++ struct task_struct *tsk; ++ struct mm_struct *mm; ++ struct vm_area_struct *vma; ++ siginfo_t info; ++ int fault; ++ unsigned int mask = VM_READ | VM_WRITE | VM_EXEC; ++ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; ++ ++ error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE); ++ tsk = current; ++ mm = tsk->mm; ++ info.si_code = SEGV_MAPERR; ++ /* ++ * We fault-in kernel-space virtual memory on-demand. The ++ * 'reference' page table is init_mm.pgd. ++ * ++ * NOTE! We MUST NOT take any locks for this case. We may ++ * be in an interrupt or a critical region, and should ++ * only copy the information from the master page table, ++ * nothing more. ++ */ ++ if (addr >= TASK_SIZE) { ++ if (user_mode(regs)) ++ goto bad_area_nosemaphore; ++ ++ if (addr >= TASK_SIZE && addr < VMALLOC_END && (entry == 2)) ++ goto vmalloc_fault; ++ else ++ goto no_context; ++ } ++ ++ /* ++ * If we're in an interrupt or have no user ++ * context, we must not take the fault.. ++ */ ++ if (unlikely(in_atomic() || !mm)) ++ goto no_context; ++ ++ /* ++ * As per x86, we may deadlock here. However, since the kernel only ++ * validly references user space from well defined areas of the code, ++ * we can bug out early if this is from code which shouldn't. ++ */ ++ if (unlikely(!down_read_trylock(&mm->mmap_sem))) { ++ if (!user_mode(regs) && ++ !search_exception_tables(instruction_pointer(regs))) ++ goto no_context; ++retry: ++ down_read(&mm->mmap_sem); ++ } else { ++ /* ++ * The above down_read_trylock() might have succeeded in which ++ * case, we'll have missed the might_sleep() from down_read(). ++ */ ++ might_sleep(); ++#ifdef CONFIG_DEBUG_VM ++ if (!user_mode(regs) && ++ !search_exception_tables(instruction_pointer(regs))) ++ goto no_context; ++#endif ++ } ++ ++ vma = find_vma(mm, addr); ++ ++ if (unlikely(!vma)) ++ goto bad_area; ++ ++ if (vma->vm_start <= addr) ++ goto good_area; ++ ++ if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) ++ goto bad_area; ++ ++ if (unlikely(expand_stack(vma, addr))) ++ goto bad_area; ++ ++ /* ++ * Ok, we have a good vm_area for this memory access, so ++ * we can handle it.. ++ */ ++ ++good_area: ++ info.si_code = SEGV_ACCERR; ++ ++ /* first do some preliminary protection checks */ ++ if (entry == 2) { ++ if (error_code & ITYPE_mskINST) ++ mask = VM_EXEC; ++ else { ++ mask = VM_READ | VM_WRITE; ++ if (vma->vm_flags & VM_WRITE) ++ flags |= FAULT_FLAG_WRITE; ++ } ++ } else if (entry == 3) { ++ switch (error_code & ITYPE_mskETYPE) { ++ case RD_PROT: ++ mask = VM_READ; ++ break; ++ case WRT_PROT: ++ mask = VM_WRITE; ++ flags |= FAULT_FLAG_WRITE; ++ break; ++ case NOEXEC: ++ mask = VM_EXEC; ++ break; ++ case PAGE_MODIFY: ++ mask = VM_WRITE; ++ flags |= FAULT_FLAG_WRITE; ++ break; ++ case ACC_BIT: ++ BUG(); ++ default: ++ break; ++ } ++ ++ } ++ if (!(vma->vm_flags & mask)) ++ goto bad_area; ++ ++ /* ++ * If for any reason at all we couldn't handle the fault, ++ * make sure we exit gracefully rather than endlessly redo ++ * the fault. ++ */ ++ ++ fault = handle_mm_fault(mm, vma, addr, flags); ++ ++ /* ++ * If we need to retry but a fatal signal is pending, handle the ++ * signal first. We do not need to release the mmap_sem because it ++ * would already be released in __lock_page_or_retry in mm/filemap.c. ++ */ ++ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) ++ return; ++ ++ if (unlikely(fault & VM_FAULT_ERROR)) { ++ if (fault & VM_FAULT_OOM) ++ goto out_of_memory; ++ else if (fault & VM_FAULT_SIGBUS) ++ goto do_sigbus; ++ BUG(); ++ } ++ ++ /* ++ * Major/minor page fault accounting is only done on the initial ++ * attempt. If we go through a retry, it is extremely likely that the ++ * page will be found in page cache at that point. ++ */ ++ if (flags & FAULT_FLAG_ALLOW_RETRY) { ++ if (fault & VM_FAULT_MAJOR) ++ tsk->maj_flt++; ++ else ++ tsk->min_flt++; ++ if (fault & VM_FAULT_RETRY) { ++ flags &= ~FAULT_FLAG_ALLOW_RETRY; ++ flags |= FAULT_FLAG_TRIED; ++ ++ /* No need to up_read(&mm->mmap_sem) as we would ++ * have already released it in __lock_page_or_retry ++ * in mm/filemap.c. ++ */ ++ goto retry; ++ } ++ } ++ ++ up_read(&mm->mmap_sem); ++ return; ++ ++ /* ++ * Something tried to access memory that isn't in our memory map.. ++ * Fix it, but check if it's kernel or user first.. ++ */ ++bad_area: ++ up_read(&mm->mmap_sem); ++ ++bad_area_nosemaphore: ++ ++ /* User mode accesses just cause a SIGSEGV */ ++ ++ if (user_mode(regs)) { ++ tsk->thread.address = addr; ++ tsk->thread.error_code = error_code; ++ tsk->thread.trap_no = 14; ++ info.si_signo = SIGSEGV; ++ info.si_errno = 0; ++ /* info.si_code has been set above */ ++ info.si_addr = (void *)addr; ++ force_sig_info(SIGSEGV, &info, tsk); ++ return; ++ } ++ ++no_context: ++ ++ /* Are we prepared to handle this kernel fault? ++ * ++ * (The kernel has valid exception-points in the source ++ * when it acesses user-memory. When it fails in one ++ * of those points, we find it in a table and do a jump ++ * to some fixup code that loads an appropriate error ++ * code) ++ */ ++ ++ { ++ const struct exception_table_entry *entry; ++ ++ if ((entry = ++ search_exception_tables(instruction_pointer(regs))) != ++ NULL) { ++ /* Adjust the instruction pointer in the stackframe */ ++ instruction_pointer(regs) = entry->fixup; ++ return; ++ } ++ } ++ ++ /* ++ * Oops. The kernel tried to access some bad page. We'll have to ++ * terminate things with extreme prejudice. ++ */ ++ ++ bust_spinlocks(1); ++ printk(KERN_ALERT ++ "Unable to handle kernel %s at virtual address %08lx\n", ++ (addr < PAGE_SIZE) ? "NULL pointer dereference" : ++ "paging request", addr); ++ ++ show_pte(mm, addr); ++ die("Oops", regs, error_code); ++ bust_spinlocks(0); ++ do_exit(SIGKILL); ++ ++ /* TODO: verify this necessity */ ++ return; ++ ++ /* ++ * We ran out of memory, or some other thing happened to us that made ++ * us unable to handle the page fault gracefully. ++ */ ++ ++out_of_memory: ++ up_read(&mm->mmap_sem); ++ if (!user_mode(regs)) ++ goto no_context; ++ pagefault_out_of_memory(); ++ return; ++ ++do_sigbus: ++ up_read(&mm->mmap_sem); ++ ++ /* Kernel mode? Handle exceptions or die */ ++ if (!user_mode(regs)) ++ goto no_context; ++ ++ /* ++ * Send a sigbus ++ */ ++ tsk->thread.address = addr; ++ tsk->thread.error_code = error_code; ++ tsk->thread.trap_no = 14; ++ info.si_signo = SIGBUS; ++ info.si_errno = 0; ++ info.si_code = BUS_ADRERR; ++ info.si_addr = (void *)addr; ++ force_sig_info(SIGBUS, &info, tsk); ++ ++ return; ++ ++vmalloc_fault: ++ { ++ /* ++ * Synchronize this task's top level page-table ++ * with the 'reference' page table. ++ * ++ * Use current_pgd instead of tsk->active_mm->pgd ++ * since the latter might be unavailable if this ++ * code is executed in a misfortunately run irq ++ * (like inside schedule() between switch_mm and ++ * switch_to...). ++ */ ++ ++ unsigned int index = pgd_index(addr); ++ pgd_t *pgd, *pgd_k; ++ pud_t *pud, *pud_k; ++ pmd_t *pmd, *pmd_k; ++ pte_t *pte_k; ++ ++ pgd = (pgd_t *) __va(GET_L1_PPTB()) + index; ++ pgd_k = init_mm.pgd + index; ++ ++ if (!pgd_present(*pgd_k)) ++ goto no_context; ++ ++ pud = pud_offset(pgd, addr); ++ pud_k = pud_offset(pgd_k, addr); ++ if (!pud_present(*pud_k)) ++ goto no_context; ++ ++ pmd = pmd_offset(pud, addr); ++ pmd_k = pmd_offset(pud_k, addr); ++ if (!pmd_present(*pmd_k)) ++ goto no_context; ++ ++ if (!pmd_present(*pmd)) { ++ set_pmd(pmd, *pmd_k); ++ /* TODO: need to do a cache flush like arm, ++ * maybe add at header file */ ++ } else ++ ++ BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); ++ ++ /* ++ * Since the vmalloc area is global, we don't ++ * need to copy individual PTE's, it is enough to ++ * copy the pgd pointer into the pte page of the ++ * root task. If that is there, we'll find our pte if ++ * it exists. ++ */ ++ ++ /* Make sure the actual PTE exists as well to ++ * catch kernel vmalloc-area accesses to non-mapped ++ * addres. If we don't do this, this will just ++ * silently loop forever. ++ */ ++ ++ pte_k = pte_offset_kernel(pmd_k, addr); ++ if (!pte_present(*pte_k)) ++ goto no_context; ++ ++ return; ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/mm/fault.h linux-3.4.110/arch/nds32/mm/fault.h +--- linux-3.4.110.orig/arch/nds32/mm/fault.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/fault.h 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,5 @@ ++void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs); ++ ++void show_pte(struct mm_struct *mm, unsigned long addr); ++ ++unsigned long search_exception_table(unsigned long addr); +diff -Nur linux-3.4.110.orig/arch/nds32/mm/highmem.c linux-3.4.110/arch/nds32/mm/highmem.c +--- linux-3.4.110.orig/arch/nds32/mm/highmem.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/highmem.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,76 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void *kmap(struct page *page) ++{ ++ unsigned long vaddr; ++ might_sleep(); ++ if (!PageHighMem(page)) ++ return page_address(page); ++ vaddr = (unsigned long)kmap_high(page); ++ return (void *)vaddr; ++} ++ ++EXPORT_SYMBOL(kmap); ++ ++void kunmap(struct page *page) ++{ ++ BUG_ON(in_interrupt()); ++ if (!PageHighMem(page)) ++ return; ++ kunmap_high(page); ++} ++ ++EXPORT_SYMBOL(kunmap); ++ ++/* ++ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because ++ * no global lock is needed and because the kmap code must perform a global TLB ++ * invalidation when the kmap pool wraps. ++ * ++ * However when holding an atomic kmap is is not legal to sleep, so atomic ++ * kmaps are appropriate for short, tight code paths only. ++ */ ++void *kmap_atomic(struct page *page) ++{ ++ unsigned int idx; ++ unsigned long vaddr, pte; ++ int type; ++ ++ pagefault_disable(); ++ if (!PageHighMem(page)) ++ return page_address(page); ++ ++ type = kmap_atomic_idx_push(); ++ ++ idx = type + KM_TYPE_NR * smp_processor_id(); ++ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); ++ pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL); ++ asm volatile ("mtsr %0, $TLB_VPN\n\t" ++ "dsb\n\t" ++ "tlbop %1, RWLK\n\t" ++ "isb\n\t" ++ ::"r" (vaddr), "r"(pte)); ++ return (void *)vaddr; ++} ++ ++EXPORT_SYMBOL(kmap_atomic); ++ ++void __kunmap_atomic(void *kvaddr) ++{ ++ if (kvaddr >= (void *)FIXADDR_START) { ++ kmap_atomic_idx_pop(); ++ asm volatile ("tlbop %0, UNLK\n\t" ++ "tlbop %0, INV\n\t" ++ ::"r" (kvaddr)); ++ } ++ pagefault_enable(); ++} ++ ++EXPORT_SYMBOL(__kunmap_atomic); +diff -Nur linux-3.4.110.orig/arch/nds32/mm/init.c linux-3.4.110/arch/nds32/mm/init.c +--- linux-3.4.110.orig/arch/nds32/mm/init.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/init.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,438 @@ ++/* ++ * linux/arch/nds32/mm/init.c ++ * ++ * Copyright (C) 1995-2002 Russell King ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mm.h" ++#include "../../kernel/signal.h" ++ ++#define TABLE_SIZE (PTRS_PER_PTE * sizeof(pte_t)) ++ ++DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); ++DEFINE_SPINLOCK(anon_alias_lock); ++extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; ++extern unsigned long phys_initrd_start; ++extern unsigned long phys_initrd_size; ++ ++/* ++ * empty_zero_page is a special page that is used for ++ * zero-initialized data and COW. ++ */ ++struct page *empty_zero_page; ++ ++void show_mem(unsigned int flags) ++{ ++ int free = 0, total = 0, reserved = 0; ++ int shared = 0, cached = 0, slab = 0, node; ++ ++ printk("Mem-info:\n"); ++ show_free_areas(flags); ++ printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT - 10)); ++ ++ for_each_online_node(node) { ++ struct page *page, *end; ++ ++ page = NODE_MEM_MAP(node); ++ end = page + NODE_DATA(node)->node_spanned_pages; ++ ++ do { ++ total++; ++ if (PageReserved(page)) ++ reserved++; ++ else if (PageSwapCache(page)) ++ cached++; ++ else if (PageSlab(page)) ++ slab++; ++ else if (!page_count(page)) ++ free++; ++ else ++ shared += page_count(page) - 1; ++ page++; ++ } while (page < end); ++ } ++ ++ printk("%d pages of RAM\n", total); ++ printk("%d free pages\n", free); ++ printk("%d reserved pages\n", reserved); ++ printk("%d slab pages\n", slab); ++ printk("%d pages shared\n", shared); ++ printk("%d pages swap cached\n", cached); ++} ++ ++struct node_info { ++ unsigned int start; ++ unsigned int end; ++ int bootmap_pages; ++}; ++ ++#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) ++#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) ++ ++#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) ++#define V_PFN_UP(x) O_PFN_UP(__pa(x)) ++ ++#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) ++#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ ++ (((unsigned long)(s)) & PAGE_MASK)) ++#ifdef CONFIG_EARLY_PRINTK ++#include ++ ++/* ++ * Using tlbop to create an early I/O mapping ++ */ ++void __iomem *__init early_io_map(phys_addr_t pa) ++{ ++ unsigned long va; ++ pa &= PAGE_MASK; ++ pa += pgprot_val(PAGE_DEVICE); ++ va = fix_to_virt(FIX_EARLY_DEBUG); ++ /* insert and lock this page to tlb entry directly */ ++ asm volatile ("mtsr %0, $TLB_VPN\n\t" ++ "dsb\n\t" ++ "tlbop %1, RWLK\n\t" "isb\n\t"::"r" (va), "r"(pa)); ++ return (void __iomem *)va; ++} ++ ++int __init early_io_unmap(void) ++{ ++ unsigned long va; ++ va = fix_to_virt(FIX_EARLY_DEBUG); ++ asm volatile ("tlbop %0, UNLK\n\t" ++ "tlbop %0, INV\n\t" "isb\n\t"::"r" (va)); ++ return 0; ++} ++ ++late_initcall(early_io_unmap); ++#endif ++ ++static void __init zone_sizes_init(void) ++{ ++ unsigned long zones_size[MAX_NR_ZONES]; ++ ++ /* Clear the zone sizes */ ++ memset(zones_size, 0, sizeof(zones_size)); ++ ++ zones_size[ZONE_NORMAL] = max_low_pfn; ++#ifdef CONFIG_HIGHMEM ++ zones_size[ZONE_HIGHMEM] = max_pfn; ++#endif ++ free_area_init_nodes(zones_size); ++ ++} ++ ++/* ++ * Map all physical memory under high_memory into kernel's address space. ++ * ++ * This is explicitly coded for two-level page tables, so if you need ++ * something else then this needs to change. ++ */ ++static void __init map_ram(void) ++{ ++ unsigned long v, p, e; ++ pgd_t *pge; ++ pud_t *pue; ++ pmd_t *pme; ++ pte_t *pte; ++ /* These mark extents of read-only kernel pages... ++ * ...from vmlinux.lds.S ++ */ ++ ++ p = (u32) memblock_start_of_DRAM() & PAGE_MASK; ++ e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory)); ++ ++ v = (u32) __va(p); ++ pge = pgd_offset_k(v); ++ ++ while (p < e) { ++ int j; ++ pue = pud_offset(pge, v); ++ pme = pmd_offset(pue, v); ++ ++ if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) { ++ panic("%s: Kernel hardcoded for " ++ "two-level page tables", __func__); ++ } ++ ++ /* Alloc one page for holding PTE's... */ ++ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); ++ set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); ++ ++ /* Fill the newly allocated page with PTE'S */ ++ for (j = 0; p < e && j < PTRS_PER_PTE; ++ v += PAGE_SIZE, p += PAGE_SIZE, j++, pte++) { ++ /* Create mapping between p and v. */ ++ /* TODO: more fine grant for page access permission */ ++ set_pte(pte, __pte(p + pgprot_val(PAGE_KERNEL))); ++ } ++ ++ pge++; ++ } ++} ++ ++static void __init fixedrange_init(void) ++{ ++ unsigned long vaddr, phys, prot; ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *pte; ++ ++ /* ++ * Fixed mappings: ++ */ ++ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); ++ pgd = swapper_pg_dir + pgd_index(vaddr); ++ pud = pud_offset(pgd, vaddr); ++ pmd = pmd_offset(pud, vaddr); ++ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); ++ set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); ++ ++ /* create return_syscall mapping. */ ++ vaddr = __fix_to_virt(FIX_RETURN_SYSCALL); ++ phys = RETURN_SYSCALL_PA_BASE; ++ prot = PAGE_UXKRWX_V2; ++ pte = pte_offset_kernel(pmd, vaddr); ++ set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); ++ ++#ifdef CONFIG_HIGHMEM ++ /* ++ * Permanent kmaps: ++ */ ++ vaddr = PKMAP_BASE; ++ ++ pgd = swapper_pg_dir + pgd_index(vaddr); ++ pud = pud_offset(pgd, vaddr); ++ pmd = pmd_offset(pud, vaddr); ++ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); ++ set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); ++ pkmap_page_table = pte; ++#endif /* CONFIG_HIGHMEM */ ++} ++ ++/* ++ * paging_init() sets up the page tables, initialises the zone memory ++ * maps, and sets up the zero page, bad page and bad page tables. ++ */ ++void __init paging_init(struct machine_desc *mdesc) ++{ ++ void *zero_page; ++ int i; ++ ++ printk(KERN_INFO "Setting up paging and PTEs.\n"); ++ ++#ifdef CONFIG_BLK_DEV_INITRD ++ if (phys_initrd_size) { ++ /* assume initrd is put on node 0 */ ++ reserve_bootmem_node(NODE_DATA(0), phys_initrd_start, ++ phys_initrd_size, BOOTMEM_DEFAULT); ++ initrd_start = __phys_to_virt(phys_initrd_start); ++ initrd_end = initrd_start + phys_initrd_size; ++ printk(KERN_INFO ++ "initrd_start at 0x%08lx, initrd_end at 0x%08lx\n", ++ initrd_start, initrd_end); ++ } ++#endif ++ ++ /* clear out the init_mm.pgd that will contain the kernel's mappings */ ++ for (i = 0; i < PTRS_PER_PGD; i++) ++ swapper_pg_dir[i] = __pgd(1); ++ ++ map_ram(); ++ ++ if (mdesc->map_io) ++ mdesc->map_io(); ++ ++ fixedrange_init(); ++ ++ /* allocate space for empty_zero_page */ ++ zero_page = alloc_bootmem_low_pages(PAGE_SIZE); ++ memset(zero_page, 0, PAGE_SIZE); ++ ++ zone_sizes_init(); ++ ++ empty_zero_page = virt_to_page(zero_page); ++#ifdef CONFIG_NO_KERNEL_LARGE_PAGE ++ SET_MMU_CTL(GET_MMU_CTL() & ~0x400); ++#endif ++#ifdef CONFIG_SMP ++ cpu_dcache_wbinval_all(); ++#endif ++ flush_dcache_page(empty_zero_page); ++} ++ ++static inline int free_area(unsigned long addr, unsigned long end, char *s) ++{ ++ unsigned int size = (end - addr) >> 10; ++ int pages = 0; ++ ++ for (; addr < end; addr += PAGE_SIZE) { ++ struct page *page = virt_to_page(addr); ++ ClearPageReserved(page); ++ init_page_count(page); ++ free_page(addr); ++ totalram_pages++; ++ pages++; ++ } ++ ++ if (size && s) ++ printk(KERN_INFO "free_area: Freeing %s memory: %dK\n", s, ++ size); ++ ++ return pages; ++} ++ ++/* Free the reserved page into the buddy system, so it gets managed. */ ++static inline void __free_reserved_page(struct page *page) ++{ ++ ClearPageReserved(page); ++ init_page_count(page); ++ __free_page(page); ++} ++ ++#ifdef CONFIG_HIGHMEM ++void free_highmem_page(struct page *page) ++{ ++ __free_reserved_page(page); ++ totalram_pages++; ++ totalhigh_pages++; ++} ++#endif ++ ++static inline void __init free_highmem(void) ++{ ++#ifdef CONFIG_HIGHMEM ++ unsigned long pfn; ++ for (pfn = PFN_UP(__pa(high_memory)); pfn < max_pfn; pfn++) { ++ phys_addr_t paddr = (phys_addr_t) pfn << PAGE_SHIFT; ++ if (!memblock_is_reserved(paddr)) ++ free_highmem_page(pfn_to_page(pfn)); ++ } ++#endif ++} ++ ++static void __init set_max_mapnr_init(void) ++{ ++ max_mapnr = max_pfn; ++} ++ ++/* ++ * mem_init() marks the free areas in the mem_map and tells us how much ++ * memory is free. This is done after various parts of the system have ++ * claimed their memory after the kernel image. ++ */ ++void __init mem_init(void) ++{ ++ phys_addr_t memory_start = memblock_start_of_DRAM(); ++ BUG_ON(!mem_map); ++ set_max_mapnr_init(); ++ ++ free_highmem(); ++ ++ /* this will put all low memory onto the freelists */ ++ totalram_pages += free_all_bootmem(); ++ ++ printk(KERN_INFO "virtual kernel memory layout:\n" ++ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" ++#ifdef CONFIG_HIGHMEM ++ " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" ++#endif ++ " consist : 0x%08lx - 0x%08lx (%4ld MB)\n" ++ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" ++ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" ++ " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" ++ " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" ++ " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", ++ FIXADDR_START, FIXADDR_TOP, (FIXADDR_TOP - FIXADDR_START) >> 10, ++#ifdef CONFIG_HIGHMEM ++ PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, ++ (LAST_PKMAP * PAGE_SIZE) >> 10, ++#endif ++ CONSISTENT_BASE, CONSISTENT_END, ++ ((CONSISTENT_END) - (CONSISTENT_BASE)) >> 20, VMALLOC_START, ++ (unsigned long)VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20, ++ (unsigned long)__va(memory_start), (unsigned long)high_memory, ++ ((unsigned long)high_memory - ++ (unsigned long)__va(memory_start)) >> 20, ++ (unsigned long)&__init_begin, (unsigned long)&__init_end, ++ ((unsigned long)&__init_end - ++ (unsigned long)&__init_begin) >> 10, (unsigned long)&_etext, ++ (unsigned long)&_edata, ++ ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, ++ (unsigned long)&_text, (unsigned long)&_etext, ++ ((unsigned long)&_etext - (unsigned long)&_text) >> 10); ++ ++ /* ++ * Check boundaries twice: Some fundamental inconsistencies can ++ * be detected at build time already. ++ */ ++#define __FIXADDR_TOP (-PAGE_SIZE) ++#ifdef CONFIG_HIGHMEM ++ BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START); ++ BUILD_BUG_ON((CONSISTENT_END) > PKMAP_BASE); ++#endif ++ BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE); ++#define high_memory (-128UL << 20) ++ BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END); ++#undef high_memory ++#undef __FIXADDR_TOP ++ ++#ifdef CONFIG_HIGHMEM ++ BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START); ++ BUG_ON(CONSISTENT_END > PKMAP_BASE); ++#endif ++ BUG_ON(VMALLOC_END > CONSISTENT_BASE); ++ BUG_ON(VMALLOC_START >= VMALLOC_END); ++ BUG_ON((unsigned long)high_memory > VMALLOC_START); ++ ++ return; ++} ++ ++void free_initmem(void) ++{ ++ free_area((unsigned long)(&__init_begin), ++ (unsigned long)(&__init_end), "init"); ++} ++ ++#ifdef CONFIG_BLK_DEV_INITRD ++static int keep_initrd; ++ ++void free_initrd_mem(unsigned long start, unsigned long end) ++{ ++ if (!keep_initrd) ++ free_area(start, end, "initrd"); ++} ++ ++static int __init keepinitrd_setup(char *__unused) ++{ ++ keep_initrd = 1; ++ return 1; ++} ++ ++__setup("keepinitrd", keepinitrd_setup); ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/mm/ioremap.c linux-3.4.110/arch/nds32/mm/ioremap.c +--- linux-3.4.110.orig/arch/nds32/mm/ioremap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/ioremap.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,89 @@ ++/* ++ * linux/arch/nds32/mm/ioremap.c ++ * ++ * Re-map IO memory to kernel address space so that we can access it. ++ * ++ * (C) Copyright 1995 1996 Linus Torvalds ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * Hacked for ARM by Phil Blundell ++ * Hacked to allow all architectures to build, and various cleanups ++ * by Russell King ++ * ++ * This allows a driver to remap an arbitrary region of bus memory into ++ * virtual space. One should *only* use readl, writel, memcpy_toio and ++ * so on with such remapped areas. ++ * ++ * Because the ARM only has a 32-bit address space we can't address the ++ * whole of the (physical) PCI space at once. PCI huge-mode addressing ++ * allows us to circumvent this restriction by splitting PCI space into ++ * two 2GB chunks and mapping only one at a time into processor memory. ++ * We use MMU protection domains to trap any attempt to access the bank ++ * that is not currently mapped. (This isn't fully implemented yet.) ++ */ ++#include ++#include ++#include ++#include ++ ++/* ++ * Remap an arbitrary physical address space into the kernel virtual ++ * address space. Needed when the kernel wants to access high addresses ++ * directly. ++ * ++ * NOTE! We need to allow non-page-aligned mappings too: we will obviously ++ * have to convert them into an offset in a page-aligned mapping, but the ++ * caller shouldn't need to know that small detail. ++ * ++ * 'flags' are the extra L_PTE_ flags that you want to specify for this ++ * mapping. See include/asm-arm/proc-armv/pgtable.h for more information. ++ */ ++void __iomem *__ioremap(unsigned long phys_addr, size_t size, ++ unsigned long flags, unsigned long align) ++{ ++ struct vm_struct *area; ++ unsigned long addr, offset, last_addr; ++ pgprot_t prot; ++ ++ /* Don't allow wraparound or zero size */ ++ last_addr = phys_addr + size - 1; ++ if (!size || last_addr < phys_addr) ++ return NULL; ++ ++ /* ++ * Mappings have to be page-aligned ++ */ ++ offset = phys_addr & ~PAGE_MASK; ++ phys_addr &= PAGE_MASK; ++ size = PAGE_ALIGN(last_addr + 1) - phys_addr; ++ ++ /* ++ * Ok, go for it.. ++ */ ++ area = get_vm_area(size, VM_IOREMAP); ++ if (!area) ++ return NULL; ++ ++ area->phys_addr = phys_addr; ++ addr = (unsigned long)area->addr; ++ /* TODO: verify this value for ioremap */ ++ prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | ++ _PAGE_G | _PAGE_C_DEV | flags); ++ /* TODO: verify this use generic ioremap_page_range instead of ++ * self's remap_area_pages */ ++ if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { ++ vunmap((void *)addr); ++ return NULL; ++ } ++ return (__force void __iomem *)(offset + (char *)addr); ++ ++} ++ ++EXPORT_SYMBOL(__ioremap); ++ ++void __iounmap(void __iomem * addr) ++{ ++ vunmap((void *)(PAGE_MASK & (unsigned long)addr)); ++} ++ ++EXPORT_SYMBOL(__iounmap); +diff -Nur linux-3.4.110.orig/arch/nds32/mm/Makefile linux-3.4.110/arch/nds32/mm/Makefile +--- linux-3.4.110.orig/arch/nds32/mm/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/Makefile 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,24 @@ ++# ++# Makefile for the linux arm-specific parts of the memory manager. ++# ++ ++obj-y := consistent.o extable.o \ ++ fault.o init.o ioremap.o mmap.o \ ++ mm-nds32.o cacheflush.o ++ ++obj-y += proc-n12.o ++obj-$(CONFIG_CCTL) += cctl.o ++obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o ++ifneq ($(CONFIG_CPU_NO_CONTEXT_ID), y) ++obj-y += tlb.o ++endif ++gcc_ver :=$(shell $(CC) -E -dM -xc /dev/null | grep __VERSION__ | sed 's/\#define __VERSION__ //') ++ifeq ($(shell expr `echo $(gcc_ver)` \>= 4.9.2 ), 1) ++CFLAGS_proc-n12.o += -fomit-frame-pointer ++else ++CFLAGS_proc-n12.o += -fomit-frame-pointer -mno-16bit ++endif ++obj-$(CONFIG_HIGHMEM) += highmem.o ++ifdef CONFIG_FUNCTION_TRACER ++CFLAGS_REMOVE_proc-n12.o = -pg ++endif +diff -Nur linux-3.4.110.orig/arch/nds32/mm/mmap.c linux-3.4.110/arch/nds32/mm/mmap.c +--- linux-3.4.110.orig/arch/nds32/mm/mmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/mmap.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,101 @@ ++/* ++ * linux/arch/nds32/mm/mmap.c ++ * ++ * Copyright (C) 2009 Andes Technology Corporation ++ */ ++#include ++#include ++#include ++ ++#define COLOUR_ALIGN(addr,pgoff) \ ++ ((((addr)+REALSHMLBA-1)&~(REALSHMLBA-1)) + \ ++ (((pgoff)<mm; ++ struct vm_area_struct *vma; ++ unsigned long start_addr; ++ int do_align = 0; ++#ifdef CONFIG_CPU_CACHE_NONALIASING ++ int aliasing = 0; ++#else ++ int aliasing = 1; ++#endif ++ ++ /* ++ * We only need to do colour alignment if either the I or D ++ * caches alias. ++ */ ++ if (aliasing) ++ do_align = filp || (flags & MAP_SHARED); ++ ++ /* ++ * We should enforce the MAP_FIXED case. However, currently ++ * the generic kernel code doesn't allow us to handle this. ++ */ ++ if (flags & MAP_FIXED) { ++ if (aliasing && flags & MAP_SHARED && addr & (REALSHMLBA - 1)) ++ return -EINVAL; ++ return addr; ++ } ++ ++ if (len > TASK_SIZE) ++ return -ENOMEM; ++ ++ if (addr) { ++ if (do_align) ++ addr = COLOUR_ALIGN(addr, pgoff); ++ else ++ addr = PAGE_ALIGN(addr); ++ ++ vma = find_vma(mm, addr); ++ if (TASK_SIZE - len >= addr && ++ (!vma || addr + len <= vma->vm_start)) ++ return addr; ++ } ++ start_addr = addr = mm->free_area_cache; ++ ++full_search: ++ if (do_align) ++ addr = COLOUR_ALIGN(addr, pgoff); ++ else ++ addr = PAGE_ALIGN(addr); ++ ++ for (vma = find_vma(mm, addr);; vma = vma->vm_next) { ++ /* At this point: (!vma || addr < vma->vm_end). */ ++ if (TASK_SIZE - len < addr) { ++ /* ++ * Start a new search - just in case we missed ++ * some holes. ++ */ ++ if (start_addr != TASK_UNMAPPED_BASE) { ++ start_addr = addr = TASK_UNMAPPED_BASE; ++ goto full_search; ++ } ++ return -ENOMEM; ++ } ++ if (!vma || addr + len <= vma->vm_start) { ++ /* ++ * Remember the place where we stopped the search: ++ */ ++ mm->free_area_cache = addr + len; ++ return addr; ++ } ++ addr = vma->vm_end; ++ if (do_align) ++ addr = COLOUR_ALIGN(addr, pgoff); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/mm/mm.h linux-3.4.110/arch/nds32/mm/mm.h +--- linux-3.4.110.orig/arch/nds32/mm/mm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/mm.h 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,19 @@ ++/* the upper-most page table pointer */ ++ ++#ifdef CONFIG_MMU ++ ++extern pmd_t *top_pmd; ++ ++#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) ++ ++static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) ++{ ++ return pmd_offset(pgd, virt); ++} ++ ++static inline pmd_t *pmd_off_k(unsigned long virt) ++{ ++ return pmd_off(pgd_offset_k(virt), virt); ++} ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/mm/mm-nds32.c linux-3.4.110/arch/nds32/mm/mm-nds32.c +--- linux-3.4.110.orig/arch/nds32/mm/mm-nds32.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/mm-nds32.c 2016-04-07 10:20:50.982082572 +0200 +@@ -0,0 +1,267 @@ ++/* ++ * linux/arch/nds32/mm/mm-nds32.c ++ * ++ * Copyright (C) 1998-2002 Russell King ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * Page table sludge for Andes N10/N12 processor architectures. ++ */ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include "./../kernel/signal.h" ++ ++extern void _text, _stext, _etext; ++extern void *high_memory; ++ ++#define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD) ++ ++/* ++ * need to get a 4k page for level 1 ++ */ ++ ++pgd_t *get_pgd_slow(struct mm_struct *mm) ++{ ++ pgd_t *new_pgd, *init_pgd; ++ int i; ++ ++ new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0); //M order 0: one page ++ if (!new_pgd) ++ return NULL; ++ for (i = 0; i < PTRS_PER_PGD; i++) { ++ (*new_pgd) = 1; ++ new_pgd++; ++ } ++ new_pgd -= PTRS_PER_PGD; ++ ++ init_pgd = pgd_offset_k(0); ++ ++ memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, ++ (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); ++ ++ cpu_dcache_wb_range((unsigned long)new_pgd, ++ (unsigned long)new_pgd + ++ PTRS_PER_PGD * sizeof(pgd_t)); ++ inc_zone_page_state(virt_to_page((unsigned long *)new_pgd), ++ NR_PAGETABLE); ++ ++ return new_pgd; ++} ++ ++void free_pgd_slow(struct mm_struct *mm, pgd_t * pgd) ++{ ++ pmd_t *pmd; ++ struct page *pte; ++ ++ if (!pgd) ++ return; ++ ++ pmd = (pmd_t *) pgd; ++ if (pmd_none(*pmd)) ++ goto free; ++ if (pmd_bad(*pmd)) { ++ pmd_ERROR(*pmd); ++ pmd_clear(pmd); ++ goto free; ++ } ++ ++ pte = pmd_page(*pmd); ++ pmd_clear(pmd); ++ dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); ++ pte_free(mm, pte); ++ pmd_free(mm, pmd); ++free: ++ free_pages((unsigned long)pgd, 0); ++} ++ ++/* ++ * Add a PAGE mapping between VIRT and PHYS in domain ++ * DOMAIN with protection PROT. Note that due to the ++ * way we map the PTEs, we must allocate two PTE_SIZE'd ++ * blocks - one for the Linux pte table, and one for ++ * the hardware pte table. ++ */ ++static inline void ++alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, ++ pgprot_t prot) ++{ ++ pmd_t *pmdp; ++ pte_t *ptep; ++ ++ pmdp = pmd_offset(pgd_offset_k(virt), virt); //L1PTE ++ if (pmd_none(*pmdp)) { //must not or 0xc0000000 ++ ptep = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t)); ++ set_pmd(pmdp, __mk_pmd(ptep, 0)); ++ } ++ ptep = pte_offset_kernel(pmdp, virt); //L2PTE ++ set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); ++} ++ ++/* ++ * Clear any PGD mapping. On a two-level page table system, ++ * the clearance is done by the middle-level functions (pmd) ++ * rather than the top-level (pgd) functions. ++ */ ++static inline void clear_mapping(unsigned long virt) ++{ ++ pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); ++} ++ ++struct mem_types { ++ unsigned int prot_pte; ++ unsigned int prot_l1; ++}; ++ ++static struct mem_types mem_types[] __initdata = { ++ [MT_DEVICE] = { ++ .prot_pte = 0x9f, //_KERNPG_TABLE, ++ .prot_l1 = PMD_TYPE_TABLE, ++ }, ++ [MT_CACHECLEAN] = { ++ .prot_l1 = PMD_TYPE_TABLE, ++ .prot_pte = 0x0, //_KERNPG_TABLE, ++ }, ++ [MT_MINICLEAN] = { ++ .prot_l1 = PMD_TYPE_TABLE, ++ .prot_pte = 0x0, // _KERNPG_TABLE, ++ }, ++ [MT_CACHE_L1] = { ++ .prot_pte = PAGE_CACHE_L1, ++ .prot_l1 = PMD_TYPE_TABLE, ++ }, ++ [MT_UXKRWX_V1] = { ++ .prot_pte = PAGE_UXKRWX_V1, ++ .prot_l1 = PMD_TYPE_TABLE, ++ }, ++ [MT_UXKRWX_V2] = { ++ .prot_pte = PAGE_UXKRWX_V2, ++ .prot_l1 = PMD_TYPE_TABLE, ++ }, ++ [MT_MEMORY] = { ++ .prot_pte = PAGE_MEMORY, ++ .prot_l1 = PMD_TYPE_TABLE, ++ }, ++ [MT_ROM] = { ++ .prot_l1 = PMD_TYPE_TABLE, ++ .prot_pte = 0x2bb, // _KERNPG_TABLE, ++ }, ++ [MT_ILM] = { ++ .prot_l1 = PMD_TYPE_TABLE, ++ .prot_pte = 0x2b7, // _KERNPG_TABLE, ++ }, ++ [MT_DLM] = { ++ .prot_l1 = PMD_TYPE_TABLE, ++ .prot_pte = 0x297, // _KERNPG_TABLE, ++ } ++}; ++ ++/* ++ * Create the page directory entries and any necessary ++ * page tables for the mapping specified by `md'. We ++ * are able to cope here with varying sizes and address ++ * offsets, and we take full advantage of sections. ++ */ ++static void __init create_mapping(struct map_desc *md) ++{ ++ unsigned long virt, length; ++ int prot_l1; ++ pgprot_t prot_pte; ++ long off; ++ ++ printk("virt:0x%08lx,phys:%08lx,size:%08lx,pte:%08x\n", ++ md->virtual, md->physical, md->length, ++ __pgprot(mem_types[md->type].prot_pte)); ++ ++ if (md->virtual < TASK_SIZE) { ++ printk(KERN_WARNING "BUG: not creating mapping area for " ++ "0x%08lx at 0x%08lx in user region, next frame\n", ++ md->physical, md->virtual); ++ panic("In :%s, line:%d", __func__, __LINE__); ++ return; ++ } ++ ++ if ((md->type == MT_DEVICE || md->type == MT_ROM) && ++ md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { ++ printk(KERN_WARNING "BUG: mapping area for 0x%08lx at 0x%08lx " ++ "overlaps vmalloc space, next frame\n", ++ md->physical, md->virtual); ++ panic("In :%s, line:%d", __func__, __LINE__); ++ } ++ ++ prot_pte = __pgprot(mem_types[md->type].prot_pte); ++ prot_l1 = mem_types[md->type].prot_l1; ++ virt = md->virtual; ++ off = md->physical - virt; ++ ++ length = md->length; ++ if (mem_types[md->type].prot_l1 == 1 && ++ (virt & 0xfffff || (virt + off) & 0xfffff ++ || (virt + length) & 0xfffff)) { ++ printk(KERN_WARNING ++ "BUG: map area for 0x%08lx at 0x%08lx can not " ++ "be mapped using pages, ignoring. next frame\n", ++ md->physical, md->virtual); ++ panic("In :%s, line:%d", __func__, __LINE__); ++ return; ++ } ++ ++ while (length >= PAGE_SIZE) { ++#ifdef CONFIG_SMP ++ if (((virt >= (unsigned long)&_text) ++ && (virt < (unsigned long)&_etext)) ++ || ((virt >= 0xc0000000) && (virt < 0xc0008000))) ++ prot_pte = __pgprot(mem_types[MT_CACHE_L1].prot_pte); ++#endif ++ alloc_init_page(virt, virt + off, prot_l1, prot_pte); ++ virt += PAGE_SIZE; ++ length -= PAGE_SIZE; ++ } ++} ++ ++/* ++ * In order to soft-boot, we need to insert a 1:1 mapping in place of ++ * the user-mode pages. This will then ensure that we have predictable ++ * results when turning the mmu off ++ */ ++void setup_mm_for_reboot(char mode) ++{ ++ unsigned long pmdval; ++ pgd_t *pgd; ++ pmd_t *pmd; ++ int i; ++ ++ if (current->mm && current->mm->pgd) ++ pgd = current->mm->pgd; ++ else ++ pgd = init_mm.pgd; ++ ++ for (i = 0; i < USER_PTRS_PER_PGD; i++) { ++ pmdval = (i << PGDIR_SHIFT); ++ pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); ++ set_pmd(pmd, __pmd(pmdval)); ++ } ++} ++ ++/* ++ * Create the architecture specific mappings ++ */ ++void __init iotable_init(struct map_desc *io_desc, int nr) ++{ ++ int i; ++ ++ for (i = 0; i < nr; i++) { ++ create_mapping(io_desc + i); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/mm/proc-n12.c linux-3.4.110/arch/nds32/mm/proc-n12.c +--- linux-3.4.110.orig/arch/nds32/mm/proc-n12.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/proc-n12.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,845 @@ ++/* ++ * linux/arch/nds32/mm/proc-nds32.c ++ * ++ * Copyright (C) 2006 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ++ * These are the low level assembler for performing cache and TLB ++ * functions on the nds32. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_CACHE_L2 ++#include ++#endif ++#include ++ ++#include ++extern struct cache_info L1_cache_info[2]; ++ ++#ifdef CONFIG_CACHE_L2 ++void n12_L2cache_inval(void) ++{ ++ unsigned long cmd = CCTL_CMD_L2_IX_INVAL | CCTL_ALL_CMD; ++ ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, CCTL_CMD_L2_SYNC); ++ L2_CMD_RDY(); ++} ++ ++void n12_L2cache_wb(void) ++{ ++ unsigned long cmd = CCTL_CMD_L2_IX_WB | CCTL_ALL_CMD; ++ ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, CCTL_CMD_L2_SYNC); ++ L2_CMD_RDY(); ++} ++#endif ++ ++int va_kernel_present(unsigned long addr) ++{ ++ pmd_t *pmd; ++ pte_t *ptep, pte; ++ int ret = 0; ++ ++ pmd = pmd_offset(pgd_offset_k(addr), addr); ++ if (!pmd_none(*pmd)) { ++ ptep = pte_offset_map(pmd, addr); ++ pte = *ptep; ++ if (pte_present(pte)) ++ ret = 1; ++ } ++ return ret; ++} ++ ++int va_present(struct mm_struct *mm, unsigned long addr) ++{ ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *ptep, pte; ++ int ret = 0; ++ ++ pgd = pgd_offset(mm, addr); ++ if (!pgd_none(*pgd)) { ++ pud = pud_offset(pgd, addr); ++ if (!pud_none(*pud)) { ++ pmd = pmd_offset(pud, addr); ++ if (!pmd_none(*pmd)) { ++ ptep = pte_offset_map(pmd, addr); ++ pte = *ptep; ++ if (pte_present(pte)) ++ ret = 1; ++ } ++ } ++ } ++ return ret; ++ ++} ++ ++int va_readable(struct pt_regs *regs, unsigned long addr) ++{ ++ struct mm_struct *mm = current->mm; ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *ptep, pte; ++ int ret = 0; ++ ++ if (user_mode(regs)) { ++ /* user mode */ ++ pgd = pgd_offset(mm, addr); ++ if (!pgd_none(*pgd)) { ++ pud = pud_offset(pgd, addr); ++ if (!pud_none(*pud)) { ++ pmd = pmd_offset(pud, addr); ++ if (!pmd_none(*pmd)) { ++ ptep = pte_offset_map(pmd, addr); ++ pte = *ptep; ++ if (pte_present(pte) && pte_read(pte)) ++ ret = 1; ++ } ++ } ++ } ++ } else { ++ /* superuser mode is always readable, so we can only ++ * check it is present or not*/ ++ pmd = pmd_offset(pgd_offset_k(addr), addr); ++ if (!pmd_none(*pmd)) { ++ ptep = pte_offset_map(pmd, addr); ++ pte = *ptep; ++ if (pte_present(pte)) ++ ret = 1; ++ } ++ } ++ return ret; ++} ++ ++int va_writable(struct pt_regs *regs, unsigned long addr) ++{ ++ struct mm_struct *mm = current->mm; ++ pgd_t *pgd; ++ pud_t *pud; ++ pmd_t *pmd; ++ pte_t *ptep, pte; ++ int ret = 0; ++ ++ if (user_mode(regs)) { ++ /* user mode */ ++ pgd = pgd_offset(mm, addr); ++ if (!pgd_none(*pgd)) { ++ pud = pud_offset(pgd, addr); ++ if (!pud_none(*pud)) { ++ pmd = pmd_offset(pud, addr); ++ if (!pmd_none(*pmd)) { ++ ptep = pte_offset_map(pmd, addr); ++ pte = *ptep; ++ if (pte_present(pte) && pte_write(pte)) ++ ret = 1; ++ } ++ } ++ } ++ } else { ++ /* superuser mode */ ++ pmd = pmd_offset(pgd_offset_k(addr), addr); ++ if (!pmd_none(*pmd)) { ++ ptep = pte_offset_map(pmd, addr); ++ pte = *ptep; ++ if (pte_present(pte) && pte_kernel_write(pte)) ++ ret = 1; ++ } ++ } ++ return ret; ++} ++ ++#if 0 ++static inline void flush_fill_buffer(void) ++{ ++ unsigned long kaddr, pte, flags; ++ ++ local_irq_save(flags); ++#define BASE_ADDR2 0xffff4000 ++ kaddr = BASE_ADDR2; ++ pte = (0x6000 | _PAGE_V | _PAGE_M_KRW | _PAGE_G | _PAGE_C_DEV); ++ asm("tlbop %0, INV\nisb\n"::"r"(kaddr)); ++ asm("mtsr %1, $mr2\ndsb\n" ++ "tlbop %0, RWR\nisb\n"::"r"(pte), "r"(kaddr)); ++asm("lmw.bi $r0, [%0], $r1\n"::"r"(kaddr):"$r0", "$r1"); ++ local_irq_restore(flags); ++} ++#else ++static inline void flush_fill_buffer(void) ++{ ++} ++#endif ++ ++/* ++ * All ++ */ ++void n12_icache_inval_all(void) ++{ ++ unsigned long end, line_size; ++ ++ line_size = L1_cache_info[ICACHE].line_size; ++ end = ++ line_size * L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].sets; ++ ++ do { ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); ++ } while (end > 0); ++} ++ ++void n12_dcache_inval_all(void) ++{ ++#ifdef CONFIG_PLAT_AG102 ++ __asm__ volatile ("\n\tcctl L1D_INVALALL"); ++#else ++ unsigned long end, line_size; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ end = ++ line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets; ++ ++ do { ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++ } while (end > 0); ++#endif ++} ++ ++void n12_dcache_wb_all(void) ++{ ++#ifdef __NDS32_BASELINE_V3 ++#ifdef CONFIG_CACHE_L2 ++ __nds32__cctl_l1d_wball_alvl(); ++#else ++ __nds32__cctl_l1d_wball_one_lvl(); ++#endif ++#else ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ unsigned long end, line_size; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ end = ++ line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets; ++ ++ do { ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++ } while (end > 0); ++#endif ++#endif ++} ++ ++void n12_dcache_wbinval_all(void) ++{ ++ unsigned long end, line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ unsigned long saved_gie; ++#endif ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ end = ++ line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets; ++ ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ GIE_SAVE(&saved_gie); ++#endif ++#ifdef __NDS32_BASELINE_V3 ++#ifdef CONFIG_CACHE_L2 ++ __nds32__cctl_l1d_wball_alvl(); ++#else ++ __nds32__cctl_l1d_wball_one_lvl(); ++#endif ++ __nds32__cctl_l1d_invalall(); ++#else ++ do { ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++#endif ++#ifndef CONFIG_PLAT_AG102 ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++#endif ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++#endif ++#ifndef CONFIG_PLAT_AG102 ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++#endif ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++#endif ++#ifndef CONFIG_PLAT_AG102 ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++#endif ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); ++#endif ++#ifndef CONFIG_PLAT_AG102 ++ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); ++#endif ++ } while (end > 0); ++#ifdef CONFIG_PLAT_AG102 ++ __asm__ volatile ("\n\tcctl L1D_INVALALL"); ++#endif ++#endif ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ GIE_RESTORE(saved_gie); ++#endif ++} ++ ++/* ++ * Page ++ */ ++void n12_icache_inval_page(unsigned long start) ++{ ++ unsigned long line_size, end; ++ ++ line_size = L1_cache_info[ICACHE].line_size; ++ end = start + PAGE_SIZE; ++ ++ do { ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); ++ } while (end != start); ++} ++ ++void n12_dcache_inval_page(unsigned long start) ++{ ++ unsigned long line_size, end; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ end = start + PAGE_SIZE; ++ ++ flush_fill_buffer(); ++ do { ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ } while (end != start); ++} ++ ++void n12_dcache_wb_page(unsigned long start) ++{ ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ unsigned long line_size, end; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ end = start + PAGE_SIZE; ++ ++ flush_fill_buffer(); ++ do { ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++ end -= line_size; ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++ } while (end != start); ++#endif ++} ++ ++void n12_dcache_wbinval_page(unsigned long start) ++{ ++ unsigned long line_size, end; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ end = start + PAGE_SIZE; ++ ++ flush_fill_buffer(); ++ do { ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++#endif ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++#endif ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++#endif ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ end -= line_size; ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); ++#endif ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); ++ } while (end != start); ++} ++ ++void n12_cache_wbinval_page(unsigned long page, int flushi) ++{ ++ n12_dcache_wbinval_page(page); ++ if (flushi) ++ n12_icache_inval_page(page); ++} ++ ++/* These functions are used to invalidate cache by idx instead of ++ * virtual address. User can use virtual address to do this purpose. ++ * It supports 4way and 32KB cache size with 32bytes cacheline size. */ ++#include ++//#define WB_WITH_IDX ++inline unsigned long va2idx(unsigned long va, unsigned int cache_type, ++ unsigned long *way_offset) ++{ ++ unsigned char set_bits, way_bits, line_bits; ++ unsigned int idx; ++ set_bits = L1_cache_info[cache_type].set_bits; ++ way_bits = L1_cache_info[cache_type].way_bits; ++ line_bits = L1_cache_info[cache_type].line_bits; ++ *way_offset = set_bits + line_bits; ++ ++ idx = (va & (((1 << set_bits) - 1) << line_bits)); ++ return idx; ++} ++ ++static inline void n12_dcache_inval_idx(unsigned long p) ++{ ++ unsigned long idx, i, way_offset; ++ unsigned char ways; ++ ways = L1_cache_info[DCACHE].ways; ++ ++ /* Unroll loop. Not support 2 ways invalidate. */ ++ if (ways == 2) ++ panic("This way size is not supported. ways:%u, %s\n", ways, ++ __func__); ++ idx = va2idx(p, DCACHE, &way_offset); ++ for (i = 0; i < ways / 4; i++) { ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | i << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | (i + 1) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | (i + 2) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | (i + 3) << way_offset)); ++ } ++} ++ ++static inline void n12_dcache_wb_idx(unsigned long p) ++{ ++ unsigned long idx, i, way_offset; ++ unsigned char ways; ++ ways = L1_cache_info[DCACHE].ways; ++ ++ /* Unroll the loop. Not support 2 ways invalidate. */ ++ if (ways == 2) ++ panic("This way size is not supported. ways:%d, %s\n", ways, ++ __func__); ++ idx = va2idx(p, DCACHE, &way_offset); ++ for (i = 0; i < ways / 4; i++) { ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | i << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | i << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | (i + 1) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | (i + 1) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | (i + 2) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | (i + 2) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | (i + 3) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, ++ (idx | (i + 3) << way_offset)); ++ } ++} ++ ++static inline void n12_dcache_wbinval_idx(unsigned long p) ++{ ++ unsigned long idx, i, way_offset; ++ unsigned char ways; ++ ways = L1_cache_info[DCACHE].ways; ++ ++ /* Unroll the loop. Not support 2 ways invalidate. */ ++ if (ways == 2) ++ panic("This way size is not supported. ways:%d, %s\n", ways, ++ __func__); ++ idx = va2idx(p, DCACHE, &way_offset); ++ for (i = 0; i < ways / 4; i++) { ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | i << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | (i + 1) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | (i + 2) << way_offset)); ++ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, ++ (idx | (i + 3) << way_offset)); ++ } ++} ++ ++/* ++ * Range ++ */ ++void n12_icache_inval_range(unsigned long start, unsigned long end) ++{ ++ unsigned long line_size; ++ ++ line_size = L1_cache_info[ICACHE].line_size; ++ ++ while (end > start) { ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (start)); ++ start += line_size; ++ } ++} ++ ++void n12_dcache_inval_range(unsigned long start, unsigned long end) ++{ ++ unsigned long line_size; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ ++ flush_fill_buffer(); ++ while (end > start) { ++#ifdef WB_WITH_IDX ++ n12_dcache_inval_idx(start); ++#else ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start)); ++#endif ++ start += line_size; ++ } ++} ++ ++void n12_dcache_wb_range(unsigned long start, unsigned long end) ++{ ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++ unsigned long line_size; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ ++ flush_fill_buffer(); ++ while (end > start) { ++#ifdef WB_WITH_IDX ++ n12_dcache_wb_idx(start); ++#else ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start)); ++#endif ++ start += line_size; ++ } ++#endif ++} ++ ++void n12_dcache_wbinval_range(unsigned long start, unsigned long end) ++{ ++ unsigned long line_size; ++ ++ line_size = L1_cache_info[DCACHE].line_size; ++ ++ flush_fill_buffer(); ++ while (end > start) { ++#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH ++#ifdef WB_WITH_IDX ++ n12_dcache_wbinval_idx(start); ++#else ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start)); ++#endif ++#endif ++ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start)); ++ start += line_size; ++ } ++} ++ ++void n12_cache_wbinval_range(unsigned long start, unsigned long end, int flushi) ++{ ++ n12_dcache_wbinval_range(start, end); ++ if (flushi) ++ n12_icache_inval_range(start, end); ++} ++ ++void n12_cache_wbinval_range_check(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++ unsigned long line_size, t_start, t_end; ++ int flushi; ++ ++ flushi = vma->vm_flags & VM_EXEC; ++ line_size = L1_cache_info[DCACHE].line_size; ++ start = start & ~(line_size - 1); ++ end = (end + line_size - 1) & ~(line_size - 1); ++ ++ if ((end - start) > (8 * PAGE_SIZE)) { ++ n12_dcache_wbinval_all(); ++ if (flushi) ++ n12_icache_inval_all(); ++ return; ++ } ++ ++ t_start = (start + PAGE_SIZE) & PAGE_MASK; ++ t_end = ((end - 1) & PAGE_MASK); ++ ++ if ((start & PAGE_MASK) == t_end) { ++ if (va_present(vma->vm_mm, start)) ++ n12_cache_wbinval_range(start, end, flushi); ++ return; ++ } ++ ++ if (va_present(vma->vm_mm, start)) ++ n12_cache_wbinval_range(start, t_start, flushi); ++ ++ if (va_present(vma->vm_mm, end - 1)) ++ n12_cache_wbinval_range(t_end, end, flushi); ++ ++ while (t_start < t_end) { ++ if (va_present(vma->vm_mm, t_start)) ++ n12_cache_wbinval_page(t_start, flushi); ++ t_start += PAGE_SIZE; ++ } ++} ++ ++/* ++ * DMA ++ */ ++void n12_dma_wb_range(unsigned long start, unsigned long end) ++{ ++ unsigned long line_size; ++ line_size = L1_cache_info[DCACHE].line_size; ++ start = start & (~(line_size - 1)); ++ end = (end + line_size - 1) & (~(line_size - 1)); ++ if (unlikely(start == end)) ++ return; ++ ++ n12_dcache_wb_range(start, end); ++ ++#ifdef CONFIG_CACHE_L2 ++ { ++ unsigned long p_start = __pa(start); ++ unsigned long p_end = __pa(end); ++ unsigned long cmd; ++ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE ++ line_size = L2_CACHE_LINE_SIZE(); ++ cmd = ++ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WB | ++ CCTL_SINGLE_CMD; ++ do { ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ cmd += line_size; ++ p_start += line_size; ++ } while (p_end > p_start); ++ cmd = CCTL_CMD_L2_SYNC; ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ L2_CMD_RDY(); ++ ++ } ++#endif ++} ++ ++#ifdef CONFIG_CACHE_L2 ++void n12_l2dcache_wbinval_range(unsigned long start, unsigned long end) ++{ ++ unsigned long p_start; ++ unsigned long p_end; ++ unsigned long cmd; ++ unsigned long line_size; ++ ++ p_start = __pa(start); ++ p_end = __pa(end); ++ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE ++ line_size = L2_CACHE_LINE_SIZE(); ++ cmd = ++ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WBINVAL | ++ CCTL_SINGLE_CMD; ++ do { ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ cmd += line_size; ++ p_start += line_size; ++ } while (p_end > p_start); ++ cmd = CCTL_CMD_L2_SYNC; ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ L2_CMD_RDY(); ++ ++} ++#endif ++ ++void n12_dma_inval_range(unsigned long start, unsigned long end) ++{ ++ unsigned long line_size; ++ unsigned long old_start = start; ++ unsigned long old_end = end; ++ line_size = L1_cache_info[DCACHE].line_size; ++ start = start & (~(line_size - 1)); ++ end = (end + line_size - 1) & (~(line_size - 1)); ++ if (unlikely(start == end)) ++ return; ++ if (start != old_start) { ++ n12_dcache_wbinval_range(start, start + line_size); ++#ifdef CONFIG_CACHE_L2 ++ n12_l2dcache_wbinval_range(start, start + line_size); ++#endif ++ } ++ if (end != old_end) { ++ n12_dcache_wbinval_range(end - line_size, end); ++#ifdef CONFIG_CACHE_L2 ++ n12_l2dcache_wbinval_range(end - line_size, end); ++#endif ++ } ++ n12_dcache_inval_range(start, end); ++#ifdef CONFIG_CACHE_L2 ++ unsigned long p_start = __pa(start); ++ unsigned long p_end = __pa(end); ++ unsigned long cmd; ++ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE ++ line_size = L2_CACHE_LINE_SIZE(); ++ cmd = ++ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_INVAL | ++ CCTL_SINGLE_CMD; ++ do { ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ cmd += line_size; ++ p_start += line_size; ++ } while (p_end > p_start); ++ cmd = CCTL_CMD_L2_SYNC; ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ L2_CMD_RDY(); ++#endif ++ ++} ++ ++void n12_dma_wbinval_range(unsigned long start, unsigned long end) ++{ ++ unsigned long line_size; ++ line_size = L1_cache_info[DCACHE].line_size; ++ start = start & (~(line_size - 1)); ++ end = (end + line_size - 1) & (~(line_size - 1)); ++ if (unlikely(start == end)) ++ return; ++ ++ n12_dcache_wbinval_range(start, end); ++#ifdef CONFIG_CACHE_L2 ++ { ++ unsigned long p_start = __pa(start); ++ unsigned long p_end = __pa(end); ++ unsigned long cmd; ++ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE ++ line_size = L2_CACHE_LINE_SIZE(); ++ cmd = ++ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WBINVAL | ++ CCTL_SINGLE_CMD; ++ do { ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ cmd += line_size; ++ p_start += line_size; ++ } while (p_end > p_start); ++ cmd = CCTL_CMD_L2_SYNC; ++ L2_CMD_RDY(); ++ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); ++ L2_CMD_RDY(); ++ ++ } ++#endif ++} ++ ++void n12_proc_init(void) ++{ ++} ++ ++void n12_proc_fin(void) ++{ ++} ++ ++void n12_do_idle(void) ++{ ++ STANDBY(no_wake_grant); ++} ++ ++void n12_reset(unsigned long reset) ++{ ++ GIE_DISABLE(); ++ SET_CACHE_CTL(GET_CACHE_CTL() & ++ ~(CACHE_CTL_mskIC_EN | CACHE_CTL_mskDC_EN)); ++ n12_dcache_wbinval_all(); ++ n12_icache_inval_all(); ++ ++ __asm__ __volatile__("jr.toff %0\n\t"::"r"(reset)); ++} ++ ++void n12_switch_mm(struct mm_struct *mm) ++{ ++ unsigned long cid; ++#ifndef CONFIG_CPU_NO_CONTEXT_ID ++ cid = GET_TLB_MISC(); ++ cid = (cid & ~TLB_MISC_mskCID) | mm->context.id; ++ SET_TLB_MISC(cid); ++#endif ++ SET_L1_PPTB(__pa(mm->pgd)); ++ //workaround N10 single-entry cache flush issue ++ //the following line can be removed once the issue is fixed. ++ __asm__ __volatile__("tlbop %0, INV"::"r"(cid)); ++ __nds32__isb(); ++#ifdef CONFIG_CPU_NO_CONTEXT_ID ++ local_flush_tlb_mm(mm); ++#endif ++} +diff -Nur linux-3.4.110.orig/arch/nds32/mm/tlb.c linux-3.4.110/arch/nds32/mm/tlb.c +--- linux-3.4.110.orig/arch/nds32/mm/tlb.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/mm/tlb.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,47 @@ ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int cpu_last_cid = { TLB_MISC_mskCID + (2 << TLB_MISC_offCID) }; ++ ++DEFINE_SPINLOCK(cid_lock); ++ ++void local_flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++ unsigned long flags, ocid, ncid; ++ ++ if ((end - start) > 0x400000) { ++ asm("tlbop FLUA"); ++ __nds32__isb(); ++ return; ++ } ++ ++ spin_lock_irqsave(&cid_lock, flags); ++ ocid = GET_TLB_MISC(); ++ ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id; ++ SET_TLB_MISC(ncid); ++ while (start < end) { ++ asm("tlbop %0, INV"::"r"(start)); ++ __nds32__isb(); ++ start += PAGE_SIZE; ++ } ++ SET_TLB_MISC(ocid); ++ spin_unlock_irqrestore(&cid_lock, flags); ++} ++ ++void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) ++{ ++ unsigned long flags, ocid, ncid; ++ ++ spin_lock_irqsave(&cid_lock, flags); ++ ocid = GET_TLB_MISC(); ++ ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id; ++ SET_TLB_MISC(ncid); ++ asm("tlbop %0, INV"::"r"(addr)); ++ __nds32__isb(); ++ SET_TLB_MISC(ocid); ++ spin_unlock_irqrestore(&cid_lock, flags); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/common.c linux-3.4.110/arch/nds32/oprofile/common.c +--- linux-3.4.110.orig/arch/nds32/oprofile/common.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/oprofile/common.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,104 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2004, 2005 Ralf Baechle ++ * Copyright (C) 2005 MIPS Technologies, Inc. ++ * Copyright (C) 2008 Andes Technology Corporation ++ */ ++#include ++#include ++#include ++#include ++ ++#include "op_impl.h" ++ ++extern struct op_nds32_model op_model_nds32_ops __attribute__ ((weak)); ++ ++static struct op_nds32_model *model; ++ ++static struct op_counter_config ctr[20]; ++ ++static int op_nds32_setup(void) ++{ ++ /* Pre-compute the values to stuff in the hardware registers. */ ++ model->reg_setup(ctr); ++ ++ /* Configure the registers on all cpus. */ ++ on_each_cpu(model->cpu_setup, NULL, 1); ++ ++ return 0; ++} ++ ++static int op_nds32_create_files(struct super_block *sb, struct dentry *root) ++{ ++ int i; ++ ++ for (i = 0; i < model->num_counters; ++i) { ++ struct dentry *dir; ++ char buf[4]; ++ ++ snprintf(buf, sizeof buf, "%d", i); ++ dir = oprofilefs_mkdir(sb, root, buf); ++ ++ oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); ++ oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); ++ oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); ++ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); ++ oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); ++ oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl); ++ /* Dummy. */ ++ oprofilefs_create_ulong(sb, dir, "unit_mask", ++ &ctr[i].unit_mask); ++ } ++ ++ return 0; ++} ++ ++static int op_nds32_start(void) ++{ ++ on_each_cpu(model->cpu_start, NULL, 1); ++ ++ return 0; ++} ++ ++static void op_nds32_stop(void) ++{ ++ /* Disable performance monitoring for all counters. */ ++ on_each_cpu(model->cpu_stop, NULL, 1); ++} ++ ++int __init oprofile_arch_init(struct oprofile_operations *ops) ++{ ++ struct op_nds32_model *lmodel = NULL; ++ int res; ++ ++ lmodel = &op_model_nds32_ops; ++ ++ if (!lmodel) ++ return -ENODEV; ++ ++ res = lmodel->init(); ++ if (res) ++ return res; ++ ++ model = lmodel; ++ ++ ops->create_files = op_nds32_create_files; ++ ops->setup = op_nds32_setup; ++ ops->start = op_nds32_start; ++ ops->stop = op_nds32_stop; ++ ops->cpu_type = lmodel->cpu_type; ++ ++ printk(KERN_INFO "oprofile: using %s performance monitoring.\n", ++ lmodel->cpu_type); ++ ++ return 0; ++} ++ ++void oprofile_arch_exit(void) ++{ ++ if (model) ++ model->exit(); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/Makefile linux-3.4.110/arch/nds32/oprofile/Makefile +--- linux-3.4.110.orig/arch/nds32/oprofile/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/oprofile/Makefile 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,11 @@ ++EXTRA_CFLAGS := ++ ++obj-$(CONFIG_OPROFILE) += oprofile.o ++ ++DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ ++ oprof.o cpu_buffer.o buffer_sync.o \ ++ event_buffer.o oprofile_files.o \ ++ oprofilefs.o oprofile_stats.o \ ++ timer_int.o ) ++ ++oprofile-y := $(DRIVER_OBJS) common.o op_model_nds32.o +diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/op_impl.h linux-3.4.110/arch/nds32/oprofile/op_impl.h +--- linux-3.4.110.orig/arch/nds32/oprofile/op_impl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/oprofile/op_impl.h 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,42 @@ ++/** ++ * @file arch/alpha/oprofile/op_impl.h ++ * ++ * @remark Copyright 2002 OProfile authors ++ * @remark Read the file COPYING ++ * ++ * @author Richard Henderson ++ */ ++ ++#ifndef OP_IMPL_H ++#define OP_IMPL_H 1 ++ ++struct pt_regs; ++ ++extern int null_perf_irq(struct pt_regs *regs); ++extern int (*perf_irq)(struct pt_regs *regs); ++ ++/* Per-counter configuration as set via oprofilefs. */ ++struct op_counter_config { ++ unsigned long enabled; ++ unsigned long event; ++ unsigned long count; ++ /* Dummies because I am too lazy to hack the userspace tools. */ ++ unsigned long kernel; ++ unsigned long user; ++ unsigned long exl; ++ unsigned long unit_mask; ++}; ++ ++/* Per-architecture configury and hooks. */ ++struct op_nds32_model { ++ void (*reg_setup) (struct op_counter_config *); ++ void (*cpu_setup) (void * dummy); ++ int (*init)(void); ++ void (*exit)(void); ++ void (*cpu_start)(void *args); ++ void (*cpu_stop)(void *args); ++ char *cpu_type; ++ unsigned char num_counters; ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/oprofile/op_model_nds32.c linux-3.4.110/arch/nds32/oprofile/op_model_nds32.c +--- linux-3.4.110.orig/arch/nds32/oprofile/op_model_nds32.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/oprofile/op_model_nds32.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,400 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2004, 2005 by Ralf Baechle ++ * Copyright (C) 2005 by MIPS Technologies, Inc. ++ * Copyright (C) 2007 Andes Technology Corporation ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "op_impl.h" ++ ++#ifdef CONFIG_PLAT_AG102 ++#include ++#define NDS32_PERFCNTR_IRQA 23 ++#define NDS32_PERFCNTR_IRQB 22 ++#else ++#define NDS32_PERFCNTR_IRQA 10 ++#endif ++#define NDS32_PERFCTL_EN(num) (1 << num) ++#define NDS32_PERFCTL_INTEN (1UL << 3) ++#define NDS32_PERFCTL_OVERFLOW (1UL << 6) ++#define NDS32_PERFCTL_NOKERNEL (1UL << 9) ++#define NDS32_PERFCTL_NOUSER (1UL << 12) ++#define NDS32_PERFCTL_EVENT_0(event) (event << 15) ++#define NDS32_PERFCTL_EVENT_1(event) (event << 16) ++#define NDS32_PERFCTL_EVENT_2(event) (event << 22) ++ ++static unsigned long long ov0, ov1, ov2; ++static int syscall = 0; ++ ++struct pmu_counter { ++ volatile unsigned long ovf; ++ unsigned long reset_counter; ++}; ++ ++enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS }; ++ ++static struct pmu_counter results[MAX_COUNTERS]; ++ ++static inline unsigned int read_perfcntr(int counter) ++{ ++ switch (counter) { ++ case PFMC0: ++ return GET_PFMC0(); ++ break; ++ case PFMC1: ++ return GET_PFMC1(); ++ break; ++ case PFMC2: ++ return GET_PFMC2(); ++ break; ++ default: ++ printk(KERN_ERR ++ "Oprofile read_perfcntr: CPU has no %d performance counters\n", ++ counter); ++ } ++ ++ return 0; ++} ++ ++static inline unsigned int read_perfctrl(void) ++{ ++ return GET_PFM_CTL(); ++} ++ ++static inline void write_perfcntr(int counter, unsigned int value) ++{ ++ switch (counter) { ++ case PFMC0: ++ SET_PFMC0(value); ++ break; ++ case PFMC1: ++ SET_PFMC1(value); ++ break; ++ case PFMC2: ++ SET_PFMC2(value); ++ break; ++ default: ++ printk(KERN_ERR ++ "Oprofile write_perfcntr: CPU has no %d performance counters\n", ++ counter); ++ } ++} ++ ++static inline void write_perfctrl(unsigned int value) ++{ ++ SET_PFM_CTL(value); ++} ++ ++struct op_nds32_model op_model_nds32_ops; ++ ++static struct nds32_register_config { ++ unsigned int control[3]; ++ unsigned int counter[3]; ++} reg; ++ ++/* Compute all of the registers in preparation for enabling profiling. */ ++ ++static void nds32_reg_setup(struct op_counter_config *ctr) ++{ ++ unsigned int counters = op_model_nds32_ops.num_counters; ++ int i; ++ ++ /* Compute the performance counter control word. */ ++ /* For now count kernel and user mode */ ++ for (i = 0; i < counters; i++) { ++ reg.control[i] = 0; ++ reg.counter[i] = 0; ++ ++ if (!ctr[i].enabled) ++ continue; ++ ++ switch (i) { ++ case 0: ++ reg.control[i] = NDS32_PERFCTL_EVENT_0(ctr[i].event) | ++ (NDS32_PERFCTL_INTEN << i); ++ break; ++ case 1: ++ reg.control[i] = NDS32_PERFCTL_EVENT_1(ctr[i].event) | ++ (NDS32_PERFCTL_INTEN << i); ++ break; ++ case 2: ++ reg.control[i] = NDS32_PERFCTL_EVENT_2(ctr[i].event) | ++ (NDS32_PERFCTL_INTEN << i); ++ break; ++ default: ++ printk(KERN_ERR ++ "Oprofile nds32_reg_setup: CPU has no %d performance counters\n", ++ i); ++ } ++ if (!(ctr[i].kernel)) ++ reg.control[i] |= (NDS32_PERFCTL_NOKERNEL << i); ++ if (!(ctr[i].user)) ++ reg.control[i] |= (NDS32_PERFCTL_NOUSER << i); ++ reg.counter[i] = -ctr[i].count; ++ } ++} ++ ++/* Program all of the registers in preparation for enabling profiling. */ ++ ++static void nds32_cpu_setup(void *args) ++{ ++ unsigned int counters = op_model_nds32_ops.num_counters; ++ ++ switch (counters) { ++ case 3: ++ write_perfcntr(2, reg.counter[2]); ++ case 2: ++ write_perfcntr(1, reg.counter[1]); ++ case 1: ++ write_perfcntr(0, reg.counter[0]); ++ } ++ write_perfctrl(0); ++} ++ ++/* Start all counters on current CPU */ ++static void nds32_cpu_start(void *args) ++{ ++ unsigned int counters = op_model_nds32_ops.num_counters; ++ unsigned int value = 0; ++ ++ switch (counters) { ++ case 3: ++ if (reg.control[2]) ++ value |= (NDS32_PERFCTL_EN(2) | reg.control[2]); ++ case 2: ++ if (reg.control[1]) ++ value |= (NDS32_PERFCTL_EN(1) | reg.control[1]); ++ case 1: ++ if (reg.control[0]) ++ value |= (NDS32_PERFCTL_EN(0) | reg.control[0]); ++ } ++ write_perfctrl(value); ++} ++ ++/* Stop all counters on current CPU */ ++static void nds32_cpu_stop(void *args) ++{ ++ write_perfctrl(0); ++} ++ ++static irqreturn_t nds32_perfcount_handler(int irq, void *dev_id) ++{ ++ unsigned int control, i; ++ ++ control = read_perfctrl(); ++ write_perfctrl(0); ++ ++ if (syscall) { ++ if (control & PFM_CTL_mskOVF0) ++ ov0++; ++ if (control & PFM_CTL_mskOVF1) ++ ov1++; ++ if (control & PFM_CTL_mskOVF2) ++ ov2++; ++ } else { ++ for (i = 0; i < MAX_COUNTERS; i++) { ++ if ((control & (NDS32_PERFCTL_INTEN << i)) ++ && (control & (NDS32_PERFCTL_OVERFLOW << i))) { ++ oprofile_add_sample(get_irq_regs(), i); ++ write_perfcntr(i, reg.counter[i]); ++ break; ++ } ++ } ++ } ++ write_perfctrl(control); ++ ++ return IRQ_HANDLED; ++} ++ ++static inline int n_counters(void) ++{ ++ return 3; ++} ++ ++static inline void reset_counters(int counters) ++{ ++ switch (counters) { ++ case 3: ++ write_perfcntr(2, 0); ++ case 2: ++ write_perfcntr(1, 0); ++ case 1: ++ write_perfcntr(0, 0); ++ } ++ write_perfctrl(0); ++} ++ ++static int __init nds32_init(void) ++{ ++ int counters, ret; ++ ++ counters = n_counters(); ++ if (counters == 0) { ++ printk(KERN_ERR "Oprofile: CPU has no performance counters\n"); ++ return -ENODEV; ++ } ++ ++ reset_counters(counters); ++ ++ op_model_nds32_ops.num_counters = counters; ++ op_model_nds32_ops.cpu_type = "nds32"; ++ ++ ret = ++ request_irq(NDS32_PERFCNTR_IRQA, nds32_perfcount_handler, ++ IRQF_SHARED, "NDS32 PERFCNTR", (void *)results); ++ if (ret < 0) { ++ printk(KERN_ERR "oprofile: unable to request IRQ%d\n", ++ NDS32_PERFCNTR_IRQA); ++ return ret; ++ } ++#ifdef CONFIG_PLAT_AG102 ++ unsigned int tmp; ++ /* Set NDS32_PERFCNTR_IRQA to bind on core A */ ++ tmp = ++ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + ++ ((NDS32_PERFCNTR_IRQA >> 4) << 2)); ++ tmp &= ~(0x11 << ((NDS32_PERFCNTR_IRQA & ~0x10) * 2)); ++ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + ++ ((NDS32_PERFCNTR_IRQA >> 4) << 2)) = tmp; ++ tmp = ++ (*(volatile unsigned long *)(AMIC_VA_BASE + CPUDC)) & ~(1 << ++ NDS32_PERFCNTR_IRQA); ++ *(volatile unsigned long *)(AMIC_VA_BASE + CPUDC) = tmp; ++ ++ ret = ++ request_irq(NDS32_PERFCNTR_IRQB, nds32_perfcount_handler, ++ IRQF_SHARED, "NDS32 PERFCNTR", (void *)results); ++ if (ret < 0) { ++ printk(KERN_ERR "oprofile: unable to request IRQ%d\n", ++ NDS32_PERFCNTR_IRQB); ++ return ret; ++ } ++ /* Set NDS32_PERFCNTR_IRQB to bind on core B */ ++ tmp = ++ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + ++ ((NDS32_PERFCNTR_IRQB >> 4) << 2)); ++ tmp &= ~(0x11 << ((NDS32_PERFCNTR_IRQB & ~0x10) * 2)); ++ tmp |= 1 << ((NDS32_PERFCNTR_IRQB & ~0x10) * 2); ++ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + ++ ((NDS32_PERFCNTR_IRQB >> 4) << 2)) = tmp; ++ tmp = ++ (*(volatile unsigned long *)(AMIC_VA_BASE + CPUDC)) & ~(1 << ++ NDS32_PERFCNTR_IRQB); ++ *(volatile unsigned long *)(AMIC_VA_BASE + CPUDC) = tmp; ++#endif ++ ++ return 0; ++} ++ ++static void nds32_exit(void) ++{ ++ reset_counters(op_model_nds32_ops.num_counters); ++ ++ free_irq(NDS32_PERFCNTR_IRQA, results); ++#ifdef CONFIG_PLAT_AG102 ++ free_irq(NDS32_PERFCNTR_IRQB, results); ++#endif ++} ++ ++void sys_pfmctl(int event0, int event1, int event2, int start) ++{ ++ unsigned int ctl = 0; ++ ++ if (start) { ++ syscall = 1; ++ if (event0 >= 0) ++ ctl |= ++ (NDS32_PERFCTL_EVENT_0(event0) | ++ (NDS32_PERFCTL_INTEN << 0) | NDS32_PERFCTL_EN(0)); ++ if (event1 >= 0) ++ ctl |= ++ (NDS32_PERFCTL_EVENT_1(event1) | ++ (NDS32_PERFCTL_INTEN << 1) | NDS32_PERFCTL_EN(1)); ++ if (event2 >= 0) ++ ctl |= ++ (NDS32_PERFCTL_EVENT_2(event2) | ++ (NDS32_PERFCTL_INTEN << 2) | NDS32_PERFCTL_EN(2)); ++ } else { ++ syscall = 0; ++ if (event0 >= 0) ++ ctl &= ++ ~((NDS32_PERFCTL_INTEN << 0) | NDS32_PERFCTL_EN(0)); ++ if (event1 >= 0) ++ ctl &= ++ ~((NDS32_PERFCTL_INTEN << 1) | NDS32_PERFCTL_EN(1)); ++ if (event2 >= 0) ++ ctl &= ++ ~((NDS32_PERFCTL_INTEN << 2) | NDS32_PERFCTL_EN(2)); ++ } ++ ++ write_perfctrl(ctl); ++ ++} ++ ++int sys_getpfm(struct pcounter __user * p) ++{ ++ struct pcounter pfm; ++ unsigned int control; ++ ++ control = read_perfctrl(); ++ write_perfctrl(0); ++ ++ pfm.pfm0 = ov0 << 32 | GET_PFMC0(); ++ pfm.pfm1 = ov1 << 32 | GET_PFMC1(); ++ pfm.pfm2 = ov2 << 32 | GET_PFMC2(); ++ ++ if (copy_to_user(p, &pfm, sizeof(pfm))) ++ return -EFAULT; ++ ++ write_perfctrl(control); ++ ++ return 0; ++} ++ ++int sys_setpfm(int pfm0, int pfm1, int pfm2, struct pcounter __user * p) ++{ ++ struct pcounter pfm; ++ unsigned int control; ++ ++ control = read_perfctrl(); ++ write_perfctrl(0); ++ ++ if (copy_from_user(&pfm, p, sizeof(pfm))) ++ return -EFAULT; ++ ++ if (pfm0) { ++ SET_PFMC0((unsigned int)(pfm.pfm0 & 0xffffffff)); ++ ov0 = pfm.pfm0 >> 32; ++ } ++ if (pfm1) { ++ SET_PFMC1((unsigned int)(pfm.pfm1 & 0xffffffff)); ++ ov1 = pfm.pfm1 >> 32; ++ } ++ if (pfm2) { ++ SET_PFMC2((unsigned int)(pfm.pfm2 & 0xffffffff)); ++ ov2 = pfm.pfm2 >> 32; ++ } ++ ++ write_perfctrl(control); ++ ++ return 0; ++} ++ ++struct op_nds32_model op_model_nds32_ops = { ++ .reg_setup = nds32_reg_setup, ++ .cpu_setup = nds32_cpu_setup, ++ .init = nds32_init, ++ .exit = nds32_exit, ++ .cpu_start = nds32_cpu_start, ++ .cpu_stop = nds32_cpu_stop, ++}; +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/cpu-fcs.c linux-3.4.110/arch/nds32/platforms/ag101/cpu-fcs.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/cpu-fcs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/cpu-fcs.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,401 @@ ++/* ++ * linux/arch/nds32/platforms/ag101/cpu-fcs.c ++ * ++ * Copyright (C) 2002,2003 Intrinsyc Software ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * History: ++ * 31-Jul-2002 : Initial version [FB] ++ * 29-Jan-2003 : added PXA255 support [FB] ++ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) ++ * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.) ++ * ++ * Note: ++ * This driver may change the memory bus clock rate, but will not do any ++ * platform specific access timing changes... for example if you have flash ++ * memory connected to CS0, you will need to register a platform specific ++ * notifier which will adjust the memory access strobes to maintain a ++ * minimum strobe width. ++ * ++ */ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define NDS32_FCS_IRQ 8 ++#define AG101_MIN_FREQ 100000 ++#define AG101_MAX_FREQ 400000 ++#define OSC_KHZ 10000 /* 10 MHz AG101 */ ++ ++#define USE_CACHE 0 ++struct ag101_freq_struct { ++ ++ unsigned int khz; /* cpu_clk in khz */ ++ unsigned int pll; /* pll mul */ ++ unsigned int div; /* ahb div */ ++ unsigned int frange; /* pll1 freq range */ ++}; ++ ++struct ag101_freq_struct ag101_run_freqs[] = { ++ ++ /* khz , pll, div, frange pll/cpu/ahb/apb */ ++ {100000, 10, 2, 0}, /* 400/400/050/025 */ ++ {200000, 20, 4, 1}, /* 400/400/050/025 */ ++ {300000, 30, 6, 2}, /* 400/400/050/025 */ ++ {400000, 40, 8, 2}, /* 400/400/050/025 */ ++ {500000, 50, 10, 3}, /* 500/500/050/025 */ ++ {0,} ++}; ++ ++#define NUM_RUN_FREQS ARRAY_SIZE( ag101_run_freqs) ++static struct cpufreq_frequency_table ag101_run_freq_table[NUM_RUN_FREQS + 1]; ++ ++/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ ++static struct ag101_freq_struct ag101_turbo_freqs[] = { ++ ++ /* khz , pll, div, frange pll/cpu/ahb/apb */ ++ {100000, 10, 2, 0}, /* 400/400/050/025 */ ++ {200000, 20, 4, 1}, /* 400/400/050/025 */ ++ {300000, 30, 6, 2}, /* 400/400/050/025 */ ++ {400000, 40, 8, 2}, /* 400/400/050/025 */ ++ {500000, 50, 10, 3}, /* 500/500/050/025 */ ++ {0,} ++}; ++ ++#define NUM_TURBO_FREQS ARRAY_SIZE( ag101_turbo_freqs) ++static struct cpufreq_frequency_table ag101_turbo_freq_table[NUM_TURBO_FREQS + ++ 1]; ++ ++/* Generic helper function get CPU clocks in kHz */ ++unsigned int ag101_cpufreq_get(unsigned int dummy) ++{ ++ ++ unsigned int mul = (REG32(PMU_FTPMU010_VA_BASE + 0x30) >> 3UL) & 0x01ff; /* pll1 mul */ ++ return OSC_KHZ * mul; ++} ++ ++/* find a valid frequency point */ ++static int ag101_verify_policy(struct cpufreq_policy *policy) ++{ ++ ++ struct cpufreq_frequency_table *ag101_freqs_table; ++ ++ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { ++ ++ ag101_freqs_table = ag101_run_freq_table; ++ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { ++ ++ ag101_freqs_table = ag101_turbo_freq_table; ++ } else { ++ printk ++ ("CPU PXA: Unknown policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); ++ ag101_freqs_table = ag101_run_freq_table; ++ } ++ ++ printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min, ++ policy->max); ++ ++ return cpufreq_frequency_table_verify(policy, ag101_freqs_table); ++} ++ ++static int cal_edivahbclk(int div) ++{ ++ ++ switch (div) { ++ ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ return --div; ++ case 8: ++ return 8; ++ case 10: ++ return 9; ++ case 12: ++ return 10; ++ case 14: ++ return 11; ++ case 15: ++ return 12; ++ case 18: ++ return 13; ++ case 20: ++ return 14; ++ default: ++ printk("Error: No such CPU/AHB frequency ratio %d", div); ++ } ++ ++ return 9; ++} ++ ++void start_fcs(unsigned int pll, unsigned int frange, unsigned int div) ++{ ++ ++ /* PDLLCR0 */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x30) &= ~0x00003ff8; /* clear PLL1NS and PLL1FRANG fields */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (pll << 3); /* set PLL1NS */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (frange << 12); /* set PLL1FRANG */ ++ ++ /* PMODE */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~0x000000ff; /* clear EDIVAHBCLK field */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (div << 4); /* set EDIVAHBCLK [7:4] */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (1UL << 2); /* [2]: FCS */ ++ ++ __asm__ __volatile__("msync all"); ++ __asm__ __volatile__("isb"); ++ __asm__ __volatile__("standby wake_grant"); ++ REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (1UL << 16); /* PDLLCR0 bit[16]==1:disable dll */ ++} ++ ++void end_fcs(void) ++{ ++ ++ /* Leave this function as a place marker. */ ++} ++ ++static int nds32_fcs_handler(int irq, void *dev_id) ++{ ++ ++ REG32(PMU_FTPMU010_VA_BASE + 0x20) = (1UL << 17); /* Clear IntFCS PMSR[17] */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(1UL << 2); /* Power Mode Register */ ++ ++ return 1; ++} ++ ++static int ag101_speedstep(int idx) ++{ ++ ++ unsigned int pll, frange, div; ++ unsigned long flags = 0; ++ int irq, saved_irq_mask; ++ void (*do_fcs) (unsigned int pll, unsigned int frange, ++ unsigned int div); ++ ++#if USE_CACHE ++ ++ int i; ++ int line_size = CACHE_LINE_SIZE(ICACHE); ++ unsigned long start = ((unsigned long)start_fcs) & ~(line_size - 1); ++ unsigned long end = ++ (((unsigned long)end_fcs) + line_size) & ~(line_size - 1); ++ ++ printk("&start_fcs(): 0x%08lx, aligned to: 0x%08lx\n", ++ (unsigned long)start_fcs, start); ++ printk("&end_fcs(): 0x%08lx, aligned to: 0x%08lx\n", ++ (unsigned long)end_fcs, end); ++ ++ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK":: ++ "r" (i):"memory"); ++ ++ do_fcs = start_fcs; ++#else ++ unsigned long buf, aligned_buf, len = PAGE_SIZE; ++ ++ buf = (unsigned long)kmalloc(0x100000 + 1000, GFP_KERNEL); ++ if (!buf) ++ printk("Error: kmalloc( base) failed\n"); ++ ++ aligned_buf = (buf + 0x100000 - 1) & 0xFFF00000; ++ ++ if (sys_lmmap(LM_ILM, aligned_buf, aligned_buf + 0x1000, 0, NULL)) { ++ printk("Error: lmmap failed, can't scale frequency.\n"); ++#ifdef CONFIG_CPU_FREQ_DEBUG ++ WARN_ON(1); ++#endif ++ return 0; ++ } ++ ++ if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 9) ++ len = 0x400; ++ else if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 10) ++ len = 0x800; ++ memcpy((unsigned char *)aligned_buf, (unsigned char *)start_fcs, len); ++ ++ do_fcs = (void *)aligned_buf; ++#endif ++ pll = ag101_run_freqs[idx].pll; ++ div = cal_edivahbclk(ag101_run_freqs[idx].div); ++ frange = ag101_run_freqs[idx].frange; ++ ++ irq = ++ request_irq(NDS32_FCS_IRQ, nds32_fcs_handler, ++ IRQF_DISABLED | IRQF_TRIGGER_FALLING, ++ "NDS32 Frequency Change Sequence", ++ (void *)ag101_run_freqs); ++ if (irq < 0) ++ printk(KERN_ERR "Error: unable to request FCS IRQ%d\n", ++ NDS32_FCS_IRQ); ++ ++ local_irq_save(flags); ++ ++ saved_irq_mask = REG32(INTC_FTINTC010_VA_BASE + 0x04); ++ REG32(INTC_FTINTC010_VA_BASE + 0x04) = (1UL << NDS32_FCS_IRQ); ++ ++ do_fcs(pll, frange, div); ++ ++ REG32(INTC_FTINTC010_VA_BASE + 0x04) = saved_irq_mask; ++ ++ local_irq_restore(flags); ++ free_irq(NDS32_FCS_IRQ, ag101_run_freqs); ++ ++#if USE_CACHE ++ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory"); ++#else ++ if (sys_lmunmap(aligned_buf, 0)) ++ printk("Error: lmunmap failed\n"); ++ ++ kfree((void *)buf); ++#endif ++ return 1; ++} ++ ++static int ag101_set_target(struct cpufreq_policy *policy, ++ unsigned int target_freq, unsigned int relation) ++{ ++ ++ unsigned int idx; ++ struct cpufreq_frequency_table *ag101_freqs_table; ++ struct ag101_freq_struct *ag101_freq_settings; ++ struct cpufreq_freqs freqs; ++ ++ /* Get the current policy */ ++ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { ++ ++ ag101_freq_settings = ag101_run_freqs; ++ ag101_freqs_table = ag101_run_freq_table; ++ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { ++ ++ ag101_freq_settings = ag101_turbo_freqs; ++ ag101_freqs_table = ag101_turbo_freq_table; ++ } else { ++ printk ++ ("Unknown FCS policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); ++ ag101_freq_settings = ag101_run_freqs; ++ ag101_freqs_table = ag101_run_freq_table; ++ } ++ ++ /* Lookup the next frequency */ ++ if (cpufreq_frequency_table_target ++ (policy, ag101_freqs_table, target_freq, relation, &idx)) ++ return -EINVAL; ++ ++ freqs.old = policy->cur; ++ freqs.new = ag101_freq_settings[idx].khz; ++ freqs.cpu = policy->cpu; ++ ++ /* ++ * Tell everyone what we're about to do... ++ * you should add a notify client with any platform specific ++ * Vcc changing capability ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); ++ ++ if (freqs.new != freqs.old) { ++ if (!ag101_speedstep(idx)) ++ return -ENODEV; ++ } ++ ++ /* ++ * Tell everyone what we've just done... ++ * you should add a notify client with any platform specific ++ * SDRAM refresh timer adjustments ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); ++ ++ return 0; ++} ++ ++static int ag101_cpufreq_init(struct cpufreq_policy *policy) ++{ ++ ++ int i; ++ /* set default policy and cpuinfo */ ++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; ++ policy->policy = CPUFREQ_POLICY_PERFORMANCE; ++ policy->cpuinfo.max_freq = AG101_MAX_FREQ; ++ policy->cpuinfo.min_freq = AG101_MIN_FREQ; ++ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ ++ policy->cur = ag101_cpufreq_get(0); /* current freq */ ++ policy->min = policy->max = policy->cur; ++ ++ /* Generate the run cpufreq_frequency_table struct */ ++ for (i = 0; i < NUM_RUN_FREQS; i++) { ++ ++ ag101_run_freq_table[i].frequency = ag101_run_freqs[i].khz; ++ ag101_run_freq_table[i].index = i; ++ } ++ ++ ag101_run_freq_table[i].frequency = CPUFREQ_TABLE_END; ++ ++ /* Generate the turbo cpufreq_frequency_table struct */ ++ for (i = 0; i < NUM_TURBO_FREQS; i++) { ++ ++ ag101_turbo_freq_table[i].frequency = ag101_turbo_freqs[i].khz; ++ ag101_turbo_freq_table[i].index = i; ++ } ++ ++ ag101_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; ++ ++ printk("CPU frequency change support initialized\n"); ++ ++ return 0; ++} ++ ++static struct cpufreq_driver ag101_cpufreq_driver = { ++ ++ .verify = ag101_verify_policy, ++ .target = ag101_set_target, ++ .init = ag101_cpufreq_init, ++ .get = ag101_cpufreq_get, ++ .name = "AG101", ++}; ++ ++static int __init ag101_cpu_init(void) ++{ ++ ++ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) { ++ ++ /* Clear IntFS, IntFCS and irq8 */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x20) = (1UL << 16); ++ return cpufreq_register_driver(&ag101_cpufreq_driver); ++ } else ++ return -ENODEV; ++} ++ ++static void __exit ag101_cpu_exit(void) ++{ ++ ++ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) ++ cpufreq_unregister_driver(&ag101_cpufreq_driver); ++} ++ ++MODULE_AUTHOR("Andes Technology Corporation"); ++MODULE_DESCRIPTION("CPU frequency changing driver for the AG101 architecture"); ++MODULE_LICENSE("GPL"); ++module_init(ag101_cpu_init); ++module_exit(ag101_cpu_exit); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/devices.c linux-3.4.110/arch/nds32/platforms/ag101/devices.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/devices.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,94 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++const struct map_desc platform_io_desc[] __initdata = { ++ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, ++ PAGE_SIZE, MT_DEVICE_NCB}, ++ {KMI_FTKBC010_0_VA_BASE, KMI_FTKBC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCNB}, ++ {KMI_FTKBC010_1_VA_BASE, KMI_FTKBC010_1_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCNB}, ++ {USB_FUSB220_0_VA_BASE, USB_FUSB220_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCNB}, ++ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x000FF000, MT_DEVICE_NCB}, ++ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} ++}; ++ ++static void __init platform_map_io(void) ++{ ++ iotable_init((struct map_desc *)platform_io_desc, ++ ARRAY_SIZE(platform_io_desc)); ++} ++ ++static struct uart_port uart0 = { ++ .membase = (void __iomem *)UART0_VA_BASE, ++ .irq = UART0_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 0, ++ .mapbase = UART0_PA_BASE, ++}; ++ ++static struct uart_port uart1 = { ++ .membase = (void __iomem *)UART1_VA_BASE, ++ .irq = UART1_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 1, ++ .mapbase = UART1_PA_BASE, ++}; ++ ++void ag101_calc_ahb_clk(void); ++static void __init soc_init(void) ++{ ++ ag101_calc_ahb_clk(); ++ early_serial_setup(&uart0); ++ early_serial_setup(&uart1); ++} ++ ++MACHINE_START(FARADAY, PLATFORM_NAME) ++ .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = platform_init_irq,.timer = &platform_timer, /* defined in timer.c */ ++ .init_machine = soc_init, MACHINE_END +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/fia320.c linux-3.4.110/arch/nds32/platforms/ag101/fia320.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/fia320.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/fia320.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,103 @@ ++/* ++ * linux/arch/nds32/platforms/ag101/fia320.c ++ * ++ * Faraday A320D Platform Dependent Functions ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/26/2005 Created ++ * Peter Liao 09/29/2005 Port dynamically getting AHB clock ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef CONFIG_AUTO_SYS_CLK ++#include ++#define AG101B0 (0x0c020003) ++ ++/* ++ * Table for ahb divisor, PMODE[07:04] ++ */ ++static const int ahb_div[16] = { ++ 1, 2, 3, 4, 5, 6, 3, 5, ++ 8, 10, 12, 14, 15, 18, 20, -1 ++}; ++ ++/* ag101_get_ahb_clk() ++ * ++ * return AHB clock in Hz. ++ */ ++static int ahbclk; ++void ag101_calc_ahb_clk(void) ++{ ++ /* ++ * FIXME: We should not put AG101 term in here, Harry@Oct.23.2007 ++ */ ++ const unsigned int osc = 10; // OSC in MHz ++ unsigned int mul, div, cpu, pll; ++ unsigned int ahb = 0; // ahb clk in Hz ++ unsigned int cpu_ver; ++ ++ mul = (REG32(PMU_FTPMU010_0_VA_BASE + 0x30) >> 3) & 0x01ff; // pll1 mul ++ div = (REG32(PMU_FTPMU010_0_VA_BASE + 0x4) >> 8) & 0x000f; // pll1 div ++ ahb = (REG32(PMU_FTPMU010_0_VA_BASE + 0x4) >> 4) & 0x000f; // ahb div ++ div += 1; ++ ++ pll = (osc * mul / div); // depend on OSC. ++ ++ //AG101B0 PLL divider fix ++ cpu_ver = __nds32__mfsr(NDS32_SR_CPU_VER); ++ if (AG101B0 == cpu_ver) ++ pll >>= 1; ++ ++ if (-1 != ahb_div[ahb]) { ++ if ((ahb == 6) || (ahb == 7)) // special cases for 3:2 & 5:2 ++ cpu = pll >> 1; // divide by 2 ++ else ++ cpu = pll; ++ ++ ahb = pll / ahb_div[ahb]; // become ahb clk in MHz. ++ ++ printk("AG101 auto-detected AHB clock: CPU/AHB=%uMHz/%uMHz\n", ++ cpu, ahb); ++ ahb *= 1000000; // become ahb clk in Hz. ++ ahbclk = (int)ahb; ++ } else { ++ printk("Unknown AHB divisor:0x%x\n", ahb); ++ ahbclk = 0; ++ } ++ ++ ahbclk = (int)ahb; ++} ++ ++int ag101_get_ahb_clk(void) ++{ ++ return ahbclk; ++} ++ ++EXPORT_SYMBOL(ag101_get_ahb_clk); ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/freq-scaling.c linux-3.4.110/arch/nds32/platforms/ag101/freq-scaling.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/freq-scaling.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/freq-scaling.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,367 @@ ++/* ++ * linux/arch/nds32/platforms/ag101/cpu-fcs.c ++ * ++ * Copyright (C) 2002,2003 Intrinsyc Software ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * History: ++ * 31-Jul-2002 : Initial version [FB] ++ * 29-Jan-2003 : added PXA255 support [FB] ++ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) ++ * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.) ++ * ++ * Note: ++ * This driver may change the memory bus clock rate, but will not do any ++ * platform specific access timing changes... for example if you have flash ++ * memory connected to CS0, you will need to register a platform specific ++ * notifier which will adjust the memory access strobes to maintain a ++ * minimum strobe width. ++ * ++ */ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define NDS32_FCS_IRQ 8 ++#define AG101_MIN_FREQ 70000 ++#define AG101_MAX_FREQ 420000 ++#define OSC_KHZ 10000 /* 10 MHz AG101 */ ++ ++#define USE_CACHE 0 ++struct ag101_freq_struct { ++ ++ unsigned int khz; /* cpu_clk in khz */ ++ unsigned int sf; /* scaling factor */ ++ unsigned int cr; /* clock ratio */ ++}; ++ ++struct ag101_freq_struct ag101_run_freqs[] = { ++ ++ /* khz , sf, cr pll/cpu/ahb/apb */ ++ {AG101_MAX_FREQ / 6, 6, 1}, /* 420/070/070/035 */ ++ {AG101_MAX_FREQ / 1, 1, 6}, /* 420/420/070/035 */ ++ {0} ++}; ++ ++#define NUM_RUN_FREQS ARRAY_SIZE( ag101_run_freqs) ++static struct cpufreq_frequency_table ag101_run_freq_table[NUM_RUN_FREQS + 1]; ++ ++/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ ++static struct ag101_freq_struct ag101_turbo_freqs[] = { ++ ++ /* khz , sf, cr pll/cpu/ahb/apb */ ++ {AG101_MAX_FREQ / 6, 6, 1}, /* 420/070/070/035 */ ++ {AG101_MAX_FREQ / 1, 1, 6}, /* 420/420/070/035 */ ++ {0} ++}; ++ ++#define NUM_TURBO_FREQS ARRAY_SIZE( ag101_turbo_freqs) ++static struct cpufreq_frequency_table ag101_turbo_freq_table[NUM_TURBO_FREQS + ++ 1]; ++ ++/* Generic helper function get CPU clocks in kHz */ ++unsigned int ag101_cpufreq_get(unsigned int dummy) ++{ ++ ++ unsigned int pll = (REG32(PMU_FTPMU010_VA_BASE + 0x30) >> 3UL) & 0x01ff; /* pll */ ++ unsigned int sf = (REG32(PMU_FTPMU010_VA_BASE + 0x0c) >> 8UL) & 0x0f; /* scaling factor */ ++ ++ return OSC_KHZ * pll / (sf + 1); ++} ++ ++/* find a valid frequency point */ ++static int ag101_verify_policy(struct cpufreq_policy *policy) ++{ ++ ++ struct cpufreq_frequency_table *ag101_freqs_table; ++ ++ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { ++ ++ ag101_freqs_table = ag101_run_freq_table; ++ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { ++ ++ ag101_freqs_table = ag101_turbo_freq_table; ++ } else { ++ printk ++ ("CPU PXA: Unknown policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); ++ ag101_freqs_table = ag101_run_freq_table; ++ } ++ ++ printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min, ++ policy->max); ++ ++ return cpufreq_frequency_table_verify(policy, ag101_freqs_table); ++} ++ ++void start_fcs(unsigned int sf, unsigned cr) ++{ ++ ++ /* set EFSF in PMODE [11:8] */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(0xfUL << 8); ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (sf << 8); ++ ++ /* set EDIVAHBCLK [7:4] */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(0xffUL << 0); ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (cr << 4); ++ ++ /* PMR[1]: scaling mode */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (1UL << 1); ++ ++ __asm__ __volatile__("msync all"); ++ __asm__ __volatile__("isb"); ++ __asm__ __volatile__("standby wake_grant"); ++ // REG32( PMU_FTPMU010_VA_BASE + 0x30) |= ( 1UL << 16); /* PDLLCR0 bit[16]==1:disable dll */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(1UL << 1); /* Power Mode Register */ ++} ++ ++void end_fcs(void) ++{ ++ ++ /* Leave this function as a place marker. */ ++} ++ ++static int cal_edivahbclk(int div) ++{ ++ ++ switch (div) { ++ ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ case 6: ++ return --div; ++ case 8: ++ return 8; ++ case 10: ++ return 9; ++ case 12: ++ return 10; ++ case 14: ++ return 11; ++ case 15: ++ return 12; ++ case 18: ++ return 13; ++ case 20: ++ return 14; ++ default: ++ printk("Error: No such CPU/AHB frequency ratio %d", div); ++ } ++ ++ return 9; ++} ++ ++static int ag101_speedstep(int idx) ++{ ++ ++ unsigned int sf, cr; ++ unsigned long flags = 0; ++ void (*do_fcs) (unsigned int efsf, unsigned int edivhbaclk); ++ ++#if USE_CACHE ++ ++ int i; ++ int line_size = CACHE_LINE_SIZE(ICACHE); ++ unsigned long start = ((unsigned long)start_fcs) & ~(line_size - 1); ++ unsigned long end = ++ (((unsigned long)end_fcs) + line_size) & ~(line_size - 1); ++ ++ printk("&start_fcs(): 0x%08lx, aligned to: 0x%08lx\n", ++ (unsigned long)start_fcs, start); ++ printk("&end_fcs(): 0x%08lx, aligned to: 0x%08lx\n", ++ (unsigned long)end_fcs, end); ++ ++ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK":: ++ "r" (i):"memory"); ++ ++ do_fcs = start_fcs; ++#else ++ unsigned long buf, aligned_buf, len = PAGE_SIZE; ++ ++ buf = (unsigned long)kmalloc(0x100000 + 1000, GFP_KERNEL); ++ if (!buf) ++ printk("Error: kmalloc( base) failed\n"); ++ ++ aligned_buf = (buf + 0x100000 - 1) & 0xFFF00000; ++ ++ if (sys_lmmap(LM_ILM, aligned_buf, aligned_buf + 0x1000, 0, NULL)) { ++ printk("Error: lmmap failed, can't scale frequency.\n"); ++#ifdef CONFIG_CPU_FREQ_DEBUG ++ WARN_ON(1); ++#endif ++ return 0; ++ } ++ ++ if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 9) ++ len = 0x400; ++ else if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 10) ++ len = 0x800; ++ memcpy((unsigned char *)aligned_buf, (unsigned char *)start_fcs, len); ++ ++ do_fcs = (void *)aligned_buf; ++#endif ++ sf = ag101_run_freqs[idx].sf - 1; ++ cr = cal_edivahbclk(ag101_run_freqs[idx].cr); ++ ++ local_irq_save(flags); ++ do_fcs(sf, cr); ++ local_irq_restore(flags); ++ ++#if USE_CACHE ++ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory"); ++#else ++ if (sys_lmunmap(aligned_buf, 0)) ++ printk("Error: lmunmap failed\n"); ++ ++ kfree((void *)buf); ++#endif ++ return 1; ++} ++ ++static int ag101_set_target(struct cpufreq_policy *policy, ++ unsigned int target_freq, unsigned int relation) ++{ ++ ++ unsigned int idx; ++ struct cpufreq_frequency_table *ag101_freqs_table; ++ struct ag101_freq_struct *ag101_freq_settings; ++ struct cpufreq_freqs freqs; ++ ++ /* Get the current policy */ ++ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { ++ ++ ag101_freq_settings = ag101_run_freqs; ++ ag101_freqs_table = ag101_run_freq_table; ++ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { ++ ++ ag101_freq_settings = ag101_turbo_freqs; ++ ag101_freqs_table = ag101_turbo_freq_table; ++ } else { ++ printk ++ ("Unknown FCS policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); ++ ag101_freq_settings = ag101_run_freqs; ++ ag101_freqs_table = ag101_run_freq_table; ++ } ++ ++ /* Lookup the next frequency */ ++ if (cpufreq_frequency_table_target ++ (policy, ag101_freqs_table, target_freq, relation, &idx)) ++ return -EINVAL; ++ ++ freqs.old = policy->cur; ++ freqs.new = ag101_freq_settings[idx].khz; ++ freqs.cpu = policy->cpu; ++ ++ /* ++ * Tell everyone what we're about to do... ++ * you should add a notify client with any platform specific ++ * Vcc changing capability ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); ++ ++ if (freqs.new != freqs.old) { ++ ++ if (!ag101_speedstep(idx)) ++ return -ENODEV; ++ } ++ ++ /* ++ * Tell everyone what we've just done... ++ * you should add a notify client with any platform specific ++ * SDRAM refresh timer adjustments ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); ++ ++ return 0; ++} ++ ++static int ag101_cpufreq_init(struct cpufreq_policy *policy) ++{ ++ ++ int i; ++ /* set default policy and cpuinfo */ ++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; ++ policy->policy = CPUFREQ_POLICY_PERFORMANCE; ++ policy->cpuinfo.max_freq = AG101_MAX_FREQ; ++ policy->cpuinfo.min_freq = AG101_MIN_FREQ; ++ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ ++ policy->cur = ag101_cpufreq_get(0); /* current freq */ ++ policy->min = policy->max = policy->cur; ++ ++ /* Generate the run cpufreq_frequency_table struct */ ++ for (i = 0; i < NUM_RUN_FREQS; i++) { ++ ++ ag101_run_freq_table[i].frequency = ag101_run_freqs[i].khz; ++ ag101_run_freq_table[i].index = i; ++ } ++ ++ ag101_run_freq_table[i].frequency = CPUFREQ_TABLE_END; ++ ++ /* Generate the turbo cpufreq_frequency_table struct */ ++ for (i = 0; i < NUM_TURBO_FREQS; i++) { ++ ++ ag101_turbo_freq_table[i].frequency = ag101_turbo_freqs[i].khz; ++ ag101_turbo_freq_table[i].index = i; ++ } ++ ++ ag101_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; ++ ++ printk("CPU frequency change support initialized\n"); ++ ++ return 0; ++} ++ ++static struct cpufreq_driver ag101_cpufreq_driver = { ++ ++ .verify = ag101_verify_policy, ++ .target = ag101_set_target, ++ .init = ag101_cpufreq_init, ++ .get = ag101_cpufreq_get, ++ .name = "AG101", ++}; ++ ++static int __init ag101_cpu_init(void) ++{ ++ ++ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) ++ return cpufreq_register_driver(&ag101_cpufreq_driver); ++ else ++ return -ENODEV; ++} ++ ++static void __exit ag101_cpu_exit(void) ++{ ++ ++ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) ++ cpufreq_unregister_driver(&ag101_cpufreq_driver); ++} ++ ++MODULE_AUTHOR("Andes Technology Corporation"); ++MODULE_DESCRIPTION("CPU frequency changing driver for the AG101 architecture"); ++MODULE_LICENSE("GPL"); ++module_init(ag101_cpu_init); ++module_exit(ag101_cpu_exit); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/Kconfig linux-3.4.110/arch/nds32/platforms/ag101/Kconfig +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/Kconfig 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,9 @@ ++menu "AG101 Platform Options" ++ ++config AUTO_SYS_CLK ++ bool "Automatic AHB Clock Detection" ++ default y ++ help ++ Automatic detection of AHB clock ++ ++endmenu +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/Makefile linux-3.4.110/arch/nds32/platforms/ag101/Makefile +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/Makefile 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,5 @@ ++obj-y = devices.o ++obj-$(CONFIG_AUTO_SYS_CLK) += fia320.o ++obj-$(CONFIG_PM) += pm.o sleep.o ++obj-$(CONFIG_AG101_CPU_FREQ_FCS) += cpu-fcs.o ++obj-$(CONFIG_AG101_CPU_FREQ_SCALING_MODE) += freq-scaling.o +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/pm.c linux-3.4.110/arch/nds32/platforms/ag101/pm.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/pm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/pm.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,190 @@ ++/* ++ * AG101 Power Management Routines ++ * ++ * Copyright (c) 2007 Harry Pan ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License. ++ * ++ * Abstract: ++ * ++ * This program is for AG101 power management routines. ++ * It is initail referred from 2.6.11 SA1100 PM driver. ++ * ++ * Revision History: ++ * ++ * Jul.13.2007 Initial code by Harry. ++ */ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++extern void ag101_cpu_sleep(void); ++extern void ag101_cpu_resume(void); ++extern void ag101_cpu_resume2(void); ++ ++#include ++/* ++ * AG101 PMU sleep mode handler. ++ */ ++void ag101_pmu_sleep(void) ++{ ++ int i; ++ static int irq_saves[3]; ++ ++ irq_saves[0] = REG32(INTC_FTINTC010_VA_BASE + 0x4); ++ irq_saves[1] = REG32(INTC_FTINTC010_VA_BASE + 0xc); ++ irq_saves[2] = REG32(INTC_FTINTC010_VA_BASE + 0x10); ++ ++ /* save SDRAM settings */ ++ for (i = 0; i < 0x30; i += 4) ++ REG32(PMU_FTPMU010_VA_BASE + 0x50 + i) = REG32(SDMC_FTSDMC021_VA_BASE + i); //SDRAMC ++ ++ /* set resume return address */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x88) = ++ virt_to_phys(ag101_cpu_resume) | 0x10000000; ++ REG32(PMU_FTPMU010_VA_BASE + 0x8c) = (u32) ag101_cpu_resume2; ++ REG32(PMU_FTPMU010_VA_BASE + 0x80) = GET_L1_PPTB(); ++ ++ /* setup wakeup sources */ ++ REG32(PMU_FTPMU010_VA_BASE + 0x14) |= -1; ++ REG32(PMU_FTPMU010_VA_BASE + 0x10) |= 0x1fff; ++ ++ cpu_dcache_wbinval_all(); ++ cpu_icache_inval_all(); ++ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN); ++ ag101_cpu_sleep(); ++ ++#ifndef CONFIG_ANDES_PAGE_SIZE_8KB ++ ++ if (CPU_IS_N1213_43U1HA0()) { ++ int tmp = 0; ++ /* Downsize cache to bypass cache aliasing issue */ ++ ++ if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096) ++ tmp = 0x02 << SDZ_CTL_offICDZ; ++ ++ if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096) ++ tmp |= 0x02 << SDZ_CTL_offDCDZ; ++ ++ SET_SDZ_CTL(tmp); ++ ISB(); ++ } ++#endif ++ ++ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN); ++ REG32(INTC_FTINTC010_VA_BASE + 0x4) = irq_saves[0]; ++ REG32(INTC_FTINTC010_VA_BASE + 0xc) = irq_saves[1]; ++ REG32(INTC_FTINTC010_VA_BASE + 0x10) = irq_saves[2]; ++} ++ ++static int ag101_pm_valid(suspend_state_t state) ++{ ++ switch (state) { ++ case PM_SUSPEND_ON: ++ case PM_SUSPEND_STANDBY: ++ case PM_SUSPEND_MEM: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++static int ag101_pm_begin(suspend_state_t state) ++{ ++ /* TBD if we need it */ ++ return 0; ++} ++ ++static unsigned long irq_save; ++static inline void setup_wakeup_event(void) ++{ ++ REG32(GPIO_FTGPIO010_VA_BASE + 0x20) = 1; ++ irq_save = REG32(INTC_FTINTC010_VA_BASE + 0x4); ++ REG32(INTC_FTINTC010_VA_BASE + 0x4) &= ~(1 << 19); ++ REG32(INTC_FTINTC010_VA_BASE + 0x4) |= 1 << 13; ++} ++ ++static inline void remove_wakeup_event(void) ++{ ++ REG32(GPIO_FTGPIO010_VA_BASE + 0x30) = 1; ++ REG32(GPIO_FTGPIO010_VA_BASE + 0x20) = 0; ++ REG32(INTC_FTINTC010_VA_BASE + 0x4) = irq_save; ++} ++ ++static inline void cpu_standby(void) ++{ ++ asm __volatile__("standby no_wake_grant"); ++} ++ ++static int ag101_pm_enter(suspend_state_t state) ++{ ++ switch (state) { ++ case PM_SUSPEND_STANDBY: ++ setup_wakeup_event(); ++ cpu_standby(); ++ remove_wakeup_event(); ++ return 0; ++ case PM_SUSPEND_MEM: ++ ag101_pmu_sleep(); ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++/* ++ * Called after processes are frozen, but before we shutdown devices. ++ */ ++static int ag101_pm_prepare(void) ++{ ++ /* TBD if we need it */ ++ return 0; ++} ++ ++/* ++ * Called after devices are wakeuped, but before processes are thawed. ++ */ ++static void ag101_pm_finish(void) ++{ ++ /* TBD if we need it */ ++} ++ ++static void ag101_pm_end(void) ++{ ++ /* TBD if we need it */ ++} ++ ++/* ++ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. ++ */ ++static struct platform_suspend_ops ag101_pm_ops = { ++ .valid = ag101_pm_valid, ++ .begin = ag101_pm_begin, ++ .prepare = ag101_pm_prepare, ++ .enter = ag101_pm_enter, ++ .finish = ag101_pm_finish, ++ .end = ag101_pm_end, ++}; ++ ++static int __init ag101_pm_init(void) ++{ ++ printk("PM driver init\n"); ++ suspend_set_ops(&ag101_pm_ops); ++ REG32(GPIO_FTGPIO010_VA_BASE + 0x30) = 1; ++ REG32(INTC_FTINTC010_VA_BASE + 0x0c) &= ~(1 << 13); ++ REG32(INTC_FTINTC010_VA_BASE + 0x10) &= ~(1 << 13); ++ ++ return 0; ++} ++ ++late_initcall(ag101_pm_init); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101/sleep.S linux-3.4.110/arch/nds32/platforms/ag101/sleep.S +--- linux-3.4.110.orig/arch/nds32/platforms/ag101/sleep.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101/sleep.S 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,118 @@ ++/* ++ * AG101 Assembler Sleep/WakeUp Management Routines ++ * ++ * Copyright (c) 2007 Harry Pan ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License. ++ * ++ * Abstract: ++ * ++ * This program is for AG101 suspend/wakeup. ++ * ++ * Revision History: ++ * ++ * Jul.13.2007 Initial code by Harry. ++ */ ++#include ++#include ++#include ++#include ++ ++ .text ++ ++/* ag101_cpu_suspend() ++ * ++ * Causes AG101 to enter sleep state ++ */ ++ ++ENTRY(ag101_cpu_sleep) ++ pushm $r0, $r30 ++ mfusr $r0, $d0.lo ! $d0 lo byte ++ mfusr $r1, $d0.hi ! $d0 hi byte ++ mfusr $r2, $d1.lo ! $d1 lo byte ++ mfusr $r3, $d1.hi ! $d1 hi byte ++ mfsr $r4, $mr0 ++ mfsr $r5, $mr1 ++ mfsr $r6, $mr4 ++ mfsr $r7, $mr6 ++ mfsr $r8, $mr7 ++ mfsr $r9, $mr8 ++ mfsr $r10, $ir0 ++ mfsr $r11, $ir1 ++ mfsr $r12, $ir2 ++ mfsr $r13, $ir3 ++ mfsr $r14, $ir9 ++ mfsr $r15, $ir10 ++ mfsr $r16, $ir12 ++ mfsr $r17, $ir13 ++ mfsr $r18, $ir14 ++ mfsr $r19, $ir15 ++ pushm $r0, $r19 ++ ++ sethi $r0, hi20(PMU_FTPMU010_0_VA_BASE + 0x84) ++ ori $r2, $r0, lo12(PMU_FTPMU010_0_VA_BASE + 0x84) ++ swi $r31, [$r2] ++ ++ lwi $r2, [$r0+#0x0c] ! sleep mode ++ ori $r2, $r2, #1 ++ swi $r2, [$r0+#0x0c] ! sleep mode ++ standby wake_grant ++1: ++ b 1b ! loop waiting for sleep ++ ++/* ag101_cpu_resume() ++ * ++ * Entry point from boot code back to kernel. ++ * ++ */ ++ ++ENTRY(ag101_cpu_resume) ++ mfsr $r2, $mr0 ++ ori $r2, $r2, #0x6 ++#ifdef CONFIG_ANDES_PAGE_SIZE_8KB ++ ori $r2, $r2, #0x1 ++#endif ++ mtsr $r2, $mr0 ++ ++ sethi $r2, hi20(PMU_FTPMU010_0_PA_BASE + 0x80) ++ ori $r2, $r2, lo12(PMU_FTPMU010_0_PA_BASE + 0x80) ++ lwi $r3, [$r2] ++ lwi $r4, [$r2 + 0xc] ++ mtsr $r3, $mr1 ++ ++ mfsr $r0, $mr8 ++ ori $r0, $r0, #0x1 ++ mtsr $r0, $mr8 ++ ++ sethi $r2, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x88) ++ ori $r2, $r2, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x88) ++ movi $r3, #0x1 ++ swi $r3, [$r2] ++ ++ jral.ton $r4, $r4 ++ ++ENTRY(ag101_cpu_resume2) ++ popm $r0, $r19 ++ mtusr $r0, $d0.lo ! $d0 lo byte ++ mtusr $r1, $d0.hi ! $d0 hi byte ++ mtusr $r2, $d1.lo ! $d1 lo byte ++ mtusr $r3, $d1.hi ! $d1 hi byte ++ mtsr $r4, $mr0 ++ mtsr $r5, $mr1 ++ mtsr $r6, $mr4 ++ mtsr $r7, $mr6 ++ mtsr $r8, $mr7 ++ mtsr $r9, $mr8 ++ mtsr $r10, $ir0 ++ mtsr $r11, $ir1 ++ mtsr $r12, $ir2 ++ mtsr $r13, $ir3 ++ mtsr $r14, $ir9 ++ mtsr $r15, $ir10 ++ mtsr $r16, $ir12 ++ mtsr $r17, $ir13 ++ mtsr $r18, $ir14 ++ mtsr $r19, $ir15 ++ popm $r0, $r30 ++ ret +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/devices.c linux-3.4.110/arch/nds32/platforms/ag101p/devices.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101p/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101p/devices.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,104 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++const struct map_desc platform_io_desc[] __initdata = { ++ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, ++ PAGE_SIZE, MT_DEVICE_NCB}, ++ {USB_FOTG2XX_0_VA_BASE, USB_FOTG2XX_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, (0x000FF000 & PAGE_MASK), ++ MT_DEVICE_NCB}, ++ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {AHB_ATFAHBC020S_0_VA_BASE, AHB_ATFAHBC020S_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} ++}; ++ ++static void __init platform_map_io(void) ++{ ++ iotable_init((struct map_desc *)platform_io_desc, ++ ARRAY_SIZE(platform_io_desc)); ++} ++ ++static struct uart_port uart0 = { ++ .membase = (void __iomem *)UART0_VA_BASE, ++ .irq = UART0_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 0, ++ .mapbase = UART0_PA_BASE, ++}; ++ ++static struct uart_port uart1 = { ++ .membase = (void __iomem *)UART1_VA_BASE, ++ .irq = UART1_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 1, ++ .mapbase = UART1_PA_BASE, ++}; ++ ++static void __init soc_init(void) ++{ ++ early_serial_setup(&uart0); ++ early_serial_setup(&uart1); ++} ++ ++MACHINE_START(FARADAY, PLATFORM_NAME) ++ .param_offset = BOOT_PARAMETER_PA_BASE, ++ .map_io = platform_map_io, ++ .init_irq = platform_init_irq, ++ .timer = &platform_timer, /* defined in timer.c */ ++ .init_machine = soc_init, ++MACHINE_END static struct platform_device usb_dev_otg_host = { ++ .name = "fotg-ehci", ++}; ++ ++static int __init fotg_init(void) ++{ ++ platform_device_register(&usb_dev_otg_host); ++ return 0; ++} ++ ++device_initcall(fotg_init); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/interrupt-latency.c linux-3.4.110/arch/nds32/platforms/ag101p/interrupt-latency.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag101p/interrupt-latency.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101p/interrupt-latency.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,197 @@ ++/* ++ * interrupt_latency v1.0 11/25/01 ++ * www.embeddedlinuxinterfacing.com ++ * ++ * The original location of this code is ++ * http://www.embeddedlinuxinterfacing.com/chapters/11/ ++ * ++ * Copyright (C) 2001 by Craig Hollabaugh ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU Library 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 ++ * Library General Public License for more details. ++ * ++ * You should have received a copy of the GNU Library General Public ++ * License along with this program; if not, write to the ++ * Free Software Foundation, Inc., ++ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++/* ++ * interrupt_latency.c is based on procfs_example.c by Erik Mouw. ++ * For more information, please see, The Linux Kernel Procfs Guide, Erik Mouw ++ * http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ILT_MODULE_VERSION "1.0" ++#define MODULE_NAME "interrupt_latency" ++ ++#define USE_PFM ++static int interruptcount = 0; ++#ifdef USE_PFM ++static unsigned int start_cycle = 0, finish_cycle = 0; ++static unsigned int start_inst = 0, finish_inst = 0; ++static unsigned int start_int = 0, finish_int = 0; ++#else ++static struct timeval tv1, tv2; /* do_gettimeofday fills these */ ++#endif ++ ++#define INTERRUPT 9 ++ ++static struct proc_dir_entry *interrupt_latency_file; ++ ++/* ++ * function interrupt_interrupt_latency ++ * This function is the interrupt handler for interrupt 7. It sets the tv2 ++ * structure using do_gettimeofday. It then deasserts D7. ++ */ ++static irqreturn_t interrupt_interrupt_latency(int irq, void *dev_id) ++{ ++ unsigned int ir15, pfm_ctl; ++#ifdef USE_PFM ++ /* disable counter */ ++ pfm_ctl = 0x4410000; //cycles, instructions and icache misses ++ //pfm_ctl = 0x4c0000; //instructions and interrupts ++ //pfm_ctl = 0x4510000; //icache accesses and misses ++ __nds32__mtsr(pfm_ctl, NDS32_SR_PFM_CTL); //instructions and interrupts ++ finish_cycle = __nds32__mfsr(NDS32_SR_PFMC0); ++ finish_inst = __nds32__mfsr(NDS32_SR_PFMC2); ++ finish_int = __nds32__mfsr(NDS32_SR_PFMC1); ++#else ++ do_gettimeofday(&tv2); ++#endif ++ /* deassert the interrupt signal */ ++ ir15 = __nds32__mfsr(NDS32_SR_INT_PEND); ++ __nds32__mtsr((~0x10000) & ir15, NDS32_SR_INT_PEND); ++ __nds32__dsb(); ++ ++ interruptcount++; ++ return IRQ_HANDLED; ++} ++ ++/* ++ * function proc_read_interrupt_latency ++ * The kernel executes this function when a read operation occurs on ++ * /proc/interrupt_latency. This function sets the tv1 structure. It asserts ++ * D7 which should immediately cause interrupt 7 to occur. The handler ++ * records tv2 and deasserts D7. This function returns the time differential ++ * between tv2 and tv1. ++ */ ++static int proc_read_interrupt_latency(char *page, char **start, off_t off, ++ int count, int *eof, void *data) ++{ ++ int len; ++ unsigned int ir15, pfm_ctl; ++#ifdef USE_PFM ++ //pfm_ctl = 0x4c0007; ++ //pfm_ctl = 0x4510007; ++ pfm_ctl = 0x4410007; ++ start_cycle = __nds32__mfsr(NDS32_SR_PFMC0); ++ start_inst = __nds32__mfsr(NDS32_SR_PFMC2); ++ start_int = __nds32__mfsr(NDS32_SR_PFMC1); ++ __nds32__mtsr(pfm_ctl, NDS32_SR_PFM_CTL); ++#else ++ do_gettimeofday(&tv1); ++#endif ++ /* assert the interrupt signal */ ++ ir15 = __nds32__mfsr(NDS32_SR_INT_PEND); ++ __nds32__mtsr(0x10000 | ir15, NDS32_SR_INT_PEND); ++ __nds32__dsb(); ++ ++#ifdef USE_PFM ++ len = ++ sprintf(page, ++ "Cnt0 %11u Start %11u Finish %11u Cycles %11u\n" ++ "Cnt2 %11u Start %11u Finish %11u icache miss %11u\n" ++ "Cnt1 %11u Start %11u Finish %11u Instructions %11u\n" ++ "Count %11i\n", ((pfm_ctl & 0x8000) >> 15), start_cycle, ++ finish_cycle, (finish_cycle - start_cycle), ++ ((pfm_ctl & 0xfc00000) >> 22), start_inst, finish_inst, ++ (finish_inst - start_inst), ((pfm_ctl & 0x3f0000) >> 16), ++ start_int, finish_int, (finish_int - start_int), ++ interruptcount); ++#else ++ len = sprintf(page, "Start %9i.%06i\nFinish %9i.%06i\nLatency %17i\n\ ++Count %19i\n", (int)tv1.tv_sec, (int)tv1.tv_usec, (int)tv2.tv_sec, (int)tv2.tv_usec, (int)(tv2.tv_usec - tv1.tv_usec), interruptcount); ++#endif ++ *eof = 1; ++ return len; ++} ++ ++/* ++ * function init_interrupt_latency ++ * This function creates the /proc directory entry interrupt_latency. It ++ * also configures the parallel port then requests interrupt 7 from Linux. ++ */ ++static int __init init_interrupt_latency(void) ++{ ++ int rv = 0; ++ unsigned int ir14; ++ ++ interrupt_latency_file = ++ create_proc_entry("interrupt_latency", 0444, NULL); ++ if (interrupt_latency_file == NULL) { ++ return -ENOMEM; ++ } ++ ++ interrupt_latency_file->data = NULL; ++ interrupt_latency_file->read_proc = &proc_read_interrupt_latency; ++ interrupt_latency_file->write_proc = NULL; ++ ++ /* request interrupt from linux */ ++ rv = request_irq(INTERRUPT, interrupt_interrupt_latency, IRQF_DISABLED, ++ "interrupt_latency", (void *)NULL); ++ if (rv) { ++ printk("Can't get interrupt %d\n", INTERRUPT); ++ goto no_interrupt_latency; ++ } ++ ++ /* unmask SWI */ ++ ir14 = __nds32__mfsr(NDS32_SR_INT_MASK); ++ __nds32__mtsr((0x10000 | ir14), NDS32_SR_INT_MASK); ++ __nds32__dsb(); ++ ++ /* everything initialized */ ++ printk(KERN_INFO "%s %s initialized\n", MODULE_NAME, ++ ILT_MODULE_VERSION); ++ return 0; ++ ++ /* remove the proc entry on error */ ++no_interrupt_latency: ++ remove_proc_entry("interrupt_latency", NULL); ++ return 0; ++} ++ ++/* ++ * function cleanup_interrupt_latency ++ * This function frees interrupt then removes the /proc directory entry ++ * interrupt_latency. ++ */ ++static void __exit cleanup_interrupt_latency(void) ++{ ++ /* free the interrupt */ ++ free_irq(INTERRUPT, (void *)NULL); ++ ++ remove_proc_entry("interrupt_latency", NULL); ++ ++ printk(KERN_INFO "%s %s removed\n", MODULE_NAME, ILT_MODULE_VERSION); ++} ++ ++module_init(init_interrupt_latency); ++module_exit(cleanup_interrupt_latency); ++ ++MODULE_DESCRIPTION("interrupt_latency proc module"); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/Kconfig linux-3.4.110/arch/nds32/platforms/ag101p/Kconfig +--- linux-3.4.110.orig/arch/nds32/platforms/ag101p/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101p/Kconfig 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,11 @@ ++menu "AG101P Platform Options" ++config CACHE_L2 ++bool "Support L2 cache" ++ default n ++ ++config MEASURE_INTERRUPT_LATENCY ++ bool "Measure interrupt latency" ++ default n ++ help ++ Enable measuring interrupt latency with software interrupt ++endmenu +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag101p/Makefile linux-3.4.110/arch/nds32/platforms/ag101p/Makefile +--- linux-3.4.110.orig/arch/nds32/platforms/ag101p/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag101p/Makefile 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,2 @@ ++obj-y = devices.o ++obj-$(CONFIG_MEASURE_INTERRUPT_LATENCY) += interrupt-latency.o +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/ahbclkcal.c linux-3.4.110/arch/nds32/platforms/ag102/ahbclkcal.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/ahbclkcal.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/ahbclkcal.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,216 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#ifdef CONFIG_AUTO_SYS_CLK ++ ++#define OSCH3_CLK 33000000 ++#define OSCH_CLK 25000000 ++#define MHZ 1000000 ++/* ++ * Table for ahb divisor, PMODE[07:04] ++ */ ++static const int ahb_div[16] = { ++ 1, 2, 3, 4, 5, 6, 3, 5, ++ 8, 10, 12, 14, 15, 18, 20, -1 ++}; ++ ++/* ag102_get_ahb_clk() ++ * ++ * return AHB clock in Hz. ++ */ ++static int ahbclk; ++void ag102_calc_ahb_clk(void) ++{ ++ unsigned int pcs1_param; ++ unsigned int pcs4_param; ++ unsigned int pcs5_param; ++ unsigned int main_PLL_div; ++ unsigned int main_PLL_out; ++ unsigned int ratio; ++ unsigned int main_PLL_N; ++ unsigned int main_PLL_M = 1; ++ unsigned int F_core0; ++ unsigned int F_core1; ++ unsigned int F_l2cc; ++ unsigned int F_ddr2; ++ unsigned int F_ahb; ++ unsigned int F_apb; ++ unsigned int F_pci; ++ ++ pcs1_param = REG32(PCU_VA_BASE + 0xa4); //pcs1 parameter register, for core/ahb/apb clk ratio setting ++ main_PLL_div = (pcs1_param >> 4) & 0x3; ++ ratio = pcs1_param & 0xf; ++ ++ pcs4_param = REG32(PCU_VA_BASE + 0x104); //pcs4 parameter register, for main PLL setting ++ main_PLL_N = pcs4_param & 0xff; ++ main_PLL_out = (OSCH3_CLK * main_PLL_N / main_PLL_M) >> main_PLL_div; ++ ++ pcs5_param = REG32(PCU_VA_BASE + 0x124); //pcs5 parameter register, for PCI PLL/DLL setting ++ ++ switch (ratio) { ++ case 0: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 1: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 2: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 1; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 3: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 1; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 4: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 2; ++ F_l2cc = F_core0 >> 2; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ case 5: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 2; ++ F_l2cc = F_core0 >> 2; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 6: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 7: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0; ++ F_ddr2 = F_core0 >> 1; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 8: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = OSCH_CLK * 24 / 2; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 9: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = OSCH_CLK * 24 / 2; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ case 10: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 1; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = OSCH_CLK * 24 / 2; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 11: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 1; ++ F_l2cc = F_core0 >> 1; ++ F_ddr2 = OSCH_CLK * 24 / 2; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 12: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 2; ++ F_l2cc = F_core0 >> 2; ++ F_ddr2 = OSCH_CLK * 24 / 2; ++ F_ahb = F_core0 >> 2; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 13: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0 >> 2; ++ F_l2cc = F_core0 >> 2; ++ F_ddr2 = OSCH_CLK * 24 / 2; ++ F_ahb = F_core0 >> 3; ++ F_apb = F_ahb >> 1; ++ break; ++ ++ case 14: ++ F_core0 = main_PLL_out; ++ F_core1 = F_core0; ++ F_l2cc = F_core0; ++ F_ddr2 = F_core0; ++ F_ahb = F_core0; ++ F_apb = F_ahb; ++ break; ++ default: // 15 ++ F_core0 = OSCH3_CLK; ++ F_core1 = F_core0; ++ F_l2cc = F_core0; ++ F_ddr2 = F_core0; ++ F_ahb = F_core0; ++ F_apb = F_ahb; ++ break; ++ } ++ ++ F_pci = OSCH_CLK * 24 / 9; ++ if ((pcs5_param & 0x800) == 0) ++ F_pci = F_pci >> 1; ++ ++ ahbclk = (int)F_ahb; ++} ++ ++int ag102_get_ahb_clk(void) ++{ ++ //return ahbclk+MHZ; ++ return ahbclk; ++} ++ ++EXPORT_SYMBOL(ag102_get_ahb_clk); ++#else ++void ag102_calc_ahb_clk(void) ++{ ++} ++#endif +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/devices.c linux-3.4.110/arch/nds32/platforms/ag102/devices.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/devices.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,181 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern void amic_init(void); ++ ++const struct map_desc platform_io_desc[] __initdata = { ++ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {AMIC_VA_BASE, AMIC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {GMAC_VA_BASE, GMAC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {APBBR_VA_BASE, APBBR_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {TIMER_VA_BASE, TIMER_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x0000F000, MT_DEVICE_NCB}, ++ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {PCU_VA_BASE, PCU_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {LPC_IO_VA_BASE, LPC_IO_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {LPC_REG_VA_BASE, LPC_REG_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {GPU_VA_BASE, GPU_PA_BASE, SZ_64K, MT_DEVICE_NCB}, ++ {IDE_FTIDE020_VA_BASE, IDE_FTIDE020_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {USB_FOTG2XX_0_VA_BASE, USB_FOTG2XX_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SPI_FTSSP010_0_VA_BASE, SPI_FTSSP010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {DDR2C_VA_BASE, DDR2C_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {AHB_ATFAHBC020S_0_VA_BASE, AHB_ATFAHBC020S_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB} ++ //{ GPIO_VA_BASE, GPIO_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB } ++}; ++ ++/* hid descriptor for a keyboard */ ++static struct hidg_func_descriptor my_hid_data = { ++ .subclass = 0, /* No subclass */ ++ .protocol = 1, /* Keyboard */ ++ .report_length = 8, ++ .report_desc_length = 63, ++ .report_desc = { ++ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ ++ 0x09, 0x06, /* USAGE (Keyboard) */ ++ 0xa1, 0x01, /* COLLECTION (Application) */ ++ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ ++ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ ++ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ ++ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ ++ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ ++ 0x75, 0x01, /* REPORT_SIZE (1) */ ++ 0x95, 0x08, /* REPORT_COUNT (8) */ ++ 0x81, 0x02, /* INPUT (Data,Var,Abs) */ ++ 0x95, 0x01, /* REPORT_COUNT (1) */ ++ 0x75, 0x08, /* REPORT_SIZE (8) */ ++ 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ ++ 0x95, 0x05, /* REPORT_COUNT (5) */ ++ 0x75, 0x01, /* REPORT_SIZE (1) */ ++ 0x05, 0x08, /* USAGE_PAGE (LEDs) */ ++ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ ++ 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ ++ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ ++ 0x95, 0x01, /* REPORT_COUNT (1) */ ++ 0x75, 0x03, /* REPORT_SIZE (3) */ ++ 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */ ++ 0x95, 0x06, /* REPORT_COUNT (6) */ ++ 0x75, 0x08, /* REPORT_SIZE (8) */ ++ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ ++ 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */ ++ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ ++ 0x19, 0x00, /* USAGE_MINIMUM (Reserved) */ ++ 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */ ++ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ ++ 0xc0 /* END_COLLECTION */ ++ } ++}; ++ ++static struct platform_device my_hid = { ++ .name = "hidg", ++ .id = 0, ++ .num_resources = 0, ++ .resource = 0, ++ .dev.platform_data = &my_hid_data, ++}; ++ ++static void __init platform_map_io(void) ++{ ++ iotable_init((struct map_desc *)platform_io_desc, ++ ARRAY_SIZE(platform_io_desc)); ++} ++ ++static struct resource ftgmac100_resources[] = { ++ [0] = { ++ .start = GMAC_PA_BASE, ++ .end = GMAC_PA_BASE + SZ_4K - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = GMAC_IRQ, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ftgmac100_device = { ++ .name = "ftgmac100", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(ftgmac100_resources), ++ .resource = ftgmac100_resources, ++}; ++ ++static int __init devices_init(void) ++{ ++ platform_device_register(&ftgmac100_device); ++ platform_device_register(&my_hid); ++ return 0; ++} ++ ++arch_initcall(devices_init); ++ ++static struct uart_port uart0 = { ++ .membase = (void __iomem *)UART0_VA_BASE, ++ .irq = UART0_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 0, ++ .mapbase = UART0_PA_BASE, ++}; ++ ++static struct uart_port uart1 = { ++ .membase = (void __iomem *)UART1_VA_BASE, ++ .irq = UART1_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 1, ++ .mapbase = UART1_PA_BASE, ++}; ++ ++void ag102_calc_ahb_clk(void); ++static void __init soc_init(void) ++{ ++ ag102_calc_ahb_clk(); ++ early_serial_setup(&uart0); ++ early_serial_setup(&uart1); ++} ++ ++MACHINE_START(FARADAY, PLATFORM_NAME) ++ .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = amic_init,.timer = &platform_timer, /* defined in timer.c */ ++.init_machine = soc_init, ++ MACHINE_END static struct platform_device usb_dev_otg_host = { ++ .name = "fotg-ehci", ++}; ++ ++static int __init fotg_init(void) ++{ ++ platform_device_register(&usb_dev_otg_host); ++ return 0; ++} ++ ++device_initcall(fotg_init); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/freq-scaling.c linux-3.4.110/arch/nds32/platforms/ag102/freq-scaling.c +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/freq-scaling.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/freq-scaling.c 2016-04-07 10:20:50.986082726 +0200 +@@ -0,0 +1,512 @@ ++/* ++ * linux/arch/nds32/platforms/ag102/cpu-fcs.c ++ * ++ * Copyright (C) 2002,2003 Intrinsyc Software ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * History: ++ * 31-Jul-2002 : Initial version [FB] ++ * 29-Jan-2003 : added PXA255 support [FB] ++ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) ++ * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.) ++ * 13-Oct-2010 : ported to NDS32 AG102 architecture(Gavin Guo, Andestech Corp.) ++ * ++ * Note: ++ * This driver may change the memory bus clock rate, but will not do any ++ * platform specific access timing changes... for example if you have flash ++ * memory connected to CS0, you will need to register a platform specific ++ * notifier which will adjust the memory access strobes to maintain a ++ * minimum strobe width. ++ * ++ */ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "pcu.h" ++ ++void __ddr_fsc_lock_start(); ++void __ddr_fsc_lock_end(); ++#define AG102_MIN_FREQ 200000000 ++#define AG102_MAX_FREQ 1000000000 ++#define OSCH3_CLK 33000000 /* 33MHz AG102 */ ++ ++struct ag102_freq_struct { ++ unsigned int khz; /* cpu_clk in khz */ ++ unsigned int sf; /* scaling factor */ ++ unsigned int cr; /* clock ratio */ ++}; ++ ++struct ag102_freq_struct ag102_run_freqs[] = { ++ /* khz sf, cr */ ++ {OSCH3_CLK * 7, 7, 0}, /* CPUA 231MHz */ ++ {OSCH3_CLK * 8, 8, 0}, /* CPUA 264MHz */ ++ {OSCH3_CLK * 9, 9, 0}, ++ {OSCH3_CLK * 10, 10, 0}, ++ {OSCH3_CLK * 11, 11, 0}, ++ {OSCH3_CLK * 12, 12, 0}, ++ {OSCH3_CLK * 13, 13, 0}, ++ {OSCH3_CLK * 14, 14, 0}, ++ {OSCH3_CLK * 15, 15, 0}, ++ {OSCH3_CLK * 16, 16, 0}, ++ /* ++ * {OSCH3_CLK * 17, 17, 0}, ++ * {OSCH3_CLK * 18, 18, 0}, ++ * {OSCH3_CLK * 19, 19, 0}, ++ * {OSCH3_CLK * 20, 20, 0}, ++ * {OSCH3_CLK * 21, 21, 0}, ++ * {OSCH3_CLK * 22, 22, 0}, ++ * {OSCH3_CLK * 23, 23, 0}, ++ * {OSCH3_CLK * 24, 24, 0}, ++ * {OSCH3_CLK * 25, 25, 0}, ++ * {OSCH3_CLK * 26, 26, 0}, ++ * {OSCH3_CLK * 27, 27, 0}, ++ * {OSCH3_CLK * 28, 28, 0}, ++ * {OSCH3_CLK * 29, 29, 0}, ++ * {OSCH3_CLK * 30, 30, 0}, ++ */ ++ {0} /* The last 30 is CPUA 1000MHz */ ++}; ++ ++#define NUM_RUN_FREQS ARRAY_SIZE(ag102_run_freqs) ++static struct cpufreq_frequency_table ag102_run_freq_table[NUM_RUN_FREQS + 1]; ++ ++/* Generic helper function get CPU clocks in kHz */ ++unsigned int ag102_cpufreq_get(unsigned int dummy) ++{ ++ unsigned int main_PLL_M = 1; ++ unsigned int main_PLL_out; ++ unsigned int main_PLL_div; ++ unsigned int ratio; ++ unsigned int main_PLL_N; ++ unsigned int pcs1_param; ++ unsigned int pcs4_param; ++ ++ pcs1_param = PCU_GET_REG(PCS1_ST2); ++ main_PLL_div = PCU_EXTRACT(PCS1_ST2, DIV, pcs1_param); ++ ratio = PCU_EXTRACT(PCS1_ST2, RATIO, pcs1_param); ++ ++ pcs4_param = PCU_GET_REG(PCS4_ST2); ++ main_PLL_N = PCU_EXTRACT(PCS4_ST2, N_FACTOR, pcs4_param); ++ main_PLL_out = (OSCH3_CLK * main_PLL_N / main_PLL_M) >> main_PLL_div; ++ ++ printk("CPU frequency is %d\n", main_PLL_out); ++ return main_PLL_out; ++} ++ ++/* find a valid frequency point */ ++static int ag102_verify_policy(struct cpufreq_policy *policy) ++{ ++ printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min, ++ policy->max); ++ return cpufreq_frequency_table_verify(policy, ag102_run_freq_table); ++} ++ ++void wakeup_and_ddr_train(void) ++{ ++ unsigned int csr_reg; ++ unsigned long ddr2_va_base = DDR2C_VA_BASE; ++ /* issue standby */ ++ /*standby(PCU_STBY_WAIT_DONE); */ ++ __asm__ __volatile__("__fcs_stby:"); ++ __asm__ __volatile__("standby wait_done"); ++ /* Fill the inline assembly codes into Cache to avoid SDRAM access before the data training is done */ ++ __asm__ __volatile__("__ddr_fsc_lock_start:\n" ++ "li $p0, %0 \n" ++ "lwi $p1, [$p0 + 0x1f0] \n" ++ "ori $p1, $p1, 0x100 \n" ++ "swi $p1, [$p0 + 0x1f0] ! DLL Reset \n" ++ "msync \n" ++ "isb \n" ++ "1: \n" ++ "lwi $p1, [$p0 + 0x1f0] \n" ++ "andi $p1, $p1, 0x100 \n" ++ "bnez $p1, 1b ! Wait until DLL reset is done\n" ++ "__trigger_dt:\n" ++ "li $p0, %1 \n" ++ "lwi $p1, [$p0] \n" ++ "li $p0, 0x40000000 \n" ++ "or $p1, $p1, $p0 \n" ++ "li $p0, %2 \n" ++ "swi $p1, [$p0] ! Trigger data training\n" ++ "msync \n" ++ "isb \n" ++ "li $p0, %3 \n" ++ "__wait_init_0:\n" ++ "lwi $p1, [$p0 + 0xc] \n" ++ "srli $p1, $p1, 23 \n" ++ "andi $p1, $p1, 0x1 \n" ++ "bnez $p1, __wait_init_0 ! Wait until init bit in CSR == 0\n" ++ "lwi $p1, [$p0 + 0xc] \n" ++ "srli $p1, $p1, 20 \n" ++ "andi $p1, $p1, 0x1 \n" ++ "beqz $p1, __dt_pass ! Monitor data training result\n" ++ "li $p0, 0xff942000 \n" ++ "li $p1, 0x45 \n" ++ "swi $p1, [$p0] ! put 'E' to UART\n" ++ "li $p1, 0x52 \n" ++ "swi $p1, [$p0] ! put 'R' to UART\n" ++ "li $p1, 0x52 \n" ++ "swi $p1, [$p0] ! put 'R' to UART\n" ++ "li $p1, 0x4f \n" ++ "swi $p1, [$p0] ! put 'O' to UART\n" ++ "li $p1, 0x52 \n" ++ "swi $p1, [$p0] ! put 'R' to UART\n" ++ "li $p1, 0xd \n" ++ "swi $p1, [$p0] ! put '\\r' to UART\n" ++ "li $p1, 0xa \n" ++ "swi $p1, [$p0] ! put '\\n' to UART\n" ++ "j __ddr_fsc_lock_end \n" ++ "__dt_pass:\n" ++ "li $p0, 0xff942000 \n" ++ "li $p1, 0x50 \n" ++ "swi $p1, [$p0] ! put 'P' to UART\n" ++ "li $p1, 'A \n" ++ "swi $p1, [$p0] ! put 'A' to UART\n" ++ "li $p1, 0x53 \n" ++ "swi $p1, [$p0] ! put 'S' to UART\n" ++ "li $p1, 0x53 \n" ++ "swi $p1, [$p0] ! put 'S' to UART\n" ++ "li $p1, '\\r \n" ++ "swi $p1, [$p0] ! put '\\r' to UART\n" ++ "li $p1, '\\n \n" ++ "swi $p1, [$p0] ! put '\\n' to UART\n" ++ "__ddr_fsc_lock_end: \n":: ++ "r" ++ (ddr2_va_base), ++ "r" ++ (ddr2_va_base), ++ "r"(ddr2_va_base), "r"(ddr2_va_base)); ++ ++ csr_reg = GET_REG(DDR2C_VA_BASE + 0xc); ++ if (csr_reg & 0x100000) { ++ printk("\n###### Data training error ######\nCSR = 0x%x\n\n", ++ csr_reg); ++ } ++} ++ ++void check_status() ++{ ++ unsigned int reg_value_tmp; ++ ++ /* ++ * CPU will continue if it is waked up ++ * => check status ++ */ ++ reg_value_tmp = PCU_GET_REG(BSM_STATUS); ++ if (PCU_EXTRACT(BSM_STATUS, STS, reg_value_tmp) != PCS_BSM_DONE) { ++ printk("ERROR: BSM status is not expected:0x%x\n", ++ reg_value_tmp); ++ } ++ PCU_SET_REG(BSM_STATUS, 0x0); // write to clear the status ++ ++ /* ++ * Maybe we will need the following code in the future ++ * if (pcs1_used) { ++ * reg_value_tmp = PCU_GET_REG(PCS1_ST1); ++ * if (PCU_EXTRACT(PCS1_ST1, STS, reg_value_tmp) != PCS_STS_DONE) { ++ * printk("ERROR: PCS1 status is not expected:0x%x\n", reg_value_tmp); ++ * printk("DEBUG: PCS1 status 2 is 0x%x\n", PCU_GET_REG(PCS1_ST2)); ++ * } ++ * PCU_SET_REG(PCS1_ST1, 0x0); // write to clear the status ++ * pcs1_used = 0; ++ * } ++ */ ++ ++ /* if (pcs4_used) { */ ++ reg_value_tmp = PCU_GET_REG(PCS4_ST1); ++ if (PCU_EXTRACT(PCS4_ST1, STS, reg_value_tmp) != PCS_STS_DONE) { ++ printk("ERROR: PCS4 status is not expected:0x%x\n", ++ reg_value_tmp); ++ printk("DEBUG: PCS4 status 2 is 0x%x\n", PCU_GET_REG(PCS4_ST2)); ++ } ++ PCU_SET_REG(PCS4_ST1, 0x0); /* write to clear the status */ ++ /* pcs4_used = 0; */ ++ /* } */ ++ ++} ++ ++void start_fcs(unsigned int pll_n_factor, unsigned org_div_param) ++{ ++ unsigned int pll_range; ++ unsigned int pcs4_prmtr; ++ ++ /* ++ * We must keep the frequency between 266~533. ++ * because this is the frequency having been tested. ++ */ ++ if (org_div_param == 0) { ++ if ((pll_n_factor < 7) || (pll_n_factor > 16)) { /* 266~533 */ ++ printk("\npll_n_factor:%d, org_div_param:%d\n", ++ pll_n_factor, org_div_param); ++ printk ++ ("The input is not accepted! Please input the other value\n"); ++ return; ++ } ++ } else { /* div = 1(the divsior is 2), (pll_n_factor*33MHz/2) */ ++ if (pll_n_factor < 16) { /* (533/2~1000/2) */ ++ printk("\npll_n_factor:%d, org_div_param:%d\n", ++ pll_n_factor, org_div_param); ++ printk ++ ("The input is not accepted! Please input the other value\n"); ++ return; ++ } ++ ++ } ++ /* Setup the pll_range, pcu need to know the frequency which we setup */ ++ if (org_div_param == 0) { ++ if (pll_n_factor <= 15) { ++ pll_range = 2; ++ } else ++ pll_range = 3; ++ } else if (org_div_param == 1) { ++ if (pll_n_factor >= 16 && pll_n_factor <= 30) { ++ pll_range = 2; ++ } else ++ pll_range = 3; ++ } ++ ++ printk("\npll_n_factor:%d, org_div_param:%d, pll_range:%d\n", ++ pll_n_factor, org_div_param, pll_range); ++ /* PCS4 */ ++ PCU_SET_REG(PCS4_CFG, 0); /* stop */ ++ pcs4_prmtr = PCU_PREPARE(PCS4_PARA, IE, 1) | PCU_PREPARE(PCS4_PARA, CMD, PCS_CMD_NOP) | PCU_PREPARE(PCS4_PARA, SYNC, 1) | PCU_PREPARE(PCS4_PARA, PWDN, 0) | PCU_PREPARE(PCS4_PARA, RANGE, pll_range) | /* PLL range */ ++ pll_n_factor; /* PLL N factor */ ++ PCU_SET_REG(PCS4_PARA, pcs4_prmtr); ++ ++ /* BSM */ ++ PCU_SET_REG(BSM_CTRL, PCU_PREPARE(BSM_CTRL, IE, 1) | PCU_PREPARE(BSM_CTRL, CMD, PCS_CMD_SCALING | PCS_CMD_DRAM_SF) | PCU_PREPARE(BSM_CTRL, SYNC, 1) | PCU_PREPARE(BSM_CTRL, LINK0, 4) | /* scaling link start */ ++ PCU_PREPARE(BSM_CTRL, LINK1, 0x0)); /* wakeup link start */ ++ wakeup_and_ddr_train(); ++ check_status(); ++} ++ ++void end_fcs(void) ++{ ++ /* Leave this function as a place marker. */ ++} ++ ++#define LPS_PREC 8 ++void calibration() ++{ ++ unsigned long ticks, loopbit, lpj; ++ int lps_precision = LPS_PREC; ++ ++ lpj = (1 << 12); ++ ++ printk(KERN_INFO "Calibrating delay loop... "); ++ while ((lpj <<= 1) != 0) { ++ /* wait for "start of" clock tick */ ++ ticks = jiffies; ++ while (ticks == jiffies) ++ /* nothing */ ; ++ /* Go .. */ ++ ticks = jiffies; ++ __delay(lpj); ++ ticks = jiffies - ticks; ++ if (ticks) ++ break; ++ } ++ ++ /* ++ * Do a binary approximation to get lpj set to ++ * equal one clock (up to lps_precision bits) ++ */ ++ lpj >>= 1; ++ loopbit = lpj; ++ while (lps_precision-- && (loopbit >>= 1)) { ++ lpj |= loopbit; ++ ticks = jiffies; ++ while (ticks == jiffies) ++ /* nothing */ ; ++ ticks = jiffies; ++ __delay(lpj); ++ if (jiffies != ticks) /* longer than 1 tick */ ++ lpj &= ~loopbit; ++ } ++ ++ printk(KERN_CONT "%lu.%02lu BogoMIPS modified(lpj=%lu)\n", ++ lpj / (500000 / HZ), (lpj / (5000 / HZ)) % 100, lpj); ++} ++ ++static int ag102_speedstep(int idx) ++{ ++ unsigned int j; ++ char ch = 'a'; ++ unsigned int sf, cr; ++ unsigned long flags = 0; ++ unsigned long org_div_param; ++ void (*do_fcs) (unsigned int efsf, unsigned int edivhbaclk); ++ int i; ++ int line_size = CACHE_LINE_SIZE(ICACHE); ++ unsigned long start = ++ ((unsigned long)__ddr_fsc_lock_start) & ~(line_size - 1); ++ unsigned long end = ++ (((unsigned long)__ddr_fsc_lock_end) + line_size) & ~(line_size - ++ 1); ++ ++ printk("&__ddr_fsc_lock_start(): 0x%08lx, aligned to: 0x%08lx\n", ++ (unsigned long)__ddr_fsc_lock_start, start); ++ printk("&__ddr_fsc_lock_end(): 0x%08lx, aligned to: 0x%08lx\n", ++ (unsigned long)__ddr_fsc_lock_end, end); ++ ++ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK":: ++ "r" (i):"memory"); ++ ++ do_fcs = start_fcs; ++ org_div_param = (PCU_GET_REG(PCS1_ST2) >> 4) & 0x3; ++ sf = ag102_run_freqs[idx].sf; ++ if (org_div_param == 1) ++ sf *= 2; ++#if 0 ++ calibration(); ++ printk("pcu read value,before frequency scaling:"); ++ ag102_cpufreq_get(0); ++#endif ++ local_irq_save(flags); ++ do_fcs(sf, org_div_param); ++ local_irq_restore(flags); ++#if 0 ++ printk("\npcu read value,after frequency scaling:"); ++ ag102_cpufreq_get(0); ++#endif ++ ++ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) ++ __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory"); ++ ++ return 1; ++} ++ ++static int ag102_set_target(struct cpufreq_policy *policy, ++ unsigned int target_freq, unsigned int relation) ++{ ++ unsigned int idx, i, j; ++ char ch = 'a'; ++ struct cpufreq_frequency_table *ag102_freqs_table; ++ struct ag102_freq_struct *ag102_freq_settings; ++ struct cpufreq_freqs freqs; ++ ++ ag102_freq_settings = ag102_run_freqs; ++ ag102_freqs_table = ag102_run_freq_table; ++ ++ if (target_freq > AG102_MAX_FREQ || target_freq < AG102_MIN_FREQ) { ++ printk ++ ("\nThe frequency you input is illegal!!Please enter the frequency between %d ~ %d\n", ++ AG102_MIN_FREQ, AG102_MAX_FREQ); ++ return -EINVAL; ++ } ++ ++ /* Lookup the next frequency */ ++ if (cpufreq_frequency_table_target ++ (policy, ag102_freqs_table, target_freq, relation, &idx)) ++ return -EINVAL; ++ ++ freqs.old = policy->cur; ++ freqs.new = ag102_freq_settings[idx].khz; ++ freqs.cpu = policy->cpu; ++ ++ /* ++ * Tell everyone what we're about to do... ++ * you should add a notify client with any platform specific ++ * Vcc changing capability ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); ++ ++ if (freqs.new != freqs.old) { ++ ++ if (!ag102_speedstep(idx)) ++ return -ENODEV; ++ } ++ ++ /* ++ * Tell everyone what we've just done... ++ * you should add a notify client with any platform specific ++ * SDRAM refresh timer adjustments ++ */ ++ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); ++#if 0 ++ printk("After CPUFREQ_POSTCHANGE, scaling:\n"); ++ calibration(); ++ printk("Speed test..."); ++ for (i = 0; i < 26; i++) { ++ for (j = 0; j < 500000000; j++) ; ++ printk("%c", ch); ++ ch += 1; ++ } ++ printk("\n"); ++#endif ++ return 0; ++} ++ ++static int ag102_cpufreq_init(struct cpufreq_policy *policy) ++{ ++ int i; ++ /* set default policy and cpuinfo */ ++ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; ++ policy->policy = CPUFREQ_POLICY_PERFORMANCE; ++ policy->cpuinfo.max_freq = AG102_MAX_FREQ; ++ policy->cpuinfo.min_freq = AG102_MIN_FREQ; ++ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ ++ policy->cur = ag102_cpufreq_get(0); /* current freq */ ++ policy->min = AG102_MIN_FREQ; ++ policy->max = AG102_MAX_FREQ; ++ ++ /* Generate the run cpufreq_frequency_table struct */ ++ for (i = 0; i < NUM_RUN_FREQS; i++) { ++ ++ ag102_run_freq_table[i].frequency = ag102_run_freqs[i].khz; ++ ag102_run_freq_table[i].index = i; ++ } ++ ++ ag102_run_freq_table[i].frequency = CPUFREQ_TABLE_END; ++ ++ printk("CPU frequency change support initialized\n"); ++ ++ return 0; ++} ++ ++static struct cpufreq_driver ag102_cpufreq_driver = { ++ ++ .verify = ag102_verify_policy, ++ .target = ag102_set_target, ++ .init = ag102_cpufreq_init, ++ .get = ag102_cpufreq_get, ++ .name = "AG102", ++}; ++ ++static int __init ag102_cpu_init(void) ++{ ++ return cpufreq_register_driver(&ag102_cpufreq_driver); ++} ++ ++static void __exit ag102_cpu_exit(void) ++{ ++ cpufreq_unregister_driver(&ag102_cpufreq_driver); ++} ++ ++MODULE_AUTHOR("Andes Technology Corporation"); ++MODULE_DESCRIPTION("CPU frequency changing driver for the AG102 architecture"); ++MODULE_LICENSE("GPL"); ++module_init(ag102_cpu_init); ++module_exit(ag102_cpu_exit); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/gmac.h linux-3.4.110/arch/nds32/platforms/ag102/gmac.h +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/gmac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/gmac.h 2016-04-07 10:20:51.002083345 +0200 +@@ -0,0 +1,354 @@ ++#ifdef CONFIG_PLAT_AG102 ++#include ++#else ++#include ++#endif ++ ++#ifndef __GMAC_H ++#define __GMAC_H ++ ++// ====================================================== ++// GMAC register definition ++// ====================================================== ++// GMAC register ++// ++//#define CPE_GMAC_BASE 0xFF90B000 //VA Base ++#define CPE_DDR2_MEM_BASE 0x00000000 ++ ++#define BIT_MASK(bit_h, bit_l) ((((UINT32)0x1<<(1+bit_h-bit_l))-(UINT32)0x1)< ++#include ++#include ++ ++#include ++ ++#define LPC_REG_SCR 0x10 ++#define LPC_REG_SIR 0x14 ++#define LPC_REG_SIMR 0x18 ++ ++/* ++ * Level trigger IRQ chip methods ++ */ ++ ++static void lpc_level_unmask_irq(unsigned int irq) ++{ ++ unsigned int val; ++// *(volatile unsigned int *) (LPC_REG_BASE + LPC_REG_SIR) = ++// 1 << (irq - PLATFORM_LPC_IRQ_BASE); ++ val = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR); ++ val &= ~(1 << (irq - PLATFORM_LPC_IRQ_BASE)); ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = val; ++} ++ ++static void lpc_level_mask_irq(unsigned int irq) ++{ ++ unsigned int val; ++ val = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR); ++ val |= 1 << (irq - PLATFORM_LPC_IRQ_BASE); ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = val; ++} ++ ++static void lpc_level_ack_irq(unsigned int irq) ++{ ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR) = ++ 1 << (irq - PLATFORM_LPC_IRQ_BASE); ++} ++ ++static struct irq_chip lpc_simple_chip = { ++ .ack = lpc_level_ack_irq, ++ .mask = lpc_level_mask_irq, ++ .unmask = lpc_level_unmask_irq, ++}; ++ ++void lpc_irq_rounter(unsigned int irq, struct irq_desc *desc) ++{ ++ unsigned int lpc_status; ++ unsigned int lpc_mask; ++ unsigned int lpc_irq; ++ int i; ++ struct irq_desc *lpc_desc; ++ ++ desc->chip->mask(irq); ++ desc->chip->ack(irq); ++ ++ lpc_status = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR); ++ lpc_mask = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR); ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = 0xffffffff; ++ for (i = 0; i < PLATFORM_LPC_IRQ_TOTALCOUNT; i++) { ++ if (!(~lpc_mask & (1 << i) & lpc_status)) ++ continue; ++ lpc_irq = PLATFORM_LPC_IRQ_BASE + i; ++ lpc_desc = irq_desc + lpc_irq; ++ lpc_desc->handle_irq(lpc_irq, lpc_desc); ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR) = ++ 1 << i; ++ } ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = lpc_mask; ++ ++ desc->chip->unmask(irq); ++} ++ ++int __init lpc_init_irq(void) ++{ ++ int i; ++ ++ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SCR) = 0x1f3; ++ /* Register all IRQ */ ++ for (i = PLATFORM_LPC_IRQ_BASE; ++ i < PLATFORM_LPC_IRQ_BASE + PLATFORM_LPC_IRQ_TOTALCOUNT; i++) { ++ // level trigger ++ set_irq_chip(i, &lpc_simple_chip); ++ set_irq_handler(i, handle_simple_irq); ++ ++ } ++ set_irq_chained_handler(LPC_IRQ, lpc_irq_rounter); ++ ++ return 0; ++} ++ ++device_initcall(lpc_init_irq); ++ ++#define ITE_ADDR 0x2e ++#define ITE_DATA 0x2f ++void outlpc(unsigned int addr, unsigned int data) ++{ ++ *(volatile unsigned int *)(LPC_IO_VA_BASE + 4 * addr) = data; ++} ++ ++unsigned int inlpc(unsigned int addr) ++{ ++ return *(volatile unsigned int *)(LPC_IO_VA_BASE + 4 * addr); ++} ++ ++int __init ite8717_init(void) ++{ ++ unsigned char data1, data2; ++ unsigned int count; ++ /* enter configure mode */ ++ outlpc(ITE_ADDR, 0x87); ++ outlpc(ITE_ADDR, 0x01); ++ outlpc(ITE_ADDR, 0x55); ++ outlpc(ITE_ADDR, 0x55); ++ /* check chip */ ++ outlpc(ITE_ADDR, 0x20); ++ data1 = inlpc(ITE_DATA); ++ outlpc(ITE_ADDR, 0x21); ++ data2 = inlpc(ITE_DATA); ++ if ((data1 != 0x87) && (data2 != 0x17)) ++ goto not_found; ++ /* earlyio program */ ++ outlpc(ITE_ADDR, 0x07); // LDN=0 -> FDC ++ outlpc(ITE_DATA, 0x00); ++ outlpc(ITE_ADDR, 0x30); // Enable FDC ++ outlpc(ITE_DATA, 0x01); ++ outlpc(ITE_ADDR, 0xf1); // Set (Index 0F1h) = 90h ++ outlpc(ITE_DATA, 0x80); ++ ++ outlpc(0x64, 0xaa); // Send KBC self-test command ++ count = 0; ++ do { ++ if (count++ > 0x10000) ++ break; ++ data1 = ~inlpc(0x64); ++ } while (data1 & 0x01); ++ data2 = inlpc(0x60); ++ outlpc(0x64, 0xcb); // Set PS2 mode ++ count = 0; ++ do { ++ if (count++ > 0x10000) ++ break; ++ data1 = inlpc(0x64); ++ } while (data1 & 0x02); ++ outlpc(0x60, 0x01); ++ count = 0; ++ do { ++ if (count++ > 0x10000) ++ break; ++ data1 = inlpc(0x64); ++ } while (data1 & 0x02); ++ outlpc(0x64, 0x60); // 60h = write 8042 command byte ++ count = 0; ++ do { ++ if (count++ > 0x10000) ++ break; ++ data1 = inlpc(0x64); ++ } while (data1 & 0x02); ++ outlpc(0x60, 0x45); // AT interface, keyboard enabled, system flag ++ count = 0; ++ do { ++ if (count++ > 0x10000) ++ break; ++ data1 = inlpc(0x64); ++ } while (data1 & 0x02); ++ outlpc(0x64, 0xae); ++ count = 0; ++ do { ++ if (count++ > 0x10000) ++ break; ++ data1 = ~inlpc(0x64); ++ } while (data1 & 0x01); ++ outlpc(ITE_ADDR, 0x23); ++ outlpc(ITE_DATA, 0x00); ++ ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x04); ++ outlpc(ITE_ADDR, 0xf0); ++ data1 = inlpc(ITE_DATA); ++ data1 &= 0x18; ++ data1 |= 0x0; ++ outlpc(ITE_DATA, data1); ++ outlpc(ITE_ADDR, 0xf2); ++ data1 = inlpc(ITE_DATA); ++ data1 &= 0x2e; ++ data1 |= 0xa; ++ outlpc(ITE_DATA, data1); ++ outlpc(ITE_ADDR, 0xf4); ++ data1 = inlpc(ITE_DATA); ++ data1 &= 0xaf; ++ data1 |= 0x80; ++ outlpc(ITE_DATA, data1); ++ outlpc(ITE_ADDR, 0xf5); ++ data1 = inlpc(ITE_DATA); ++ data1 &= 0x3f; ++ data1 |= 0x0; ++ outlpc(ITE_DATA, data1); ++ /* initialize all device */ ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x04); ++ outlpc(ITE_ADDR, 0x30); ++ outlpc(ITE_DATA, 0x01); ++#if 1 ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x05); ++ outlpc(ITE_ADDR, 0xf0); ++ outlpc(ITE_DATA, 0x4e); ++ outlpc(ITE_ADDR, 0x71); ++ outlpc(ITE_DATA, 0x01); ++#endif ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x06); ++ outlpc(ITE_ADDR, 0x30); ++ outlpc(ITE_DATA, 0x01); ++#if 1 ++ outlpc(ITE_ADDR, 0xf0); ++ outlpc(ITE_DATA, 0x01); ++ outlpc(ITE_ADDR, 0x71); ++ outlpc(ITE_DATA, 0x01); ++#endif ++ ++ /* exit configure mode */ ++ outlpc(ITE_ADDR, 0x02); ++ outlpc(ITE_DATA, 0x02); ++ return 0; ++not_found: ++ printk("ITE8717 not found\n"); ++ return -1; ++} ++ ++subsys_initcall(ite8717_init); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/Makefile linux-3.4.110/arch/nds32/platforms/ag102/Makefile +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/Makefile 2016-04-07 10:20:51.002083345 +0200 +@@ -0,0 +1,5 @@ ++obj-y += devices.o ahbclkcal.o ++obj-$(CONFIG_LPC) += lpc.o ++obj-$(CONFIG_PM) += pm.o sleep.o ++obj-$(CONFIG_AG102_CPU_FREQ_FCS) += cpu-fcs.o ++obj-$(CONFIG_AG102_CPU_FREQ_SCALING_MODE) += freq-scaling.o +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/pcu.h linux-3.4.110/arch/nds32/platforms/ag102/pcu.h +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/pcu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/pcu.h 2016-04-07 10:20:51.002083345 +0200 +@@ -0,0 +1,1887 @@ ++#ifndef __PCU_H ++#define __PCU_H ++#include ++#define CPE_PCU_BASE PCU_VA_BASE ++//Data type ++typedef enum Bool { ++ FALSE, ++ TRUE ++} BOOL; ++ ++typedef enum { ++ SUCCESS=0, ++ FAIL ++} STATUS; ++ ++typedef unsigned char UINT8; ++typedef char INT8; ++typedef unsigned short UINT16; ++typedef short INT16; ++typedef unsigned int UINT32; ++typedef int INT32; ++typedef unsigned long long UINT64; ++typedef long long INT64; ++ ++//Registion IO operation macro ++#define REG32(a) (*(volatile UINT32 *)(a)) ++#define REG16(a) (*(volatile UINT16 *)(a)) ++#define REG8(a) (*(volatile UINT8 *)(a)) ++ ++#define inb(a) REG8(a) ++#define inhw(a) REG16(a) ++#define inw(a) REG32(a) ++ ++#define outb(a, v) (REG8(a) = (UINT8)(v)) ++#define outhw(a, v) (REG16(a) = (UINT16)(v)) ++#define outw(a, v) (REG32(a) = (UINT32)(v)) ++ ++ ++// Register bit operation macro ++#define ANDES_BIT_MASK(bit_h, bit_l) ((((UINT32)0x1<<(1+bit_h-bit_l))-(UINT32)0x1)<> (offset)) ++ ++#define TEST_FIELD(addr, mask) (inw(addr)&(mask)) ++ ++#define SET_REG(addr, value) do { outw(addr, value); } while (0) ++#define GET_REG(addr) (inw(addr)) ++ ++#define CHECK_FIELD(value, mask) ( (value)&(mask) ) ++#define EXTRACT_FIELD(value, mask, offset) ( ((value)&(mask))>>(offset) ) ++#define PREPARE_FIELD(value, mask, offset) ( ((value)<<(offset))&(mask) ) ++ ++ ++// Variable bit operation macro ++#define VAR_TEST_BIT(var, sig) ((var)&(sig)) ++#define VAR_SET_BIT(var, sig) ((var) = (var)|(sig)) ++#define VAR_CLR_BIT(var, sig) ((var) = (var)&(~(sig))) ++// ============================ ++// PCU register definition ++// ============================ ++#define PCU_REG_VER (CPE_PCU_BASE+0x000) //version ++#define PCU_REG_SPINFO (CPE_PCU_BASE+0x004) //scartch pad information ++#define PCU_REG_SOCID (CPE_PCU_BASE+0x010) //SoC ID ++#define PCU_REG_AHB_CFG (CPE_PCU_BASE+0x014) //AHB device configuration ++#define PCU_REG_APB_CFG (CPE_PCU_BASE+0x018) //APB device configuration ++#define PCU_REG_DCSR0 (CPE_PCU_BASE+0x020) //driving capability and slew rate control 0 ++#define PCU_REG_DCSR1 (CPE_PCU_BASE+0x024) //driving capability and slew rate control 1 ++#define PCU_REG_DCSR2 (CPE_PCU_BASE+0x028) //driving capability and slew rate control 2 ++#define PCU_REG_MFPS0 (CPE_PCU_BASE+0x030) //multi-function port setting 0 ++#define PCU_REG_MFPS1 (CPE_PCU_BASE+0x034) //multi-function port setting 1 ++#define PCU_REG_DMA_SEL (CPE_PCU_BASE+0x038) //dma engin selection ++#define PCU_REG_OSC_CTRL (CPE_PCU_BASE+0x040) //OSC control register ++#define PCU_REG_PWM_DIV (CPE_PCU_BASE+0x044) //PWM clock divider value ++#define PCU_REG_MISC (CPE_PCU_BASE+0x048) //misc register ++#define PCU_REG_BSM_CTRL (CPE_PCU_BASE+0x080) //BSM control register ++#define PCU_REG_BSM_STATUS (CPE_PCU_BASE+0x084) //BSM status ++#define PCU_REG_WAKEUP_SEN (CPE_PCU_BASE+0x088) //wakeup event signal sensitivity ++#define PCU_REG_WAKEUP_STATUS (CPE_PCU_BASE+0x08c) //wakeup event status ++#define PCU_REG_RESET_TIMER (CPE_PCU_BASE+0x090) //reset timer register ++#define PCU_REG_INTR (CPE_PCU_BASE+0x094) //interrup register ++#define PCU_REG_PCS1_CFG (CPE_PCU_BASE+0x0a0) ++#define PCU_REG_PCS1_PARA (CPE_PCU_BASE+0x0a4) ++#define PCU_REG_PCS1_ST1 (CPE_PCU_BASE+0x0a8) ++#define PCU_REG_PCS1_ST2 (CPE_PCU_BASE+0x0ac) ++#define PCU_REG_PCS1_PDD (CPE_PCU_BASE+0x0b0) ++#define PCU_REG_PCS2_CFG (CPE_PCU_BASE+0x0c0) ++#define PCU_REG_PCS2_PARA (CPE_PCU_BASE+0x0c4) ++#define PCU_REG_PCS2_ST1 (CPE_PCU_BASE+0x0c8) ++#define PCU_REG_PCS2_ST2 (CPE_PCU_BASE+0x0cc) ++#define PCU_REG_PCS2_PDD (CPE_PCU_BASE+0x0d0) ++#define PCU_REG_PCS3_CFG (CPE_PCU_BASE+0x0e0) ++#define PCU_REG_PCS3_PARA (CPE_PCU_BASE+0x0e4) ++#define PCU_REG_PCS3_ST1 (CPE_PCU_BASE+0x0e8) ++#define PCU_REG_PCS3_ST2 (CPE_PCU_BASE+0x0ec) ++#define PCU_REG_PCS3_PDD (CPE_PCU_BASE+0x0f0) ++#define PCU_REG_PCS4_CFG (CPE_PCU_BASE+0x100) ++#define PCU_REG_PCS4_PARA (CPE_PCU_BASE+0x104) ++#define PCU_REG_PCS4_ST1 (CPE_PCU_BASE+0x108) ++#define PCU_REG_PCS4_ST2 (CPE_PCU_BASE+0x10c) ++#define PCU_REG_PCS4_PDD (CPE_PCU_BASE+0x110) ++#define PCU_REG_PCS5_CFG (CPE_PCU_BASE+0x120) ++#define PCU_REG_PCS5_PARA (CPE_PCU_BASE+0x124) ++#define PCU_REG_PCS5_ST1 (CPE_PCU_BASE+0x128) ++#define PCU_REG_PCS5_ST2 (CPE_PCU_BASE+0x12c) ++#define PCU_REG_PCS5_PDD (CPE_PCU_BASE+0x130) ++#define PCU_REG_PCS6_CFG (CPE_PCU_BASE+0x140) ++#define PCU_REG_PCS6_PARA (CPE_PCU_BASE+0x144) ++#define PCU_REG_PCS6_ST1 (CPE_PCU_BASE+0x148) ++#define PCU_REG_PCS6_ST2 (CPE_PCU_BASE+0x14c) ++#define PCU_REG_PCS6_PDD (CPE_PCU_BASE+0x150) ++#define PCU_REG_PCS7_CFG (CPE_PCU_BASE+0x160) ++#define PCU_REG_PCS7_PARA (CPE_PCU_BASE+0x164) ++#define PCU_REG_PCS7_ST1 (CPE_PCU_BASE+0x168) ++#define PCU_REG_PCS7_ST2 (CPE_PCU_BASE+0x16c) ++#define PCU_REG_PCS7_PDD (CPE_PCU_BASE+0x170) ++#define PCU_REG_PCS8_CFG (CPE_PCU_BASE+0x180) ++#define PCU_REG_PCS8_PARA (CPE_PCU_BASE+0x184) ++#define PCU_REG_PCS8_ST1 (CPE_PCU_BASE+0x188) ++#define PCU_REG_PCS8_ST2 (CPE_PCU_BASE+0x18c) ++#define PCU_REG_PCS8_PDD (CPE_PCU_BASE+0x190) ++#define PCU_REG_PCS9_CFG (CPE_PCU_BASE+0x1a0) ++#define PCU_REG_PCS9_PARA (CPE_PCU_BASE+0x1a4) ++#define PCU_REG_PCS9_ST1 (CPE_PCU_BASE+0x1a8) ++#define PCU_REG_PCS9_ST2 (CPE_PCU_BASE+0x1ac) ++#define PCU_REG_PCS9_PDD (CPE_PCU_BASE+0x1b0) ++ ++#define PCU_SCRATCH_OFFSET_SHIFT (8) ++#define PCU_SCRATCH_SIZE_SHIFT (2) // in byte, 2 means (1<<2) = 4 bytes ++#define PCU_REG_SCRATCH_MEM (CPE_PCU_BASE+ (PCU_SPINFO_OFFSET_DEFAULT< ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License. ++ * ++ * Abstract: ++ * ++ * This program is for AG102 power management routines. ++ * ++ * Revision History: ++ * ++ * Jul.19.2010 Initial code by Gavin. ++ */ ++#include ++#include ++#include ++#include ++#include ++/* ++ * the following include file is for testing device node ++ */ ++#include ++#include ++#include ++/*************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pcu.h" ++#include "gmac.h" ++ ++#ifdef CONFIG_PLAT_AG102 ++#include ++#endif ++ ++#define ANDES_PCU_STRING "andes_pcu" ++static int andes_pcu_major; ++static struct class *andes_pcu_class; ++extern void ag102_cpu_sleep(void); ++extern void ag102_cpu_resume(void); ++extern void ag102_cpu_resume2(void); ++extern void __SELF_REFRESH_LOCK_START(); ++extern void __SELF_REFRESH_LOCK_END(); ++extern void ftpci_postinit(void /**sysdata*/ ); ++UINT32 mac_dah, mac_dal; ++ ++// ADD by river 2010.12.07 for WOL ++ ++UINT32 eth_phy_reg_read(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg, ++ UINT32 * phy_data) ++{ ++ UINT32 cycthr = GMAC_GET_FIELD(PHYCR, MDC_CYCTHR); ++ UINT32 wdata; ++ UINT32 rdata; ++ //TIMER_P timer; ++ ++ printk(">>>>> GMAC : Calling eth_phy_reg_read()...\n"); ++ ++ wdata = GMAC_PREPARE(PHYCR, MIIRD, 0x1) | ++ GMAC_PREPARE(PHYCR, PHYAD, phy_addr) | ++ GMAC_PREPARE(PHYCR, REGAD, phy_reg) | cycthr; ++ ++ printk(">>>>> GMAC : wdata = [0x%08x]\n", wdata); ++ ++ GMAC_SET_REG(PHYCR, wdata); ++ ++ // wait phy data read ++ //TIMER_INIT(timer, 10000); // trigger timer & wait until finish of data read ++ //while ( (!TIMER_IS_TIMEOUT(timer)) && (GMAC_GET_FIELD(PHYCR, MIIRD))) { ++ // TIMER_TICK(timer); ++ //} ++ ++ while (GMAC_GET_FIELD(PHYCR, MIIRD)) { ++ mdelay(50); ++ } ++ ++ if (GMAC_GET_FIELD(PHYCR, MIIRD)) { ++ printk("ERR: GPHY read reg[%x] timeout!\n", phy_reg); ++ return 1; ++ } else { ++ rdata = GMAC_GET_FIELD(PHYDATA, MIIRDATA); ++ *phy_data = rdata; ++ printk("GPHY read [%x] \n", rdata); ++ return 0; ++ } ++} ++ ++UINT32 eth_phy_reg_write(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg, ++ UINT32 phy_data) ++{ ++ UINT32 wdata; ++ //TIMER_P timer; ++ ++ printk(">>>>> GMAC : Calling eth_phy_reg_write()...\n"); ++ ++ GMAC_SET_FIELD(PHYDATA, MIIWDATA, phy_data); ++ wdata = GMAC_PREPARE(PHYCR, MIIWR, 0x1) | GMAC_PREPARE(PHYCR, PHYAD, phy_addr) | GMAC_PREPARE(PHYCR, REGAD, phy_reg) | 0x34; //cycthr; ++ GMAC_SET_REG(PHYCR, wdata); ++ ++ // wait phy data write ++ //TIMER_INIT(timer, 10000); // trigger timer & wait until finish of data write ++ //while ( (!TIMER_IS_TIMEOUT(timer)) && (GMAC_GET_FIELD(PHYCR, MIIWR))) { ++ // TIMER_TICK(timer); ++ //} ++ ++ while (GMAC_GET_FIELD(PHYCR, MIIWR)) { ++ mdelay(50); ++ } ++ ++ if (GMAC_GET_FIELD(PHYCR, MIIWR)) { ++ printk("ERR: GPHY write reg[%x] = %x timeout!\n", phy_reg, ++ phy_data); ++ return 1; ++ } else { ++ return 0; ++ } ++} ++ ++INT32 eth_phy_detect(UINT32 * phy_addr, UINT32 * phy_id) ++{ ++ UINT32 i, find, data1, data2; ++ ++ printk(">>>>> GMAC : Calling eth_phy_detect()...\n"); ++ ++ for (i = 0, find = 0; i <= 0x1f; i++) { ++ eth_phy_reg_read(i, 0, 2, &data1); ++ if ((data1 != 0) && (data1 != 0xffff)) { ++ find = 1; ++ break; ++ } ++ } ++ ++ if (find == 0) { ++ printk("Err: no valid phy found!\n"); ++ *phy_id = 0; ++ return (-1); ++ } ++ ++ eth_phy_reg_read(i, 0, 2, &data1); ++ eth_phy_reg_read(i, 0, 3, &data2); ++ *phy_id = (data1 << 16) | (data2 & 0xffff); ++ *phy_addr = i; ++ printk("Info: phy id = 0x%08x!\n", *phy_id); ++ return 0; ++} ++ ++void eth_phy_init(UINT32 phy_addr) ++{ ++ UINT32 data, i; ++ //TIMER_P timer; ++ //phy_addr = DVC_PHY_ADDR; ++ ++ printk(">>>>> GMAC : Calling eth_phy_init()...\n"); ++ // GPHY SW reset ++ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data); ++ data |= ++ DVC_PHY_REG_CTL_SW_RST | DVC_PHY_REG_CTL_AN_EN | ++ DVC_PHY_REG_CTL_AN_RST; ++ eth_phy_reg_write(phy_addr, 0, DVC_PHY_REG_CTL, data); ++ for (i = 0; i < 10000; i++) { // must delay enough for phy to get ready ++ //eth_mdelay(2000); ++ mdelay(2); ++ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data); ++ if ((data & 0x8000) == 0) ++ break; ++ } ++ if ((data & 0x8000) != 0) { ++ printk("Err: phy sw reset timeout!!!\n"); ++ } ++ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data); ++ printk("phy control = 0x%x\n", data); ++ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_STS, &data); ++ printk("phy status = 0x%x\n", data); ++ ++ return; ++} ++ ++// initialize MAC setting ++void eth_mac_init(ETH_PHY_STAT * phy_stat) ++{ ++ UINT32 i, wdata, rdata; ++ UINT32 duplex, speed, gmac; ++ //UINT32 mac_dah, mac_dal; ++ printk(">>>>> GMAC : Calling eth_mac_init()...\n"); ++ ++ wdata = GMAC_PREPARE(MACCR, SW_RST, 0x1); ++ GMAC_SET_REG(MACCR, wdata); ++ for (i = 0; i < 1000; i++) { // must delay enough for phy to get ready ++ //eth_mdelay(8000); // delay should be enough ++ mdelay(8); ++ rdata = GMAC_GET_REG(FEAR); ++ if ((rdata >> 31) == 0) ++ break; ++ } ++ if ((rdata >> 31) != 0) { ++ printk("Err: mac sw reset timeout!!!\n"); ++ } ++ if (phy_stat->speed == 2) { //giga ++ gmac = 0x1; ++ speed = 0x1; ++ } else if (phy_stat->speed == 1) { //100 Mbps ++ gmac = 0x0; ++ speed = 0x1; ++ } else { //10 Mbps ++ gmac = 0x0; ++ speed = 0x0; ++ } ++ duplex = phy_stat->duplex; ++ GMAC_SET_REG(ISR, 0xffff); // Interrupt Status, write 1 to clear ++ GMAC_SET_REG(IME, 0xffff); // Interrupt Enable, enabling all interrupts ++ GMAC_SET_REG(MAC_MADR, mac_dah); ++ GMAC_SET_REG(MAC_LADR, mac_dal); ++ rdata = GMAC_GET_REG(FEAR); ++ GMAC_SET_FIELD(TPAFCR, TFIFO_SIZE, ++ GMAC_EXTRACT(FEAR, TFIFO_RSIZE, rdata)); ++ GMAC_SET_FIELD(TPAFCR, RFIFO_SIZE, ++ GMAC_EXTRACT(FEAR, RFIFO_RSIZE, rdata)); ++ ++ wdata = GMAC_PREPARE(MACCR, RX_MULTIPKT_EN, 0x1) | ++ GMAC_PREPARE(MACCR, BROADPKT_EN, 0x1) | ++ GMAC_PREPARE(MACCR, RX_ALLADR, 0x1) | ++ GMAC_PREPARE(MACCR, CRC_APD, 0x1) | ++ GMAC_PREPARE(MACCR, FULLDUP, duplex) | ++ GMAC_PREPARE(MACCR, RX_RUNT, 0x1) | ++ GMAC_PREPARE(MACCR, SPEED, speed) | ++ GMAC_PREPARE(MACCR, GMAC_MODE, gmac) | ++ GMAC_PREPARE(MACCR, RXMAC_EN, 0x1) | ++ GMAC_PREPARE(MACCR, TXMAC_EN, 0x1) | ++ GMAC_PREPARE(MACCR, RXDMA_EN, 0x1) | ++ GMAC_PREPARE(MACCR, TXDMA_EN, 0x1); ++ GMAC_SET_REG(MACCR, wdata); ++ ++#ifdef AHBC_NO_REMAP ++ GMAC_SET_REG(NPTXR_BADR, FTGMAC100_TXR_BASE | 0x40000000); ++ GMAC_SET_REG(RXR_BADR, FTGMAC100_RXR_BASE | 0x40000000); ++#else ++ GMAC_SET_REG(NPTXR_BADR, FTGMAC100_TXR_BASE); ++ GMAC_SET_REG(RXR_BADR, FTGMAC100_RXR_BASE); ++#endif ++ return; ++} ++ ++UINT32 eth_phy_stat(UINT32 phy_addr, ETH_PHY_STAT * phy_stat) ++{ ++ ++ phy_stat->speed = 0x1; ++ phy_stat->duplex = 0x1; ++ ++ return 0; ++} ++ ++void gmac_set_wol() ++{ ++ UINT32 wdata; ++ ++ // Set Rx Wake-up Frame ++ // write 1 clear register before enable power saving mode ++ GMAC_SET_REG(WOLSR, 0xffffffff); // clear wol status ++ ++ // set wakeup_sel and power saving mode enable ++ wdata = GMAC_PREPARE(WOLCR, MAGICPKT_EN, 0x1) | ++ GMAC_PREPARE(WOLCR, PWRSAV, 0x1); ++ ++ GMAC_SET_REG(WOLCR, wdata); ++ ++ return; ++} ++ ++// End ADD by river 2010.12.07 for WOL ++ ++//////////////////////////////// LPC wake up /////////////////////////////////////////////////// ++#define CPE_LPCIO_BASE LPC_IO_VA_BASE //VA Base ++#define CPE_LPCREG_BASE LPC_REG_VA_BASE //VA Base ++#define CPE_IC_BASE AMIC_VA_BASE ++ ++#define ITE_ADDR 0x2e ++#define ITE_DATA 0x2f ++ ++#define KBC_CMD 0x64 ++#define KBC_STATUS KBC_CMD ++#define KBC_DATA 0x60 ++ ++#define BIT_OBF 0x01 ++#define BIT_IBF 0x02 ++ ++#define LPC_REG_SCR 0x10 ++#define LPC_REG_SIR 0x14 ++#define LPC_REG_SIMR 0x18 ++ ++#define SIRQ_KB 1 ++#define SIRQ_MS 12 ++ ++//#define outlpc(addr, data) outb(data, CPE_LPCIO_BASE + 4 * addr) ++//#define inlpc(addr) inb(CPE_LPCIO_BASE + 4 * addr) ++#define inlpc(addr) REG32(CPE_LPCIO_BASE + 4 * addr) ++ ++#define IRQ_LPC 29 ++#define LEVEL 0 ++#define H_ACTIVE 0 ++#define L_ACTIVE 1 ++#define IRQ_MASK 0x80 ++#define IRQ_MODE 0x20 ++#define IRQ_LEVEL 0x24 ++ ++UINT32 IRQSources = 0; //define the current irq source for debug ++ ++static inline void outlpc(unsigned long addr, unsigned long data) ++{ ++ REG32(CPE_LPCIO_BASE + 4 * addr) = data; ++} ++ ++static void kbc_cmd(UINT8 cmd) ++{ ++ int loop_limit = 1000; ++ int i; ++ UINT8 tmpc; ++ ++ // wait until the input buffer is empty ++ for (i = 0; i < loop_limit; i++) { ++ tmpc = inlpc(KBC_STATUS); ++ if ((tmpc & BIT_IBF) == 0) ++ break; ++ } ++ ++ outlpc(KBC_CMD, cmd); ++} ++ ++static void kbc_wdata(UINT8 wdata) ++{ ++ int loop_limit = 1000; ++ int i; ++ UINT8 tmpc; ++ ++ // wait until the input buffer is empty ++ for (i = 0; i < loop_limit; i++) { ++ tmpc = inlpc(KBC_STATUS); ++ if ((tmpc & BIT_IBF) == 0) ++ break; ++ } ++ ++ outlpc(KBC_DATA, wdata); ++} ++ ++static UINT8 kbc_rdata(void) ++{ ++ int loop_limit = 1000; ++ int i; ++ UINT8 rdata; ++ UINT8 tmpc; ++ ++ // wait until the output buffer is not empty ++ for (i = 0; i < loop_limit; i++) { ++ tmpc = inlpc(KBC_STATUS); ++ if (tmpc & BIT_OBF) ++ break; ++ } ++ ++ rdata = inlpc(KBC_DATA); ++ return (rdata); ++} ++ ++static void delay_loop(int max_no) ++{ ++ int i; ++ ++ for (i = 0; i < max_no; i++) ; ++} ++ ++static UINT8 get_response(void) ++{ ++ UINT8 tmpc; ++ ++ delay_loop(200000); ++ tmpc = kbc_rdata(); ++ return (tmpc); ++} ++ ++int it8718f_init(void) ++{ ++ static int initialized = 0; ++ UINT8 tmpc; ++ unsigned int chip_id; ++ ++ if (initialized == 1) ++ return (0); ++ ++ // Enter the configuration mode ++ outlpc(ITE_ADDR, 0x87); ++ outlpc(ITE_ADDR, 0x01); ++ outlpc(ITE_ADDR, 0x55); ++ outlpc(ITE_ADDR, 0x55); ++ ++ // Check the chip ID ++ printk("Check IT8718F chip ID => "); ++ outlpc(ITE_ADDR, 0x20); ++ tmpc = inlpc(ITE_DATA); ++ chip_id = (tmpc & 0xff) << 8; ++ outlpc(ITE_ADDR, 0x21); ++ tmpc = inlpc(ITE_DATA); ++ chip_id |= tmpc & 0xff; ++ ++ if (chip_id != 0x8718) { ++ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, ++ chip_id & 0xff); ++ return (1); ++ } else ++ printk("PASSED\n"); ++ ++ // KBC Self Test ++ printk("KBC self-test => "); ++ kbc_cmd(0xaa); ++ tmpc = kbc_rdata(); ++ if (tmpc != 0x55) { ++ printk("FAILED with code = 0x%C\n", tmpc & 0xff); ++ return (2); ++ } else ++ printk("PASSED\n"); ++ ++ // KBC Interface Test ++ printk("KBC interface test => "); ++ kbc_cmd(0xab); ++ tmpc = kbc_rdata(); ++ switch (tmpc) { ++ case 0: ++ printk("PASSED\n"); ++ break; ++ ++ case 1: ++ printk("FAILED as the clock is stuck low\n"); ++ return (3); ++ ++ case 2: ++ printk("FAILED as the clock is stuck high\n"); ++ return (3); ++ ++ case 3: ++ printk("FAILED as the data is stuck low\n"); ++ return (3); ++ ++ case 4: ++ printk("FAILED as the data is stuck high\n"); ++ return (3); ++ ++ default: ++ printk("FAILED with unknown error\n"); ++ return (3); ++ break; ++ } ++ ++ // Read the KBC mode ++ kbc_cmd(0xca); ++ tmpc = kbc_rdata(); ++ ++ // Set KBC to the PS/2 mode ++ tmpc |= 0x01; ++ kbc_cmd(0xcb); ++ kbc_wdata(tmpc); ++ ++ // Enable keyboard ++ kbc_wdata(0xf4); ++ tmpc = get_response(); ++ printk("@@@@@ : Response of enabling keyboard = 0x%x\n", tmpc & 0xff); ++ ++ // Enable mouse ++ kbc_cmd(0xd4); ++ kbc_wdata(0xf4); ++ tmpc = get_response(); ++ //outmsg("Response of enabling mouse = 0x%C\n", tmpc & 0xff); ++ ++ // bit 6: translate ++ // bit 5: mouse enable ++ // bit 4: keyboard enable ++ // bit 3: ignore keyboard lock ++ // bit 2: system flag ++ // bit 1: mouse interrupt enable ++ // bit 0: Keyboard interrupt enable ++ kbc_cmd(0x60); ++ kbc_wdata(0x47); ++ ++ // Set repeat rate and delay ++ kbc_wdata(0xf3); ++ kbc_wdata(0x00); ++ tmpc = get_response(); ++ ++ // Set LDN = 5 (Keyboard) ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x05); ++ ++ // KBC clock = 8MHz, Key lock enabled, interrupt type can be changed ++ outlpc(ITE_ADDR, 0xf0); ++ outlpc(ITE_DATA, 0x4e); ++ ++ // Low-level triggered interrupt ++ outlpc(ITE_ADDR, 0x71); ++ outlpc(ITE_DATA, 0x01); ++ ++ // Set LDN = 6 (Mouse) ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x06); ++ ++ // Enable mouse ++ outlpc(ITE_ADDR, 0x30); ++ outlpc(ITE_DATA, 0x01); ++ ++ // Interrupt type can be changed ++ outlpc(ITE_ADDR, 0xf0); ++ outlpc(ITE_DATA, 0x01); ++ ++ // Low-level triggered interrupt ++ outlpc(ITE_ADDR, 0x71); ++ outlpc(ITE_DATA, 0x01); ++ ++ // Exit the configuration mode ++ outlpc(ITE_ADDR, 0x02); ++ outlpc(ITE_DATA, 0x02); ++ ++ initialized = 1; ++ return (0); ++} ++ ++//INT for lpc ++/* Turn the interrupt source on. */ ++void UnmaskIRQ(UINT32 IRQ) ++{ ++ volatile UINT32 *IRQBase; ++ ++ IRQBase = (UINT32 *) CPE_IC_BASE; ++ ++ IRQBase[(IRQ_MASK / sizeof(UINT32))] |= (1 << IRQ); ++} ++ ++void EnableIRQ() ++{ ++ ++ __asm__ volatile ("setgie.d\n\t" ++ "isb\n\t" ++ "mfsr $r1, $INT_MASK\n\t" ++ "ori $r1, $r1, #0x3f\n\t" ++ "mtsr $r1, $INT_MASK\n\t" ++ "setgie.e\n\t" "isb\n\t"); ++ ++} ++ ++void SetIRQmode(UINT32 IRQ, UINT32 edge) ++{ ++ volatile UINT32 *IRQBase; ++ ++ IRQBase = (UINT32 *) CPE_IC_BASE; ++ ++ if (edge) ++ IRQBase[(IRQ_MODE / sizeof(UINT32))] |= (1 << IRQ); ++ else ++ IRQBase[(IRQ_MODE / sizeof(UINT32))] &= ~(1 << IRQ); ++} ++ ++void SetIRQlevel(UINT32 IRQ, UINT32 low) ++{ ++ volatile UINT32 *IRQBase; ++ ++ IRQBase = (UINT32 *) CPE_IC_BASE; ++ ++ if (low) ++ IRQBase[(IRQ_LEVEL / sizeof(UINT32))] |= (1 << IRQ); ++ else ++ IRQBase[(IRQ_LEVEL / sizeof(UINT32))] &= ~(1 << IRQ); ++} ++ ++BOOL SetIntTrig(UINT32 intNum, int intMode, int intLevel) ++{ ++ if (intNum >= 32) { ++ printk("ERROR: The interrupt number %d is incorrect\n", intNum); ++ return FALSE; ++ } else { ++ SetIRQmode(intNum, intMode); ++ SetIRQlevel(intNum, intLevel); ++ return TRUE; ++ } ++} ++ ++BOOL EnableInt(UINT32 intNum) ++{ ++ ++ if (intNum >= 32) { ++ printk("ERROR: The interrupt number %d is incorrect\n", intNum); ++ return FALSE; ++ } else { ++ IRQSources |= 1 << intNum; ++ UnmaskIRQ(intNum); ++ EnableIRQ(); ++ return TRUE; ++ } ++} ++ ++//End INT for lpc ++ ++void enable_sirq(void) ++{ ++ UINT32 data; ++ ++ // Unmask SERIRQs of Keyboard and Mouse ++ data = inw(CPE_LPCREG_BASE + LPC_REG_SIMR); ++ data &= ~((1 << SIRQ_KB) | (1 << SIRQ_MS)); ++ outw(CPE_LPCREG_BASE + LPC_REG_SIMR, data); ++ ++ // Enable SERIRQ ++ data = inw(CPE_LPCREG_BASE + LPC_REG_SCR); ++ data |= 0x1; ++ outw(CPE_LPCREG_BASE + LPC_REG_SCR, data); ++} ++ ++void ite_set_pme() ++{ ++ ++ UINT8 tmpc; ++ unsigned int chip_id; ++ // Enter the configuration mode ++ outlpc(ITE_ADDR, 0x87); ++ outlpc(ITE_ADDR, 0x01); ++ outlpc(ITE_ADDR, 0x55); ++ outlpc(ITE_ADDR, 0x55); ++ ++ // Check the chip ID ++ printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n"); ++ outlpc(ITE_ADDR, 0x20); ++ tmpc = inlpc(ITE_DATA); ++ chip_id = (tmpc & 0xff) << 8; ++ outlpc(ITE_ADDR, 0x21); ++ tmpc = inlpc(ITE_DATA); ++ chip_id |= tmpc & 0xff; ++ ++ printk("@@@@@ : chip_id = 0x%08x\n", chip_id); ++ if (chip_id != 0x8718) { ++ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, ++ chip_id & 0xff); ++ return (1); ++ } else ++ printk("@@@@@ : PASSED\n"); ++ ++ // Set LDN = 5 ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x05); ++ ++ //Read index 30 ++ outlpc(ITE_ADDR, 0x30); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x30] = 0x%x\n", tmpc); ++ //Set index 30 bit0 = 0; ++ outlpc(ITE_ADDR, 0x30); ++ outlpc(ITE_DATA, tmpc & 0xFE); ++ ++ // Set LDN = 6 ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x06); ++ ++ //Read index 30 ++ outlpc(ITE_ADDR, 0x30); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x30] = 0x%x\n", tmpc); ++ //Set index 30 bit0 = 0; ++ outlpc(ITE_ADDR, 0x30); ++ outlpc(ITE_DATA, tmpc & 0xFE); ++ ++ // Set LDN = 4 for PME ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x04); ++ ++ //Read index F0 ++ outlpc(ITE_ADDR, 0xF0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF0] = 0x%x\n", tmpc); ++ //Set index F0 BIT[4:3]=1; ++ outlpc(ITE_ADDR, 0xF0); ++ outlpc(ITE_DATA, tmpc | 0x18); ++ ++ //PME output enable ++ //Read index F2 ++ outlpc(ITE_ADDR, 0xF2); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF2] = 0x%x\n", tmpc); ++ //Set index F2 bit6=0; ++ outlpc(ITE_ADDR, 0xF2); ++ outlpc(ITE_DATA, tmpc & 0xBF); ++ ++ // Exit the configuration mode ++ outlpc(ITE_ADDR, 0x02); ++ outlpc(ITE_DATA, 0x02); ++} ++ ++void get_keyboard_status() ++{ ++ ++ printk("Getting keyboard status....\n"); ++ ++ UINT8 tmpc; ++ unsigned int chip_id; ++ ++ // Enter the configuration mode ++ outlpc(ITE_ADDR, 0x87); ++ outlpc(ITE_ADDR, 0x01); ++ outlpc(ITE_ADDR, 0x55); ++ outlpc(ITE_ADDR, 0x55); ++ ++ // Check the chip ID ++ //printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n"); ++ outlpc(ITE_ADDR, 0x20); ++ tmpc = inlpc(ITE_DATA); ++ chip_id = (tmpc & 0xff) << 8; ++ outlpc(ITE_ADDR, 0x21); ++ tmpc = inlpc(ITE_DATA); ++ chip_id |= tmpc & 0xff; ++ ++ //printk("@@@@@ : chip_id = 0x%08x\n", chip_id); ++ if (chip_id != 0x8718) { ++ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, ++ chip_id & 0xff); ++ return (1); ++ } ++ // Set LDN = 4 for PME ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x04); ++ ++ ///////// Dump configuration register ++ outlpc(ITE_ADDR, 0xf1); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf1] = 0x%x\n", tmpc); ++ ++ ///////// Dump configuration register ++ outlpc(ITE_ADDR, 0xf0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf0] = 0x%x\n", tmpc); ++ ++} ++ ++void get_lpc_value() ++{ ++ UINT8 tmpc; ++ unsigned int chip_id; ++ ++ // Enter the configuration mode ++ outlpc(ITE_ADDR, 0x87); ++ outlpc(ITE_ADDR, 0x01); ++ outlpc(ITE_ADDR, 0x55); ++ outlpc(ITE_ADDR, 0x55); ++ ++ // Check the chip ID ++ printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n"); ++ outlpc(ITE_ADDR, 0x20); ++ tmpc = inlpc(ITE_DATA); ++ chip_id = (tmpc & 0xff) << 8; ++ outlpc(ITE_ADDR, 0x21); ++ tmpc = inlpc(ITE_DATA); ++ chip_id |= tmpc & 0xff; ++ ++ printk("@@@@@ : chip_id = 0x%08x\n", chip_id); ++ if (chip_id != 0x8718) { ++ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, ++ chip_id & 0xff); ++ return (1); ++ } else ++ printk("@@@@@ : PASSED\n"); ++ ++ printk("=================== Get Values ==================\n"); ++ //////////// Environment Controller configuration register ++ printk("@@@@@ : Environment Controller configuration register\n"); ++ // Set LDN = 4 for PME ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x04); ++ ++ printk("@@@@@ : LDN = 4\n"); ++ ++ ///////// Dump configuration register ++ outlpc(ITE_ADDR, 0x30); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x30] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x60); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x60] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x61); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x61] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x62); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x62] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x63); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x63] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x70); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x70] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf0] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf1); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf1] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf2); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf2] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf3); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf3] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf4); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf4] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf5); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf5] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf6); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf6] = 0x%x\n", tmpc); ++ ++ //////////// Keyboard configuration register ++ printk("@@@@@ : Keyboard configuration register\n"); ++ // Set LDN = 5 ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x05); ++ ++ printk("@@@@@ : LDN = 5\n"); ++ ++ outlpc(ITE_ADDR, 0x30); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x30] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x60); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x60] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x61); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x61] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x62); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x62] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x63); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x63] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x70); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x70] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x71); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x71] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xf0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xf0] = 0x%x\n", tmpc); ++ ++ //////////// GPIO configuration register ++ printk("@@@@@ : GPIO configuration register\n"); ++ // Set LDN = 7 for GPIO ++ outlpc(ITE_ADDR, 0x07); ++ outlpc(ITE_DATA, 0x07); ++ ++ printk("@@@@@ : LDN = 7\n"); ++ ++ outlpc(ITE_ADDR, 0x60); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x60] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x62); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x62] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x63); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x63] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x64); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x64] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x65); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x65] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x70); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x70] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x71); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x71] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x72); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x72] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x73); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x73] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0x74); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0x74] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB0] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB1); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB1] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB2); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB2] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB3); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB3] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB4); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB4] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB5); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB5] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xB8); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xB8] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xBA); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xBA] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xBB); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xBB] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xBC); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xBC] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xBD); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xBD] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC0] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC1); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC1] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC2); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC2] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC3); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC3] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC4); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC4] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC5); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC5] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC8); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC8] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xC9); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xC9] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xCA); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xCA] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xCB); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xCB] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xCC); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xCC] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xCD); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xCD] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE0] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE1); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE1] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE2); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE2] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE3); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE3] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE4); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE4] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE5); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE5] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xE6); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xE6] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF0); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF0] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF1); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF1] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF2); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF2] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF3); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF3] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF4); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF4] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF5); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF5] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF6); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF6] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF7); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF7] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF8); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF8] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xF9); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xF9] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xFA); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xFA] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xFB); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xFB] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xFC); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xFC] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xFD); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xFD] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xFE); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xFE] = 0x%x\n", tmpc); ++ ++ outlpc(ITE_ADDR, 0xFF); ++ tmpc = inlpc(ITE_DATA); ++ printk("[0xFF] = 0x%x\n", tmpc); ++ ++ printk("=================== End Get Values ==================\n"); ++ ++} ++ ++/////////////////////////////// End LPC wake up /////////////////////////////////////////////// ++ ++/* ++ * AG102 PMU sleep mode handler. ++ */ ++void andes_suspend_to_ram() ++{ ++ int i, k, l, checksum, checksuma; ++ unsigned int addr, reg; ++ static int irq_saves[3]; ++ unsigned int tmp; ++ pgd_t *pgdv; ++ pud_t *pudv; ++ pmd_t *pmdv; ++ pte_t *ptev; ++ unsigned int resume_addr /*, resume_temp */ ; ++ //unsigned int *resume_tempaddr; ++ __asm__ volatile ("mfsr %0, $ir14\n\t":"=&r" (tmp)); ++ //printk("\nag102_cpu_resume:0x%x\n", ag102_cpu_resume); ++ //printk( KERN_WARNING "\nag102_cpu_resume2:0x%x\n", ag102_cpu_resume2); ++ pgdv = ++ (pgd_t *) __va((GET_L1_PPTB() & L1_PPTB_mskBASE)) + ++ pgd_index((unsigned int)ag102_cpu_resume); ++ pudv = pud_offset(pgdv, (unsigned int)ag102_cpu_resume); ++ pmdv = pmd_offset(pudv, (unsigned int)ag102_cpu_resume); ++ ptev = pte_offset_map(pmdv, (unsigned int)ag102_cpu_resume); ++ //printk("ag102_cpu_resume pte:0x%x\n", ptev); ++ resume_addr = ++ ((*ptev) & TLB_DATA_mskPPN) | ((unsigned int)ag102_cpu_resume & ++ 0x00000fff); ++ printk("resume_addr using Page Table :0x%08x\n", resume_addr); ++ ++ //ADD by river 2010.09.23 ++ printk("@@@@@ resume_addr(VA):0x%08x\n", ag102_cpu_resume); ++ printk("@@@@@ resume_addr2(VA):0x%08x\n", ag102_cpu_resume2); ++ printk("@@@@@ resume_addr(PA) using virt_to_phys :0x%08x\n", ++ virt_to_phys(ag102_cpu_resume)); ++ printk("@@@@@ resume_addr2(PA):0x%08x\n", ++ virt_to_phys(ag102_cpu_resume2)); ++ printk("@@@@@ AHB Controller for ROM :0x%08x\n", ++ REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x10)); ++ printk("@@@@@ AHB Controller for RAM :0x%08x\n", ++ REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x18)); ++ //End ADD by river 2010.09.23 ++ ++ /* trigger mode regs */ ++ irq_saves[0] = REG32(AMIC_VA_BASE + 0x20); ++ /* trigger level regs */ ++ irq_saves[1] = REG32(AMIC_VA_BASE + 0x24); ++ /* interrupt enable regs */ ++ irq_saves[2] = REG32(AMIC_VA_BASE + 0x80); ++ /* save SDRAM settings */ ++ ++ /* set resume return address */ ++ //REG32(PCU_VA_BASE + 0x400) = (resume_addr); ++ REG32(PCU_VA_BASE + 0x400) = (resume_addr) | 0x80000000; ++ REG32(PCU_VA_BASE + 0x404) = (u32) ag102_cpu_resume2; ++ REG32(PCU_VA_BASE + 0x410) = GET_L1_PPTB(); ++ //ADD by river 2010.12.02 for reserve kernel remap ++ REG32(PCU_VA_BASE + 0x418) = REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x10); ++ REG32(PCU_VA_BASE + 0x41C) = REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x18); ++ //End ADD by river 2010.12.02 for reserve kernel remap ++ printk("L1_PPTB (PA) =0x%08x\n", GET_L1_PPTB()); ++ printk("L1_PPTB (VA) in virtual address =0x%08x\n", ++ phys_to_virt(GET_L1_PPTB())); ++ ++ //ADD by river 2010.12.07 ++ UINT32 phy_id, phy_addr; ++ ETH_PHY_STAT phy_stat; ++ ++ if (eth_phy_detect(&phy_addr, &phy_id) != 0) { ++ printk("ERR: fail to detect known PHY!!!\n"); ++ return; ++ } ++ //TEST by river 2010.12.10 ++ eth_phy_init(phy_addr); ++ eth_phy_stat(phy_addr, &phy_stat); ++ eth_mac_init(&phy_stat); ++ //End TEST by river 2010.12.10 ++ gmac_set_wol(); ++ //End ADD by river 2010.12.07 ++ ++ /////////// ADD by river 2010.12.20 for LPC wakeup ///////////////////////////// ++ if (it8718f_init() != 0) ++ return; ++ ++ //INTC setup ++ SetIntTrig(IRQ_LPC, LEVEL, H_ACTIVE); ++ EnableInt(IRQ_LPC); // including INT_MASK and GIE in Core ++ ++ enable_sirq(); ++ ++ //__asm__ volatile ("1:\n\t"); ++ //__asm__ volatile ("b 1b\n\t"); ++ ++ printk("Calling ite_set_pme() YAYAYA....\n"); ++ ite_set_pme(); ++ ++ printk("Get Value..... YAYAYA....1\n"); ++ get_lpc_value(); ++ ++ /////////// End ADD by river 2010.12.20 for LPC wakeup ///////////////////////////// ++ ++ //set GPIO[2] as suspend2dram power control pin ++ PCU_SET_FIELD(MFPS1, SUSPEND_GPIO, 0x1); ++ PCU_SET_FIELD(PCS9_PDD, SUSP2RAM, 0x1); ++ //ADD by river 2010.12.07 ++ PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, PCS_WKEN_WOL | PCS_WKEN_LPC | PCS_WKEN_RTC)); // use only gpio0 and wol ++ //PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, PCS_WKEN_LPC)); // use lpc ++ ++ //End ADD by river 2010.12.07 ++ ++ /* set pwoer status */ ++ //int par = PCS_POWER_GPU_AND_DAC|PCS_POWER_CPUB; ++ int reg_tmp = PCU_PREPARE(PCS9_PARA, IE, 0x1) | ++ PCU_PREPARE(PCS9_PARA, CMD, ++ PCS_CMD_PW_DOWN /*PCS_CMD_SCALING|PCS_CMD_DRAM_SF */ ) | ++ PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | PCU_PREPARE(PCS9_PARA, NXTPAR, 0 /*par */ ); // change power status ++ PCU_SET_REG(PCS9_PARA, reg_tmp); ++ ++ //PCU_SET_FIELD(MFPS1, SUSPEND_GPIO, 0x1); ++ /* setup wakeup sources */ ++ /* ++ k = PCU_PREPARE(WAKEUP_SEN, GPIO0_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, GPIO1_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, GPIO2_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, GPIO3_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, GPIO4_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, GPIO5_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, WOL_POL, 0x1) | ++ PCU_PREPARE(WAKEUP_SEN, LPC_POL, 0x1); ++ l = ~k; //set polarity ++ //l = 0x1c0; ++ PCU_SET_REG(WAKEUP_SEN, l); ++ PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, k)); ++ */ ++ /* Set PDD register and set suspend_to_ram */ ++ //PCU_SET_FIELD(PCS9_PDD, SUSP2RAM, 0x1); ++ ++ cpu_dcache_wbinval_all(); ++ cpu_icache_inval_all(); ++ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN); ++ ++ /* lock self-refresh code to L1 cache */ ++ ++ addr = (unsigned int)__SELF_REFRESH_LOCK_START; ++ reg = (((unsigned int)__SELF_REFRESH_LOCK_END - (unsigned int)__SELF_REFRESH_LOCK_START) >> 5) + 1; // ++ ++ for (i = 0; i < reg; i++) { ++ __asm__ volatile ("li $p0, 0x0\n\t" ++ "add $p0, $p0, %0\n\t" ++ "cctl $p0, L1I_VA_FILLCK\n\t" ++ "isb\n\t"::"r" (addr)); ++ ++ addr += 32; ++ } ++ ++ unsigned char *ptr; ++ //ADD by river 2010.11.19 ++ printk("The resume address's content is :\n"); ++ ptr = (unsigned char *)ag102_cpu_resume; ++ for (i = 0; i < 20; i++) { ++ printk("0x%02x - ", *ptr++); ++ } ++ ++ printk("Get Value..... YAYAYA....2\n"); ++ get_lpc_value(); ++ ++ //End ADD by river 2010.11.19 ++ ag102_cpu_sleep(); ++ printk("return success-1..........\n"); ++ /* wakeup and ckeck */ ++ /* ++ reg_tmp = PCU_GET_REG(PCS9_ST2);// check Status-2 ++ if (PCU_EXTRACT(PCS9_ST2, CURPAR, reg_tmp) != par) ++ printk("Parameter setup is not the same!\n"); ++ ++ reg_tmp = PCU_GET_REG(PCS9_ST1); // check Status-1 ++ if (PCU_EXTRACT(PCS9_ST1, STS, reg_tmp) != PCS_STS_DONE) ++ printk("The work is not done?!\n"); ++ if (PCU_EXTRACT(PCS9_ST1, ERR, reg_tmp) != PCS_ERR_NONE) ++ printk("Some error happened!!\n"); ++ PCU_SET_REG(PCS9_ST1, 0x0); //clear status ++ ++ */ ++ ftpci_postinit(); ++ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN); ++ /* trigger mode regs */ ++ REG32(AMIC_VA_BASE + 0x20) = irq_saves[0]; ++ /* trigger level regs */ ++ REG32(AMIC_VA_BASE + 0x24) = irq_saves[1]; ++ /* interrupt enable regs */ ++ REG32(AMIC_VA_BASE + 0x80) = irq_saves[2]; ++ __asm__ volatile ("mtsr %0, $ir14\n\t"::"r" (tmp)); ++ ++ printk("return success-2..........\n"); ++ dump_stack(); ++ ++} ++ ++static int ag102_pm_valid(suspend_state_t state) ++{ ++ switch (state) { ++ case PM_SUSPEND_ON: ++ case PM_SUSPEND_STANDBY: ++ case PM_SUSPEND_MEM: ++ return 1; ++ ++ default: ++ return 0; ++ } ++} ++ ++static int ag102_pm_begin(suspend_state_t state) ++{ ++ /* TBD if we need it */ ++ return 0; ++} ++ ++static void andes_suspend_cpu(void) ++{ ++ unsigned int irq_save; ++ /* setup GPIO interrupt enable regs to enable GPIO0 */ ++ REG32(GPIO_VA_BASE + 0x20) = 1; ++ /* save interrupt enable regs */ ++ irq_save = REG32(AMIC_VA_BASE + 0x80); ++ /* accept all interrupts to wake up except timer interrupt */ ++ REG32(AMIC_VA_BASE + 0x80) &= ~(1 << 19); ++ /* enable UART0 interrupt */ ++ REG32(AMIC_VA_BASE + 0x80) |= 1 << 13; ++ ++ /* ++ * for more IRQ info, please refer to ++ * arch/nds32/include/asm/spec.h&spec-ag102.h ++ */ ++ ++ __asm__ volatile ("standby no_wake_grant\n\t"); ++ /* clear GPIO interrupt */ ++ REG32(GPIO_VA_BASE + 0x30) = 1; ++ /* disable GPIO interrupt */ ++ REG32(GPIO_VA_BASE + 0x20) = 0; ++ /* restore GPIO enable regs */ ++ REG32(AMIC_VA_BASE + 0x80) = irq_save; ++} ++ ++static int ag102_pm_enter(suspend_state_t state) ++{ ++ switch (state) { ++ case PM_SUSPEND_STANDBY: ++ andes_suspend_cpu(); ++ return 0; ++ case PM_SUSPEND_MEM: ++ printk("@@@@@@@@@@ : ag102_pm_enter()... from gavin.......\n"); ++ andes_suspend_to_ram(); ++ return 0; ++ default: ++ return -EINVAL; ++ } ++} ++ ++/* ++ * Called after processes are frozen, but before we shutdown devices. ++ */ ++static int ag102_pm_prepare(void) ++{ ++ /* TBD if we need it */ ++ return 0; ++} ++ ++/* ++ * Called after devices are wakeuped, but before processes are thawed. ++ */ ++static void ag102_pm_finish(void) ++{ ++ /* TBD if we need it */ ++} ++ ++static void ag102_pm_end(void) ++{ ++ /* TBD if we need it */ ++#if 0 ++ class_destroy(andes_pcu_class); ++ unregister_chrdev(andes_pcu_major, ANDES_PCU_STRING); ++#endif ++ printk("pm_exit\n"); ++} ++ ++static int andes_pcu_ioctl(struct inode *inode, struct file *file, ++ unsigned int cmd, unsigned long arg) ++{ ++ return 0; ++} ++ ++static int andes_pcu_open(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++static ssize_t andes_pcu_write(struct file *filp, const char *buff, ++ size_t count, loff_t * ppos) ++{ ++ char data; ++ get_user(data, buff); ++ switch (data) { ++ case 's': ++ printk("Just suspend cpu\n"); ++ andes_suspend_cpu(); ++ break; ++ case 'm': ++ printk("Suspend to ram\n"); ++ andes_suspend_to_ram(); ++ break; ++ } ++ return 0; ++} ++ ++static int andes_pcu_release(struct inode *inode, struct file *file) ++{ ++ return 0; ++} ++ ++static struct file_operations andes_pcu_fops = { ++ .owner = THIS_MODULE, ++ .ioctl = andes_pcu_ioctl, ++ .open = andes_pcu_open, ++ .write = andes_pcu_write, ++ .release = andes_pcu_release, ++}; ++ ++static struct platform_suspend_ops ag102_pm_ops = { ++ .valid = ag102_pm_valid, ++ .begin = ag102_pm_begin, ++ .prepare = ag102_pm_prepare, ++ .enter = ag102_pm_enter, ++ .finish = ag102_pm_finish, ++ .end = ag102_pm_end, ++}; ++ ++//PCU power-off workaround { ++#undef IRQ_LEVEL ++#include ++#include ++ ++//#define PM_DEBUG ++#ifdef PM_DEBUG ++#define PRINTK printk ++#else ++#define PRINTK(...) ++#endif ++ ++static volatile int pcuirq = 0; ++ ++static inline void poweroff_pcu(void) ++{ ++ PRINTK(KERN_INFO "[kernel] poweroff_pcu()"); ++ REG32(PCU_VA_BASE + 0x1a4) = (2 << 28) | (1 << 24) | (6 << 0); //power-down, sync CPUA, domain GPU+CPUB ++ __asm__ volatile ("standby wait_done\n"); ++ REG32(PCU_VA_BASE + 0x1a8) = 0x0; //PCS9 status normal, no error ++} ++ ++static inline void clear_pcu_status(void) ++{ ++ PRINTK(KERN_INFO "[kernel] clear_pcu_status()"); ++ REG32(PCU_VA_BASE + 0x1b0) |= (1 << 31); //clear poweroff flag ++ asm("msync store\nisb"); ++} ++ ++static irqreturn_t gpio0_isr(int irq, void *dev_id) ++{ ++ PRINTK(KERN_INFO "[kernel] gpio0_isr(irq=%d)\n", irq); ++ ++ // is GPIO0 IRQ ++ if (REG32(GPIO_VA_BASE + 0x28) & (1 << 0)) { ++ PRINTK(KERN_INFO "GPIO#0 ASSERT!\n"); ++ ++ pcuirq = 0; ++ ++ //disable GPIO0 IRQ ++ REG32(GPIO_VA_BASE + 0x2c) |= (1 << 0); //GPIO0 IRQ mask, level mode AMIC.GPIO#0 also cleared ++ ++// REG32(AMIC_VA_BASE + 0x84) = (1<<13); //AMIC clear GPIO interrupt ++ ++ return IRQ_HANDLED; ++ } ++ ++ return IRQ_NONE; ++} ++ ++#define GPIO_SEC (1<<11) ++static irqreturn_t pcu_isr(int irq, void *dev_id) ++{ ++ UINT32 status = REG32(PCU_VA_BASE + 0x94); ++ PRINTK(KERN_INFO "[kernel] pcu_isr(irq=%d) status=0x%08x\n", irq, ++ status); ++ if (0 == (GPIO_SEC & status)) ++ return IRQ_NONE; ++ ++ PRINTK(KERN_INFO "[kernel] GPIO_SEC\n"); ++ clear_pcu_status(); //clear PCS9 IRQ (level mode => AMIC.PCU also cleared) ++ pcuirq++; ++ if (1 == pcuirq) { ++ //enable GPIO0 IRQ ++ REG32(GPIO_VA_BASE + 0x30) = (1 << 0); //GPIO0 IRQ cleared ++// REG32(AMIC_VA_BASE + 0x84) = (1 << 13); //AMIC clear GPIO interrupt ++// enable_irq(GPIO_FTGPIO010_IRQ); ++ REG32(AMIC_VA_BASE + 0x80) |= (1 << 13); //AMIC enable GPIO IRQ ++ REG32(GPIO_VA_BASE + 0x2c) &= ~(1 << 0); //GPIO0 IRQ unmask ++ } else if (5 == pcuirq) { ++ poweroff_pcu(); ++ } ++// REG32(AMIC_VA_BASE + 0x84) = (1 << 8); //PCU IRQ clear ++ ++ return IRQ_HANDLED; ++} ++ ++//PCU power-off workaround } ++ ++static int __init ag102_pm_init(void) ++{ ++ int ret = 0; ++ struct device *temp_class; ++ printk("PM driver init\n"); ++ suspend_set_ops(&ag102_pm_ops); ++ ++ andes_pcu_major = register_chrdev(0, ANDES_PCU_STRING, &andes_pcu_fops); ++ ++ printk("@@@@@ : andes_pcu_major = 0x%08x\n", andes_pcu_major); ++ if (andes_pcu_major < 0) { ++ printk("Unable to get a major for andes pcu driver!\n"); ++ return andes_pcu_major; ++ } ++ ++ andes_pcu_class = class_create(THIS_MODULE, ANDES_PCU_STRING); ++ ++ if (IS_ERR(andes_pcu_class)) { ++ printk(KERN_ERR "Error creating andes pcu class.\n"); ++ ret = PTR_ERR(andes_pcu_class); ++ goto err_out1; ++ } ++ ++ temp_class = device_create(andes_pcu_class, NULL, ++ MKDEV(andes_pcu_major, 0), ++ NULL, ANDES_PCU_STRING); ++ ++ if (IS_ERR(temp_class)) { ++ printk(KERN_ERR "Error creating andes pcu class device.\n"); ++ ret = PTR_ERR(temp_class); ++ goto err_out2; ++ } ++ ++ mac_dah = GMAC_GET_REG(MAC_MADR); ++ mac_dal = GMAC_GET_REG(MAC_LADR); ++ ++ //poweroff workaround ++ { ++ if (request_irq ++ (PCU_IRQ, pcu_isr, IRQF_SHARED, "PCU_POWEROFF", pcu_isr)) { ++ printk("Failed to request PCU interrupt.\n"); ++ } ++ ++ if (request_irq ++ (GPIO_FTGPIO010_IRQ, gpio0_isr, IRQF_SHARED, ++ "GPIO0_FOR_PCU", gpio0_isr)) { ++ printk("Failed to request GPIO0 interrupt.\n"); ++ } ++ ++ REG32(PCU_VA_BASE + 0x1b0) |= (3 << 28); //poweroff in 5s ++ ++ //AMIC setup ++ // PCU IRQ default edge trigger, rising edge ++ // GPIO_FTGPIO010_IRQ default edge trigger, rising edge ++// REG32(AMIC_VA_BASE + 0x20) &= ~(1 << 8); //PCU IRQ level trigger ++// REG32(AMIC_VA_BASE + 0x24) &= ~(1 << 8); //PCU IRQ active-high ++// REG32(AMIC_VA_BASE + 0x20) &= ~(1 << 13); //GPIO IRQ level trigger ++ ++ //GPIO #0 setup ++ REG32(GPIO_VA_BASE + 0x08) &= ~(1 << 0); //GPIO0 input ++ REG32(GPIO_VA_BASE + 0x18) &= ~(1 << 0); //GPIO0 not pulled (external pull-high) ++ REG32(GPIO_VA_BASE + 0x2c) |= (1 << 0); //GPIO0 IRQ masked ++ REG32(GPIO_VA_BASE + 0x34) |= (1 << 0); //GPIO0 IRQ level trigger ++// REG32(GPIO_VA_BASE + 0x38) &= ~(1<<0); //GPIO0 IRQ single edge ++ REG32(GPIO_VA_BASE + 0x3c) &= ~(1 << 0); //GPIO0 IRQ high-active ++ REG32(GPIO_VA_BASE + 0x40) |= (1 << 0); //GPIO0 enable bounce ++ REG32(GPIO_VA_BASE + 0x40) = 0xffff; //GPIO bounce time = x/PCLK ++// REG32(GPIO_VA_BASE + 0x30) = (1<<0); //GPIO0 IRQ cleared ++ REG32(GPIO_VA_BASE + 0x20) |= (1 << 0); //GPIO0 IRQ enable ++ ++// enable_irq(PCU_IRQ); ++ REG32(AMIC_VA_BASE + 0x80) |= (1 << 8); //IRQ enabled ++ } ++ ++ printk("pm_init\n"); ++ return 0; ++err_out2: ++ class_destroy(andes_pcu_class); ++err_out1: ++ unregister_chrdev(andes_pcu_major, ANDES_PCU_STRING); ++ return 1; ++} ++ ++//static void resume_to_ccode(void) ++//{ ++// printk("Resume to C code successfully....\n"); ++//} ++ ++late_initcall(ag102_pm_init); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ag102/sleep.S linux-3.4.110/arch/nds32/platforms/ag102/sleep.S +--- linux-3.4.110.orig/arch/nds32/platforms/ag102/sleep.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ag102/sleep.S 2016-04-07 10:20:51.002083345 +0200 +@@ -0,0 +1,465 @@ ++#include ++.text ++ ++.globl ag102_cpu_sleep ++.globl ag102_cpu_resume ++.globl ag102_cpu_resume2 ++.globl __SELF_REFRESH_LOCK_START ++.globl __SELF_REFRESH_LOCK_END ++ ++#! 0x94200000; keep r0, r1, r2 ++ .macro putch ch ++ li $r0, #0x94200000 ++ move $r2, \ch ++88: ++ lwi $r1, [$r0+#0x14] ++ srli $r1, $r1, #5 ++ andi $r1, $r1, #0x1 ++ beqz $r1, 88b ++ swi $r2, [$r0] ++ .endm ++#! 0x94200000; keep r3, r4 ++ .macro hex2asc val ++ addi \val, \val, -10 ++ bltz \val, 1f ++ addi \val, \val, 0x41 ++ j 2f ++1: ++ addi \val, \val, 0x3a ++2: ++ .endm ++ ++ .macro print_hex mhex ++ move $r3, \mhex ++ ++ srli $r4, $r3, #28 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ srli $r4, $r3, #24 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ srli $r4, $r3, #20 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ srli $r4, $r3, #16 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ srli $r4, $r3, #12 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ srli $r4, $r3, #8 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ srli $r4, $r3, #4 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ move $r4, $r3 ++ andi $r4, $r4, 0xf ++ hex2asc $r4 ++ putch $r4 ++ .endm ++ ++ag102_cpu_resume2: ++/*1: ++b 1b*/ ++ //MOD by river 2010.10.13 ++ popm $r0, $r19 ++ mtusr $r0, $d0.lo ! $d0 lo byte ++ mtusr $r1, $d0.hi ! $d0 hi byte ++ mtusr $r2, $d1.lo ! $d1 lo byte ++ mtusr $r3, $d1.hi ! $d1 hi byte ++ mtsr $r4, $mr0 ++ mtsr $r5, $mr1 ++ mtsr $r6, $mr4 ++ mtsr $r7, $mr6 ++ mtsr $r8, $mr7 ++ mtsr $r9, $mr8 ++ mtsr $r10, $ir0 ++ mtsr $r11, $ir1 ++ mtsr $r12, $ir2 ++ mtsr $r13, $ir3 ++ mtsr $r14, $ir9 ++ mtsr $r15, $ir10 ++ mtsr $r16, $ir12 ++ mtsr $r17, $ir13 ++ mtsr $r18, $ir14 ++ mtsr $r19, $ir15 ++ //End MOD by river 2010.10.13 ++ popm $r0, $r30 ++ ret ++ ++ag102_cpu_sleep: ++ ++ pushm $r0, $r30 ++ //MOD by river 2010.10.13 ++ mfusr $r0, $d0.lo ! $d0 lo byte ++ mfusr $r1, $d0.hi ! $d0 hi byte ++ mfusr $r2, $d1.lo ! $d1 lo byte ++ mfusr $r3, $d1.hi ! $d1 hi byte ++ mfsr $r4, $mr0 ++ mfsr $r5, $mr1 ++ mfsr $r6, $mr4 ++ mfsr $r7, $mr6 ++ mfsr $r8, $mr7 ++ mfsr $r9, $mr8 ++ mfsr $r10, $ir0 ++ mfsr $r11, $ir1 ++ mfsr $r12, $ir2 ++ mfsr $r13, $ir3 ++ mfsr $r14, $ir9 ++ mfsr $r15, $ir10 ++ mfsr $r16, $ir12 ++ mfsr $r17, $ir13 ++ mfsr $r18, $ir14 ++ mfsr $r19, $ir15 ++ pushm $r0, $r19 ++ //End MOD by river 2010.10.13 ++ ++ /* store $sp to 0x408 scratch pad */ ++ sethi $r0, hi20(PCU_VA_BASE + 0x408) ++ ori $r2, $r0, lo12(PCU_VA_BASE + 0x408) ++ swi $r31, [$r2] ++ ++ /* set signaure "SUSP" to 0x40c */ ++ li $r0, (PCU_VA_BASE + 0x40c) ++ li $r1, 0x53555350 ! set signature "SUSP" to scratch pad register offset 0x40c ++ swi $r1, [$r0] ++ ++ /* ++ * store 8 bytes from 16mb to pcu scratch pad resgister ++ * due to data training process will destroy it ++ */ ++ li $r0, 0x10000 ++ li $r2, (PCU_VA_BASE + 0x414) ++ lwi $r1, [$r0] ++ swi $r1, [$r2] ++ lwi $r1, [$r0 + 0x4] ++ swi $r1, [$r2 + 0x4] ++ ++ /* ADD by river 2010.09.23 */ ++ /* Save PSW in PCU_VA_BASE + 0x420 */ ++ li $r0, (PCU_VA_BASE + 0x420) ++ mfsr $r1, $ir0 ++ swi $r1, [$r0] ++ /* Save $mr0 in PCU_VA_BASE + 0x424 */ ++ li $r0, (PCU_VA_BASE + 0x424) ++ mfsr $r1, $mr0 ++ swi $r1, [$r0] ++ /* Save $mr1 in PCU_VA_BASE + 0x428 */ ++ li $r0, (PCU_VA_BASE + 0x428) ++ mfsr $r1, $mr1 ++ swi $r1, [$r0] ++ /* Save $mr2 in PCU_VA_BASE + 0x42c */ ++ li $r0, (PCU_VA_BASE + 0x42c) ++ mfsr $r1, $mr2 ++ swi $r1, [$r0] ++ /* Save $mr3 in PCU_VA_BASE + 0x430 */ ++ li $r0, (PCU_VA_BASE + 0x430) ++ mfsr $r1, $mr3 ++ swi $r1, [$r0] ++ /* Save $mr4 in PCU_VA_BASE + 0x434 */ ++ li $r0, (PCU_VA_BASE + 0x434) ++ mfsr $r1, $mr4 ++ swi $r1, [$r0] ++ /* Save $mr5 in PCU_VA_BASE + 0x438 */ ++ //li $r0, (PCU_VA_BASE + 0x438) ++ //mfsr $r1, $mr5 ++ //swi $r1, [$r0] ++ /* Save $mr6 in PCU_VA_BASE + 0x43c */ ++ li $r0, (PCU_VA_BASE + 0x43c) ++ mfsr $r1, $mr6 ++ swi $r1, [$r0] ++ /* Save $mr7 in PCU_VA_BASE + 0x440 */ ++ li $r0, (PCU_VA_BASE + 0x440) ++ mfsr $r1, $mr7 ++ swi $r1, [$r0] ++ /* Save $mr8 in PCU_VA_BASE + 0x444 */ ++ li $r0, (PCU_VA_BASE + 0x444) ++ mfsr $r1, $mr8 ++ swi $r1, [$r0] ++ ++ /* Save $ir3 in PCU_VA_BASE + 0x450 */ ++ li $r0, (PCU_VA_BASE + 0x450) ++ mfsr $r1, $ir3 ++ swi $r1, [$r0] ++ ++ /* Save $ir14 in PCU_VA_BASE + 0x454 */ ++ li $r0, (PCU_VA_BASE + 0x454) ++ mfsr $r1, $ir14 ++ swi $r1, [$r0] ++ ++ /* Save $ir15 in PCU_VA_BASE + 0x458 */ ++ li $r0, (PCU_VA_BASE + 0x458) ++ mfsr $r1, $ir15 ++ swi $r1, [$r0] ++ ++ tlbop FlushAll ++ isb ++ /* End ADD by river 2010.09.23 */ ++ ++ //Trace by river 2010.12.01 ++ /*1: ++ b 1b*/ ++ //End Trace by river 2010.12.01 ++.p2align 5 ++__SELF_REFRESH_LOCK_START: ++ /*sethi $r0, hi20(0x900005cc) ++ ori $r0, $r0, lo12(0x900005cc) ++ sethi $r1, hi20(DDR2C_VA_BASE) ++ swi $r0, [$r1+0x4] ++ ++ msync ++ isb ++ ++ standby wake_grant ++ .p2align 5*/ ++ sethi $r0, hi20(DDR2C_VA_BASE) ++ lwi $r1, [$r0+0x4] ++ li $r2, 0x07ffefff ++ and $r1, $r2, $r1 ++ li $r2, 0x90001000 ++ or $r1, $r2, $r1 ++ swi $r1, [$r0+0x4] ++ ++ msync ++ isb ++ ++ standby wake_grant ++ .p2align ++ ++__SELF_REFRESH_LOCK_END: ++ ++ag102_cpu_resume: ++ /* TRACE by river 2010.12.02 */ ++ /*1: ++ b 1b*/ ++ /* End TRACE by river 2010.12.02 */ ++ mfsr $r2, $mr0 ++ ori $r2, $r2, #0x6 ++#ifdef CONFIG_ANDES_PAGE_SIZE_8KB ++ ori $r2, $r2, #0x1 ++#endif ++ mtsr $r2, $mr0 ++ ++ /* ADD by river 2010.09.23 */ ++ li $r3, 'C ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'P ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'U ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'R ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'E ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'S ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'U ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'M ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ li $r3, 'E ++ putch $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ /* ADD by river 2010.09.23 */ ++ ++ /*tlbop FlushAll*/ ! invalidate TLB\n" ++ ++ /* ADD by river 2010.09.23 */ ++ /* restore PSW */ ++ //sethi $r2, hi20(PCU_PA_BASE + 0x420) ++ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x420) ++ //lwi $r3, [$r2] ++ //mtsr $r3, $ir0 ++ //move $p1, $r3 ++ /* restore $mr0 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x424) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x424) ++ lwi $r3, [$r2] ++ mtsr $r3, $mr0 ++ /* restore $mr1 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x428) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x428) ++ lwi $r3, [$r2] ++ mtsr $r3, $mr1 ++ ++ /* restore $mr2 */ ++ //sethi $r2, hi20(PCU_PA_BASE + 0x42c) ++ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x42c) ++ //lwi $r3, [$r2] ++ //mtsr $r3, $mr2 ++ /* restore $mr3 */ ++ //sethi $r2, hi20(PCU_PA_BASE + 0x430) ++ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x430) ++ //lwi $r3, [$r2] ++ //mtsr $r3, $mr3 ++ /* restore $mr4 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x434) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x434) ++ lwi $r3, [$r2] ++ mtsr $r3, $mr4 ++ /* restore $mr5 */ ++ //sethi $r2, hi20(PCU_PA_BASE + 0x438) ++ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x438) ++ //lwi $r3, [$r2] ++ //mtsr $r3, $mr5 ++ /* restore $mr6 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x43c) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x43c) ++ lwi $r3, [$r2] ++ mtsr $r3, $mr6 ++ /* restore $mr7 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x440) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x440) ++ lwi $r3, [$r2] ++ mtsr $r3, $mr7 ++ /* restore $mr8 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x444) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x444) ++ lwi $r3, [$r2] ++ /* ADD by river 2010.12.02 for ICache Enable */ ++ ori $r3, $r3, #0x1 ++ /* End ADD by river 2010.12.02 for ICache Enable */ ++ mtsr $r3, $mr8 ++ ++ /* restore $ir3 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x450) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x450) ++ lwi $r3, [$r2] ++ mtsr $r3, $ir3 ++ ++ move $p1, $r3 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ print_hex $p1 ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ ++ ++ /* restore $ir14 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x454) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x454) ++ lwi $r3, [$r2] ++ mtsr $r3, $ir14 ++ ++ /* restore $ir15 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x458) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x458) ++ lwi $r3, [$r2] ++ mtsr $r3, $ir15 ++ ++ li $r3, '\r ++ putch $r3 ++ li $r3, '\n ++ putch $r3 ++ move $p1, $r3 ++ print_hex $p1 ++ ++ /* End ADD by river 2010.09.23 */ ++ ++ /* in this buggy version(ram locate at 1G) TC01 we don't need to do remap. ++ * ebios set memory locate at 1G & size = 1G, for more detail info, please ++ * refer to ebios boot.S. ++ * ++ * sethi $r2, hi20(0x90c00000 + 0x88) ++ * ori $r2, $r2, lo12(0x90c00000 + 0x88) ++ * movi $r3, #0x1 ++ * swi $r3, [$r2] ++ **/ ++ ++ /* restore 8 bytes from pcu scratch pad resgister to 16mb */ ++ li $r0, 0x10000 ++ li $r2, (PCU_PA_BASE + 0x414) ++ lwi $r1, [$r2] ++ swi $r1, [$r0] ++ lwi $r1, [$r2 + 0x4] ++ swi $r1, [$r0 + 0x4] ++ ++ .p2align 5 ++ resume_lock_start: ++ /* ADD by river 2010.12.02 for ag102_cpu_resume2 for jral.ton $r4, $r4 */ ++ sethi $r2, hi20(PCU_PA_BASE + 0x404) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x404) ++ lwi $r4, [$r2] ++ /* End ADD by river 2010.12.02 for ag102_cpu_resume2 */ ++ ++ /* ADD by river 2010.12.02 for restore kernel ROM map */ ++ sethi $r0, hi20(0x40080000) ++ ori $r0, $r0, lo12(0x40080000) ++ sethi $r1, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x10) ++ ori $r1, $r1, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x10) ++ swi $r0, [$r1] ++ ++ /* ADD by river 2010.12.02 for restore kernel RAM map */ ++ sethi $r0, hi20(0x000A0000) ++ ori $r0, $r0, lo12(0x000A0000) ++ sethi $r1, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x18) ++ ori $r1, $r1, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x18) ++ swi $r0, [$r1] ++ ++ /******************* Gavin version ***************************/ ++ //MOD by river 2010.10.13 ++ /*sethi $r2, hi20(PCU_PA_BASE + 0x404) ++ ori $r2, $r2, lo12(PCU_PA_BASE + 0x404) ++ lwi $r4, [$r2] ++ mtsr $r4, $IPC ++ li $r1, 0xcb ++ mtsr $r1, $IPSW ++ iret*/ ++ //End MOD by river 2010.10.13 ++ //End Gavin version//////////////////////////////////////////////////////////// ++ ++ /* End ADD by river 2010.09.23 */ ++ //MOD by river 2010.10.13 ++ //////// jral.ton version //////////////////////////////////////////////////// ++ ++ jral.ton $r4, $r4 ++ .p2align ++ resume_lock_end: ++ //End MOD by river 2010.10.13 +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/amic.c linux-3.4.110/arch/nds32/platforms/amic.c +--- linux-3.4.110.orig/arch/nds32/platforms/amic.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/amic.c 2016-04-07 10:20:51.002083345 +0200 +@@ -0,0 +1,203 @@ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define DEBUG(enabled, tagged, ...) \ ++ do { \ ++ if (enabled) { \ ++ if (tagged) \ ++ printk("[ %30s() ] ", __func__); \ ++ printk(__VA_ARGS__); \ ++ } \ ++ } while (0) ++ ++static DEFINE_SPINLOCK(amic_irq_lock); ++ ++static void amic_ack_irq(unsigned int irq) ++{ ++ unsigned int data; ++ ++ spin_lock(&amic_irq_lock); ++ writel(1 << irq, AMIC_BASE + INTSTA); ++ data = readl(AMIC_BASE + INTSTA); ++ spin_unlock(&amic_irq_lock); ++} ++ ++static void amic_mask_irq(unsigned int irq) ++{ ++ unsigned int data; ++ ++ spin_lock(&amic_irq_lock); ++ data = readl(AMIC_BASE + INTEN); ++ data &= ~(1 << irq); ++ writel(data, AMIC_BASE + INTEN); ++ data = readl(AMIC_BASE + INTEN); ++ spin_unlock(&amic_irq_lock); ++} ++ ++static int amic_set_type(unsigned int irq, unsigned int flow_type) ++{ ++ unsigned int data; ++ ++ spin_lock(&amic_irq_lock); ++ if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { ++ data = readl(AMIC_BASE + INTTRG); ++ data |= 1 << irq; ++ writel(data, AMIC_BASE + INTTRG); ++ } ++ ++ if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { ++ data = readl(AMIC_BASE + INTTRG); ++ data &= ~(1 << irq); ++ writel(data, AMIC_BASE + INTTRG); ++ } ++ ++ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { ++ data = readl(AMIC_BASE + INTLVL); ++ data |= 1 << irq; ++ writel(data, AMIC_BASE + INTLVL); ++ } ++ ++ if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) { ++ data = readl(AMIC_BASE + INTLVL); ++ data &= ~(1 << irq); ++ writel(data, AMIC_BASE + INTLVL); ++ } ++ spin_unlock(&amic_irq_lock); ++ return 0; ++} ++ ++static void amic_unmask_irq(unsigned int irq) ++{ ++ unsigned int data; ++ ++ spin_lock(&amic_irq_lock); ++ data = readl(AMIC_BASE + INTEN); ++ data |= 1 << irq; ++ writel(data, AMIC_BASE + INTEN); ++ data = readl(AMIC_BASE + INTEN); ++ spin_unlock(&amic_irq_lock); ++} ++ ++static int amic_set_affinity(unsigned int irq, const struct cpumask *dest) ++{ ++ int cnt = 0; ++ int cpu; ++ volatile unsigned int data; ++ volatile unsigned int dc, amic_irq; ++ ++ if (num_online_cpus() > 2) ++ return 0; ++ ++ spin_lock(&amic_irq_lock); ++ /* remap irq number for real controller */ ++ /* this may be needed in future */ ++ /* amic_irq = irq_remap(irq); */ ++ amic_irq = irq; ++ ++ /* change owner */ ++ data = readl(AMIC_BASE + CPUID0 + ((amic_irq >> 4) << 2)); ++ for_each_online_cpu(cpu) { ++ if (cpumask_test_cpu(cpu, dest)) { ++ data &= ~(0x3 << ((amic_irq & ~0x10) * 2)); ++ data |= cpu << ((amic_irq & ~0x10) * 2); ++ cnt++; ++ } ++ } ++ writel(data, AMIC_BASE + CPUID0 + ((amic_irq >> 4) << 2)); ++ ++ dc = readl(AMIC_BASE + CPUDC); ++ if (cnt == 2) /* set bit */ ++ writel((dc | (1 << amic_irq)), (AMIC_BASE + CPUDC)); ++ else /* clear bit */ ++ writel((dc & ~(1 << amic_irq)), (AMIC_BASE + CPUDC)); ++ ++ spin_unlock(&amic_irq_lock); ++ ++ DEBUG(0, 1, "en=%08x,status=%08x\n", readl(AMIC_BASE + INTEN), ++ readl(AMIC_BASE + INTSTA)); ++ ++ return 0; ++} ++ ++static struct irq_chip amic_chip = { ++ .name = "AMIC", ++ .ack = amic_ack_irq, ++ .mask = amic_mask_irq, ++ .unmask = amic_unmask_irq, ++ .set_affinity = amic_set_affinity, ++ .set_type = amic_set_type, ++}; ++ ++void __init amic_init(void) ++{ ++ int i, edge; ++ unsigned int temp = smp_processor_id(); ++ temp |= temp << 2; ++ temp |= temp << 4; ++ temp |= temp << 8; ++ temp |= temp << 16; ++ ++ writel(0x0, AMIC_BASE + INTEN); ++ writel(0x0, AMIC_BASE + CPUDC); ++ writel(temp, AMIC_BASE + CPUID0); ++ writel(temp, AMIC_BASE + CPUID1); ++ writel(0xffff, AMIC_BASE + IPISTA); ++ writel(0xffffffff, AMIC_BASE + INTSTA); ++ writel(0x11111111, AMIC_BASE + PRITY0); ++ writel(0x11111111, AMIC_BASE + PRITY1); ++ writel(0x11111111, AMIC_BASE + PRITY2); ++ writel(0x11111111, AMIC_BASE + PRITY3); ++ writel(DEFAULT_MODE, AMIC_BASE + INTTRG); ++ writel(~DEFAULT_LEVEL, AMIC_BASE + INTLVL); ++ printk("AMIC config %x %x\n", temp, readl(AMIC_BASE + CONFIG)); ++ ++ for (i = IRQ_BASE, edge = 1; i < IRQ_BASE + IRQ_TOTAL; i++, edge <<= 1) { ++ set_irq_chip(i, &amic_chip); ++ if (DEFAULT_MODE & edge) ++ set_irq_handler(i, handle_edge_irq); ++ else ++ set_irq_handler(i, handle_level_irq); ++ } ++ ++} ++ ++unsigned int get_IntSrc(void) ++{ ++ unsigned int irqsta, irq = 31; ++ ++ spin_lock(&amic_irq_lock); ++ irqsta = readl(AMIC_BASE + IPISTA); ++ if (irqsta != 0) ++ irqsta = 0; ++ else ++ irqsta = readl(AMIC_BASE + INTSTA); ++ spin_unlock(&amic_irq_lock); ++ ++ if (irqsta == 0) ++ return 32; ++ if (irqsta & 0x0000ffff) { ++ irq -= 16; ++ irqsta <<= 16; ++ } ++ if (irqsta & 0x00ff0000) { ++ irq -= 8; ++ irqsta <<= 8; ++ } ++ if (irqsta & 0x0f000000) { ++ irq -= 4; ++ irqsta <<= 4; ++ } ++ if (irqsta & 0x30000000) { ++ irq -= 2; ++ irqsta <<= 2; ++ } ++ if (irqsta & 0x40000000) { ++ irq -= 1; ++ } ++ return irq; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/dmad.c linux-3.4.110/arch/nds32/platforms/dmad.c +--- linux-3.4.110.orig/arch/nds32/platforms/dmad.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/dmad.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,3601 @@ ++/***************************************************************************** ++ * ++ * Copyright Andes Technology Corporation 2007-2008 ++ * All Rights Reserved. ++ * ++ * Revision History: ++ * ++ * Aug.21.2007 Created. ++ * Feb.23.2009 Porting to Linux 2.6. ++*****************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++#define DMAD_AHB_MAX_CHANNELS DMAC_MAX_CHANNELS ++#else ++#define DMAD_AHB_MAX_CHANNELS 0 ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++#define DMAD_APB_MAX_CHANNELS APBBR_DMA_MAX_CHANNELS ++#else ++#define DMAD_APB_MAX_CHANNELS 0 ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++#define DMAD_DRB_POOL_SIZE 32 /* 128 */ ++ ++/* reg/io supplementals */ ++static inline void setbl(addr_t bit, addr_t reg) ++{ ++ outl(inl(reg) | (addr_t) ((addr_t) 1 << bit), reg); ++} ++ ++static inline void clrbl(addr_t bit, addr_t reg) ++{ ++ outl(inl(reg) & (~((addr_t) ((addr_t) 1 << bit))), reg); ++} ++ ++static inline addr_t getbl(addr_t bit, addr_t reg) ++{ ++ return inl(reg) & (addr_t) ((addr_t) 1 << bit); ++} ++ ++/******************************************************************************/ ++ ++enum DMAD_DRQ_FLAGS { ++ DMAD_DRQ_STATE_READY = 0x00000001, /* channel allocation status */ ++ DMAD_DRQ_STATE_ABORT = 0x00000002, /* abort drb alloc block-wait */ ++ DMAD_DRQ_DIR_A1_TO_A0 = 0x00000004, /* Transfer direction */ ++}; ++ ++#define DMAD_DRQ_DIR_MASK DMAD_DRQ_DIR_A1_TO_A0 ++ ++/* DMA request queue, one instance per channel */ ++typedef struct dmad_drq { ++ u32 state; /* enum DMAD_DRQ_STATE */ ++ ++ addr_t channel_base; /* register base address */ ++ addr_t enable_port; /* enable register */ ++ addr_t src_port; /* source address register */ ++ addr_t dst_port; /* dest address register */ ++ addr_t cyc_port; /* size(cycle) register */ ++ ++ u32 flags; /* enum DMAD_CHREQ_FLAGS */ ++ ++ spinlock_t drb_pool_lock; ++ dmad_drb *drb_pool; /* drb pool */ ++ ++ u32 fre_head; /* free list head */ ++ u32 fre_tail; /* free list tail */ ++ ++ u32 rdy_head; /* ready list head */ ++ u32 rdy_tail; /* ready list tail */ ++ ++ u32 sbt_head; /* submitted list head */ ++ u32 sbt_tail; /* submitted list tail */ ++ ++ u32 data_width; /* dma transfer data width */ ++ ++ struct completion drb_alloc_sync; ++ ++ /* client supplied callback function, executed in interrupt context ++ * client private data to be passed to data argument of completion_cb(). ++ */ ++ void (*completion_cb) (int channel, u16 status, void *data); ++ void *completion_data; ++ ++ /* ring-mode fields are valid for DMAD_FLAGS_RING_MODE */ ++ dma_addr_t ring_base; /* ring buffer base address */ ++ dma_addr_t ring_size; /* size (of data width) */ ++ addr_t ring_port; /* for setup/fetch hw_ptr */ ++ dmad_drb *ring_drb; ++ ++ addr_t dev_addr; /* device data port */ ++ ++ int periods; /* interrupts periods */ ++ dma_addr_t period_size; /* of dma data with */ ++ dma_addr_t period_bytes; /* Period size, in bytes */ ++ ++ /* ring_size - period_size * periods */ ++ dma_addr_t remnant_size; ++ ++ dma_addr_t sw_ptr; /* sw pointer */ ++ int sw_p_idx; /* current ring_ptr */ ++ dma_addr_t sw_p_off; /* offset to period base */ ++ ++} dmad_drq; ++ ++/* To shrink code size and improve performance, common channel registers ++ * are preload in drq struct at channel allocation time. One of the key ++ * dependency is the enable bit of both DMAC and APBDMA channel command ++ * registers. Please make sure hw design them at bit 0 of the command register ++ * in future evolvement. ++ */ ++#if (DMAC_CSR_CH_EN_BIT != APBBR_DMA_CHEN_BIT) ++#error "DMAC_CSR_CH_EN_BIT != APBBR_DMA_CHEN_BIT" ++#endif ++ ++#define DMAD_PORT_ENABLE_BIT APBBR_DMA_CHEN_BIT ++ ++static inline void dmad_enable_channel(dmad_drq * drq) ++{ ++ setbl(DMAD_PORT_ENABLE_BIT, drq->enable_port); ++} ++ ++static inline void dmad_disable_channel(dmad_drq * drq) ++{ ++ clrbl(DMAD_PORT_ENABLE_BIT, drq->enable_port); ++} ++ ++static inline addr_t dmad_is_channel_enabled(dmad_drq * drq) ++{ ++ return (addr_t) getbl(DMAD_PORT_ENABLE_BIT, drq->enable_port); ++} ++ ++/* AHB DMAC channel re-route table structure */ ++typedef struct _DMAD_AHB_CH_ROUTE { ++ u32 dev_reqn; /* device req/gnt number */ ++ addr_t clear_cr; /* routing control register address */ ++ addr_t route_cr; /* routing control register address */ ++} DMAD_AHB_CH_ROUTE; ++ ++#ifdef CONFIG_PLAT_AG102 ++#if 0 ++/* AHB DMAC channel re-route table. Indexed by AHB DMAC req/ack number. */ ++static DMAD_AHB_CH_ROUTE ahb_ch_route_table[] __attribute__ ((__unused__)) = { ++ /* all todo ... */ ++ ++ { ++ 0x00, DMAC_REQN_IDERX, DMAC_REQN_IDERX}, { ++ 0x01, DMAC_REQN_IDETX, DMAC_REQN_IDETX}, { ++ 0x02, DMAC_REQN_I2SAC97RX, DMAC_REQN_I2SAC97RX}, { ++ 0x03, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97TX}, { ++ 0x04, DMAC_REQN_UART2RX, DMAC_REQN_UART2RX}, { ++ 0x05, DMAC_REQN_UART2TX, DMAC_REQN_UART2TX}, { ++ 0x06, DMAC_REQN_UART1RX, DMAC_REQN_UART1RX}, { ++ 0x07, DMAC_REQN_UART1TX, DMAC_REQN_UART1TX}, { ++ 0x08, DMAC_REQN_SDC, DMAC_REQN_SDC}, { ++ 0x09, DMAC_REQN_CFC, DMAC_REQN_CFC}, { ++ 0x0a, DMAC_REQN_LPCREQ0, DMAC_REQN_LPCREQ0}, { ++ 0x0b, DMAC_REQN_LPCREQ1, DMAC_REQN_LPCREQ1}, { ++ 0x0c, DMAC_REQN_LPCREQ2, DMAC_REQN_LPCREQ2}, { ++ 0x0d, DMAC_REQN_LPCREQ3, DMAC_REQN_LPCREQ3}, { ++ 0x0e, 0, 0}, { ++0x0f, DMAC_REQN_LPCREQ5, DMAC_REQN_LPCREQ5},}; ++#endif ++#else /* CONFIG_PLAT_AG102 */ ++ ++/* AHB DMAC channel re-route table. Indexed by AHB DMAC req/ack number. */ ++static DMAD_AHB_CH_ROUTE ahb_ch_route_table[] = { ++ {0x00, 0, 0}, ++ {0x01, PMU_CFC_REQACK_CFG, PMU_CFC_REQACK_CFG}, ++ {0x02, PMU_SSP1_REQACK_CFG, PMU_SSP1_REQACK_CFG}, ++ {0x03, PMU_UART1RX_REQACK_CFG, PMU_UART1TX_REQACK_CFG}, ++ {0x04, PMU_UART1TX_REQACK_CFG, PMU_UART1RX_REQACK_CFG}, ++ {0x05, PMU_UART2RX_REQACK_CFG, PMU_UART2TX_REQACK_CFG}, ++ {0x06, PMU_UART2TX_REQACK_CFG, PMU_UART2RX_REQACK_CFG}, ++ {0x07, PMU_SDC_REQACK_CFG, PMU_SDC_REQACK_CFG}, ++ {0x08, PMU_I2SAC97RX_REQACK_CFG, PMU_I2SAC97TX_REQACK_CFG}, ++ {0x09, 0, 0}, ++ {0x0a, PMU_I2SAC97TX_REQACK_CFG, PMU_I2SAC97RX_REQACK_CFG}, ++ {0x0b, PMU_USB_REQACK_CFG, PMU_USB_REQACK_CFG}, ++ {0x0c, 0, 0}, ++ {0x0d, 0, 0}, ++ {0x0e, PMU_EXT0_REQACK_CFG, PMU_EXT0_REQACK_CFG}, ++ {0x0f, PMU_EXT1_REQACK_CFG, PMU_EXT1_REQACK_CFG}, ++}; ++ ++#endif /* CONFIG_PLAT_AG102 */ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ ++/* system irq number (per channel, ahb) */ ++static const unsigned int ahb_irqs[DMAD_AHB_MAX_CHANNELS] = { ++ DMAC_FTDMAC020_0_IRQ0, ++ DMAC_FTDMAC020_0_IRQ1, ++ DMAC_FTDMAC020_0_IRQ2, ++ DMAC_FTDMAC020_0_IRQ3, ++ DMAC_FTDMAC020_0_IRQ4, ++ DMAC_FTDMAC020_0_IRQ5, ++ DMAC_FTDMAC020_0_IRQ6, ++ DMAC_FTDMAC020_0_IRQ7, ++}; ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++/* APB Bridge DMA request number re-route table */ ++typedef struct _DMAD_APB_REQN_ROUTE { ++ u32 apb_reqn; /* APB device req/gnt number */ ++ u32 ahb_reqn_tx; /* AHB DMAC req/ack number (tx) */ ++ u32 ahb_reqn_rx; /* AHB DMAC req/ack number (rx) */ ++ u32 bus_sel; /* APBBR_ADDRSEL_APB(0) or APBBR_ADDRSEL_AHB(1) */ ++} DMAD_APB_REQN_ROUTE; ++ ++#ifdef CONFIG_PLAT_AG102 ++ ++/* APB Bridge DMA request number re-route table. Indexed by APB DMA req/gnt ++ * number. */ ++static DMAD_APB_REQN_ROUTE apb_reqn_route_table[] = { ++ {0x00, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x01, DMAC_REQN_CFC, DMAC_REQN_CFC, APBBR_ADDRSEL_APB}, ++ {0x02, 0x00, 0x00, APBBR_ADDRSEL_APB}, ++ {0x03, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x04, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ //MOD by river 2010.10.20 ++ {0x05, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ //End MOD by river 2010.10.20 ++ {0x06, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, ++ {0x07, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ //MOD by river 2010.10.20 ++ {0x08, DMAC_REQN_SDC, DMAC_REQN_SDC, APBBR_ADDRSEL_APB}, ++ //End MOD by river 2010.10.20 ++ {0x09, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0a, DMAC_REQN_UART2TX, DMAC_REQN_UART2RX, APBBR_ADDRSEL_APB}, ++ {0x0b, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0c, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0d, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, ++ {0x0e, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0f, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++}; ++ ++#else /* CONFIG_PLAT_AG102 */ ++ ++/* APB Bridge DMA request number re-route table. Indexed by APB DMA req/gnt ++ * number. */ ++static DMAD_APB_REQN_ROUTE apb_reqn_route_table[] = { ++ {0x00, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x01, DMAC_REQN_CFC, DMAC_REQN_CFC, APBBR_ADDRSEL_APB}, ++ {0x02, DMAC_REQN_SSP, DMAC_REQN_SSP, APBBR_ADDRSEL_APB}, ++ {0x03, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x04, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x05, DMAC_REQN_SDC, DMAC_REQN_SDC, APBBR_ADDRSEL_APB}, ++ {0x06, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, ++/* for amerald ++ { 0x07, 0x00, 0x00, APBBR_ADDRSEL_AHB },*/ ++ {0x07, APBBR_REQN_SDC_AMERALD, APBBR_REQN_SDC_AMERALD, ++ APBBR_ADDRSEL_AHB}, ++/* for amerald ac97 ++ { 0x08, 0x00, 0x00, APBBR_ADDRSEL_AHB }, */ ++ {0x08, APBBR_REQN_I2SAC97TX_AMERALD, APBBR_REQN_I2SAC97TX_AMERALD, ++ APBBR_ADDRSEL_APB}, ++ {0x09, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0a, DMAC_REQN_UART2TX, DMAC_REQN_UART2RX, APBBR_ADDRSEL_APB}, ++ {0x0b, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0c, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0d, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, ++ {0x0e, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++ {0x0f, 0x00, 0x00, APBBR_ADDRSEL_AHB}, ++}; ++ ++#endif /* CONFIG_PLAT_AG102 */ ++ ++/* system irq number (per channel, apb) */ ++static const unsigned int apb_irqs[DMAD_APB_MAX_CHANNELS] = { ++ APBBRG_FTAPBBRG020S_0_IRQ0, ++ APBBRG_FTAPBBRG020S_0_IRQ1, ++ APBBRG_FTAPBBRG020S_0_IRQ2, ++ APBBRG_FTAPBBRG020S_0_IRQ3, ++}; ++ ++#endif ++ ++/* Driver data structure, one instance per system */ ++typedef struct DMAD_DATA_STRUCT { ++ /* Driver data initialization flag */ ++ ++ /* DMA queue pool access control object */ ++ spinlock_t drq_pool_lock; ++ ++ /* DMA queue base address, to ease alloc/free flow */ ++ dmad_drq *drq_pool; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ /* DMA queue for AHB DMA channels */ ++ dmad_drq *ahb_drq_pool; ++#endif ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ /* DMA queue for APB DMA channels */ ++ dmad_drq *apb_drq_pool; ++#endif ++ ++} DMAD_DATA; ++ ++/* Driver data structure instance, one instance per system */ ++static DMAD_DATA dmad __attribute__ ((aligned(4))) = { ++ .drq_pool_lock = __SPIN_LOCK_UNLOCKED(dmad.drq_pool_lock), ++// .drq_pool_lock = SPIN_LOCK_UNLOCKED, ++ .drq_pool = 0, ++#ifdef CONFIG_PLATFORM_AHBDMA ++ .ahb_drq_pool = 0, ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ .apb_drq_pool = 0, ++#endif ++}; ++ ++/** ++ * dmad_next_drb - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @node : [in] The node number to lookup its next node ++ * @drb : [out] The drb next to the "node" node number ++ * ++ * Lookup next DRB of the specified node number. "drb" is null if reaches end ++ * of the list. ++ */ ++static inline void dmad_next_drb(dmad_drb * drb_pool, u32 node, dmad_drb ** drb) ++{ ++ if (likely(drb_pool[node].next != 0)) ++ *drb = &drb_pool[drb_pool[node].next]; ++ else ++ *drb = 0; ++} ++ ++/** ++ * dmad_prev_drb - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @node : [in] The node number to lookup its previous node ++ * @drb : [out] The drb previous to the "node" node number ++ * ++ * Lookup previous DRB of the specified node number. "drb" is null if reaches ++ * head-end of the list. ++ */ ++static inline void dmad_prev_drb(dmad_drb * drb_pool, u32 node, dmad_drb ** drb) ++{ ++ if (unlikely(drb_pool[node].prev != 0)) ++ *drb = &drb_pool[drb_pool[node].prev]; ++ else ++ *drb = 0; ++} ++ ++/** ++ * dmad_detach_node - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @node : [in] The node to be dettached from the queue ++ * ++ * Detached a DRB specified by the node number from the queue. The head and ++ * tail records will be updated accordingly. ++ */ ++static inline void dmad_detach_node(dmad_drb * drb_pool, ++ u32 * head, u32 * tail, u32 node) ++{ ++ if (likely(drb_pool[node].prev != 0)) { ++ /* prev->next = this->next (= 0, if this is a tail) */ ++ drb_pool[drb_pool[node].prev].next = drb_pool[node].next; ++ } else { ++ /* this node is head, move head to next node ++ * (= 0, if this is the only one node) */ ++ *head = drb_pool[node].next; ++ } ++ ++ if (unlikely(drb_pool[node].next != 0)) { ++ /* next->prev = this->prev (= 0, if this is a head) */ ++ drb_pool[drb_pool[node].next].prev = drb_pool[node].prev; ++ } else { ++ /* this node is tail, move tail to previous node ++ * (= 0, if this is the only one node) */ ++ *tail = drb_pool[node].prev; ++ } ++ ++ drb_pool[node].prev = drb_pool[node].next = 0; ++} ++ ++/** ++ * dmad_detach_head - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @drb : [out] The detached head node; null if the queue is empty ++ * ++ * Detached a DRB from the head of the queue. The head and tail records will ++ * be updated accordingly. ++ */ ++static inline void dmad_detach_head(dmad_drb * drb_pool, ++ u32 * head, u32 * tail, dmad_drb ** drb) ++{ ++ if (unlikely(*head == 0)) { ++ *drb = NULL; ++ return; ++ } ++ ++ *drb = &drb_pool[*head]; ++ ++ if (likely((*drb)->next != 0)) { ++ /* next->prev = this->prev (= 0, if this is a head) */ ++ drb_pool[(*drb)->next].prev = 0; ++ ++ /* prev->next = this->next (do nothing, if this is a head) */ ++ ++ /* head = this->next */ ++ *head = (*drb)->next; ++ } else { ++ /* head = tail = 0 */ ++ *head = 0; ++ *tail = 0; ++ } ++ ++ /* this->prev = this->next = 0 (do nothing, if save code size) */ ++ (*drb)->prev = (*drb)->next = 0; ++} ++ ++/** ++ * dmad_get_head - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @drb : [out] The head node; null if the queue is empty ++ * ++ * Get a DRB from the head of the queue. The head and tail records remain ++ * unchanged. ++ */ ++static inline void dmad_get_head(dmad_drb * drb_pool, const u32 * head, ++ const u32 * tail, dmad_drb ** drb) ++{ ++ if (unlikely(*head == 0)) { ++ *drb = NULL; ++ return; ++ } ++ ++ *drb = &drb_pool[*head]; ++} ++ ++/** ++ * dmad_detach_tail - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @drb : [out] The tail node; null if the queue is empty ++ * ++ * Detached a DRB from the head of the queue. The head and tail records will ++ * be updated accordingly. ++ */ ++static inline void dmad_detach_tail(dmad_drb * drb_pool, ++ u32 * head, u32 * tail, dmad_drb ** drb) ++{ ++ if (unlikely(*tail == 0)) { ++ *drb = NULL; ++ return; ++ } ++ ++ *drb = &drb_pool[*tail]; ++ ++ if (likely((*drb)->prev != 0)) { ++ /* prev->next = this->next (= 0, if this is a tail) */ ++ drb_pool[(*drb)->prev].next = 0; ++ ++ /* next->prev = this->prev (do nothing, if this is a tail) */ ++ ++ /* tail = this->prev */ ++ *tail = (*drb)->prev; ++ } else { ++ /* head = tail = 0 */ ++ *head = 0; ++ *tail = 0; ++ } ++ ++ /* this->next = this->prev = 0 (do nothing, if save code size) */ ++ (*drb)->prev = (*drb)->next = 0; ++} ++ ++/** ++ * dmad_get_tail - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @drb : [out] The tail node; null if the queue is empty ++ * ++ * Get a DRB from the tail of the queue. The head and tail records remain ++ * unchanged. ++ */ ++static inline void dmad_get_tail(dmad_drb * drb_pool, ++ u32 * head, u32 * tail, dmad_drb ** drb) ++{ ++ if (unlikely(*tail == 0)) { ++ *drb = NULL; ++ return; ++ } ++ ++ *drb = &drb_pool[*tail]; ++} ++ ++/** ++ * dmad_attach_head - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @node : [in] The node to be attached ++ * ++ * Attach a DRB node to the head of the queue. The head and tail records will ++ * be updated accordingly. ++ */ ++static inline void dmad_attach_head(dmad_drb * drb_pool, ++ u32 * head, u32 * tail, u32 node) ++{ ++ if (likely(*head != 0)) { ++ /* head->prev = this */ ++ drb_pool[*head].prev = node; ++ ++ /* this->next = head */ ++ drb_pool[node].next = *head; ++ /* this->prev = 0 */ ++ drb_pool[node].prev = 0; ++ ++ /* head = node */ ++ *head = node; ++ } else { ++ /* head = tail = node */ ++ *head = *tail = node; ++ drb_pool[node].prev = drb_pool[node].next = 0; ++ } ++} ++ ++/** ++ * dmad_attach_head - static function ++ * @drb_pool : [in] The raw DRB pool of a DMA channel ++ * @head : [in/out] Reference to the head node number ++ * @tail : [in/out] Reference to the tail node number ++ * @node : [in] The node to be attached ++ * ++ * Attach a DRB node to the tail of the queue. The head and tail records will ++ * be updated accordingly. ++ */ ++static inline void dmad_attach_tail(dmad_drb * drb_pool, ++ u32 * head, u32 * tail, u32 node) ++{ ++ if (likely(*tail != 0)) { ++ /* tail->next = this */ ++ drb_pool[*tail].next = node; ++ ++ /* this->prev = tail */ ++ drb_pool[node].prev = *tail; ++ /* this->next = 0 */ ++ drb_pool[node].next = 0; ++ ++ /* tail = node */ ++ *tail = node; ++ } else { ++ /* head = tail = node */ ++ *head = *tail = node; ++ drb_pool[node].prev = drb_pool[node].next = 0; ++ } ++} ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ ++/** ++ * dmad_ahb_isr - AHB DMA interrupt service routine ++ * ++ * @irq : [in] The irq number ++ * @dev_id : [in] The identifier to identify the asserted channel ++ * ++ * This is the ISR that services all AHB DMA channels. ++ */ ++static irqreturn_t dmad_ahb_isr(int irq, void *dev_id) ++{ ++ dmad_drq *drq; ++ dmad_drb *drb, *drb_iter; ++ u32 channel = ((u32) dev_id) - 1; ++ u8 tc_int = 0; ++ u8 err_int = 0; ++ u8 abt_int = 0; ++ u8 cpl_events = 1; ++ ++ dmad_dbg("%s() >> channel(%d)\n", __func__, channel); ++ ++ if (channel >= DMAD_AHB_MAX_CHANNELS) { ++ dmad_err("%s() invlaid channel number: %d!\n", ++ __func__, channel); ++ return IRQ_HANDLED; ++ } ++ ++ /* Fetch channel's DRQ struct (DMA Request Queue) */ ++ drq = (dmad_drq *) & dmad.ahb_drq_pool[channel]; ++ ++ /* Check DMA status register to get channel number */ ++ if (likely(getbl(channel, DMAC_INT_TC))) { ++ ++ /* Mark as TC int */ ++ tc_int = 1; ++ ++ /* DMAC INT TC status clear */ ++ setbl(channel, DMAC_INT_TC_CLR); ++ ++ } else if (getbl(channel + DMAC_INT_ERR_SHIFT, DMAC_INT_ERRABT)) { ++ ++ /* Mark as ERR int */ ++ err_int = 1; ++ ++ /* DMAC INT ERR status clear */ ++ setbl(channel + DMAC_INT_ERR_CLR_SHIFT, DMAC_INT_ERRABT_CLR); ++ ++ } else if (getbl(channel + DMAC_INT_ABT_SHIFT, DMAC_INT_ERRABT)) { ++ ++ /* Mark as ABT int */ ++ abt_int = 1; ++ ++ /* DMAC INT ABT status clear */ ++ setbl(channel + DMAC_INT_ABT_CLR_SHIFT, DMAC_INT_ERRABT_CLR); ++ ++ } else { ++ ++ dmad_err("%s() possible false-fired ahb dma int," ++ "channel %d status-reg: tc(0x%08x) arrabt(0x%08x)\n", ++ __func__, channel, ++ inl(DMAC_INT_TC), inl(DMAC_INT_ERRABT_CLR)); ++ ++ /* Stop DMA channel (make sure the channel will be stopped) */ ++ clrbl(DMAC_CSR_CH_EN_BIT, drq->channel_base + DMAC_CSR_OFFSET); ++ ++ return IRQ_HANDLED; ++ } ++ ++ /* DMAC ++ * Stop DMA channel temporarily */ ++ dmad_disable_channel(drq); ++ ++ spin_lock(&drq->drb_pool_lock); ++ ++ /* Lookup/detach latest submitted DRB (DMA Request Block) from ++ * the DRQ (DMA Request Queue), so ISR could kick off next DRB */ ++ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); ++ if (drb == NULL) { ++ spin_unlock(&drq->drb_pool_lock); ++ /* submitted list could be empty if client cancel all requests ++ * of the channel. */ ++ return IRQ_HANDLED; ++ } ++ ++ /* release blocking of drb-allocation, if any ... */ ++ if (unlikely((drq->fre_head == 0) && ++ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK))) { ++ complete_all(&drq->drb_alloc_sync); ++ } ++ ++ /* Process DRBs according to interrupt reason */ ++ if (tc_int) { ++ ++ dmad_dbg("dma finish\n"); ++ ++ dmad_dbg("finish drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x)\n", ++ drb->node, (u32) drb, drb->src_addr, ++ drb->dst_addr, drb->req_cycle); ++ ++ if (drb->req_cycle == 0) ++ cpl_events = 0; ++ ++ // Mark DRB state as completed ++ drb->state = DMAD_DRB_STATE_COMPLETED; ++ if (cpl_events && drb->sync) ++ complete_all(drb->sync); ++ ++ dmad_attach_tail(drq->drb_pool, &drq->fre_head, ++ &drq->fre_tail, drb->node); ++ ++ // Check whether there are pending requests in the DRQ ++ if (drq->sbt_head != 0) { ++ ++ // Lookup next DRB (DMA Request Block) ++ drb_iter = &drq->drb_pool[drq->sbt_head]; ++ ++ dmad_dbg("exec drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x)\n", ++ drb_iter->node, (u32) drb_iter, ++ drb_iter->src_addr, drb_iter->dst_addr, ++ drb_iter->req_cycle); ++ ++ // Kick-off DMA for next DRB ++ // - Source and destination address ++ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { ++ outl(drb_iter->addr1, drq->src_port); ++ outl(drb_iter->addr0, drq->dst_port); ++ } else { ++ outl(drb_iter->addr0, drq->src_port); ++ outl(drb_iter->addr1, drq->dst_port); ++ } ++ ++ /* - Transfer size (in units of source width) */ ++ outl(drb_iter->req_cycle, drq->cyc_port); ++ ++ /* Kick off next request */ ++ dmad_enable_channel(drq); ++ ++ drb_iter->state = DMAD_DRB_STATE_EXECUTED; ++ ++ } else { ++ /* No pending requests, keep the DMA channel stopped */ ++ } ++ ++ } else { ++ ++ dmad_err("%s() ahb dma channel %d error!\n", __func__, channel); ++ ++ /* Zero out src, dst, and size */ ++ outl(0, drq->src_port); ++ outl(0, drq->dst_port); ++ outl(0, drq->cyc_port); ++ ++ /* Remove all pending requests in the queue */ ++ drb_iter = drb; ++ while (drb_iter) { ++ ++ dmad_err("abort drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x)\n", ++ drb_iter->node, (u32) drb_iter, ++ drb_iter->src_addr, drb_iter->dst_addr, ++ drb_iter->req_cycle); ++ ++ if (drb_iter->req_cycle == 0) ++ cpl_events = 0; ++ ++ /* Mark DRB state as abort */ ++ drb_iter->state = DMAD_DRB_STATE_ABORT; ++ ++ if (cpl_events && drb_iter->sync) ++ complete_all(drb_iter->sync); ++ ++ dmad_attach_tail(drq->drb_pool, &drq->fre_head, ++ &drq->fre_tail, drb_iter->node); ++ ++ /* Detach next submitted DRB (DMA Request Block) ++ * from the DRQ (DMA Request Queue) */ ++ dmad_detach_head(drq->drb_pool, &drq->sbt_head, ++ &drq->sbt_tail, &drb_iter); ++ } ++ } ++ ++ spin_unlock(&drq->drb_pool_lock); ++ ++ /* dispatch interrupt-context level callbacks */ ++ if (cpl_events && drq->completion_cb) { ++ /* signal DMA driver that new node is available */ ++ drq->completion_cb(channel, tc_int, drq->completion_data); ++ } ++ ++ dmad_dbg("%s() <<\n", __func__); ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * dmad_ahb_config_dir - prepare command reg according to tx direction ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @channel_cmds : [out] Reference to array of command words to be prepared with ++ * @return : none ++ * ++ * Prepare command registers according to transfer direction ... ++ * channel_cmd[0] DMAC_CSR ++ * channel_cmd[1] DMAC_CFG ++ * ++ * This function only serves as local helper. No protection wrappers. ++ */ ++static void dmad_ahb_config_dir(dmad_chreq * ch_req, addr_t * channel_cmds) ++{ ++ dmad_drq *drq = (dmad_drq *) ch_req->drq; ++ dmad_ahb_chreq *ahb_req = (dmad_ahb_chreq *) (&ch_req->ahb_req); ++/* for amerald */ ++ u32 reqn0, reqn1; ++ dmad_dbg("%s() channel_cmds(0x%08x, 0x%08x)\n", ++ __func__, channel_cmds[0], channel_cmds[1]); ++/* for amerald */ ++ if ((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) { ++ reqn0 = ahb_req->addr0_reqn; ++ reqn1 = ahb_req->addr1_reqn; ++ } else { ++ reqn0 = ch_req->channel; ++ reqn1 = ch_req->channel; ++ } ++ channel_cmds[0] &= ~(addr_t) ++ (DMAC_CSR_SRC_WIDTH_MASK | DMAC_CSR_SRCAD_CTL_MASK | ++ DMAC_CSR_DST_WIDTH_MASK | DMAC_CSR_DSTAD_CTL_MASK | ++ DMAC_CSR_MODE_MASK); ++ channel_cmds[1] &= ~(addr_t) ++ (DMAC_CFG_INT_SRC_RS_MASK | DMAC_CFG_INT_SRC_HE_MASK | ++ DMAC_CFG_INT_DST_RS_MASK | DMAC_CFG_INT_DST_HE_MASK); ++ ++ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ ++ if (ahb_req->tx_dir == 0) { ++ ++ dmad_dbg("%s() addr0 --> addr1\n", __func__); ++ ++ /* - Channel CSR ++ * DST_SEL : 0 (Master 0) ++ * SRC_SEL : 0 (Master 0) ++ * DSTAD_CTL : ahb_req->dst_ctrl ++ * SRCAD_CTL : ahb_req->src_ctrl ++ * MODE : 0 (normal) ++ * DST_WIDTH : ahb_req->dst_width ++ * SRC_WIDTH : ahb_req->src_width ++ * SRC_SIZE : 0 (burst size = 1 byte) ++ */ ++ channel_cmds[0] |= ++ (((ahb_req->addr0_width << DMAC_CSR_SRC_WIDTH_SHIFT) & ++ DMAC_CSR_SRC_WIDTH_MASK) | ++ ((ahb_req->addr0_ctrl << DMAC_CSR_SRCAD_CTL_SHIFT) & ++ DMAC_CSR_SRCAD_CTL_MASK) | ++ ((ahb_req->addr1_width << DMAC_CSR_DST_WIDTH_SHIFT) & ++ DMAC_CSR_DST_WIDTH_MASK) | ++ ((ahb_req->addr1_ctrl << DMAC_CSR_DSTAD_CTL_SHIFT) & ++ DMAC_CSR_DSTAD_CTL_MASK)); ++ ++ /* - Channel CFG ++ * SRC_RS : channel number (not reqn) ++ * SRC_HE : 0 if memory, 1 if device ++ * DST_RS : channel number (not reqn) ++ * DST_HE : 0 if memory, 1 if device ++ */ ++ if (likely(ahb_req->hw_handshake != 0)) { ++ /* Channel CSR - Enable HW-handshake mode */ ++ channel_cmds[0] |= DMAC_CSR_MODE_MASK; ++ ++ /* Channel CFG - Device REQN and HW-handshake mode */ ++#ifdef CONFIG_PLAT_AG102 ++ /* AG102 fixes this bug */ ++ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | ++ ((ahb_req->addr0_reqn << ++ DMAC_CFG_INT_SRC_RS_SHIFT) ++ & ++ DMAC_CFG_INT_SRC_RS_MASK)); ++ } ++ ++ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | ++ ((ahb_req->addr1_reqn << ++ DMAC_CFG_INT_DST_RS_SHIFT) ++ & ++ DMAC_CFG_INT_DST_RS_MASK)); ++ } ++#else ++ /* AG101/XC5 bug */ ++/* for amerald */ ++ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | ++ ((reqn0 << ++ DMAC_CFG_INT_SRC_RS_SHIFT) ++ & ++ DMAC_CFG_INT_SRC_RS_MASK)); ++ } ++ ++ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | ++ ((reqn1 << ++ DMAC_CFG_INT_DST_RS_SHIFT) ++ & ++ DMAC_CFG_INT_DST_RS_MASK)); ++ } ++#endif ++ } ++ ++ /* update source data width for faster cycle/byte size conversion */ ++ drq->data_width = ahb_req->addr0_width; ++ ++ /* remember channel transfer direction */ ++ drq->flags &= ~(addr_t) DMAD_DRQ_DIR_A1_TO_A0; ++ ++ } else { ++ ++ dmad_dbg("%s() addr0 <-- addr1\n", __func__); ++ ++ /* - Channel CSR ++ * DST_SEL : 0 (Master 0) ++ * SRC_SEL : 0 (Master 0) ++ * DSTAD_CTL : ahb_req->dst_ctrl ++ * SRCAD_CTL : ahb_req->src_ctrl ++ * MODE : 0 (normal) ++ * DST_WIDTH : ahb_req->dst_width ++ * SRC_WIDTH : ahb_req->src_width ++ * SRC_SIZE : 0 (burst size = 1 byte) ++ */ ++ channel_cmds[0] |= ++ (((ahb_req->addr1_width << DMAC_CSR_SRC_WIDTH_SHIFT) & ++ DMAC_CSR_SRC_WIDTH_MASK) | ++ ((ahb_req->addr1_ctrl << DMAC_CSR_SRCAD_CTL_SHIFT) & ++ DMAC_CSR_SRCAD_CTL_MASK) | ++ ((ahb_req->addr0_width << DMAC_CSR_DST_WIDTH_SHIFT) & ++ DMAC_CSR_DST_WIDTH_MASK) | ++ ((ahb_req->addr0_ctrl << DMAC_CSR_DSTAD_CTL_SHIFT) & ++ DMAC_CSR_DSTAD_CTL_MASK)); ++ ++ /* - Channel CFG ++ * SRC_RS : channel number (not reqn) ++ * SRC_HE : 0 if memory, 1 if device ++ * DST_RS : channel number (not reqn) ++ * DST_HE : 0 if memory, 1 if device ++ */ ++ if (likely(ahb_req->hw_handshake != 0)) { ++ /* Channel CSR - Enable HW-handshake mode */ ++ channel_cmds[0] |= DMAC_CSR_MODE_MASK; ++ ++ /* Channel CFG - Device REQN and HW-handshake mode */ ++#ifdef CONFIG_PLAT_AG102 ++ /* AG102 fixes this bug */ ++ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | ++ ((ahb_req->addr1_reqn << ++ DMAC_CFG_INT_SRC_RS_SHIFT) ++ & ++ DMAC_CFG_INT_SRC_RS_MASK)); ++ } ++ ++ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | ++ ((ahb_req->addr0_reqn << ++ DMAC_CFG_INT_DST_RS_SHIFT) ++ & ++ DMAC_CFG_INT_DST_RS_MASK)); ++ } ++#else ++ /* AG101/XC5 bug */ ++/* for amerald */ ++ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | ++ ((reqn1 << ++ DMAC_CFG_INT_SRC_RS_SHIFT) ++ & ++ DMAC_CFG_INT_SRC_RS_MASK)); ++ } ++ ++ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { ++ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | ++ ((reqn0 << ++ DMAC_CFG_INT_DST_RS_SHIFT) ++ & ++ DMAC_CFG_INT_DST_RS_MASK)); ++ } ++#endif ++ } ++ ++ /* source data width */ ++ drq->data_width = ahb_req->addr1_width; ++ ++ /* remember channel transfer direction */ ++ drq->flags |= (addr_t) DMAD_DRQ_DIR_A1_TO_A0; ++ } ++ ++ dmad_dbg("%s() channel_cmds(0x%08x, 0x%08x)\n", ++ __func__, channel_cmds[0], channel_cmds[1]); ++} ++ ++/** ++ * dmad_ahb_init - initialize a ahb dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * Register AHB DMA ISR and performs hw initialization for the given DMA ++ * channel. ++ */ ++static int dmad_ahb_init(dmad_chreq * ch_req) ++{ ++ int err = 0; ++ dmad_drq *drq = (dmad_drq *) ch_req->drq; ++ dmad_ahb_chreq *ahb_req = (dmad_ahb_chreq *) (&ch_req->ahb_req); ++ u32 channel = (u32) ch_req->channel; ++ addr_t channel_base = drq->channel_base; ++ addr_t channel_cmds[2]; // [0] DMAC_CSR; [1] DMAC_CFG ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ /* register interrupt handler */ ++ err = request_irq(ahb_irqs[channel], dmad_ahb_isr, 0, ++ "AHB_DMA", (void *)(channel + 1)); ++ if (unlikely(err != 0)) { ++ dmad_err("unable to request IRQ %d for AHB DMA " ++ "(error %d)\n", ahb_irqs[channel], err); ++ free_irq(ahb_irqs[channel], (void *)(channel + 1)); ++ return err; ++ } ++ ++ spin_lock_irqsave(&dmad.drq_pool_lock, lock_flags); ++ ++ /********************************************************** ++ * Following code require _safe_exit return path ++ */ ++ ++#ifdef CONFIG_PLAT_AG102 ++ /* PCU ++ * ++ * Add by Dennis 2011.03.09 ++ * set 0 to dma selection register to using AHB ++ * DMA. ++ */ ++ if (ahb_req->dst_reqn == ahb_req->src_reqn) { ++ dmad_err ++ ("[dmad] invalid source reqn(%d) or destination reqn(%d)\n", ++ ahb_req->src_reqn, ahb_req->dst_reqn); ++ err = -EBADR; ++ goto _safe_exit; ++ } ++ outl(0, PCU_DMA_SEL); ++#else /* CONFIG_PLAT_AG102 */ ++ ++ /* PMU ++ * ++ * Route APB device DMA to an AHB DMAC channel and specify the channel ++ * number. (connection status could be read back from PMU_AHBDMA_REQACK ++ * register) ++ * ++ * Note: Only one device is routed per AHB DMA channel, the other target ++ * should be either (1) the same device (same reqn), or (2) the AHB ++ * device (reqn = 0). ++ */ ++ ++ if (ahb_req->dst_reqn != DMAC_REQN_NONE) { ++ // DMA transfer to device ++ if ((ahb_req->dst_reqn > DMAC_REQN_MAX) || ++ (ahb_ch_route_table[ahb_req->dst_reqn].route_cr == 0)) { ++ dmad_err("Invalid destination reqn(%d) " ++ "or route_cr(0x%08x)\n", ahb_req->dst_reqn, ++ (u32) ahb_ch_route_table[ahb_req->dst_reqn]. ++ route_cr); ++ err = -EBADR; ++ goto _safe_exit; ++ } ++ ++ outl(0, ahb_ch_route_table[ahb_req->dst_reqn].clear_cr); ++ outl(PMU_DMACUSED_MASK | ((channel << PMU_CHANNEL_SHIFT) & ++ PMU_CHANNEL_MASK), ++ ahb_ch_route_table[ahb_req->dst_reqn].route_cr); ++ ++ } else if (ahb_req->src_reqn != DMAC_REQN_NONE) { ++ ++ // DMA transfer from device ++ if ((ahb_req->src_reqn > DMAC_REQN_MAX) || ++ (ahb_ch_route_table[ahb_req->src_reqn].route_cr == 0)) { ++ dmad_err("Invalid source reqn(%d) or " ++ "route_cr(0x%08x)\n", ahb_req->src_reqn, ++ (u32) ahb_ch_route_table[ahb_req->src_reqn]. ++ route_cr); ++ err = -EBADR; ++ goto _safe_exit; ++ } ++ ++ outl(0, ahb_ch_route_table[ahb_req->src_reqn].clear_cr); ++ outl(PMU_DMACUSED_MASK | ((channel << PMU_CHANNEL_SHIFT) & ++ PMU_CHANNEL_MASK), ++ ahb_ch_route_table[ahb_req->src_reqn].route_cr); ++ } ++#endif /* CONFIG_PLAT_AG102 */ ++ ++ /* DMAC (Controller Setting) */ ++ ++ /* - INT TC/ERR/ABT status clear */ ++ setbl(channel, DMAC_INT_TC_CLR); ++ setbl(channel + DMAC_INT_ERR_CLR_SHIFT, DMAC_INT_ERRABT_CLR); ++ setbl(channel + DMAC_INT_ABT_CLR_SHIFT, DMAC_INT_ERRABT_CLR); ++ ++ // - CSR (enable DMAC, set M0 & M1 default to little endian) ++ outl(DMAC_DMACEN_MASK | ++ ((DMAC_ENDIAN_LITTLE << DMAC_M0ENDIAN_BIT) & DMAC_M0ENDIAN_MASK) | ++ ((DMAC_ENDIAN_LITTLE << DMAC_M1ENDIAN_BIT) & DMAC_M1ENDIAN_MASK), ++ DMAC_CSR); ++ ++ /* DMAC (Channel-Specific Setting) */ ++ /* - SYNC */ ++ if (ahb_req->sync) ++ setbl(channel, DMAC_SYNC); ++ else ++ clrbl(channel, DMAC_SYNC); ++ ++ /* - Channel CSR ++ * CH_EN : 0 (disable) ++ * DST_SEL : 0 (Master 0) ++ * SRC_SEL : 0 (Master 0) ++ * DSTAD_CTL : ahb_req->dst_ctrl ++ * SRCAD_CTL : ahb_req->src_ctrl ++ * MODE : 0 (normal) ++ * DST_WIDTH : ahb_req->dst_width ++ * SRC_WIDTH : ahb_req->src_width ++ * ABT : 0 (not abort) ++ * SRC_SIZE : 0 (burst size = 1 byte) ++ * PROT1 : 0 (user mode) ++ * PROT2 : 0 (bot bufferable) ++ * PROT3 : 0 (not cacheable) ++ * CHPRI : ahb_req->priority ++ * DMA_FF_TH : 0 (FIA320 only, threshold = 1) ++ * TC_MSK : 0 (TC counter status enable) ++ */ ++ channel_cmds[0] = (ahb_req->priority << DMAC_CSR_CHPRI_SHIFT) & ++ DMAC_CSR_CHPRI_MASK; ++ channel_cmds[0] |= (ahb_req->burst_size << DMAC_CSR_SRC_SIZE_SHIFT) & ++ DMAC_CSR_SRC_SIZE_MASK; ++ ++ // - Channel CFG ++ // INT_TC_MSK : 0 (enable TC int) ++ // INT_ERR_MSK : 0 (enable ERR int) ++ // INT_ABT_MSK : 0 (enable ABT int) ++ // SRC_RS : 0 ++ // SRC_HE : 0 ++ // BUSY : r/o ++ // DST_RS : 0 ++ // DST_HE : 0 ++ // LLP_CNT : r/o ++ channel_cmds[1] = 0; ++ ++ if (0 == ++ (ch_req->flags & (DMAD_FLAGS_RING_MODE | DMAD_FLAGS_BIDIRECTION))) ++ ahb_req->tx_dir = 0; ++ ++ dmad_ahb_config_dir(ch_req, channel_cmds); ++ ++ outl(channel_cmds[0], channel_base + DMAC_CSR_OFFSET); ++ outl(channel_cmds[1], channel_base + DMAC_CFG_OFFSET); ++ ++ /* SRCADR and DESADR */ ++ outl(0, (addr_t) drq->src_port); ++ outl(0, (addr_t) drq->dst_port); ++ ++ /* CYC (transfer size) */ ++ outl(0, (addr_t) drq->cyc_port); ++ ++ /* LLP */ ++ outl(0, channel_base + DMAC_LLP_OFFSET); ++ ++ /* TOT_SIZE - not now */ ++ ++_safe_exit: ++ ++ spin_unlock_irqrestore(&dmad.drq_pool_lock, lock_flags); ++ ++ return err; ++} ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++/** ++ * dmad_apb_isr - APB DMA interrupt service routine ++ * ++ * @irq : [in] The irq number ++ * @dev_id : [in] The identifier to identify the asserted channel ++ * ++ * This is the ISR that services all APB DMA channels. ++ */ ++static irqreturn_t dmad_apb_isr(int irq, void *dev_id) ++{ ++ dmad_drq *drq; ++ dmad_drb *drb, *drb_iter; ++ u32 channel = ((u32) dev_id) - 1; ++ u32 status; ++ u8 finish_int = 0; ++ u8 err_int = 0; ++ u8 cpl_events = 1; ++ ++ dmad_dbg("%s() >> channel(%d)\n", __func__, channel); ++ ++ if (channel >= DMAD_APB_MAX_CHANNELS) { ++ dmad_err("%s() invlaid channel number: %d!\n", ++ __func__, channel); ++ return IRQ_HANDLED; ++ } ++ ++ /* Lookup channel's DRQ (DMA Request Queue) */ ++ drq = (dmad_drq *) & dmad.apb_drq_pool[channel]; ++ ++ /* - Check DMA status register to get channel number */ ++ status = inl((addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ ++ if (likely(status & APBBR_DMA_FINTST_MASK)) { ++ ++ /*dmad_dbg("apb dma int status: finish (0x%08x)\n", status); */ ++ finish_int = 1; ++ ++ /* APB DMA finish int status clear */ ++ clrbl(APBBR_DMA_FINTST_BIT, ++ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ ++ } else if (status & APBBR_DMA_ERRINTST_MASK) { ++ ++ /* Perform DMA error checking if no valid channel was found ++ * who assert the finish signal. */ ++ dmad_err("apb dma int status: err (0x%08x)\n", status); ++ ++ /* Mark as error int */ ++ err_int = 1; ++ ++ /* APB DMA error int status clear */ ++ clrbl(APBBR_DMA_ERRINTST_BIT, ++ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ ++ } else { ++ ++ dmad_err("%s() possible false-fired apb dma int," ++ " channel %d status-reg: 0x%08x\n", ++ __func__, channel, status); ++ ++ /* Stop DMA channel (make sure the channel will be stopped) */ ++ clrbl(APBBR_DMA_CHEN_BIT, ++ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ ++ return IRQ_HANDLED; ++ } ++ ++ /* Stop DMA channel (make sure the channel will be stopped) */ ++ dmad_disable_channel(drq); ++ ++ spin_lock(&drq->drb_pool_lock); ++ ++ /* Lookup/detach latest submitted DRB (DMA Request Block) from */ ++ /* the DRQ (DMA Request Queue), so ISR could kick off next DRB */ ++ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); ++ ++ if (unlikely(drb == NULL)) { ++ spin_unlock(&drq->drb_pool_lock); ++ return IRQ_HANDLED; ++ } ++ ++ /* release blocking of drb-allocation, if any ... */ ++ if (unlikely((drq->fre_head == 0) && ++ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK))) { ++ complete_all(&drq->drb_alloc_sync); ++ } ++ ++ /* Process DRBs according to the cause of this interrupt */ ++ if (likely(finish_int)) { ++ ++ if (drb->req_cycle == 0) ++ cpl_events = 0; ++ ++ /* Mark DRB state as completed */ ++ drb->state = DMAD_DRB_STATE_COMPLETED; ++ if (cpl_events && drb->sync) ++ complete_all(drb->sync); ++ ++ dmad_attach_tail(drq->drb_pool, &drq->fre_head, ++ &drq->fre_tail, drb->node); ++ ++ /* Check whether there are pending requests in the DRQ */ ++ if (drq->sbt_head != 0) { ++ ++ /* Lookup next DRB (DMA Request Block) */ ++ drb_iter = &drq->drb_pool[drq->sbt_head]; ++ ++ dmad_dbg("exec drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x)\n", ++ drb_iter->node, (u32) drb_iter, ++ drb_iter->src_addr, drb_iter->dst_addr, ++ drb_iter->req_cycle); ++ ++ /* Kick-off DMA for next DRB */ ++ /* - Source and destination address */ ++ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { ++ outl(drb_iter->addr1, drq->src_port); ++ outl(drb_iter->addr0, drq->dst_port); ++ } else { ++ outl(drb_iter->addr0, drq->src_port); ++ outl(drb_iter->addr1, drq->dst_port); ++ } ++ ++ /* - Transfer size (in units of source width) */ ++ outl(drb_iter->req_cycle, drq->cyc_port); ++ ++ /* Kick off next request */ ++ dmad_enable_channel(drq); ++ ++ drb_iter->state = DMAD_DRB_STATE_EXECUTED; ++ ++ } else { ++ /* No pending requests, keep the DMA channel stopped */ ++ } ++ ++ } else if (err_int) { ++ ++ dmad_err("%s() apb dma channel %d error!\n", __func__, channel); ++ ++ /* Zero out src, dst, and size */ ++ outl(0, drq->src_port); ++ outl(0, drq->dst_port); ++ outl(0, drq->cyc_port); ++ ++ /* Remove all pending requests in the queue */ ++ drb_iter = drb; ++ while (drb_iter) { ++ ++ dmad_err("abort drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x)\n", ++ drb_iter->node, (u32) drb_iter, ++ drb_iter->src_addr, drb_iter->dst_addr, ++ drb_iter->req_cycle); ++ ++ if (drb_iter->req_cycle == 0) ++ cpl_events = 0; ++ ++ /* Mark DRB state as abort */ ++ drb_iter->state = DMAD_DRB_STATE_ABORT; ++ ++ if (cpl_events && drb_iter->sync) ++ complete_all(drb_iter->sync); ++ ++ dmad_attach_tail(drq->drb_pool, &drq->fre_head, ++ &drq->fre_tail, drb_iter->node); ++ ++ dmad_detach_head(drq->drb_pool, &drq->sbt_head, ++ &drq->sbt_tail, &drb_iter); ++ } ++ } ++ ++ spin_unlock(&drq->drb_pool_lock); ++ ++ /* dispatch interrupt-context level callbacks */ ++ if (cpl_events && drq->completion_cb) { ++ /* signal DMA driver that new node is available */ ++ drq->completion_cb(channel, status, drq->completion_data); ++ } ++ ++ dmad_dbg("%s() <<\n", __func__); ++ ++ return IRQ_HANDLED; ++} ++ ++/** ++ * dmad_apb_config_dir - prepare command reg according to tx direction ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @channel_cmds : [out] Reference to array of command words to be prepared with ++ * @return : none ++ * ++ * Prepare command registers according to transfer direction ... ++ * channel_cmd[0] APBBR_DMA_CMD ++ * ++ * This function only serves as local helper. No protection wrappers. ++ */ ++static void dmad_apb_config_dir(dmad_chreq * ch_req, addr_t * channel_cmds) ++{ ++ dmad_drq *drq = (dmad_drq *) ch_req->drq; ++ dmad_apb_chreq *apb_req = (dmad_apb_chreq *) (&ch_req->apb_req); ++ ++ dmad_dbg("%s() channel_cmd(0x%08x)\n", __func__, channel_cmds[0]); ++ ++ *channel_cmds &= ~(addr_t) ++ (APBBR_DMA_SRCADDRINC_MASK | APBBR_DMA_DSTADDRINC_MASK | ++ APBBR_DMA_DSTADDRSEL_MASK | APBBR_DMA_DREQSEL_MASK | ++ APBBR_DMA_SRCADDRSEL_MASK | APBBR_DMA_SREQSEL_MASK); ++ ++ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ ++ if (apb_req->tx_dir == 0) { ++ ++ dmad_dbg("%s() addr0 --> addr1\n", __func__); ++ ++ /* APB Bridge DMA (Channel Setting) ++ * - CMD ++ * SRCADR : apb_req->src_ctrl ++ * DESADR : apb_req->dst_ctrl ++ */ ++ *channel_cmds |= ++ (((apb_req->addr0_ctrl << APBBR_DMA_SRCADDRINC_SHIFT) & ++ APBBR_DMA_SRCADDRINC_MASK) | ++ ((apb_req->addr1_ctrl << APBBR_DMA_DSTADDRINC_SHIFT) & ++ APBBR_DMA_DSTADDRINC_MASK)); ++ ++ /* - CMD ++ * DESADRSEL : AHB/APB, driver auto-conf ++ * DREQSEL ++ */ ++ *channel_cmds |= ++ ((addr_t) (APBBR_DMA_DSTADDRSEL_MASK & ++ (apb_reqn_route_table[apb_req->addr1_reqn]. ++ bus_sel << APBBR_DMA_DSTADDRSEL_BIT)) | ++ (((addr_t) apb_req-> ++ addr1_reqn << APBBR_DMA_DREQSEL_SHIFT) & ++ APBBR_DMA_DREQSEL_MASK)); ++ ++ /* - CMD ++ * SRCADRSEL : AHB/APB, driver auto-conf ++ * SREQSEL ++ */ ++ *channel_cmds |= ++ ((addr_t) (APBBR_DMA_SRCADDRSEL_MASK & ++ (apb_reqn_route_table[apb_req->addr0_reqn]. ++ bus_sel << APBBR_DMA_SRCADDRSEL_BIT)) | ++ (((addr_t) apb_req-> ++ addr0_reqn << APBBR_DMA_SREQSEL_SHIFT) & ++ APBBR_DMA_SREQSEL_MASK)); ++ ++ drq->flags &= ~(addr_t) DMAD_DRQ_DIR_A1_TO_A0; ++ ++ } else { ++ ++ dmad_dbg("%s() addr0 <-- addr1\n", __func__); ++ ++ /* APB Bridge DMA (Channel Setting) ++ * - CMD ++ * SRCADR : apb_req->src_ctrl ++ * DESADR : apb_req->dst_ctrl ++ */ ++ *channel_cmds |= ++ (((apb_req->addr1_ctrl << APBBR_DMA_SRCADDRINC_SHIFT) & ++ APBBR_DMA_SRCADDRINC_MASK) | ++ ((apb_req->addr0_ctrl << APBBR_DMA_DSTADDRINC_SHIFT) & ++ APBBR_DMA_DSTADDRINC_MASK)); ++ ++ /* - CMD ++ * DESADRSEL : AHB/APB, driver auto-conf ++ * DREQSEL ++ */ ++ *channel_cmds |= ((addr_t) (APBBR_DMA_DSTADDRSEL_MASK & ++ (apb_reqn_route_table ++ [apb_req->addr0_reqn]. ++ bus_sel << ++ APBBR_DMA_DSTADDRSEL_BIT)) | ++ (((addr_t) apb_req-> ++ addr0_reqn << APBBR_DMA_DREQSEL_SHIFT) & ++ APBBR_DMA_DREQSEL_MASK)); ++ ++ /* - CMD ++ * SRCADRSEL : AHB/APB, driver auto-conf ++ * SREQSEL ++ */ ++ *channel_cmds |= ((addr_t) (APBBR_DMA_SRCADDRSEL_MASK & ++ (apb_reqn_route_table ++ [apb_req->addr1_reqn]. ++ bus_sel << ++ APBBR_DMA_SRCADDRSEL_BIT)) | ++ (((addr_t) apb_req-> ++ addr1_reqn << APBBR_DMA_SREQSEL_SHIFT) & ++ APBBR_DMA_SREQSEL_MASK)); ++ ++ drq->flags |= (addr_t) DMAD_DRQ_DIR_A1_TO_A0; ++ } ++ ++ dmad_dbg("%s() channel_cmd(0x%08x)\n", __func__, channel_cmds[0]); ++} ++ ++/** ++ * dmad_apb_init - initialize a apb dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * Register APB DMA ISR and performs hw initialization for the given DMA ++ * channel. ++ */ ++static int dmad_apb_init(dmad_chreq * ch_req) ++{ ++ int err = 0; ++ dmad_drq *drq = (dmad_drq *) ch_req->drq; ++ dmad_apb_chreq *apb_req = (dmad_apb_chreq *) (&ch_req->apb_req); ++ u32 channel = (u32) ch_req->channel; ++ addr_t channel_cmd = 0; ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ /* register interrupt handler */ ++ err = request_irq(apb_irqs[channel], dmad_apb_isr, 0, ++ "APB_DMA", (void *)(channel + 1)); ++ if (unlikely(err != 0)) { ++ dmad_err("unable to request IRQ %d for APB DMA (error %d)\n", ++ apb_irqs[channel], err); ++ free_irq(apb_irqs[channel], (void *)(channel + 1)); ++ return err; ++ } ++ ++ spin_lock_irqsave(&dmad.drq_pool_lock, lock_flags); ++ ++ /********************************************************** ++ * Following code require _safe_exit return path ++ */ ++ ++#ifdef CONFIG_PLAT_AG102 ++ ++ /* PCU ++ * ++ */ ++ //ADD by river 2010.10.20 ++ if (unlikely((apb_req->src_reqn > APBBR_REQN_MAX) || ++ (apb_req->dst_reqn > APBBR_REQN_MAX))) { ++ dmad_err("Invalid source reqn(%d) or destination reqn(%d)\n", ++ apb_req->src_reqn, apb_req->dst_reqn); ++ err = -EBADR; ++ goto _safe_exit; ++ } ++ ++ if (apb_req->src_reqn != APBBR_REQN_NONE) { ++ u32 ahb_reqn; ++ ++ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_tx; ++ else ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_rx; ++ ++ } ++ ++ if (apb_req->dst_reqn != APBBR_REQN_NONE) { ++ u32 ahb_reqn; ++ ++ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_tx; ++ else ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_rx; ++ ++ } ++ //End ADD by river 2010.10.20 ++ ++#else /* CONFIG_PLAT_AG102 */ ++ ++ /* PMU ++ * - Undo APB device DMA to AHB DMAC channel routing. (connection status ++ * is obtained from reading back the PMU_AHBDMA_REQACK register) ++ */ ++ if (unlikely((apb_req->src_reqn > APBBR_REQN_MAX) || ++ (apb_req->dst_reqn > APBBR_REQN_MAX))) { ++ dmad_err("Invalid source reqn(%d) or destination reqn(%d)\n", ++ apb_req->src_reqn, apb_req->dst_reqn); ++ err = -EBADR; ++ goto _safe_exit; ++ } ++ ++ if (apb_req->src_reqn != APBBR_REQN_NONE) { ++ u32 ahb_reqn; ++ ++ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_tx; ++ else ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_rx; ++ ++ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); ++ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); ++ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); ++ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); ++ } ++ ++ if (apb_req->dst_reqn != APBBR_REQN_NONE) { ++ u32 ahb_reqn; ++ ++ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_tx; ++ else ++ ahb_reqn = ++ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_rx; ++ ++ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); ++ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); ++ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); ++ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); ++ } ++#endif /* CONFIG_PLAT_AG102 */ ++ ++ /* APB Bridge DMA (Channel Setting) ++ * - CMD ++ * ENBDIS : 0 (disable for now) ++ * FININTSTS : 0 (clear finishing interrupt status) ++ * FININTENB : 1 (enable finishing interrupt) ++ * BURMOD : apb_req->burst_mode ++ * ERRINTSTS : 0 (clear error interrupt status) ++ * ERRINTENB : 1 (enable error interrupt) ++ * SRCADRSEL : AHB/APB, driver auto-conf ++ * DESADRSEL : AHB/APB, driver auto-conf ++ * SRCADR : apb_req->src_ctrl ++ * DESADR : apb_req->dst_ctrl ++ * REQSEL : apb_req->src_reqn ++ * DATAWIDTH : apb_req->data_width ++ */ ++ ++ /* - CMD ++ * ENBDIS ++ * FININTSTS ++ * FININTENB ++ * BURMOD ++ * ERRINTSTS ++ * ERRINTENB ++ * DATAWIDTH ++ */ ++ channel_cmd = ++ ((addr_t) APBBR_DMA_FINTEN_MASK | APBBR_DMA_ERRINTEN_MASK | ++ ((apb_req-> ++ burst_mode << APBBR_DMA_BURST_BIT) & APBBR_DMA_BURST_MASK) | ++ ((apb_req-> ++ data_width << APBBR_DMA_DATAWIDTH_SHIFT) & ++ APBBR_DMA_DATAWIDTH_MASK)); ++ ++ /* - CMD ++ * SRCADRSEL ++ * DESADRSEL ++ * SRCADR ++ * DESADR ++ * REQSEL ++ */ ++ if (0 == ++ (ch_req->flags & (DMAD_FLAGS_RING_MODE | DMAD_FLAGS_BIDIRECTION))) ++ apb_req->tx_dir = 0; ++ dmad_apb_config_dir(ch_req, &channel_cmd); ++ ++ /* - CMD outport */ ++ outl(channel_cmd, (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ ++ /* SRCADR and DESADR */ ++ outl(0, (addr_t) drq->src_port); ++ outl(0, (addr_t) drq->dst_port); ++ ++ /* CYC (transfer size) */ ++ outl(0, (addr_t) drq->cyc_port); ++ ++ /* keep channel data width for faster cycle/byte size conversion */ ++ drq->data_width = apb_req->data_width; ++ ++_safe_exit: ++ ++ spin_unlock_irqrestore(&dmad.drq_pool_lock, lock_flags); ++ ++ return err; ++} ++ ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++/** ++ * dmad_channel_init - initialize given dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * This function serves as the abstraction layer of dmad_ahb_init() ++ * and dmad_apb_init() functions. ++ */ ++static int dmad_channel_init(dmad_chreq * ch_req) ++{ ++ int err = 0; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) ++ return -EFAULT; ++ ++ if (unlikely(ch_req->drq == NULL)) ++ return -EBADR; ++ ++ /* Initialize DMA controller */ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) ++ err = dmad_ahb_init(ch_req); ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) ++ err = dmad_apb_init(ch_req); ++#endif ++ ++ return err; ++} ++ ++static inline void dmad_reset_channel(dmad_drq * drq) ++{ ++ /* disable dma controller */ ++ dmad_disable_channel(drq); ++ ++ /* Source and destination address */ ++ outl(0, drq->src_port); ++ outl(0, drq->dst_port); ++ ++ /* Transfer size (in units of source width) */ ++ outl(0, drq->cyc_port); ++} ++ ++/** ++ * dmad_channel_reset - reset given dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * This function serves as the abstraction layer of dmad_ahb_reset() ++ * and dmad_apb_reset() functions. ++ */ ++static int dmad_channel_reset(dmad_chreq * ch_req) ++{ ++ u32 channel = (u32) ch_req->channel; ++ unsigned long lock_flags; ++ int err = 0; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) ++ return -EFAULT; ++ ++ if (unlikely(ch_req->drq == NULL)) ++ return -EBADR; ++ ++ spin_lock_irqsave(&((dmad_drq *) ch_req->drq)->drb_pool_lock, ++ lock_flags); ++ ++ /* stop DMA channel */ ++ dmad_reset_channel((dmad_drq *) ch_req->drq); ++ ++ spin_unlock_irqrestore(&((dmad_drq *) ch_req->drq)->drb_pool_lock, ++ lock_flags); ++ ++ /* unregister interrupt handler */ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) ++ free_irq(ahb_irqs[channel], (void *)(channel + 1)); ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) ++ free_irq(apb_irqs[channel], (void *)(channel + 1)); ++#endif ++ ++ return err; ++} ++ ++/** ++ * dmad_channel_alloc - allocates and initialize a dma channel ++ * @ch_req : [in/out] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * This function allocates a DMA channel according to client's request ++ * parameters. ISR and HW state will also be initialized accordingly. ++ */ ++int dmad_channel_alloc(dmad_chreq * ch_req) ++{ ++ dmad_drq *drq_iter = NULL; ++ dmad_drb *drb_iter; ++ int err = 0; ++ u32 i = 0; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (ch_req == NULL) { ++ printk(KERN_ERR "%s() invalid argument!\n", __func__); ++ return -EFAULT; ++ } ++ ++ spin_lock(&dmad.drq_pool_lock); ++ ++ /* locate an available DMA channel */ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ ++ drq_iter = dmad.ahb_drq_pool; ++ ++ if ((ch_req->ahb_req.src_reqn != DMAC_REQN_NONE) || ++ (ch_req->ahb_req.dst_reqn != DMAC_REQN_NONE)) { ++ /* [2007-12-03] It looks current board have problem to ++ * do dma traffic for APB devices on DMAC channel 0/1. ++ * Redirect all APB devices to start from channel 2. ++ */ ++ ++ /* [todo] include USB controller ? */ ++ drq_iter = &dmad.ahb_drq_pool[2]; ++ for (i = 2; i < DMAD_AHB_MAX_CHANNELS; ++i, ++drq_iter) { ++ if (!(drq_iter->state & DMAD_DRQ_STATE_READY)) ++ break; ++ } ++ } else { ++ /* channel for other devices is free to allocate */ ++ for (i = 0; i < DMAD_AHB_MAX_CHANNELS; ++i, ++drq_iter) { ++ if (!(drq_iter->state & DMAD_DRQ_STATE_READY)) ++ break; ++ } ++ } ++ ++ if (unlikely(i == DMAD_AHB_MAX_CHANNELS)) { ++ spin_unlock(&dmad.drq_pool_lock); ++ dmad_err("out of available channels (AHB DMAC)!\n"); ++ return -ENOSPC; ++ } ++ ++ dmad_dbg("allocated channel: %d (AHB DMAC)\n", i); ++ ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ ++ drq_iter = dmad.apb_drq_pool; ++ ++ for (i = 0; i < DMAD_APB_MAX_CHANNELS; ++i, ++drq_iter) { ++ if ((drq_iter->state & DMAD_DRQ_STATE_READY) == 0) ++ break; ++ } ++ ++ if (unlikely(i == DMAD_APB_MAX_CHANNELS)) { ++ spin_unlock(&dmad.drq_pool_lock); ++ dmad_err("out of available channels (APB DMAC)!\n"); ++ return -ENOSPC; ++ } ++ ++ dmad_dbg("allocated channel: %d (APB DMAC)\n", i); ++ } ++#endif ++ if (drq_iter == NULL) { ++ spin_unlock(&dmad.drq_pool_lock); ++ printk(KERN_ERR "%s() invalid argument!\n", __func__); ++ return -EFAULT; ++ } ++ ++ spin_unlock(&dmad.drq_pool_lock); ++ memset(drq_iter, 0, sizeof(dmad_drq)); ++ ++ /* Initialize DMA channel's DRB pool as list of free DRBs */ ++ drq_iter->drb_pool = ++ kmalloc(DMAD_DRB_POOL_SIZE * sizeof(dmad_drb), GFP_ATOMIC); ++ ++ if (drq_iter->drb_pool == NULL) { ++ printk(KERN_ERR "%s() failed to allocate drb pool!\n", ++ __func__); ++ return -ENOMEM; ++ } ++ ++ /* Allocate the DMA channel */ ++ drq_iter->state = DMAD_DRQ_STATE_READY; ++ drq_iter->flags = ch_req->flags; ++ ++ /* Initialize synchronization object for DMA queue access control */ ++ spin_lock_init(&drq_iter->drb_pool_lock); ++ ++ /* Initialize synchronization object for free drb notification */ ++ init_completion(&drq_iter->drb_alloc_sync); ++ ++ /* Record the channel number in client's struct */ ++ ch_req->channel = i; ++ ++ /* Record the channel's queue handle in client's struct */ ++ ch_req->drq = drq_iter; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ drq_iter->channel_base = (addr_t) DMAC_BASE_CH(i); ++ drq_iter->enable_port = ++ (addr_t) drq_iter->channel_base + DMAC_CSR_OFFSET; ++ drq_iter->src_port = ++ (addr_t) drq_iter->channel_base + DMAC_SRC_ADDR_OFFSET; ++ drq_iter->dst_port = ++ (addr_t) drq_iter->channel_base + DMAC_DST_ADDR_OFFSET; ++ drq_iter->cyc_port = ++ (addr_t) drq_iter->channel_base + DMAC_SIZE_OFFSET; ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ drq_iter->channel_base = (addr_t) APBBR_DMA_BASE_CH(i); ++ drq_iter->enable_port = ++ (addr_t) drq_iter->channel_base + APBBR_DMA_CMD_OFFSET; ++ drq_iter->src_port = ++ (addr_t) drq_iter->channel_base + APBBR_DMA_SAD_OFFSET; ++ drq_iter->dst_port = ++ (addr_t) drq_iter->channel_base + APBBR_DMA_DAD_OFFSET; ++ drq_iter->cyc_port = ++ (addr_t) drq_iter->channel_base + APBBR_DMA_CYC_OFFSET; ++ } ++#endif ++ /* drb-0 is an invalid node - for node validation */ ++ drb_iter = &drq_iter->drb_pool[0]; ++ drb_iter->prev = 0; ++ drb_iter->next = 0; ++ drb_iter->node = 0; ++ ++drb_iter; ++ ++ /* init other drbs - link in order */ ++ for (i = 1; i < DMAD_DRB_POOL_SIZE; ++i, ++drb_iter) { ++ drb_iter->prev = i - 1; ++ drb_iter->next = i + 1; ++ drb_iter->node = i; ++ } ++ drq_iter->drb_pool[DMAD_DRB_POOL_SIZE - 1].next = 0; ++ ++ /* Initialize channel's DRB free-list, ready-list, and submitted-list */ ++ drq_iter->fre_head = 1; ++ drq_iter->fre_tail = DMAD_DRB_POOL_SIZE - 1; ++ drq_iter->rdy_head = drq_iter->rdy_tail = 0; ++ drq_iter->sbt_head = drq_iter->sbt_tail = 0; ++ ++ /* initialize ring buffer mode resources */ ++ if (ch_req->flags & DMAD_FLAGS_RING_MODE) { ++ ++ int remnant = (int)ch_req->ring_size - ++ (int)ch_req->periods * (int)ch_req->period_size; ++ if (remnant == 0) { ++ drq_iter->periods = ch_req->periods; ++ } else if (remnant > 0) { ++ drq_iter->periods = ch_req->periods; // + 1; ++ } else { ++ dmad_err("%s() Error - buffer_size < " ++ "periods * period_size!\n", __func__); ++ err = -EFAULT; ++ goto _err_exit; ++ } ++ ++ drq_iter->ring_size = ch_req->ring_size; ++ drq_iter->period_size = ch_req->period_size; ++ drq_iter->remnant_size = (dma_addr_t) remnant; ++ ++ drq_iter->ring_base = (dma_addr_t) ch_req->ring_base; ++ drq_iter->dev_addr = (dma_addr_t) ch_req->dev_addr; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ if ((ch_req->ahb_req.ring_ctrl == DMAC_CSR_AD_DEC) || ++ (ch_req->ahb_req.dev_ctrl == DMAC_CSR_AD_DEC)) { ++ dmad_err("%s() Error - decremental" ++ " addressing DMA is not supported in" ++ " ring mode currently!\n", __func__); ++ err = -EFAULT; ++ goto _err_exit; ++ } ++ ++ if (ch_req->ahb_req.ring_ctrl == DMAC_CSR_AD_FIX) { ++ dmad_err("%s() Error - ring address control is " ++ "fixed in ring DMA mode!\n", __func__); ++ err = -EFAULT; ++ goto _err_exit; ++ } ++ ++ drq_iter->period_bytes = ++ DMAC_CYCLE_TO_BYTES(ch_req->period_size, ++ ch_req->ahb_req.ring_width); ++ ++ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ ++ if (ch_req->ahb_req.tx_dir == 0) ++ drq_iter->ring_port = ++ (addr_t) drq_iter->src_port; ++ else ++ drq_iter->ring_port = ++ (addr_t) drq_iter->dst_port; ++ ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ ++ if ((ch_req->apb_req.ring_ctrl >= APBBR_ADDRINC_D1) || ++ (ch_req->apb_req.dev_ctrl >= APBBR_ADDRINC_D1)) { ++ dmad_err("%s() Error - decremental" ++ " addressing DMA is not supported in" ++ " ring mode currently!\n", __func__); ++ err = -EFAULT; ++ goto _err_exit; ++ } ++ ++ if (ch_req->apb_req.ring_ctrl == APBBR_ADDRINC_FIXED) { ++ dmad_err("%s() Error - ring address control is " ++ "fixed in ring DMA mode!\n", __func__); ++ err = -EFAULT; ++ goto _err_exit; ++ } ++ ++ drq_iter->period_bytes = ++ APBBR_DMA_CYCLE_TO_BYTES(ch_req->period_size, ++ ch_req->apb_req. ++ data_width); ++ ++ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ ++ if (ch_req->apb_req.tx_dir == 0) ++ drq_iter->ring_port = ++ (addr_t) drq_iter->src_port; ++ else ++ drq_iter->ring_port = ++ (addr_t) drq_iter->dst_port; ++ } ++#endif ++ dmad_dbg("%s() ring: base(0x%08x) port(0x%08x) periods(0x%08x)" ++ " period_size(0x%08x) period_bytes(0x%08x)" ++ " remnant_size(0x%08x)\n", ++ __func__, drq_iter->ring_base, drq_iter->ring_port, ++ drq_iter->periods, drq_iter->period_size, ++ drq_iter->period_bytes, drq_iter->remnant_size); ++ } ++ ++ drq_iter->completion_cb = ch_req->completion_cb; ++ drq_iter->completion_data = ch_req->completion_data; ++ ++ /* Initialize the channel && register isr */ ++ err = dmad_channel_init(ch_req); ++ ++_err_exit: ++ ++ if (err != 0) { ++ spin_lock(&dmad.drq_pool_lock); ++ ++ kfree(drq_iter->drb_pool); ++ memset(drq_iter, 0, sizeof(dmad_drq)); ++ ++ ch_req->channel = -1; ++ ch_req->drq = (void *)0; ++ ++ spin_unlock(&dmad.drq_pool_lock); ++ ++ dmad_err("Failed to initialize APB DMA! " ++ "Channel allocation aborted!\n"); ++ } ++ ++ return err; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_channel_alloc); ++ ++/** ++ * dmad_channel_free - release a dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * This function releases a DMA channel. The channel is available for future ++ * allocation after the invokation. ++ */ ++int dmad_channel_free(dmad_chreq * ch_req) ++{ ++ dmad_drq *drq; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ if (unlikely((ch_req->channel < 0) || ++ ((drq->state & DMAD_DRQ_STATE_READY) == 0))) { ++ dmad_err("try to free a free channel!\n"); ++ return -EBADR; ++ } ++ ++ /* Stop/abort channel I/O ++ * (forced to shutdown and should be protected against isr) ++ */ ++ dmad_drain_requests(ch_req, 1); ++ dmad_channel_reset(ch_req); ++ ++ dmad_dbg("freed channel: %d\n", ch_req->channel); ++ ++ spin_lock(&dmad.drq_pool_lock); ++ ++ kfree(drq->drb_pool); ++ memset(drq, 0, sizeof(dmad_drq)); ++ ++ ch_req->drq = 0; ++ ch_req->channel = (u32) - 1; ++ ++ spin_unlock(&dmad.drq_pool_lock); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_channel_free); ++ ++/** ++ * dmad_channel_enable - enable/disable a dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @enable : [in] 1 to enable the channel, 0 to disable ++ * @return : 0 if success, non-zero if any error ++ * ++ * Enable or disable the given DMA channel. ++ */ ++int dmad_channel_enable(const dmad_chreq * ch_req, u8 enable) ++{ ++ dmad_drq *drq; ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) ++ return -EFAULT; ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) ++ return -EBADR; ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /* Enable/disable DMA channel */ ++ if (enable) ++ dmad_enable_channel(drq); ++ else ++ dmad_disable_channel(drq); ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_channel_enable); ++ ++/** ++ * dmad_config_channel_dir - config dma channel transfer direction ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @dir : [in] DMAD_DRQ_DIR_A0_TO_A1 or DMAD_DRQ_DIR_A1_TO_A0 ++ * @return : 0 if success, non-zero if any error ++ * ++ * Reconfigure the channel transfer direction. This function works only if ++ * the channel was allocated with the DMAD_FLAGS_BIDIRECTION flags. Note ++ * that bi-direction mode and ring mode are mutual-exclusive from user's ++ * perspective. ++ */ ++int dmad_config_channel_dir(dmad_chreq * ch_req, u8 dir) ++{ ++ dmad_drq *drq; ++ addr_t channel_cmds[2]; ++ unsigned long lock_flags; ++ u8 cur_dir; ++ ++ if (unlikely(ch_req == NULL)) ++ return -EFAULT; ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) ++ return -EBADR; ++ ++ if (unlikely(!(ch_req->flags & DMAD_FLAGS_BIDIRECTION))) { ++ dmad_err("%s() Channel is not configured as" ++ " bidirectional!\n", __func__); ++ return -EFAULT; ++ } ++ ++ cur_dir = drq->flags & DMAD_DRQ_DIR_MASK; ++ if (dir == cur_dir) { ++ dmad_dbg("%s() cur_dir(%d) == dir(%d) skip reprogramming hw.\n", ++ __func__, cur_dir, dir); ++ return 0; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ if (unlikely((drq->sbt_head != 0) /*||dmad_is_channel_enabled(drq) */ )) { ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ dmad_err("%s() Cannot change direction while the " ++ "channel has pending requests!\n", __func__); ++ return -EFAULT; ++ } ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ ++ channel_cmds[0] = ++ inl((addr_t) drq->channel_base + DMAC_CSR_OFFSET); ++ channel_cmds[1] = ++ inl((addr_t) drq->channel_base + DMAC_CFG_OFFSET); ++ ++ ch_req->ahb_req.tx_dir = dir; ++ dmad_ahb_config_dir(ch_req, channel_cmds); ++ ++ outl(channel_cmds[1], ++ (addr_t) drq->channel_base + DMAC_CFG_OFFSET); ++ outl(channel_cmds[0], ++ (addr_t) drq->channel_base + DMAC_CSR_OFFSET); ++ ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ ++ channel_cmds[0] = ++ inl((addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ ++ ch_req->apb_req.tx_dir = dir; ++ dmad_apb_config_dir(ch_req, channel_cmds); ++ ++ outl(channel_cmds[0], ++ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); ++ } ++#endif ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_config_channel_dir); ++ ++/** ++ * dmad_max_size_per_drb - return maximum transfer size per drb ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : The maximum transfer size per drb, in bytes. ++ * ++ * Calculate the maximum transfer size per drb according to the setting of ++ * data width during channel initialization. ++ * ++ * Return size is aligned to 4-byte boundary; this ensures the alignment ++ * requirement of dma starting address if the function was used in a loop to ++ * separate a large size dma transfer. ++ */ ++u32 dmad_max_size_per_drb(dmad_chreq * ch_req) ++{ ++ addr_t size = 0; ++ addr_t data_width = (addr_t) ((dmad_drq *) ch_req->drq)->data_width; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ size = DMAC_CYCLE_TO_BYTES(DMAC_TOT_SIZE_MASK & ((addr_t) ~ 3), ++ data_width); ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ size = ++ APBBR_DMA_CYCLE_TO_BYTES(APBBR_DMA_CYC_MASK & ++ ((addr_t) ~ 3), data_width); ++ } ++#endif ++ dmad_dbg("%s() - 0x%08x bytes\n", __func__, size); ++ ++ return size; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_max_size_per_drb); ++ ++/** ++ * dmad_bytes_to_cycles - calculate drb transfer size, in cycles ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @byte_size : [in] The DMA transfer size to be converted, in bytes ++ * @return : The drb transfer size, in cycles. ++ * ++ * Calculate the drb transfer cycle according to the setting of channel data ++ * width and burst setting. ++ * ++ * AHB DMA : unit is number of "data width". ++ * APB DMA : unit is number of "data width * burst size" ++ * ++ * APB Note: According to specification, decrement addressing seems to regard ++ * the burst size setting. For code efficiency, ++ * dmad_make_req_cycles() does not take care of this case and might ++ * produce wrong result. ++ */ ++u32 dmad_bytes_to_cycles(dmad_chreq * ch_req, u32 byte_size) ++{ ++ addr_t cycle = 0; ++ addr_t data_width = (addr_t) ((dmad_drq *) ch_req->drq)->data_width; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ cycle = DMAC_BYTES_TO_CYCLE(byte_size, data_width); ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ cycle = APBBR_DMA_BYTES_TO_CYCLE(byte_size, data_width); ++ if (ch_req->apb_req.burst_mode) ++ cycle = cycle >> 2; ++ } ++#endif ++ ++ dmad_dbg("%s() - 0x%08x bytes --> 0x%08x cycles\n", ++ __func__, byte_size, cycle); ++ ++ return cycle; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_bytes_to_cycles); ++ ++/** ++ * dmad_alloc_drb_internal - allocate a dma-request-block of a dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @drb : [out] Reference to a drb pointer to receive the allocated drb ++ * @return : 0 if success, non-zero if any error ++ * ++ * Allocates a DRB (DMA request block) of the given DMA channel. DRB is a ++ * single dma request which will be pushed into the submission queue of the ++ * given DMA channel. This is a lightweight internal version of ++ * dmad_alloc_drb() majorly for use in ring mode. Critical access to the ++ * drb pool should be protected before entering this function. ++ */ ++static inline int dmad_alloc_drb_internal(dmad_drq * drq, dmad_drb ** drb) ++{ ++ /* Initialize drb ptr in case of fail allocation */ ++ *drb = NULL; ++ ++ if (unlikely(drq->fre_head == 0)) { ++ return -EAGAIN; ++ } ++ ++ dmad_detach_head(drq->drb_pool, &drq->fre_head, &drq->fre_tail, drb); ++ ++ dmad_attach_tail(drq->drb_pool, ++ &drq->rdy_head, &drq->rdy_tail, (*drb)->node); ++ ++ (*drb)->state = DMAD_DRB_STATE_READY; ++ (*drb)->sync = 0; ++ ++ dmad_dbg("%s() drb(%d 0x%08x)\n", __func__, (*drb)->node, (u32) (*drb)); ++ ++ return 0; ++} ++ ++/** ++ * dmad_alloc_drb - allocate a dma-request-block of a dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @drb : [out] Reference to a drb pointer to receive the allocated drb ++ * @return : 0 if success, non-zero if any error ++ * ++ * Allocates a DRB (DMA request block) of the given DMA channel. DRB is a ++ * single dma request which will be pushed into the submission queue of the ++ * given DMA channel. ++ */ ++int dmad_alloc_drb(dmad_chreq * ch_req, dmad_drb ** drb) ++{ ++ dmad_drq *drq; ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (likely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /* Initialize drb ptr in case of fail allocation */ ++ *drb = NULL; ++ ++ if (unlikely(drq->fre_head == 0)) { ++ ++ drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT; ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++_wait_for_free_drbs: ++ ++ /* Wait for free urbs */ ++ if (drq->flags & DMAD_FLAGS_SLEEP_BLOCK) { ++ ++ int timeout = ++ wait_for_completion_interruptible_timeout(&drq-> ++ drb_alloc_sync, ++ msecs_to_jiffies ++ (6000)); ++ ++ /* reset sync object */ ++ INIT_COMPLETION(drq->drb_alloc_sync); ++ ++ if (timeout < 0) { ++ dmad_err("%s() wait for" ++ " completion error! (%d)\n", ++ __func__, timeout); ++ return timeout; ++ } ++ ++ } else if (drq->flags & DMAD_FLAGS_SPIN_BLOCK) { ++ ++ u32 timeout = 0x00ffffff; ++ ++ while ((drq->fre_head == 0) && (--timeout != 0)) { ++ } ++ if (timeout == 0) { ++ dmad_err("%s() polling wait for " ++ "completion timeout!\n", __func__); ++ return -EAGAIN; ++ } ++ ++ } else { ++ return -EAGAIN; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /* check whether all the requests of the channel has been ++ * abandoned or not */ ++ if (unlikely(drq->state & DMAD_DRQ_STATE_ABORT)) { ++ dmad_dbg("%s() drb-allocation aborted due" ++ " to cancel-request ...\n", __func__); ++ drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT; ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -ECANCELED; ++ } ++ ++ /* check again to avoid non-atomic operation between above ++ * two calls */ ++ if (unlikely(drq->fre_head == 0)) { ++ dmad_dbg("%s() lost free drbs ... " ++ "continue waiting ...\n", __func__); ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ goto _wait_for_free_drbs; ++ } ++ } ++ ++ dmad_detach_head(drq->drb_pool, &drq->fre_head, &drq->fre_tail, drb); ++ ++ dmad_attach_tail(drq->drb_pool, ++ &drq->rdy_head, &drq->rdy_tail, (*drb)->node); ++ ++ (*drb)->state = DMAD_DRB_STATE_READY; ++ (*drb)->sync = 0; ++ ++ dmad_dbg("%s() drb(%d 0x%08x)\n", __func__, (*drb)->node, (u32) (*drb)); ++ ++ drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT; ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_alloc_drb); ++ ++/** ++ * dmad_free_drb - free a dma-request-block of a dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @drb : [in] Reference to a drb to be freed ++ * @return : 0 if success, non-zero if any error ++ * ++ * Frees a DRB (DMA request block) of the given DMA channel. DRB is a ++ * single dma request which will be pushed into the submission queue of the ++ * given DMA channel. ++ */ ++int dmad_free_drb(dmad_chreq * ch_req, dmad_drb * drb) ++{ ++ dmad_drq *drq; ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /**************************************************** ++ * Following code requires _safe_exit return path ++ */ ++ ++ if (unlikely((drq->rdy_head == 0) || (drb->node == 0) || ++ (drb->state != DMAD_DRB_STATE_READY) || ++ (drb->node >= DMAD_DRB_POOL_SIZE))) { ++ dmad_err("Ready-queue is empty or invalid node!\n"); ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -EBADR; ++ } ++ ++ dmad_detach_node(drq->drb_pool, ++ &drq->rdy_head, &drq->rdy_tail, drb->node); ++ dmad_attach_tail(drq->drb_pool, ++ &drq->fre_head, &drq->fre_tail, drb->node); ++ ++ drb->state = DMAD_DRB_STATE_FREE; ++ drb->sync = 0; ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_free_drb); ++ ++/** ++ * dmad_submit_request_internal - submit a dma-request-block to the dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @drb : [in] Reference to a drb to be submitted ++ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due ++ * to finishing its previous request ++ * @return : 0 if success, non-zero if any error ++ * ++ * Submit a DRB (DMA request block) of the given DMA channel to submission ++ * queue. DRB is a single dma request which will be pushed into the ++ * submission queue of the given DMA channel. This is a lightweight internal ++ * version of dmad_alloc_drb() majorly for use in ring mode. Critical access to ++ * the drb pool should be protected before entering this function. ++ */ ++static inline int dmad_submit_request_internal(dmad_drq * drq, dmad_drb * drb) ++{ ++ if (drb->state == DMAD_DRB_STATE_READY) { ++ /* Detach user node from ready list */ ++ dmad_detach_node(drq->drb_pool, ++ &drq->rdy_head, &drq->rdy_tail, drb->node); ++ ++ dmad_attach_tail(drq->drb_pool, ++ &drq->sbt_head, &drq->sbt_tail, drb->node); ++ ++ drb->state = DMAD_DRB_STATE_SUBMITTED; ++ ++ dmad_dbg("%s() submit drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x) state(%d)\n", __func__, ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, drb->state); ++ } else { ++ dmad_dbg("%s() skip drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x)" ++ " size(0x%08x) state(%d)\n", __func__, ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, drb->state); ++ } ++ ++ return 0; ++} ++ ++/** ++ * dmad_submit_request - submit a dma-request-block to the dma channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @drb : [in] Reference to a drb to be submitted ++ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due ++ * to finishing its previous request ++ * @return : 0 if success, non-zero if any error ++ * ++ * Submit a DRB (DMA request block) of the given DMA channel to submission ++ * queue. DRB is a single dma request which will be pushed into the ++ * submission queue of the given DMA channel. ++ */ ++int dmad_submit_request(dmad_chreq * ch_req, dmad_drb * drb, u8 keep_fired) ++{ ++ dmad_drq *drq; ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /****************************************************** ++ * Following code require _safe_exit return path ++ */ ++ ++ if (unlikely((drq->rdy_head == 0) || (drb->node == 0) || ++ (drb->node >= DMAD_DRB_POOL_SIZE))) { ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -EBADR; ++ } ++ ++ /* Detach user node from ready list */ ++ dmad_detach_node(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, ++ drb->node); ++ ++ /* Queue DRB to the end of the submitted list */ ++ dmad_dbg("submit drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) sync(0x%08x) fire(%d)\n", ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, (u32) drb->sync, keep_fired); ++ ++ /* Check if submission is performed to an empty queue */ ++ if (unlikely(keep_fired && (drq->sbt_head == 0))) { ++ /* DMA is not running, so kick off transmission */ ++ dmad_dbg("kickoff dma engine.\n"); ++ ++ dmad_attach_tail(drq->drb_pool, ++ &drq->sbt_head, &drq->sbt_tail, drb->node); ++ ++ /* Source and destination address */ ++ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { ++ outl(drb->addr1, (addr_t) drq->src_port); ++ outl(drb->addr0, (addr_t) drq->dst_port); ++ } else { ++ outl(drb->addr0, (addr_t) drq->src_port); ++ outl(drb->addr1, (addr_t) drq->dst_port); ++ } ++ ++ /* Transfer size (in units of source width) */ ++ outl(drb->req_cycle, (addr_t) drq->cyc_port); ++ ++ /* Enable DMA channel (Kick off transmission when client ++ * enable it's transfer state) */ ++ dmad_enable_channel(drq); ++ ++ drb->state = DMAD_DRB_STATE_EXECUTED; ++ ++ } else { ++ /* DMA is already running, so only queue DRB to the end of the ++ * list */ ++ dmad_attach_tail(drq->drb_pool, ++ &drq->sbt_head, &drq->sbt_tail, drb->node); ++ drb->state = DMAD_DRB_STATE_SUBMITTED; ++ } ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_submit_request); ++ ++/** ++ * dmad_withdraw_request - cancel a submitted dma-request-block ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @drb : [in] Reference to a drb to be submitted ++ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due ++ * to finishing its previous request ++ * @return : 0 if success, non-zero if any error ++ * ++ * Cancel a submitted DRB (DMA request block) of the given DMA channel in its ++ * submission queue. DRB is a single dma request which will be pushed into the ++ * submission queue of the given DMA channel. Cancellation fails if the DRB has ++ * already been kicked off. ++ */ ++int dmad_withdraw_request(dmad_chreq * ch_req, dmad_drb * drb) ++{ ++ dmad_drq *drq = 0; ++ unsigned long lock_flags; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ ++ if (unlikely(drq->sbt_head == 0)) ++ return -EBADR; ++ ++ if (unlikely((drb->node == 0) || (drb->node >= DMAD_DRB_POOL_SIZE))) ++ return -EBADR; ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ if (unlikely((drq->sbt_head == 0) || (drb->node == 0) || ++ (drb->state != DMAD_DRB_STATE_SUBMITTED) || ++ (drb->node >= DMAD_DRB_POOL_SIZE))) { ++ dmad_err("Submitted-queue is empty or invalid node!\n"); ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -EBADR; ++ } ++ ++ dmad_dbg("cancel drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d)\n", ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, drb->state); ++ ++ if (unlikely(drb->state == DMAD_DRB_STATE_EXECUTED)) { ++ dmad_dbg("Already running drb cannot be stopped currently!\n"); ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return 0;/*-EBADR; */ ++ } ++ ++ dmad_detach_node(drq->drb_pool, ++ &drq->rdy_head, &drq->rdy_tail, drb->node); ++ dmad_attach_tail(drq->drb_pool, ++ &drq->fre_head, &drq->fre_tail, drb->node); ++ ++ drb->state = DMAD_DRB_STATE_FREE; ++ ++ if (drb->sync) ++ complete_all(drb->sync); ++ drb->sync = 0; ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_withdraw_request); ++ ++/** ++ * dmad_kickoff_requests_internal - kickoff hw DMA transmission ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * Kickoff hw DMA transmission of the given DMA channel. This function is ++ * valid for both ring & non-ring mode. This is a lightweight internal version ++ * of dmad_kickoff_requests() majorly for use in ring mode. Critical access to ++ * the drb pool should be protected before entering this function. ++ */ ++static inline int dmad_kickoff_requests_internal(dmad_drq * drq) ++{ ++ dmad_drb *drb; ++ ++ dmad_get_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); ++ ++ if (!drb) { ++ dmad_err("%s() null drb!\n", __func__); ++ return -EBADR; ++ } ++ ++ dmad_dbg("%s() drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d)\n", __func__, ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, drb->state); ++ ++ if (drb->state == DMAD_DRB_STATE_SUBMITTED) { ++ /* Transfer size (in units of source width) */ ++ outl(drb->req_cycle, (addr_t) drq->cyc_port); ++ ++ /* Source and destination address */ ++ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { ++ outl(drb->addr1, (addr_t) drq->src_port); ++ outl(drb->addr0, (addr_t) drq->dst_port); ++ } else { ++ outl(drb->addr0, (addr_t) drq->src_port); ++ outl(drb->addr1, (addr_t) drq->dst_port); ++ } ++ ++ drb->state = DMAD_DRB_STATE_EXECUTED; ++ } ++ ++ /* Enable DMA channel */ ++ if (!dmad_is_channel_enabled(drq)) { ++ dmad_enable_channel(drq); ++ } ++ ++ return 0; ++} ++ ++/** ++ * dmad_kickoff_requests - kickoff hw DMA transmission of the given DMA channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : 0 if success, non-zero if any error ++ * ++ * Kickoff hw DMA transmission of the given DMA channel. This function is ++ * valid for both ring & non-ring mode. ++ */ ++int dmad_kickoff_requests(dmad_chreq * ch_req) ++{ ++ dmad_drq *drq = 0; ++ dmad_drb *drb = 0; ++ unsigned long lock_flags; ++ dma_addr_t req_cycle; ++ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (unlikely(ch_req == NULL)) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ if (unlikely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ dmad_get_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); ++ ++ dmad_dbg("drq(0x%08x) channel_base(0x%08x)\n", ++ (u32) drq, drq->channel_base); ++ dmad_dbg("kick off drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d) a1_to_a0(%d)\n", ++ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, ++ drb->req_cycle, drb->state, ++ drq->flags & DMAD_DRQ_DIR_A1_TO_A0); ++ ++ /* do nothing if no drbs are in the submission queue */ ++ if (unlikely((drb == 0) || (drb->state != DMAD_DRB_STATE_SUBMITTED))) { ++ dmad_dbg("%s() invalid drb(%d 0x%08x) or drb-state(%d)!\n", ++ __func__, ++ drb->node, (u32) drb, drb ? drb->state : 0xffffffff); ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return 0; ++ } ++ ++ req_cycle = drb->req_cycle; ++ ++ if (unlikely(req_cycle == 0)) { ++ dmad_dbg("%s() zero transfer size!\n", __func__); ++ goto _safe_exit; ++ } ++ ++ /* Transfer size (in units of source width) */ ++ outl(req_cycle, (addr_t) drq->cyc_port); ++ ++ /* Source and destination address */ ++ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { ++ outl(drb->addr1, (addr_t) drq->src_port); ++ outl(drb->addr0, (addr_t) drq->dst_port); ++ } else { ++ outl(drb->addr0, (addr_t) drq->src_port); ++ outl(drb->addr1, (addr_t) drq->dst_port); ++ } ++ ++ drb->state = DMAD_DRB_STATE_EXECUTED; ++ ++ /* Enable DMA channel */ ++ dmad_enable_channel(drq); ++ ++_safe_exit: ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_kickoff_requests); ++ ++/** ++ * dmad_probe_hw_ptr_src - probe DMA source hw-address of the given channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : physical address of current HW source pointer ++ * ++ * Probe DMA source hw-address of the given channel. ++ */ ++dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq * ch_req) ++{ ++ return (dma_addr_t) inl(((dmad_drq *) ch_req->drq)->src_port); ++} ++ ++EXPORT_SYMBOL_GPL(dmad_probe_hw_ptr_src); ++ ++/** ++ * dmad_probe_hw_ptr_dst - probe DMA destination hw-address of the given channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : physical address of current HW destination pointer ++ * ++ * Probe DMA destination hw-address of the given channel. ++ */ ++dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq * ch_req) ++{ ++ return (dma_addr_t) inl(((dmad_drq *) ch_req->drq)->dst_port); ++} ++ ++EXPORT_SYMBOL_GPL(dmad_probe_hw_ptr_dst); ++ ++/** ++ * dmad_update_ring - update DMA ring buffer base && size of the given channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @size : [in] The new ring buffer size, in unit of data width (cycles) ++ * @return : 0 if success, non-zero if any error ++ * ++ * Update DMA ring buffer size of the given channel. This function is valid ++ * only if the channel is initialized as ring buffer mode. ++ */ ++int dmad_update_ring(dmad_chreq * ch_req) ++{ ++ unsigned long lock_flags; ++ dmad_drq *drq = (dmad_drq *) ch_req->drq; ++ int remnant; ++ ++ if (unlikely(dmad_is_channel_enabled(drq))) { ++ dmad_err("%s() Error - dma channel should be " ++ "disabled before updating ring size!\n", __func__); ++ return -EFAULT; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /* todo: range checking */ ++ ++ remnant = (int)ch_req->ring_size - ++ (int)ch_req->periods * (int)ch_req->period_size; ++ if (remnant == 0) { ++ drq->periods = ch_req->periods; ++ } else if (remnant > 0) { ++ drq->periods = ch_req->periods; // + 1; ++ } else { ++ dmad_err("%s() Error - buffer_size < " ++ "periods * period_size!\n", __func__); ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -EFAULT; ++ } ++ ++ drq->ring_base = ch_req->ring_base; ++ drq->ring_size = ch_req->ring_size; ++ drq->period_size = ch_req->period_size; ++ drq->remnant_size = (dma_addr_t) remnant; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { ++ drq->period_bytes = ++ DMAC_CYCLE_TO_BYTES(drq->period_size, drq->data_width); ++ } ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) { ++ drq->period_bytes = ++ APBBR_DMA_CYCLE_TO_BYTES(drq->period_size, drq->data_width); ++ } ++#endif ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ dmad_dbg("%s() ring: base(0x%08x) port(0x%08x) periods(0x%08x) " ++ "period_size(0x%08x) period_bytes(0x%08x) " ++ "remnant_size(0x%08x)\n", ++ __func__, drq->ring_base, drq->ring_port, ++ drq->periods, drq->period_size, drq->period_bytes, ++ drq->remnant_size); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_update_ring); ++ ++/** ++ * dmad_update_ring_sw_ptr - update DMA ring buffer sw-pointer ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @sw_ptr : [in] The new sw-pointer for the hw-pointer to chase of ++ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due ++ * to finishing its previous request ++ * @return : 0 if success, non-zero if any error ++ * ++ * Update DMA ring buffer sw-pointer of the given channel on the fly. This ++ * function is valid only if the channel is initialized as ring buffer mode. ++ * Uint of sw_ptr is in number of dma data width. ++ */ ++int dmad_update_ring_sw_ptr(dmad_chreq * ch_req, ++ dma_addr_t sw_ptr, u8 keep_fired) ++{ ++ dmad_drq *drq; ++ unsigned long lock_flags; ++ dma_addr_t hw_off = 0, ring_ptr; ++ dma_addr_t sw_p_off, ring_p_off, period_size, period_bytes; ++ dma_addr_t remnant_size; ++ int sw_p_idx, ring_p_idx, period, periods; ++ dmad_drb *drb = NULL; ++ ++ /*if (ch_req == NULL) { */ ++ /* dmad_dbg("%s() null ch_req!\n", __func__); */ ++ /* return -EFAULT; */ ++ /*} */ ++ ++ drq = (dmad_drq *) ch_req->drq; ++ ++ /*if (drq == NULL) { */ ++ /* dmad_dbg("%s() null ch_req->drq!\n", __func__); */ ++ /* return -EBADR; */ ++ /*} */ ++ ++ if (unlikely(sw_ptr > drq->ring_size)) { ++ dmad_err("%s() Invalid ring buffer sw-pointer " ++ "range (0x%08x)! ring_size(0x%08x)\n", ++ __func__, sw_ptr, drq->ring_size); ++ return -EBADR; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ periods = drq->periods; ++ period_size = drq->period_size; ++ period_bytes = drq->period_bytes; ++ remnant_size = drq->remnant_size; ++ ++ ring_ptr = drq->sw_ptr; ++ ring_p_idx = drq->sw_p_idx; ++ ring_p_off = drq->sw_p_off; ++ ++ sw_p_idx = (int)(sw_ptr / period_size); ++ sw_p_off = sw_ptr % period_size; ++ ++ if (remnant_size && (sw_p_idx == periods)) { ++ --sw_p_idx; ++ sw_p_off += period_size; ++ } ++ ++ dmad_dbg("%s() ring_ptr(0x%08x) ring_p_idx(0x%08x) " ++ "ring_p_off(0x%08x)\n", ++ __func__, ring_ptr, ring_p_idx, ring_p_off); ++ dmad_dbg("%s() sw_ptr(0x%08x) sw_p_idx(0x%08x) sw_p_off(0x%08x)\n", ++ __func__, sw_ptr, sw_p_idx, sw_p_off); ++ ++ if (drq->ring_drb && ++ (drq->ring_drb->state & (DMAD_DRB_STATE_READY | ++ DMAD_DRB_STATE_SUBMITTED | ++ DMAD_DRB_STATE_EXECUTED))) { ++ drb = drq->ring_drb; ++ } else { ++ /* alloc new drb if there is none yet at ring_ptr */ ++ if (0 != dmad_alloc_drb_internal(drq, &drb)) { ++ dmad_err("%s() drb allocation failed!\n", __func__); ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -ENOSPC; ++ } ++ drb->addr0 = ((dma_addr_t) ring_p_idx * period_bytes) + ++ drq->ring_base; ++ drb->addr1 = drq->dev_addr; ++ drb->req_cycle = 0; // redundent, though, no harm to performance ++ ++ dmad_dbg("init_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d)\n", ++ (u32) drb->node, (u32) drb, drb->src_addr, ++ drb->dst_addr, drb->req_cycle, drb->state); ++ ++ drq->ring_drb = drb; ++ } ++ ++ /* Following code-path has been optimized. The design flow is expanded ++ * below for reference. ++ * ++ * if (sw_ptr >= ring_ptr) ++ * if (sw_p_idx == ring_p_idx) ++ * ring_drb::req_cycle <- sw_p_off ++ * if (ring_drb::state == executed) ++ * hw_cycle <- sw_p_idx ++ * fi ++ * else ++ * ring_drb::req_cycle <- period_size ++ * if (ring_drb::state == executed) ++ * hw_cycle <- period_size ++ * fi ++ * for (i = ring_p_idx+1 ~ sw_p_idx-1) ++ * new_drb::ring_addr <- i * period_bytes + ring_base ++ * new_drb::req_cycle <- period_size ++ * rof ++ * sw_drb::ring_addr <- sw_p_idx * period_bytes + ring_base ++ * sw_drb::req_cycle <- sw_p_off ++ * else ++ * // sw_ptr < ring_ptr ++ * ring_drb::req_cycle <- period_size ++ * if (ring_drb::state == executed) ++ * hw_cycle <- period_size ++ * fi ++ * for (i = ring_p_idx+1 ~ idx_max) ++ * new_drb::ring_addr <- i * period_bytes + ring_base ++ * new_drb::req_cycle <- period_size ++ * rof ++ * for (i = 0 ~ sw_p_idx-1) ++ * new_drb::ring_addr <- i * period_bytes + ring_base ++ * new_drb::req_cycle <- period_size ++ * rof ++ * sw_drb::ring_addr <- sw_p_idx * period_bytes + ring_base ++ * sw_drb::req_cycle <- sw_p_off ++ * fi ++ */ ++ if ((sw_ptr >= ring_ptr) && (sw_p_idx == ring_p_idx) && (sw_p_off != 0)) { ++ ++ dmad_dbg("update ring drb\n"); ++ ++ /* update drb size at ring_ptr */ ++ drb->req_cycle = sw_p_off; ++ ++ dmad_dbg("ring_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d)\n", ++ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, ++ drb->req_cycle, drb->state); ++ ++ /* update hw dma size of this drb if it has been sent to the ++ * controller */ ++ if (drb->state == DMAD_DRB_STATE_EXECUTED) { ++ dmad_disable_channel(drq); ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) ++ hw_off = DMAC_BYTES_TO_CYCLE((addr_t) ++ inl((addr_t) drq-> ++ ring_port) - ++ (addr_t) drb-> ++ addr0, ++ drq->data_width); ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) ++ hw_off = APBBR_DMA_BYTES_TO_CYCLE((addr_t) ++ inl((addr_t) ++ drq-> ++ ring_port) ++ - ++ (addr_t) drb-> ++ addr0, ++ drq-> ++ data_width); ++#endif ++ dmad_dbg("hw_off(0x%08x) sw_p_off(0x%08x)\n", ++ (u32) hw_off, (u32) sw_p_off); ++ ++ if (sw_p_off < hw_off) ++ dmad_err("%s() underrun! sw_p_off(0x%08x) <" ++ " hw_off(0x%08x)\n", __func__, ++ (u32) sw_p_off, (u32) hw_off); ++ else ++ outl(sw_p_off - hw_off, drq->cyc_port); ++ ++ dmad_enable_channel(drq); ++ ++ } else { ++ dmad_submit_request_internal(drq, drb); ++ } ++ ++ } else { ++ ++ dmad_dbg("fulfill ring drb - sw_ptr(0x%08x) ring_ptr(0x%08x)\n", ++ (u32) sw_ptr, (u32) ring_ptr); ++ ++ /* fulfill last drb at ring_ptr */ ++ if (ring_p_idx == (periods - 1)) ++ drb->req_cycle = period_size + remnant_size; ++ else ++ drb->req_cycle = period_size; ++ ++ dmad_dbg("ring_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d)\n", ++ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, ++ drb->req_cycle, drb->state); ++ ++ if (drb->state == DMAD_DRB_STATE_EXECUTED) { ++ dmad_disable_channel(drq); ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) ++ hw_off = DMAC_BYTES_TO_CYCLE((addr_t) ++ inl((addr_t) drq-> ++ ring_port) - ++ (addr_t) drb-> ++ addr0, ++ drq->data_width); ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) ++ hw_off = APBBR_DMA_BYTES_TO_CYCLE((addr_t) ++ inl((addr_t) ++ drq-> ++ ring_port) ++ - ++ (addr_t) drb-> ++ addr0, ++ drq-> ++ data_width); ++#endif ++ dmad_dbg("hw_off(0x%08x) period_size(0x%08x)\n", ++ (u32) hw_off, (u32) period_size); ++ ++ if (ring_p_idx == (periods - 1)) { ++ if (period_size < hw_off) ++ dmad_err("%s() illegal! " ++ "period_size(0x%08x) + " ++ "remnant_size(0x%08x) < " ++ "hw_off(0x%08x)\n", __func__, ++ (u32) period_size, ++ (u32) remnant_size, ++ (u32) hw_off); ++ else ++ outl(period_size + remnant_size - ++ hw_off, drq->cyc_port); ++ } else { ++ if (period_size < hw_off) ++ dmad_err("%s() illegal! " ++ "period_size(0x%08x) < " ++ "hw_off(0x%08x)\n", __func__, ++ (u32) period_size, ++ (u32) hw_off); ++ else ++ outl(period_size - hw_off, ++ drq->cyc_port); ++ } ++ ++ dmad_enable_channel(drq); ++ ++ } else { ++ dmad_submit_request_internal(drq, drb); ++ } ++ ++ ++ring_p_idx; ++ ++ /* adjust sw_ptr period index ahead by one ring cycle */ ++ //if (sw_ptr < ring_ptr) { ++ if (sw_p_idx < ring_p_idx) { ++ sw_p_idx += periods; ++ } ++ ++ /* allocate in-between (ring_ptr+1 to sw_ptr-1) ++ * full-cycle drbs */ ++ for (period = ring_p_idx; period < sw_p_idx; ++period) { ++ if (0 != dmad_alloc_drb_internal(drq, &drb)) { ++ dmad_err("%s() drb allocation failed!\n", ++ __func__); ++ spin_unlock_irqrestore(&drq->drb_pool_lock, ++ lock_flags); ++ return -ENOSPC; ++ } ++ ++ drb->addr0 = (dma_addr_t) (period % periods) * ++ period_bytes + drq->ring_base; ++ drb->addr1 = drq->dev_addr; ++ ++ if (period == (periods - 1)) { ++ drb->req_cycle = period_size + remnant_size; ++ } else { ++ drb->req_cycle = period_size; ++ } ++ ++ dmad_dbg("inbtw_drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x) state(%d)\n", ++ (u32) drb->node, (u32) drb, drb->addr0, ++ drb->addr1, drb->req_cycle, drb->state); ++ ++ dmad_submit_request_internal(drq, drb); ++ } ++ ++ /* allocate drb right at sw_ptr */ ++ if (0 != dmad_alloc_drb_internal(drq, &drb)) { ++ dmad_err("%s() drb allocation failed!\n", __func__); ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ return -ENOSPC; ++ } ++ drb->addr0 = (dma_addr_t) (sw_p_idx % periods) * ++ period_bytes + drq->ring_base; ++ drb->addr1 = drq->dev_addr; ++ drb->req_cycle = sw_p_off; ++ ++ dmad_dbg("swptr_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " ++ "size(0x%08x) state(%d)\n", ++ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, ++ drb->req_cycle, drb->state); ++ ++ drq->ring_drb = drb; ++ ++ if (sw_p_off > 0) ++ dmad_submit_request_internal(drq, drb); ++ } ++ ++ drq->sw_ptr = sw_ptr % drq->ring_size; ++ drq->sw_p_idx = sw_p_idx % periods; ++ drq->sw_p_off = sw_p_off; ++ ++ if (likely(keep_fired)) { ++ dmad_kickoff_requests_internal(drq); ++ } ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ return 0; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_update_ring_sw_ptr); ++ ++/** ++ * dmad_probe_ring_hw_ptr - probe DMA ring buffer position of the given channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @return : Ring buffer position of current HW ring buffer pointer ++ * ++ * Probe DMA ring buffer position of the given channel. The position is ++ * relative to the ring buffer base. This function is valid only if the ++ * channel is initialized as ring buffer mode. ++ */ ++dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq * ch_req) ++{ ++ dmad_drq *drq = (dmad_drq *) ch_req->drq; ++ dma_addr_t cycles = ++ (dma_addr_t) inl(drq->ring_port) - (dma_addr_t) drq->ring_base; ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (ch_req->controller == DMAD_DMAC_AHB_CORE) ++ cycles = DMAC_BYTES_TO_CYCLE(cycles, drq->data_width); ++#endif ++#ifdef CONFIG_PLATFORM_APBDMA ++ if (ch_req->controller == DMAD_DMAC_APB_CORE) ++ cycles = APBBR_DMA_BYTES_TO_CYCLE(cycles, drq->data_width); ++#endif ++ return cycles; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_probe_ring_hw_ptr); ++ ++/** ++ * dmad_channel_drain - cancel DMA transmission of the given DMA channel ++ * @controller : [in] One of the enum value of DMAD_DMAC_CORE ++ * @drq : [in] Reference to the DMA queue structure (dmad_drq) ++ * @shutdown : [in] Non-zero to force a immediate channel shutdown ++ * @return : 0 if success, non-zero if any error ++ * ++ * Stop the DMA transmission and cancel all submitted requests of the given ++ * DMA channel. This function drains a single channel and is the internal ++ * implementation of the interface routine dmad_drain_requests() and the ++ * module_exit function. ++ */ ++static int dmad_channel_drain(u32 controller, dmad_drq * drq, u8 shutdown) ++{ ++ dmad_drb *drb = 0; ++ unsigned long lock_flags; ++ ++ if (unlikely(drq == NULL)) { ++ dmad_err("null ch_req->drq!\n"); ++ return -EBADR; ++ } ++ ++ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); ++ ++ /* Stop DMA channel if forced to shutdown immediately */ ++ if (shutdown) { ++ /* disable dma controller */ ++ dmad_reset_channel(drq); ++ ++ /* todo: more settings to stop DMA controller ?? */ ++ ++ /*if (drb->state == DMAD_DRB_STATE_EXECUTED) { */ ++ /*} */ ++ } ++ ++ /* Detach DRBs in submit queue */ ++ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); ++ ++ while (drb) { ++ dmad_dbg("cancel sbt drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x) state(%d)\n", ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, (u32) drb->state); ++ ++ /* Mark DRB state as abort */ ++ drb->state = DMAD_DRB_STATE_ABORT; ++ ++ if (drb->sync) ++ complete_all(drb->sync); ++ ++ dmad_attach_tail(drq->drb_pool, &drq->fre_head, &drq->fre_tail, ++ drb->node); ++ ++ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, ++ &drb); ++ } ++ ++ /* Detach DRBs in ready queue */ ++ dmad_detach_head(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, &drb); ++ ++ while (drb) { ++ dmad_dbg("cancel rdy drb(%d 0x%08x) addr0(0x%08x) " ++ "addr1(0x%08x) size(0x%08x) state(%d)\n", ++ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, ++ drb->req_cycle, (u32) drb->state); ++ ++ /* Mark DRB state as abort */ ++ drb->state = DMAD_DRB_STATE_ABORT; ++ ++ dmad_attach_tail(drq->drb_pool, &drq->fre_head, &drq->fre_tail, ++ drb->node); ++ ++ /* Detach next submitted DRB (DMA Request Block) from the ++ * DRQ (DMA Request Queue) */ ++ dmad_detach_head(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, ++ &drb); ++ } ++ ++ drq->state |= DMAD_DRQ_STATE_ABORT; ++ ++ drq->ring_drb = NULL; ++ drq->sw_ptr = 0; ++ drq->sw_p_idx = 0; ++ drq->sw_p_off = 0; ++ ++ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); ++ ++ if ( /*(drq->fre_head == 0) && */ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK)) { ++ complete_all(&drq->drb_alloc_sync); ++ } ++ ++ return 0; ++} ++ ++/** ++ * dmad_cancel_requests - cancel DMA transmission of the given DMA channel ++ * @ch_req : [in] Reference to the DMA request descriptor structure ++ * @shutdown : [in] Non-zero to force a immediate channel shutdown ++ * @return : 0 if success, non-zero if any error ++ * ++ * Stop the DMA transmission and cancel all submitted requests of the given ++ * DMA channel. ++ */ ++int dmad_drain_requests(dmad_chreq * ch_req, u8 shutdown) ++{ ++ dmad_dbg("%s()\n", __func__); ++ ++ if (ch_req == NULL) { ++ dmad_err("null ch_req!\n"); ++ return -EFAULT; ++ } ++ ++ return dmad_channel_drain(ch_req->controller, ch_req->drq, shutdown); ++} ++ ++EXPORT_SYMBOL_GPL(dmad_drain_requests); ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ ++/** ++ * dmad_probe_irq_source - probe DMA channel who asserts the shared sw-irq line ++ * @return : The channel number which asserts the shared sw-irq line ++ * ++ * Probe DMA channel who asserts the shared sw-irq line. ++ */ ++int dmad_probe_irq_source_ahb(void) ++{ ++ int channel; /* interrupt channel number */ ++ ++ /* todo: spin_lock */ ++ ++ /* - Check DMA status register to get channel number */ ++ for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) { ++ if (getbl(channel, DMAC_INT_TC)) ++ return channel; ++ } ++ ++ /* Perform DMA error checking if no valid channel was found who ++ * assert the finish signal. */ ++ for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) { ++ if (getbl(channel, DMAC_INT_ERRABT)) ++ return channel; ++ if (getbl(channel << DMAC_INT_ABT_SHIFT, DMAC_INT_ERRABT)) ++ return channel; ++ } ++ ++ /* todo: spin_unlock */ ++ ++ return -EFAULT; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_probe_irq_source_ahb); ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++int dmad_probe_irq_source_apb(void) ++{ ++ int channel; /* interrupt channel number */ ++ ++ /* todo: spin_lock */ ++ ++ /* Check DMA status register to get channel number */ ++ for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) { ++ if (getbl(APBBR_DMA_FINTST_BIT, APBBR_DMA_BASE_CH(channel) + ++ APBBR_DMA_CMD_OFFSET)) ++ return channel; ++ } ++ ++ /* Perform DMA error checking if no valid channel was found who ++ * assert the finish signal. */ ++ for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) { ++ if (getbl(APBBR_DMA_ERRINTST_BIT, APBBR_DMA_BASE_CH(channel) + ++ APBBR_DMA_CMD_OFFSET)) ++ return channel; ++ } ++ ++ /* todo: spin_unlock */ ++ ++ return -EFAULT; ++} ++ ++EXPORT_SYMBOL_GPL(dmad_probe_irq_source_apb); ++ ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++/** ++ * dmad_module_init - dma module-init function ++ * @return : 0 if success, non-zero if any error ++ */ ++int __init dmad_module_init(void) ++{ ++ int err = 0; ++ dmad_dbg("%s() >>\n", __func__); ++ ++ /* clear device struct since the module may be load/unload many times */ ++ memset(&dmad, 0, sizeof(dmad)); ++ ++ dmad.drq_pool = ++ kmalloc((DMAD_AHB_MAX_CHANNELS + ++ DMAD_APB_MAX_CHANNELS) * sizeof(dmad_drq), GFP_KERNEL); ++ if (dmad.drq_pool == NULL) { ++ dmad_err("%s() failed to allocate drb pool!\n", __func__); ++ return -ENOMEM; ++ } ++ ++ memset(dmad.drq_pool, 0, ++ (DMAD_AHB_MAX_CHANNELS + DMAD_APB_MAX_CHANNELS) * ++ sizeof(dmad_drq)); ++ ++ spin_lock_init(&dmad.drq_pool_lock); ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ dmad.ahb_drq_pool = dmad.drq_pool; ++ if (unlikely(!request_region(DMAC_BASE, SZ_1K, "AHB DMAC"))) { ++ dmad_err("Cannot reserve AHB DMAC I/O region\n"); ++ err = -EBUSY; ++ } ++#endif ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ dmad.apb_drq_pool = &dmad.drq_pool[DMAD_AHB_MAX_CHANNELS]; ++ if (unlikely(!request_region(APBBR_BASE, SZ_1K, "APB DMAC"))) { ++ dmad_err("Cannot reserve APB DMAC I/O region\n"); ++ err = -EBUSY; ++ } ++#endif ++ ++ dmad_dbg("DMA module init result: (%d)\n", err); ++ dmad_dbg(" AHB channels: %d; APB channels %d; " ++ "DRBs per channel: %d\n", ++ DMAC_MAX_CHANNELS, APBBR_DMA_MAX_CHANNELS, DMAD_DRB_POOL_SIZE); ++ ++ dmad_dbg("%s() return code (%d) <<\n", __func__, err); ++ return err; ++} ++ ++/** ++ * dmad_module_init - dma module clean up function ++ */ ++void __exit dmad_module_exit(void) ++{ ++ dmad_drq *drq; ++ u32 channel; ++ ++ dmad_dbg("%s() >>\n", __func__); ++ ++ spin_lock(&dmad.drq_pool_lock); ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ /* cancel existing requests and unregister interrupt handler */ ++ for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) { ++ ++ /* shutdown dma requests */ ++ drq = (dmad_drq *) & dmad.ahb_drq_pool[channel]; ++ ++ if ((drq->state & DMAD_DRQ_STATE_READY) != 0) ++ dmad_channel_drain(DMAD_DMAC_AHB_CORE, drq, 1); ++ ++ /* free registered irq handlers */ ++ free_irq(ahb_irqs[channel], (void *)(channel + 1)); ++ } ++#endif ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ /* cancel existing requests and unregister interrupt handler */ ++ for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) { ++ ++ /* shutdown dma requests */ ++ drq = (dmad_drq *) & dmad.apb_drq_pool[channel]; ++ ++ if ((drq->state & DMAD_DRQ_STATE_READY) != 0) ++ dmad_channel_drain(DMAD_DMAC_APB_CORE, drq, 1); ++ ++ /* free registered irq handlers */ ++ free_irq(apb_irqs[channel], (void *)(channel + 1)); ++ } ++#endif ++ spin_unlock(&dmad.drq_pool_lock); ++ ++ if (dmad.drq_pool) ++ kfree(dmad.drq_pool); ++ memset(&dmad, 0, sizeof(dmad)); ++ ++ /* release I/O space */ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ release_region(DMAC_BASE, SZ_1K); ++#endif /*CONFIG_PLATFORM_AHBDMA */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ release_region(APBBR_BASE, SZ_1K); ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++ dmad_dbg("DMA module unloaded!\n"); ++} ++ ++#ifndef MODULE ++arch_initcall(dmad_module_init); ++#else ++module_init(dmad_module_init); ++module_exit(dmad_module_exit); ++#endif ++ ++#endif /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */ +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/dmad_intc.c linux-3.4.110/arch/nds32/platforms/dmad_intc.c +--- linux-3.4.110.orig/arch/nds32/platforms/dmad_intc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/dmad_intc.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,124 @@ ++/* ++ * linux/arch/armnommu/mach-faraday/platform-a320/apb_intc.c ++ * ++ * Faraday AHB DMA Interrupt Process Driver Implementation ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ++ * ChangeLog ++ * ++ * Peter Liao 09/28/2005 Created ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++extern int dmad_probe_irq_source_ahb(void); ++ ++void AHBDMA_irq_rounter(unsigned int irq, struct irq_desc *desc) ++{ ++ int ahb_irq; ++ struct irq_desc *ahb_desc; ++ struct irq_data data; ++ data.irq = irq; ++ ++ raw_spin_lock(&desc->lock); ++ desc->irq_data.chip->irq_mask(&data); ++ desc->irq_data.chip->irq_ack(&data); ++ ++ ahb_irq = dmad_probe_irq_source_ahb(); ++ if (ahb_irq >= 0) { ++ ahb_irq += DMAC_FTDMAC020_IRQ0; ++ ahb_desc = irq_desc + ahb_irq; ++ ++ raw_spin_unlock(&desc->lock); ++ ahb_desc->handle_irq(ahb_irq, ahb_desc); ++ raw_spin_lock(&desc->lock); ++ } ++ ++ desc->irq_data.chip->irq_unmask(&data); ++ raw_spin_unlock(&desc->lock); ++} ++ ++int __init intc_ftdmac020_init_irq(void) ++{ ++ int i; ++ ++ /* Register all IRQ */ ++ for (i = DMAC_FTDMAC020_IRQ0; ++ i < DMAC_FTDMAC020_IRQ0 + DMAC_FTDMAC020_IRQ_COUNT; i++) { ++ // level trigger ++ irq_set_chip(i, &dummy_irq_chip); ++ irq_set_handler(i, handle_simple_irq); ++ } ++ irq_set_chained_handler(PLATFORM_AHBDMA_IRQ, AHBDMA_irq_rounter); ++ ++ return 0; ++} ++ ++arch_initcall(intc_ftdmac020_init_irq); ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++extern int dmad_probe_irq_source_apb(void); ++ ++void APBDMA_irq_rounter(unsigned int irq, struct irq_desc *desc) ++{ ++ int apb_irq; ++ struct irq_desc *apb_desc; ++ struct irq_data data; ++ data.irq = irq; ++ ++ raw_spin_lock(&desc->lock); ++ ++ //mask_ack_irq(desc, irq); ++ desc->irq_data.chip->irq_mask(&data); ++ desc->irq_data.chip->irq_ack(&data); ++ ++ apb_irq = dmad_probe_irq_source_apb(); ++ //printk(KERN_INFO "irq (%d) ch(%d)\n", irq, apb_irq); ++ ++ if (apb_irq >= 0) { ++ apb_irq += APBBRG_FTAPBBRG020S_0_IRQ0; ++ apb_desc = irq_desc + apb_irq; ++ ++ raw_spin_unlock(&desc->lock); ++ apb_desc->handle_irq(irq, apb_desc); ++ raw_spin_lock(&desc->lock); ++ } ++ ++ desc->irq_data.chip->irq_unmask(&data); ++ raw_spin_unlock(&desc->lock); ++} ++ ++int __init intc_ftapbbrg020s_init_irq(void) ++{ ++ int i; ++ ++ /* Register all IRQ */ ++ for (i = APBBRG_FTAPBBRG020S_0_IRQ0; ++ i < APBBRG_FTAPBBRG020S_0_IRQ0 + APBBRG_FTAPBBRG020S_IRQ_COUNT; ++ i++) { ++ // level trigger ++ irq_set_chip(i, &dummy_irq_chip); ++ irq_set_handler(i, handle_simple_irq); ++ } ++ ++ irq_set_chained_handler(PLATFORM_APBDMA_IRQ, APBDMA_irq_rounter); ++ ++ return 0; ++} ++ ++arch_initcall(intc_ftapbbrg020s_init_irq); ++#endif /* CONFIG_PLATFORM_APBDMA */ +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/ftpci.c linux-3.4.110/arch/nds32/platforms/ftpci.c +--- linux-3.4.110.orig/arch/nds32/platforms/ftpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/ftpci.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,497 @@ ++/* ++ * linux/arch/nds32/platforms/ftpci.c ++ * ++ * Faraday FTPCI100 PCI Bridge Controller Device Driver Implementation ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * ++ * ChangeLog ++ * ++ * Peter Liao 09/28/2005 Created. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IPMODULE PCIC ++#define IPNAME FTPCI100 ++ ++#define DEBUGFPCI ++#undef DEBUGFPCI ++ ++#ifdef DEBUGFPCI ++#define DBGFPCI(x...) printk(x) ++#else ++#define DBGFPCI(x...) ++#endif ++#define FPCI_VA_BASE IP_VA_BASE(0) ++#define FTPCI_PCI_BRIDGE_VENID PCI_BRIDGE_VENID ++#define FPCI_IO_VA_BASE PCIIO_VA_BASE ++#define FPCI_IO_PA_BASE PCIIO_PA_BASE ++#define FPCI_IO_VA_END PCIIO_VA_LIMIT ++#define FPCI_MEM_VA_BASE PCIMEM_VA_BASE ++#define FPCI_MEM_PA_BASE PCIMEM_PA_BASE ++#define FPCI_MEM_VA_END PCIMEM_VA_LIMIT ++#define FPCI_MEM_PA_END (PCIMEM_PA_BASE + SZ_256M) ++ ++// -------------------------------------------------------------------- ++// AHB Control Register ++// -------------------------------------------------------------------- ++#define FTPCI_IOSIZE_REG 0x0 ++#define FTPCI_PROT_REG 0x4 ++#define FTPCI_CTRL_REG 0x8 ++#define FTPCI_ERREN_REG 0xc ++#define FTPCI_SOFTRST_REG 0x10 ++#define FTPCI_EN64_REG 0x14 ++#define FTPCI_ADDRH32_REG 0x18 ++#define FTPCI_CFG_ADR_REG 0x28 ++#define FTPCI_CFG_DATA_REG 0x2c ++ ++// -------------------------------------------------------------------- ++// FTPCI_IOSIZE_REG's constant definitions ++// -------------------------------------------------------------------- ++#define FTPCI_BASE_IO_SIZE_1M 0x0 ++#define FTPCI_BASE_IO_SIZE_2M 0x1 ++#define FTPCI_BASE_IO_SIZE_4M 0x2 ++#define FTPCI_BASE_IO_SIZE_8M 0x3 ++#define FTPCI_BASE_IO_SIZE_16M 0x4 ++#define FTPCI_BASE_IO_SIZE_32M 0x5 ++#define FTPCI_BASE_IO_SIZE_64M 0x6 ++#define FTPCI_BASE_IO_SIZE_128M 0x7 ++#define FTPCI_BASE_IO_SIZE_256M 0x8 ++#define FTPCI_BASE_IO_SIZE_512M 0x9 ++#define FTPCI_BASE_IO_SIZE_1G 0xa ++#define FTPCI_BASE_IO_SIZE_2G 0xb ++ ++// -------------------------------------------------------------------- ++// PCI Configuration Register ++// -------------------------------------------------------------------- ++#define PCI_INT_MASK 0x4c ++#define PCI_MEM_BASE_SIZE1 0x50 ++#define PCI_MEM_BASE_SIZE2 0x54 ++#define PCI_MEM_BASE_SIZE3 0x58 ++ ++// -------------------------------------------------------------------- ++// PCI_INT_MASK's bit definitions ++// -------------------------------------------------------------------- ++#define PCI_INTA_ENABLE (1U<<22) ++#define PCI_INTB_ENABLE (1U<<23) ++#define PCI_INTC_ENABLE (1U<<24) ++#define PCI_INTD_ENABLE (1U<<25) ++ ++// -------------------------------------------------------------------- ++// PCI_MEM_BASE_SIZE1's constant definitions ++// -------------------------------------------------------------------- ++#define FTPCI_BASE_ADR_SIZE_1MB (PHYS_OFFSET | (0x0<<16)) ++#define FTPCI_BASE_ADR_SIZE_2MB (PHYS_OFFSET | (0x1<<16)) ++#define FTPCI_BASE_ADR_SIZE_4MB (PHYS_OFFSET | (0x2<<16)) ++#define FTPCI_BASE_ADR_SIZE_8MB (PHYS_OFFSET | (0x3<<16)) ++#define FTPCI_BASE_ADR_SIZE_16MB (PHYS_OFFSET | (0x4<<16)) ++#define FTPCI_BASE_ADR_SIZE_32MB (PHYS_OFFSET | (0x5<<16)) ++#define FTPCI_BASE_ADR_SIZE_64MB (PHYS_OFFSET | (0x6<<16)) ++#define FTPCI_BASE_ADR_SIZE_128MB (PHYS_OFFSET | (0x7<<16)) ++#define FTPCI_BASE_ADR_SIZE_256MB (PHYS_OFFSET | (0x8<<16)) ++#define FTPCI_BASE_ADR_SIZE_512MB (PHYS_OFFSET | (0x9<<16)) ++#define FTPCI_BASE_ADR_SIZE_1GB (PHYS_OFFSET | (0xa<<16)) ++#define FTPCI_BASE_ADR_SIZE_2GB (PHYS_OFFSET | (0xb<<16)) ++ ++#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3) ) ++ ++struct pci_dev *pci_bridge = NULL; ++static unsigned int pci_config_addr; ++static unsigned int pci_config_data; ++int ftpci_probed = 0; ++ ++static struct resource pcic_resource = { ++ .name = "Faradat PCIC", ++ .start = IP_VA_BASE(0), ++ .end = IP_VA_LIMIT(0), ++}; ++ ++// Luke Lee 03/21/2005 mod begin ++static int ftpci_read_config_byte(struct pci_bus *bus, unsigned int devfn, ++ int where, u8 * val) ++{ ++ u32 v; ++ unsigned int shift; ++ ++ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); ++ v = inl(pci_config_data); ++ shift = (where & 0x3) * 8; ++ *val = (v >> shift) & 0xff; ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int ftpci_read_config_word(struct pci_bus *bus, unsigned int devfn, ++ int where, u16 * val) ++{ ++ u32 v; ++ unsigned int shift; ++ ++ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); ++ v = inl(pci_config_data); ++ shift = (where & 0x3) * 8; ++ *val = (v >> shift) & 0xffff; ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int ftpci_read_config_dword(struct pci_bus *bus, unsigned int devfn, ++ int where, u32 * val) ++{ ++ u32 v; ++ ++ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); ++ v = inl(pci_config_data); ++ *val = v; ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int ftpci_write_config_byte(struct pci_bus *bus, unsigned int devfn, ++ int where, u8 val) ++{ ++ u32 org_val; ++ unsigned int shift; ++ ++ shift = (where & 0x3) * 8; ++ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); ++ org_val = inl(pci_config_data); ++ org_val = (org_val & ~(0xff << shift)) | ((u32) val << shift); ++ outl(org_val, pci_config_data); ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int ftpci_write_config_word(struct pci_bus *bus, unsigned int devfn, ++ int where, u16 val) ++{ ++ u32 org_val; ++ unsigned int shift; ++ ++ shift = (where & 0x3) * 8; ++ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); ++ org_val = inl(pci_config_data); ++ org_val = (org_val & ~(0xffff << shift)) | ((u32) val << shift); ++ outl(org_val, pci_config_data); ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int ftpci_write_config_dword(struct pci_bus *bus, unsigned int devfn, ++ int where, u32 val) ++{ ++ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); ++ outl(val, pci_config_data); ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++// Luke Lee 03/21/2005 mod end ++ ++// Luke Lee 03/21/2005 ins begin ++static int ftpci_read_config(struct pci_bus *bus, unsigned int devfn, int where, ++ int size, u32 * val) ++{ ++ int r; ++ switch (size) { ++ case 1: ++ r = ftpci_read_config_byte(bus, devfn, where, (u8 *) val); // Luke Lee TOFIX 03/22/2005 : convert to (u8*) -- beware of endian ! ++ break; ++ case 2: ++ r = ftpci_read_config_word(bus, devfn, where, (u16 *) val); // Luke Lee TOFIX 03/22/2005 : convert to (u16*) -- beware of endian ! ++ break; ++ ++ default: ++ r = ftpci_read_config_dword(bus, devfn, where, val); ++ break; ++ } ++ ++ return r; ++} ++ ++static int ftpci_write_config(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 val) ++{ ++ int r; ++ switch (size) { ++ case 1: ++ r = ftpci_write_config_byte(bus, devfn, where, val); ++ break; ++ case 2: ++ r = ftpci_write_config_word(bus, devfn, where, val); ++ break; ++ ++ case 4: ++ r = ftpci_write_config_dword(bus, devfn, where, val); ++ break; ++ default: ++ printk("Invalid size for ftpci_write()\n"); ++ r = PCIBIOS_FUNC_NOT_SUPPORTED; // Luke Lee 03/23/2005 ins 1 ++ } ++ ++ return r; ++} ++ ++// Luke Lee 03/21/2005 ins end ++ ++static struct pci_ops ftpci_ops = { ++ // Luke Lee 03/21/2005 mod begin ++ .read = ftpci_read_config, ++ .write = ftpci_write_config, ++ // Luke Lee 03/21/2005 mod end ++}; ++ ++/* using virtual address for pci_resource_start() function*/ ++static struct resource pci_io = { ++ .name = "Faraday PCI I/O Space", ++ .start = FPCI_IO_VA_BASE, ++ .end = FPCI_IO_VA_END, ++ .flags = IORESOURCE_IO, ++}; ++ ++/* using physical address for memory resource*/ ++static struct resource pci_mem = { ++ .name = "Faraday PCI non-prefetchable Memory Space", ++ .start = FPCI_MEM_PA_BASE, ++ .end = FPCI_MEM_PA_END, ++ .flags = IORESOURCE_MEM, ++}; ++ ++// Luke Lee 03/23/2005 unrem 1 rem 1 ++int __init ftpci_setup_resource(struct resource **resource) ++{ ++ DBGFPCI("PCI I/O space from %08lX to %08lX\n", pci_io.start, ++ pci_io.end); ++ DBGFPCI("PCI Memory space from %08lX to %08lX\n", pci_mem.start, ++ pci_mem.end); ++ if (request_resource(&ioport_resource, &pci_io)) { ++ printk(KERN_ERR "PCI: unable to allocate io region\n"); ++ return -EBUSY; // Luke Lee 03/23/2005 unrem 1 ++ } ++ if (request_resource(&iomem_resource, &pci_mem)) { ++ printk(KERN_ERR "PCI: unable to allocate non-prefetchable " ++ "memory region\n"); ++ return -EBUSY; // Luke Lee 03/23/2005 unrem 1 ++ } ++ ++ /* ++ * bus->resource[0] is the IO resource for this bus ++ * bus->resource[1] is the mem resource for this bus ++ * bus->resource[2] is the prefetch mem resource for this bus ++ */ ++ ++ resource[0] = &pci_io; ++ resource[1] = &pci_mem; ++ resource[2] = NULL; ++ ++ return 1; // Luke Lee 03/23/2005 unrem 1 ++} ++ ++int ftpci_get_irq(void) ++{ ++ unsigned int status; ++ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, &status); // Luke Lee 03/22/2005 mod 1 ++ DBGFPCI("ftpci_get_irq,status=0x%x\n", status); ++ status = (status >> 28); ++ if (status & 0x1) ++ return 0; ++ if (status & 0x2) ++ return 1; ++ if (status & 0x4) ++ return 2; ++ if (status & 0x8) ++ return 3; ++ return -1; ++} ++ ++void ftpci_clear_irq(unsigned int irq) ++{ ++ //int i; ++ unsigned int status; ++ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, &status); // Luke Lee 03/22/2005 mod 1 ++ if (irq == 0) ++ status = (status & 0xfffffff) | ((0x1) << 28); ++ else if (irq == 1) ++ status = (status & 0xfffffff) | ((0x2) << 28); ++ else if (irq == 2) ++ status = (status & 0xfffffff) | ((0x4) << 28); ++ else if (irq == 3) ++ status = (status & 0xfffffff) | ((0x8) << 28); ++ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, status); // Luke Lee 03/22/2005 mod 1 ++} ++ ++void ftpci_unmask_irq(unsigned int irq) ++{ ++ u32 val; ++ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, ++ PCI_INT_MASK, &val); ++ val |= (PCI_INTA_ENABLE << irq); ++ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, ++ PCI_INT_MASK, val); ++} ++ ++void ftpci_mask_irq(unsigned int irq) ++{ ++ u32 val; ++ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, ++ PCI_INT_MASK, &val); ++ val &= ~(PCI_INTA_ENABLE << irq); ++ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, ++ PCI_INT_MASK, val); ++} ++ ++static int ftpci_probe(unsigned int addr_p) ++{ ++ unsigned int *addr = (unsigned int *)addr_p; ++ *(volatile unsigned int *)addr = 0x80000000; ++ if (*(volatile unsigned int *)addr == 0x80000000) { ++ DBGFPCI("Faraday FPCI bridge probed ok\n"); ++ ftpci_probed = 1; ++ } else { ++ ftpci_probed = 0; ++ } ++ *(volatile unsigned int *)addr = 0x0; ++ return ftpci_probed; ++} ++ ++void __init ftpci_preinit(void /**sysdata*/ ) // Luke Lee 03/22/2005 mod 1 ++{ ++ DBGFPCI("ftpci_preinit()\n\r"); ++ ++#ifdef CONFIG_PLAT_AG101 ++ /* Walk around for A321 but remove after leopard pci */ ++ *(volatile unsigned long *)(FPCI_VA_BASE + 0x8) = 0x10; ++#endif ++ ++ pci_config_addr = FPCI_VA_BASE + FTPCI_CFG_ADR_REG; ++ pci_config_data = FPCI_VA_BASE + FTPCI_CFG_DATA_REG; ++ DBGFPCI("Config addr is %08X, data port is %08X\n", ++ (int)pci_config_addr, (int)pci_config_data); ++ ++ if (!ftpci_probe(pci_config_addr)) ++ return; ++} ++ ++void ftpci_postinit(void /**sysdata*/ ) ++{ ++ u32 val; ++ DBGFPCI("ftpci_postinit()\n\r"); ++ pci_bridge = pci_get_device(PCI_BRIDGE_VENID, PCI_BRIDGE_DEVID, NULL); ++ if (pci_bridge == NULL) ++ return; ++ // Enable the Interrupt Mask (INTA/INTB/INTC/INTD) ++ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_INT_MASK, &val); // Luke Lee 03/22/2005 mod 1 ++ val |= ++ (PCI_INTA_ENABLE | PCI_INTB_ENABLE | PCI_INTC_ENABLE | ++ PCI_INTD_ENABLE); ++ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_INT_MASK, val); // Luke Lee 03/22/2005 mod 1 ++ ++ // Write DMA Start Address/Size Data to the Bridge configuration space ++ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_MEM_BASE_SIZE1, FTPCI_BASE_ADR_SIZE_1GB); // Luke Lee 03/22/2005 mod 1 ++ DBGFPCI("%s: Post init ok\n", __func__); ++} ++ ++/* ++ * This routine handles multiple bridges. ++ */ ++static u8 __init fpci_swizzle(struct pci_dev *dev, u8 * pinp) ++{ ++ // If there are one more bridges on our platfrom, we need to implement this function. ++ DBGFPCI("a320_swizzle(%X,%X)\n\r", (unsigned)dev, (unsigned)pinp); ++ return 0; ++} ++ ++static int __init fpci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ DBGFPCI("a320_map_irq,slot=%d pin=%d\n", PCI_SLOT(dev->devfn), pin); ++ switch ((PCI_SLOT(dev->devfn) + pin - 8 - 1) % 4) { ++ case 0: ++ return IP_IRQ0(0); ++ case 1: ++ return IP_IRQ1(0); ++ case 2: ++ return IP_IRQ2(0); ++ case 3: ++ return IP_IRQ3(0); ++ default: ++ printk(KERN_ERR "Not Support Slot %d\n", slot); ++ break; ++ } ++ return -1; ++} ++ ++int __init ftpci_setup(int nr, struct pci_sys_data *sys) ++{ ++ int ret = 0; ++ if (nr == 0) { ++ ret = ftpci_setup_resource(sys->resource); ++// sys->mem_offset = FPCI_MEM_VA_BASE - FPCI_MEM_PA_BASE; ++ sys->mem_offset = 0; ++ sys->io_offset = FPCI_IO_VA_BASE - FPCI_IO_PA_BASE; ++ } ++ return ret; ++} ++ ++static struct pci_bus *__devinit ftpci_scan_bus(int nr, ++ struct pci_sys_data *sys) ++{ ++ return pci_scan_bus(sys->busnr, &ftpci_ops, sys); ++} ++ ++static struct hw_pci a320_pci __initdata = { ++ .swizzle = fpci_swizzle, ++ .map_irq = fpci_map_irq, ++ .setup = ftpci_setup, ++ .nr_controllers = 1, ++ .scan = ftpci_scan_bus, ++ .preinit = ftpci_preinit, /* The first called init function */ ++ .postinit = ftpci_postinit, /* It is called after hw init and scanned PCI bus */ ++}; ++ ++static int __init fpci_init(void) ++{ ++#ifdef MODULE ++ printk(KERN_INFO "Faraday PCI driver Init"); ++#endif ++ printk(KERN_DEBUG "Init A321 PCI bridge controller\n"); ++ /* Register I/O address range of this PCI Bridge Controller */ ++ DBGFPCI("Name:%s, Base=%lX, End=%lX\n", pcic_resource.name, ++ pcic_resource.start, pcic_resource.end); ++ request_resource(&ioport_resource, &pcic_resource); ++ pci_common_init(&a320_pci); ++ return 0; ++} ++ ++subsys_initcall(fpci_init); ++ ++EXPORT_SYMBOL(ftpci_probed); ++EXPORT_SYMBOL(ftpci_clear_irq); ++EXPORT_SYMBOL(ftpci_get_irq); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/intc.c linux-3.4.110/arch/nds32/platforms/intc.c +--- linux-3.4.110.orig/arch/nds32/platforms/intc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/intc.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,257 @@ ++/* ++ * linux/arch/nds32/platforms/intc.c ++ * ++ * Faraday FTINTC010 Master Interrupt Controller Device Driver Implementation ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Note ++ * ++ * This program implements only the master INTC of the platform. Slave INTCs must ++ * be initialized by themselves. ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/14/2005 Created. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define IPMODULE INTC ++#define IPNAME FTINTC010 ++ ++/* ++ * Edge trigger IRQ chip methods ++ */ ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++spinlock_t irq_chip_lock; ++#endif ++ ++static void intc_ftintc010_ack_irq(struct irq_data *data) ++{ ++ unsigned int tmp; ++ ++ // ack and disable ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_lock_irq(&irq_chip_lock); ++#endif ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG) = 1 << data->irq; ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG); ++ ++ if (!(tmp & (1UL << data->irq))) { /* level trigger */ ++ ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &= ++ ~(1 << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); ++ } ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_unlock_irq(&irq_chip_lock); ++#endif ++} ++ ++static void intc_ftintc010_mask_irq(struct irq_data *data) ++{ ++ unsigned int tmp; ++ ++ // disable ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_lock_irq(&irq_chip_lock); ++#endif ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &= ++ ~(1 << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_unlock_irq(&irq_chip_lock); ++#endif ++} ++ ++static void intc_ftintc010_mask_ack_irq(struct irq_data *data) ++{ ++ unsigned int tmp; ++ ++ // disable ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_lock_irq(&irq_chip_lock); ++#endif ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &= ++ ~(1 << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); ++ ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG) = 1 << data->irq; ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG); ++ ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_unlock_irq(&irq_chip_lock); ++#endif ++} ++ ++static void intc_ftintc010_unmask_irq(struct irq_data *data) ++{ ++ unsigned int tmp; ++ ++ // enable ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_lock_irq(&irq_chip_lock); ++#endif ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) |= 1 << data->irq; ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_unlock_irq(&irq_chip_lock); ++#endif ++} ++ ++static int intc_ftintc010_set_type(struct irq_data *data, ++ unsigned int flow_type) ++{ ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_lock_irq(&irq_chip_lock); ++#endif ++ /* ++ * IRQ Trigger Mode Register 1: edge ++ * IRQ Trigger Level Register 1: active high ++ */ ++ ++ int tmp; ++ ++ if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) { ++ ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG) &= ++ ~(1UL << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG); ++ } ++ ++ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) { ++ ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG) |= ++ (1UL << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG); ++ } ++ ++ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { ++ ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG) |= ++ (1UL << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG); ++ (irq_desc + data->irq)->handle_irq = handle_edge_irq; ++ } ++ ++ if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { ++ ++ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG) &= ++ ~(1UL << data->irq); ++ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG); ++ (irq_desc + data->irq)->handle_irq = handle_level_irq; ++ } ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_unlock_irq(&irq_chip_lock); ++#endif ++ return 0; ++} ++ ++static struct irq_chip intc_ftintc010_chip = { ++ ++ .irq_ack = intc_ftintc010_ack_irq, ++ .irq_mask = intc_ftintc010_mask_irq, ++ .irq_mask_ack = intc_ftintc010_mask_ack_irq, ++ .irq_unmask = intc_ftintc010_unmask_irq, ++ .irq_set_type = intc_ftintc010_set_type, ++}; ++ ++static struct resource intc_resource = { ++ ++ .name = "Main interrupt controller", ++ .start = IP_VA_BASE(0), ++ .end = IP_VA_BASE(0) + IP_VA_SIZE(0), ++}; ++ ++/* ++ * Initialization of master interrupt controller, after this INTC is ++ * enabled, the rest of Linux initialization codes can then be completed. ++ * For example, timer interrupts and UART interrupts must be enabled during ++ * the boot process. ++ */ ++void __init intc_ftintc010_init_irq(void) ++{ ++ int i, edge; ++ ++#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) ++ spin_lock_init(&irq_chip_lock); ++#endif ++ /* Initialize the INTC */ ++ outl(0x00000000, IP_VA_BASE(0) + IRQ_MASK_REG); ++ outl(0x00000000, IP_VA_BASE(0) + FIQ_MASK_REG); ++ outl(0xffffffff, IP_VA_BASE(0) + IRQ_CLEAR_REG); ++ outl(0xffffffff, IP_VA_BASE(0) + FIQ_CLEAR_REG); ++ outl(PLATFORM_IRQ_TRIGGER_MODE, IP_VA_BASE(0) + IRQ_MODE_REG); ++ /* FTINTC010: bit 0=active high or rising edge, 1=active low or falling edge. */ ++ outl(PLATFORM_IRQ_TRIGGER_LEVEL, IP_VA_BASE(0) + IRQ_LEVEL_REG); ++ ++ /* Register all IRQ */ ++ for (i = PLATFORM_IRQ_BASE, edge = 1; ++ i < PLATFORM_IRQ_BASE + PLATFORM_IRQ_TOTALCOUNT; i++, edge <<= 1) { ++ ++ irq_set_chip(i, &intc_ftintc010_chip); ++ ++ if (PLATFORM_IRQ_TRIGGER_MODE & edge) /* edge trigger */ ++ irq_set_handler(i, handle_edge_irq); ++ ++ else /* level trigger */ ++ irq_set_handler(i, handle_level_irq); ++ } ++ ++ /* Register I/O address range of this INTC */ ++ request_resource(&ioport_resource, &intc_resource); ++ ++} ++ ++unsigned int get_IntSrc(void) ++{ ++ unsigned int irq_status, irq = 31; ++ ++ irq_status = inl(IP_VA_BASE(0) + IRQ_STATUS_REG); ++ if (irq_status == 0) ++ return 32; ++ if (irq_status & 0x0000ffff) { ++ irq -= 16; ++ irq_status <<= 16; ++ } ++ if (irq_status & 0x00ff0000) { ++ irq -= 8; ++ irq_status <<= 8; ++ } ++ if (irq_status & 0x0f000000) { ++ irq -= 4; ++ irq_status <<= 4; ++ } ++ if (irq_status & 0x30000000) { ++ irq -= 2; ++ irq_status <<= 2; ++ } ++ if (irq_status & 0x40000000) { ++ irq -= 1; ++ } ++ return irq; ++} +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/Kconfig linux-3.4.110/arch/nds32/platforms/Kconfig +--- linux-3.4.110.orig/arch/nds32/platforms/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/Kconfig 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,122 @@ ++choice ++ prompt "platform type" ++ default PLAT_AG101P ++ ++config PLAT_VEP ++ bool "vep platform" ++ select CPU_CUSTOM ++ select PLATFORM_INTC ++ ++config PLAT_AG101 ++ bool "ag101 platform" ++ select CPU_N1213 ++ select CPU_N1213_43U1HA0 ++ select PLATFORM_INTC ++ ++config PLAT_AG102 ++ bool "ag102 platform" ++ select CPU_N1233F ++ select PLATFORM_AMIC ++ ++config PLAT_AG101P ++ bool "ag101p platform" ++ select CPU_CUSTOM ++ select PLATFORM_INTC if !IVIC ++ select PLATFORM_NOINTC if IVIC ++ ++config PLAT_QEMU ++ bool "qemu platform" ++ select CPU_CUSTOM ++ select PLATFORM_INTC ++endchoice ++ ++config PLATFORM_NOINTC ++ def_bool n ++ depends on PLAT_AG101P ++ ++config PLATFORM_INTC ++ def_bool n ++ depends on !PLAT_AG102 ++ ++config PLATFORM_AMIC ++ def_bool n ++ depends on PLAT_AG102 ++ ++config ARCH_WANT_OPTIONAL_GPIOLIB ++ bool "Arch Want Optional GPIOLIB" ++ default y ++ ++if PLAT_VEP ++source "arch/nds32/platforms/vep/Kconfig" ++endif ++ ++if PLAT_AG101 ++source "arch/nds32/platforms/ag101/Kconfig" ++endif ++ ++if PLAT_AG102 ++source "arch/nds32/platforms/ag102/Kconfig" ++endif ++ ++if PLAT_AG101P ++source "arch/nds32/platforms/ag101p/Kconfig" ++endif ++ ++if PLAT_QEMU ++source "arch/nds32/platforms/qemu/Kconfig" ++endif ++ ++menu "Common Platform Options" ++ ++config PLATFORM_AHBDMA ++ tristate "AHB DMA Support" ++ help ++ AHB DMA service API support for other device drivers ++ ++config PLATFORM_APBDMA ++ tristate "APB DMA Support" ++ help ++ AHB DMA service API support for other device drivers ++ ++config SYS_CLK ++ int "AHB System Clock" ++ default 67737600 ++ help ++ Manual setting of AHB clock, must match the jumper setting on ++ the board, or the system time won't be correctly calculated. ++ Notice that even when AUTO_SYS_CLK is ON, this value is still ++ required for adjusting minor time offsets. However, the influence ++ should be within micro-second to nano-second scale. ++ ++config UART_CLK ++ int "UART Clock" ++ default 18432000 ++ help ++ Change the UART clock in case of non-3.6864MHz OSC is used as main ++ clock source, or an external UART clock source is fed from GPIO23. ++ To support external UART clock from GPIO23, set PMU ++ "Multi-Function Port Setting Register" bit #8 (UartClkSel) to 1. ++ This control register can be found at physical address 0x98100028 ++ If this options is changed, please also append "38400" to your ++ kernel command line, e.g.: ++ console=uart,shift,2,io,0xF9820000,38400 ++ Note: For A320, the default UART clock is obtained by = 5 * OSC = ++ 5 * 3.6864MHz = 18.432MHz. ++ ++menu "Memory configuration" ++ ++config SDRAM_SIZE ++ hex "SDRAM Size (hex)" ++ default 4000000 ++ ---help--- ++ RAM size ++ ++config MEMORY_START ++ hex "Physical memory start address" ++ default "0x00000000" ++ ---help--- ++ Physical memory start address, you may modify it if it is porting to ++ a new SoC with different start address. ++endmenu ++ ++endmenu +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/Makefile linux-3.4.110/arch/nds32/platforms/Makefile +--- linux-3.4.110.orig/arch/nds32/platforms/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/Makefile 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,25 @@ ++obj-y := timer.o ++ ++ifdef CONFIG_FUNCTION_TRACER ++CFLAGS_REMOVE_timer.o = -pg ++endif ++ ++obj-$(CONFIG_PLATFORM_NOINTC) += nointc.o ++obj-$(CONFIG_PLATFORM_INTC) += intc.o ++obj-$(CONFIG_PLATFORM_AMIC) += amic.o ++ ++ifeq ("$(CONFIG_PLATFORM_AHBDMA)", "y") ++ obj-y += dmad_intc.o dmad.o ++else ++ ifeq ("$(CONFIG_PLATFORM_APBDMA)", "y") ++ obj-y += dmad_intc.o dmad.o ++ endif ++endif ++ ++obj-$(CONFIG_PCI) += ftpci.o pci_intc.o ++ ++obj-$(CONFIG_PLAT_VEP) += vep/ ++obj-$(CONFIG_PLAT_AG101) += ag101/ ++obj-$(CONFIG_PLAT_AG102) += ag102/ ++obj-$(CONFIG_PLAT_AG101P) += ag101p/ ++obj-$(CONFIG_PLAT_QEMU) += qemu/ +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/nointc.c linux-3.4.110/arch/nds32/platforms/nointc.c +--- linux-3.4.110.orig/arch/nds32/platforms/nointc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/nointc.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,134 @@ ++/* ++ * linux/arch/nds32/platforms/intc.c ++ * ++ * Faraday FTINTC010 Master Interrupt Controller Device Driver Implementation ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++ ++static void nointc_ack_irq(struct irq_data *data) ++{ ++ SET_INT_PEND2(1 << data->irq); ++#if 0 ++ asm volatile ("mtsr %0, $INT_PEND2\n\t" ++ "dsb\n\t"::"r" (1 << data->irq)); ++#endif ++#if 0 ++ asm volatile ("mfsr $r6, $INT_MASK2\n\t" ++ "and $r6, $r6,%0\n\t" ++ "mtsr $r6, $INT_MASK2\n\t" ++ "dsb\n\t"::"r" (~(1 << data->irq)):"$r6"); ++#endif ++} ++ ++static void nointc_mask_irq(struct irq_data *data) ++{ ++ unsigned long int_mask2 = GET_INT_MASK2(); ++ SET_INT_MASK2(int_mask2 & (~(1 << data->irq))); ++#if 0 ++ asm volatile ("mfsr $r6, $INT_MASK2\n\t" ++ "and $r6, $r6,%0\n\t" ++ "mtsr $r6, $INT_MASK2\n\t" ++ "dsb\n\t"::"r" (~(1 << data->irq)):"$r6"); ++#endif ++} ++ ++static void nointc_mask_ack_irq(struct irq_data *data) ++{ ++ unsigned long int_mask2 = GET_INT_MASK2(); ++ SET_INT_MASK2(int_mask2 & (~(1 << data->irq))); ++ SET_INT_PEND2(1 << data->irq); ++#if 0 ++ asm volatile ("not $r7, %0\n\t" ++ "mfsr $r6, $INT_MASK2\n\t" ++ "and $r6, $r6, $r7\n\t" ++ "mtsr $r6, $INT_MASK2\n\t" ++ "mtsr %0, $INT_PEND2\n\t" ++ "dsb\n\t"::"r" (1 << data->irq):"$r6", "$r7"); ++#endif ++ ++} ++ ++static void nointc_unmask_irq(struct irq_data *data) ++{ ++ unsigned long int_mask2 = GET_INT_MASK2(); ++ SET_INT_MASK2(int_mask2 | (1 << data->irq)); ++#if 0 ++ asm volatile ("mfsr $r6, $INT_MASK2\n\t" ++ "or $r6, $r6,%0\n\t" ++ "mtsr $r6, $INT_MASK2\n\t" ++ "dsb\n\t"::"r" (1 << data->irq):"$r6"); ++#endif ++} ++ ++static int nointc_set_type(struct irq_data *data, unsigned int flow_type) ++{ ++ printk(KERN_WARNING "interrupt type is not configurable\n"); ++ return 0; ++} ++ ++static struct irq_chip nointc_chip = { ++ ++ .irq_ack = nointc_ack_irq, ++ .irq_mask = nointc_mask_irq, ++ .irq_mask_ack = nointc_mask_ack_irq, ++ .irq_unmask = nointc_unmask_irq, ++ .irq_set_type = nointc_set_type, ++}; ++ ++static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 }; ++ ++void __init nointc_init_irq(void) ++{ ++ int i; ++ unsigned long int_trigger_type, int_vec_base, nivic; ++ ++ int_vec_base = GET_IVB(); ++ ++#if 0 ++ asm volatile ("mfsr %0, $IVB\n":"=r" (int_vec_base)); ++#endif ++ ++ if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0) { ++ panic("Unable to use NOINTC option to boot on this cpu\n"); ++ } ++ ++ nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC; ++ if (nivic >= (sizeof nivic_map / sizeof nivic_map[0])) { ++ panic ++ ("The number of input for IVIC Controller is not supported on this cpu\n"); ++ } ++ nivic = nivic_map[nivic]; ++ ++ int_trigger_type = GET_INT_TRIGGER(); ++#if 0 ++ asm volatile ("mfsr %0, $INT_TRIGGER\n":"=r" (int_trigger_type)); ++#endif ++ ++ for (i = 0; i < nivic; i++) { ++ irq_set_chip(i, &nointc_chip); ++ if (int_trigger_type & (1 << i)) ++ /* edge-triggered */ ++ irq_set_handler(i, handle_edge_irq); ++ else ++ /* level-triggered */ ++ irq_set_handler(i, handle_level_irq); ++ } ++} +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/pci_intc.c linux-3.4.110/arch/nds32/platforms/pci_intc.c +--- linux-3.4.110.orig/arch/nds32/platforms/pci_intc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/pci_intc.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,93 @@ ++/* ++ * linux/arch/nds32/platforms/pci_intc.c ++ * ++ * Faraday PCI Bridge Interrupt Process Driver Implementation ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2008 Andes Technology Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * ++ * ChangeLog ++ * ++ * Luke Lee 09/15/2005 Created. ++ * Luke Lee 09/27/2005 Fixed for parent chip registration and notification. ++ * Peter Liao 09/28/2005 Port for PCI IP ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define IPMODULE PCIC ++#define IPNAME FPCI010 ++ ++/* ++ * Level trigger IRQ chip methods ++ */ ++ ++static void intc_ftpci100_level_ack_irq(unsigned int irq) ++{ ++ ftpci_clear_irq(irq - PLATFORM_PCI_IRQ_BASE); ++} ++ ++static void intc_ftpci100_level_mask_irq(unsigned int irq) ++{ ++ ftpci_mask_irq(irq - PLATFORM_PCI_IRQ_BASE); ++} ++ ++static void intc_ftpci100_level_unmask_irq(unsigned int irq) ++{ ++ ftpci_unmask_irq(irq - PLATFORM_PCI_IRQ_BASE); ++} ++ ++static struct irq_chip intc_ftpci100_level_chip = { ++ .ack = intc_ftpci100_level_ack_irq, ++ .mask = intc_ftpci100_level_mask_irq, ++ .unmask = intc_ftpci100_level_unmask_irq, ++}; ++ ++void pci_irq_rounter(unsigned int irq, struct irq_desc *desc) ++{ ++ int pci_irq; ++ struct irq_desc *pci_desc; ++ ++ desc->chip->mask(irq); ++ desc->chip->ack(irq); ++ ++ pci_irq = ftpci_get_irq(); ++ if (pci_irq >= 0) { ++ pci_irq += PCIC_FTPCI100_IRQ0; ++ pci_desc = irq_desc + pci_irq; ++ pci_desc->handle_irq(pci_irq, pci_desc); ++ } ++ ++ desc->chip->unmask(irq); ++} ++ ++int __init intc_ftpci100_init_irq(void) ++{ ++ int i; ++ ++ /* Register all IRQ */ ++ for (i = PCIC_FTPCI100_IRQ0; ++ i < PCIC_FTPCI100_IRQ0 + PCIC_FTPCI100_IRQ_COUNT; i++) { ++ // level trigger ++ set_irq_chip(i, &intc_ftpci100_level_chip); ++ set_irq_handler(i, handle_level_irq); ++ } ++#ifndef CONFIG_PLAT_AG101 ++ set_irq_chained_handler(PLATFORM_PCI_IRQ, pci_irq_rounter); ++#endif ++ ++ return 0; ++} ++ ++subsys_initcall(intc_ftpci100_init_irq); +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/qemu/devices.c linux-3.4.110/arch/nds32/platforms/qemu/devices.c +--- linux-3.4.110.orig/arch/nds32/platforms/qemu/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/qemu/devices.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,124 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++const struct map_desc platform_io_desc[] __initdata = { ++ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, ++ PAGE_SIZE, MT_DEVICE_NCB}, ++ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x000FF000, MT_DEVICE_NCB}, ++ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} ++}; ++ ++static void __init platform_map_io(void) ++{ ++ iotable_init((struct map_desc *)platform_io_desc, ++ ARRAY_SIZE(platform_io_desc)); ++} ++ ++static struct uart_port uart0 = { ++ .membase = (void __iomem *)UART0_VA_BASE, ++ .irq = UART0_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 0, ++ .mapbase = UART0_PA_BASE, ++}; ++ ++static struct uart_port uart1 = { ++ .membase = (void __iomem *)UART1_VA_BASE, ++ .irq = UART1_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 1, ++ .mapbase = UART1_PA_BASE, ++}; ++ ++static void __init soc_init(void) ++{ ++ early_serial_setup(&uart0); ++ early_serial_setup(&uart1); ++} ++ ++static struct resource smc91x_resources[] = { ++ [0] = { ++ .name = "smc91x", ++ .start = 0x92100000, ++ .end = 0x92110000, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = 25, ++ .end = 25, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device smc91x_device = { ++ .name = "smc91x", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(smc91x_resources), ++ .resource = smc91x_resources, ++}; ++ ++static __init int smc_init(void) ++{ ++ int ret; ++ ret = platform_device_register(&smc91x_device); ++ if (ret == 0) ++ printk("smc is installed now.\n"); ++ else ++ printk("smc failed.\n"); ++ return 0; ++} ++ ++module_init(smc_init); ++ ++MACHINE_START(FARADAY, PLATFORM_NAME) ++ .param_offset = BOOT_PARAMETER_PA_BASE, ++ .map_io = platform_map_io, ++ .init_irq = platform_init_irq, ++ .timer = &platform_timer, /* defined in timer.c */ ++ .init_machine = soc_init, ++MACHINE_END +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/qemu/Kconfig linux-3.4.110/arch/nds32/platforms/qemu/Kconfig +--- linux-3.4.110.orig/arch/nds32/platforms/qemu/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/qemu/Kconfig 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,3 @@ ++menu "QEMU Platform Options" ++ ++endmenu +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/qemu/Makefile linux-3.4.110/arch/nds32/platforms/qemu/Makefile +--- linux-3.4.110.orig/arch/nds32/platforms/qemu/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/qemu/Makefile 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1 @@ ++obj-y = devices.o +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/timer.c linux-3.4.110/arch/nds32/platforms/timer.c +--- linux-3.4.110.orig/arch/nds32/platforms/timer.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/timer.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,250 @@ ++/* ++ * linux/arch/nds32/platforms/timer.c ++ * ++ * Faraday FTTMR010 Timer Device Driver Implementation ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * Copyright (C) 2009 Andes Technology Corporation ++ * ++ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define REG32_TMR(x) *(volatile unsigned long *)(TIMER_FTTMR010_VA_BASE + (x)) ++#define APB_CLK_IN (AHB_CLK_IN / 2) ++ ++static struct resource timer_resource = { ++ .name = "Timer 1~3", ++ .start = TIMER_FTTMR010_VA_BASE, ++ .end = TIMER_FTTMR010_VA_LIMIT, ++}; ++ ++static inline cycle_t clocksource_read_cycles(struct clocksource *cs) ++{ ++ return (cycle_t) REG32_TMR(TIMER3_COUNT); ++} ++ ++static void clksrc_fttmr010_resume(struct clocksource *cs) ++{ ++ REG32_TMR(TIMER_INTRMASK) |= TM3MATCH1 | TM3MATCH2 | TM3OVERFLOW; ++ REG32_TMR(TIMER_TMCR) |= TM3UPDOWN | TM3ENABLE; ++} ++ ++static struct clocksource clksrc_fttmr010 = { ++ .name = "fttmr010_tm1", ++ .rating = 300, ++ .read = clocksource_read_cycles, ++ .mask = CLOCKSOURCE_MASK(32), ++ .shift = 21, ++ .flags = CLOCK_SOURCE_IS_CONTINUOUS, ++ .resume = clksrc_fttmr010_resume, ++}; ++ ++static void __init fttmr010_clocksource_init(void) ++{ ++ clksrc_fttmr010.mult = ++ clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift); ++ ++ REG32_TMR(TIMER3_LOAD) = 0; ++ REG32_TMR(TIMER_INTRMASK) |= TM3MATCH1 | TM3MATCH2 | TM3OVERFLOW; ++ REG32_TMR(TIMER_TMCR) |= TM3UPDOWN | TM3ENABLE; ++ if (clocksource_register(&clksrc_fttmr010)) ++ printk(KERN_ERR "Error: failed to register %s\n", ++ clksrc_fttmr010.name); ++} ++ ++static int fttmr010_set_next_event(unsigned long cycles, ++ struct clock_event_device *evt) ++{ ++ REG32_TMR(TIMER1_LOAD) = cycles; ++ return 0; ++} ++ ++static void fttmr010_set_mode(enum clock_event_mode mode, ++ struct clock_event_device *evt) ++{ ++ switch (mode) { ++ case CLOCK_EVT_MODE_ONESHOT: ++ REG32_TMR(TIMER1_LOAD) = 0xffffffff; ++ REG32_TMR(TIMER_TMCR) |= TM1ENABLE; ++ break; ++ ++ case CLOCK_EVT_MODE_PERIODIC: ++ REG32_TMR(TIMER1_COUNT) = APB_CLK_IN / HZ - 1; ++ REG32_TMR(TIMER1_LOAD) = APB_CLK_IN / HZ - 1; ++ REG32_TMR(TIMER_TMCR) |= TM1ENABLE; ++ break; ++ case CLOCK_EVT_MODE_UNUSED: ++ break; ++ case CLOCK_EVT_MODE_SHUTDOWN: ++ REG32_TMR(TIMER_TMCR) &= ~TM1ENABLE; ++ break; ++ case CLOCK_EVT_MODE_RESUME: ++ REG32_TMR(TIMER_INTRMASK) |= TM1MATCH1 | TM1MATCH2; ++ REG32_TMR(TIMER_TMCR) |= TM1ENABLE | TM1OFENABLE; ++ break; ++ } ++} ++ ++static struct clock_event_device clockevent_fttmr010 = { ++ .name = "fttmr010_tm1", ++ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, ++ .shift = 32, ++ .cpumask = cpu_all_mask, ++ .set_next_event = fttmr010_set_next_event, ++ .set_mode = fttmr010_set_mode, ++}; ++ ++static irqreturn_t timer1_interrupt(int irq, void *dev_id) ++{ ++ struct clock_event_device *evt = dev_id; ++ ++ REG32_TMR(TIMER_INTRSTATE) = TM1MATCH1 | TM1MATCH2 | TM1OVERFLOW; ++ ++ evt->event_handler(evt); ++ ++ return IRQ_HANDLED; ++} ++ ++static struct irqaction timer1_irq = { ++ .name = "Timer Tick", ++ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, ++ .handler = timer1_interrupt, ++ .dev_id = &clockevent_fttmr010 ++}; ++ ++static void __init fttmr010_clockevent_init(void) ++{ ++ clockevent_fttmr010.mult = ++ div_sc(APB_CLK_IN, NSEC_PER_SEC, clockevent_fttmr010.shift); ++ clockevent_fttmr010.max_delta_ns = ++ clockevent_delta2ns(0xffffffff, &clockevent_fttmr010); ++ clockevent_fttmr010.min_delta_ns = ++ clockevent_delta2ns(3, &clockevent_fttmr010); ++ ++ clockevents_register_device(&clockevent_fttmr010); ++ setup_irq(TIMER_FTTMR010_IRQ0, &timer1_irq); ++} ++ ++static void fttmr010_resume(void) ++{ ++} ++ ++#ifdef CONFIG_CPU_FREQ ++void ag102_calc_ahb_clk(void); ++static int fttmr010_cpufreq_notifier(struct notifier_block *nb, ++ unsigned long val, void *data) ++{ ++ if (val == CPUFREQ_POSTCHANGE) { ++ ++ unsigned long flags; ++#ifdef CONFIG_PLAT_AG102 ++ ag102_calc_ahb_clk(); ++#endif ++ local_irq_save(flags); ++ ++ clocksource_unregister(&clksrc_fttmr010); ++ ++ clksrc_fttmr010.mult = ++ clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift); ++#ifdef CONFIG_PLAT_AG101 ++ clksrc_fttmr010.mult_orig = ++ clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift); ++#endif ++ ++ if (clocksource_register(&clksrc_fttmr010)) ++ printk(KERN_ERR "Error: failed to re-register %s\n", ++ clksrc_fttmr010.name); ++ else ++ printk("Re-register clock source %s\n", ++ clksrc_fttmr010.name); ++ ++ local_irq_restore(flags); ++ ++ clockevent_fttmr010.mult = ++ div_sc(APB_CLK_IN, NSEC_PER_SEC, clockevent_fttmr010.shift); ++ ++#ifdef CONFIG_PLAT_AG102 ++ printk("Add timer clock modifier...\n"); ++ fttmr010_set_mode(CLOCK_EVT_MODE_PERIODIC, 0); ++#endif ++ } ++ ++ return 0; ++} ++ ++static struct notifier_block fttmr010_cpufreq_notifier_block = { ++ .notifier_call = fttmr010_cpufreq_notifier ++}; ++ ++static int __init fttmr010_init_cpufreq(void) ++{ ++ if (cpufreq_register_notifier(&fttmr010_cpufreq_notifier_block, ++ CPUFREQ_TRANSITION_NOTIFIER)) ++ printk("fttmr010: Failed to setup cpufreq notifier\n"); ++ ++ return 0; ++} ++ ++core_initcall(fttmr010_init_cpufreq); ++#endif ++ ++static int clksrc_init; ++static void __init fttmr010_init(void) ++{ ++ request_resource(&ioport_resource, &timer_resource); ++ ++ printk ++ ("FTTMR010 timer 1 installed on IRQ %d, with clock %d at %d HZ.\r\n", ++ TIMER_FTTMR010_IRQ0, APB_CLK_IN, HZ); ++ ++ REG32_TMR(TIMER_TMCR) &= ++ ~(TM1ENABLE | TM1CLOCK | TM1OFENABLE | TM1UPDOWN); ++ REG32_TMR(TIMER_INTRMASK) |= TM1MATCH1 | TM1MATCH2; ++ REG32_TMR(TIMER_TMCR) |= TM1OFENABLE; ++ ++ fttmr010_clocksource_init(); ++ fttmr010_clockevent_init(); ++ clksrc_init = 1; ++} ++ ++struct sys_timer platform_timer = { ++ .init = fttmr010_init, ++ .resume = fttmr010_resume, ++}; ++ ++unsigned long long sched_clock(void) ++{ ++ if (clksrc_init) ++ return ++ clocksource_cyc2ns(clocksource_read_cycles ++ (&clksrc_fttmr010), clksrc_fttmr010.mult, ++ clksrc_fttmr010.shift); ++ else ++ return (unsigned long long)(jiffies - INITIAL_JIFFIES) ++ * (NSEC_PER_SEC / HZ); ++} +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/vep/devices.c linux-3.4.110/arch/nds32/platforms/vep/devices.c +--- linux-3.4.110.orig/arch/nds32/platforms/vep/devices.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/vep/devices.c 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,83 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++const struct map_desc platform_io_desc[] __initdata = { ++ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, ++ PAGE_SIZE, MT_DEVICE_NCB}, ++ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, ++ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, ++ MT_DEVICE_NCB}, ++ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} ++}; ++ ++static void __init platform_map_io(void) ++{ ++ iotable_init((struct map_desc *)platform_io_desc, ++ ARRAY_SIZE(platform_io_desc)); ++} ++ ++static struct uart_port uart0 = { ++ .membase = (void __iomem *)UART0_VA_BASE, ++ .irq = UART0_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 0, ++ .mapbase = UART0_PA_BASE, ++}; ++ ++static struct uart_port uart1 = { ++ .membase = (void __iomem *)UART1_VA_BASE, ++ .irq = UART1_IRQ, ++ .uartclk = CONFIG_UART_CLK, ++ .regshift = 2, ++ .iotype = UPIO_MEM, ++ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, ++ .line = 1, ++ .mapbase = UART1_PA_BASE, ++}; ++ ++static void __init soc_init(void) ++{ ++ early_serial_setup(&uart0); ++ early_serial_setup(&uart1); ++} ++ ++MACHINE_START(FARADAY, PLATFORM_NAME) ++ .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = platform_init_irq,.timer = &platform_timer, /* defined in timer.c */ ++ .init_machine = soc_init, MACHINE_END +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/vep/Kconfig linux-3.4.110/arch/nds32/platforms/vep/Kconfig +--- linux-3.4.110.orig/arch/nds32/platforms/vep/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/vep/Kconfig 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,7 @@ ++menu "VEP Platform Options" ++ ++config CACHE_L2 ++ bool "Support L2 cache" ++ default n ++ ++endmenu +diff -Nur linux-3.4.110.orig/arch/nds32/platforms/vep/Makefile linux-3.4.110/arch/nds32/platforms/vep/Makefile +--- linux-3.4.110.orig/arch/nds32/platforms/vep/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/arch/nds32/platforms/vep/Makefile 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1 @@ ++obj-y = devices.o +diff -Nur linux-3.4.110.orig/build_linux.sh linux-3.4.110/build_linux.sh +--- linux-3.4.110.orig/build_linux.sh 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/build_linux.sh 2016-04-07 10:20:51.018083964 +0200 +@@ -0,0 +1,202 @@ ++#!/bin/sh ++ ++export ARCH=nds32 ++ ++print_help() ++{ ++ echo "Usage: [platform_defconfig] [--bootm] [--ramdisk=]" ++ echo "Stop Building." ++ exit ++} ++ ++BUILDBOOTM=0 ++BUILDBOOTPIMAGE=0 ++BUILDHEADERS=0 ++ ++case "$1" in ++ qemu) ++ TARGET=qemu_defconfig ++ IMAGE=qemu ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ vep-be) ++ TARGET=vep-be_defconfig ++ IMAGE=vep-be ++ export CROSS_COMPILE=nds32be-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ vep-le) ++ TARGET=vep-le_defconfig ++ IMAGE=vep-le ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ xc5) ++ TARGET=xc5_defconfig ++ IMAGE=xc5 ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ xc5_8k) ++ TARGET=xc5_8k_defconfig ++ IMAGE=xc5_8k ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ ag101a0) ++ TARGET=ag101a0_defconfig ++ IMAGE=ag101a0 ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ ag101b0) ++ TARGET=ag101b0_defconfig ++ IMAGE=ag101b0 ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ ag102) ++ TARGET=ag102_defconfig ++ IMAGE=ag102 ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ u200) ++ TARGET=u200_defconfig ++ IMAGE=u200 ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ xc5-qa) ++ TARGET=xc5-qa_defconfig ++ IMAGE=xc5-qa ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ ag101-qa) ++ TARGET=ag101-qa_defconfig ++ IMAGE=ag101-qa ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++ ;; ++ *) ++ if [ $# = 1 ]; then ++ echo "No defconfig is given." ++ print_help ++ fi ++ if [ ! -e $2 ]; then ++ echo "Given defconfig is not exist." ++ print_help ++ elif [ ! -f $2 ]; then ++ echo "Given defconfig is not a file." ++ print_help ++ elif [ ! -s $2 ]; then ++ echo "Given defconfig is size 0." ++ print_help ++ elif [ ! -r $2 ]; then ++ echo "Given defconfig has no read attribute." ++ print_help ++ fi ++ TARGET=none ++ IMAGE=$1 ++ export CROSS_COMPILE=nds32le-linux- ++ echo "Building $IMAGE kernel." ++esac ++ ++ZIMAGE="$IMAGE"_zImage ++VMLINUZ="$IMAGE"_vmlinuz ++VMLINUX="$IMAGE"_vmlinux ++BOOTPIMAGE="$IMAGE"_bootpImage ++BOOTP="$IMAGE"_bootp ++BOOTM="$IMAGE"_bootm ++ ++for ARG in $@; do ++ if [ $ARG = $1 ]; then ++ continue ++ fi ++ ++ if [ $ARG = $2 ]; then ++ if [ $TARGET = "none" ]; then ++ continue ++ fi ++ fi ++ ++ case "$ARG" in ++ ++ --bootm) ++ BUILDBOOTM=1 ++ ;; ++ ++ --ramdisk=*) ++ BUILDBOOTPIMAGE=1 ++ RAMDISK=${ARG#*=} ++ if [ ! -e $RAMDISK ]; then ++ echo "Given ramdisk is not exist." ++ print_help ++ elif [ ! -f $RAMDISK ]; then ++ echo "Given ramdisk is not a file." ++ print_help ++ elif [ ! -s $RAMDISK ]; then ++ echo "Given ramdisk is size 0." ++ print_help ++ elif [ ! -r $RAMDISK ]; then ++ echo "Given ramdisk has no read attribute." ++ print_help ++ fi ++ ;; ++# --headers) ++# BUILDHEADERS=1 ++# git apply ../linux-2.6-patch/headers.patch ++# echo "Exporting kernel headers." ++# ;; ++ *) ++ print_help ++ esac ++done ++ ++if [ "$OSTYPE" = "cygwin" ]; then ++ HOST_LOADLIBES=-lintl\ -lcurses ++fi ++export HOST_LOADLIBES ++ ++which ${CROSS_COMPILE}gcc &> /dev/null || export CROSS_COMPILE=nds32-elf- ++ ++make mrproper | tee $IMAGE.log ++if [ $TARGET != "none" ]; then ++ make $TARGET| tee -a $IMAGE.log ++else ++ cp $2 .config ++fi ++ ++if [ $BUILDHEADERS = 1 ]; then ++ make dep | tee -a $IMAGE.log ++ make headers_install | tee -a $IMAGE.log ++else ++ make | tee -a $IMAGE.log ++ ++ cp arch/nds32/boot/zImage ./$ZIMAGE | tee -a $IMAGE.log ++ cp arch/nds32/boot/compressed/vmlinux ./$VMLINUZ | tee -a $IMAGE.log ++ cp ./vmlinux ./$VMLINUX | tee -a $IMAGE.log ++ ++ if [ $BUILDBOOTPIMAGE = 1 ]; then ++ make bootpImage INITRD=$RAMDISK | tee -a $IMAGE.log ++ cp arch/nds32/boot/bootpImage ./$BOOTPIMAGE | tee -a $IMAGE.log ++ cp arch/nds32/boot/bootp/bootp ./$BOOTP | tee -a $IMAGE.log ++ fi ++ ++ if [ $BUILDBOOTM = 1 ]; then ++ if [ -e "../u-boot/tools/mkimage" ]; then ++ ../u-boot/tools/mkimage \ ++ -A nds32 \ ++ -O linux \ ++ -T kernel \ ++ -C none \ ++ -a 0x500000 \ ++ -e 0x500040 \ ++ -d ./arch/nds32/boot/zImage $BOOTM | tee -a $IMAGE.log ++ else ++ echo "Error: ../u-boot/tools/mkimage not found" | tee -a $IMAGE.log ++ fi ++ fi ++fi +diff -Nur linux-3.4.110.orig/drivers/block/ftcfc010.c linux-3.4.110/drivers/block/ftcfc010.c +--- linux-3.4.110.orig/drivers/block/ftcfc010.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/block/ftcfc010.c 2016-04-07 10:20:51.022084119 +0200 +@@ -0,0 +1,1299 @@ ++/* drivers/block/CPESD/ftsdc010.c ++ ******************************************************************************* ++ * Faraday FTSDC010 Device Driver ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * All Rights Reserved ++ * ++ * Porting to Linux 2.6 on 20050815 ++ * Author: Chris Lee, I-Jui Sung, Peter Liao (support APB DMA) ++ * Version: 0.2 ++ * History: ++ * 0.1 new creation ++ * 0.2 Porting to meet the style of linux dma ++ * 0.3 modify dma usage to virtual irq of dma interrupt ++ * 0.4 (20050701) Improve r/w performance ++ * 0.5 Porting to Linux 2.6 and replace busy_loop checking with timer's timeout ++ * Todo: ++ ******************************************************************************* ++ */ ++ ++#define DEBUG_OFF 0 ++ ++#define DEBUG( enable, tagged, ...) \ ++do{ \ ++ if( enable){ \ ++ if( tagged) \ ++ printk( "[ %30s() ] ", __func__); \ ++ printk( __VA_ARGS__); \ ++ } \ ++} while( 0) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* HDIO_GETGEO */ ++#include ++#include ++#include /* invalidate_bdev */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IPMODULE CFC ++#define IPNAME FTCFC010 ++ ++#include "ftcfc010.h" ++ ++static int hardsect_size = 512; ++module_param( hardsect_size, int, 0); ++ ++static int cf_major = 0; /* must be declared before including blk.h */ ++#define DEVICE_NAME "Faraday CFC" /* name for messaging */ ++ ++#define FTCFC_VA_BASE IP_VA_BASE( 0) ++#define FTCFC_PA_BASE IP_PA_BASE( 0) ++#define FTCFC_IRQ CFC_FTCFC010_IRQ1 ++ ++#undef CF_DEBUG ++#define CF_DEBUG 0 ++struct block_device_operations cf_fops; ++ ++typedef struct cf_dev { ++ ++ int size; /* device size in sectors */ ++ int usage; /* # of users currently */ ++ int media_change; /* Flag: media changed? */ ++ struct gendisk *gd; /* The gendisk structure */ ++ spinlock_t lock; /* For mutual exclusion */ ++ struct request_queue *queue; /* The device request queue */ ++ int card_state; ++ u32 lba_sec_offset; ++ dmad_chreq ch_req; ++ ++} cf_dev_t; ++ ++static cf_dev_t *cf_devices; ++static cf_card_t cf_card_info; ++ ++static dma_addr_t dma_buf; ++struct completion cf_dma_cmpl; ++ ++static uint first_run; ++static uint cf_err_code; ++ ++static int g_cf_sectors; ++ ++static void SetTransferSize( u32 Addr, u32 Type, u32 OP_Type, u32 Inc_Addr, u32 Transize) ++{ ++ u32 ctrl_reg, buf_ctrl_reg; ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ /* set read/write command */ ++ while( cfc->HostStatus & BUF_ACTIVE_BIT) ++ ; ++ ++ /* Set Transfer size mode to default */ ++ cfc->TransSzMode2En = 0; ++ ++ /* set 8/16 bits mode */ ++ ctrl_reg = cfc->ControlReg; ++ ++ if( Transize == SIZE_1_BYTE) ++ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | BYTE_MODE; ++ else ++ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | WORD_MODE; ++ ++ DEBUG( CF_DEBUG, 1, "ctrl 1: 0x%08lx\n", ( unsigned long)ctrl_reg); ++ cfc->ControlReg = ctrl_reg; ++ ++ /* Write command to buffer */ ++ buf_ctrl_reg = cfc->BuffCtrlReg; ++ buf_ctrl_reg = ( buf_ctrl_reg & ~ADR_BIT & ~TYPE_BIT & ~RW_BIT & ~INCADR_BIT & ~TRANS_SIZE_CONTROL_BIT) ++ | Addr | Type | OP_Type | Inc_Addr | ( Transize << TRANS_SIZE_LOC); ++ ++ cfc->BuffCtrlReg = buf_ctrl_reg; ++ DEBUG( CF_DEBUG, 1, "buf_ctrl 1: 0x%08lx\n", ( unsigned long)buf_ctrl_reg); ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++} ++ ++static void SetTransferSizeEx( u32 Addr, u32 Type, u32 OP_Type, u32 Inc_Addr, u32 Transize) ++{ ++ u32 ctrl_reg, buf_ctrl_reg; ++ ++ DEBUG( CF_DEBUG, 1, "Enter, SetTransferSizeEx: %d\n", Transize); ++ ++ /* set read/write command */ ++ while( cfc->HostStatus & BUF_ACTIVE_BIT) ++ ; ++ ++ /* Set Transfer size mode to default */ ++ cfc->TransSzMode2En = 1; ++ ++ /* set 8/16 bits mode */ ++ ctrl_reg = cfc->ControlReg; ++ ++ if( Transize == SIZE_1_BYTE) ++ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | BYTE_MODE; ++ else ++ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | WORD_MODE; ++ ++ cfc->ControlReg = ctrl_reg; ++ ++ /* Set Transfer size mode2 reg in FTCFC */ ++ cfc->TransSzMode2Cnt = Transize - 1; ++ ++ /* Write command to buffer */ ++ buf_ctrl_reg = cfc->BuffCtrlReg; ++ buf_ctrl_reg = ( buf_ctrl_reg & ~ADR_BIT & ~TYPE_BIT & ~RW_BIT & ~INCADR_BIT & ~TRANS_SIZE_CONTROL_BIT) ++ | Addr | Type | OP_Type | Inc_Addr; ++ ++ cfc->BuffCtrlReg = buf_ctrl_reg; ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++} ++ ++static void WriteCFCardByte( u32 Addr, u8 Value, u32 Type) ++{ ++ while( !( cfc->HostStatus & RDY_nIREQ_BIT)) ++ ; ++ ++ SetTransferSize( Addr, Type, WRITE_OP, NOINCADR, SIZE_1_BYTE); ++ ++ cfc->BufferData = Value; ++ ++ while( !( cfc->HostStatus & INTA_BIT)) ++ ; ++ ++ /* clear command complete status */ ++ cfc->HostStatus = INTA_BIT; ++} ++ ++static u8 ReadCFCardByte( u32 Addr, u32 Type) ++{ ++ u8 ret_data; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ /* wait until ready */ ++ while( !( cfc->HostStatus & RDY_nIREQ_BIT)) ++ ; ++ ++ SetTransferSize( Addr, Type, READ_OP, NOINCADR, SIZE_1_BYTE); ++ ++ while( !( cfc->HostStatus & INTA_BIT)) ++ ; ++ ++ ret_data = cfc->BufferData & 0xff; ++ DEBUG( CF_DEBUG, 1, "data: 0x%02x\n", ret_data); ++ ++ while( !( cfc->HostStatus & INTA_BIT)) ++ ; ++ ++ /* clear command complete status */ ++ cfc->HostStatus = INTA_BIT; ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ return ret_data; ++} ++ ++/* set Head-cylinder-sector on CF */ ++static u32 Translate_Config_HCS( u32 LBA, u32 Sec_count) ++{ ++ u8 DriveHead = ( u8)( 0xE0 | ( LBA >> 24)); /* 0xE0 set in LBA mode (bit 7&5 must set to 1) */ ++ u8 CylHigh = ( u8)( ( LBA >> 16) & 0xFF); ++ u8 CylLow = ( u8)( ( LBA >> 8) & 0xFF); ++ u8 SecNum = ( u8)( LBA & 0xFF); ++ ++ DEBUG( CF_DEBUG, 1, "LBA:%d, %d %d %d %d, count: %d\n", ++ LBA, DriveHead, CylHigh, CylLow, SecNum, Sec_count); ++ ++ /* Set CF-ATA reg for start sector */ ++ WriteCFCardByte( BLKMEM_DRIVE_REG, DriveHead, COMMON_MEM); ++ WriteCFCardByte( BLKMEM_CYLINDER_HIGH_REG, CylHigh, COMMON_MEM); ++ WriteCFCardByte( BLKMEM_CYLINDER_LOW_REG, CylLow, COMMON_MEM); ++ WriteCFCardByte( BLKMEM_SECTOR_NUMBER_REG, SecNum, COMMON_MEM); ++ WriteCFCardByte( BLKMEM_SECTOR_COUNT_REG, Sec_count, COMMON_MEM); ++ ++ return 1; ++} ++ ++/* ++ * SetCFCardConfiguration(): ATTRIBUTE MEMORY ++ * Set CF storgae card configuration option register ++ * Conf1 Conf0 Disk Card Mode ++ * --------------------------------------------------------------- ++ * 0 0 Memory Mapped ++ * 0 1 I/O Mapped, any 16 byte system decoded ++ * 1 0 I/O Mapped, 1F0h - 1F7h / 3F6h - 3F7h ++ * 1 1 I/O Mapped, 170h - 177h / 376h - 377h ++ */ ++static void SetCFCardMode( u8 Mode) ++{ ++ u8 Reg; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ Reg = ReadCFCardByte( CONFIG_OPTION_REG, ATTRIBUTE_MEM); /* CONFIG_OPTION_REG = 0x200 */ ++ Reg &= ( LEVLREQ_BIT | SRESET_BIT); /* clear bit0-5 */ ++ ++ WriteCFCardByte( CONFIG_OPTION_REG, Reg | Mode, ATTRIBUTE_MEM); ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++} ++ ++/* return 0: fail, 1: success */ ++static u32 CF_SendCommand( u16 Cmd) ++{ ++ u16 Reg; ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ do{ ++ WriteCFCardByte( BLKMEM_COMMAND_REG, Cmd, COMMON_MEM); ++ ++ /* ++ * Check status register of Task file register is valid for access ++ * No other bits in status register are valid when BUSY bit is ++ * set to a 1 ++ */ ++ while( ( ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM) & BUSY_BIT)) ++ ; ++ ++ Reg = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ if( Reg & ERR_BIT){ ++ ++ DEBUG( CF_DEBUG, 1, "Exit ( fail)\n"); ++ return 0; ++ } ++ ++ } while( !( Reg & RDY_BIT)); ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ return 1; ++} ++ ++static void CardReset( void) ++{ ++ u32 ctrl_reg = cfc->ControlReg; ++ u8 data; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ cfc->ControlReg = ctrl_reg | RESET_BIT | SIGNAL_ON | PWR_ON; /* set reset bit, float control, power on */ ++ ++ /* Software must manually clear this bit */ ++ mdelay( 100); ++ ++ /* clear reset bit */ ++ cfc->ControlReg = ( ctrl_reg &~ RESET_BIT) | SIGNAL_ON | PWR_ON | DATA_CMP_INT_MASK | IO_INT_MASK; ++ ++ do { ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ } while( data & BUSY_BIT); /* please be careful that is locked here */ ++ ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ /* Check if Drive Ready & Drive Seek Complete */ ++ if( data == ( RDY_BIT | DSC_BIT)) ++ DEBUG( CF_DEBUG, 1, "Reset CF OK, data: 0x%02x\n", ( unsigned char)data); ++ else ++ DEBUG( CF_DEBUG, 1, "Reset CF fail, data: 0x%02x\n", ( unsigned char)data); ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++} ++ ++static u32 CFCardInit( void) ++{ ++ u8 buff[CF_SECTOR_SIZE]; ++ u32 i; ++ u32 BSA, BSM, BSIO, BSMOW, BSIORW, apb_ns; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ if( !( cfc->HostStatus & CARD_DETECT_BIT)){ ++ ++ DEBUG( CF_DEBUG, 1, "No CF Card In Socket\n"); ++ return -1; ++ } ++ ++ CardReset(); ++ ++ /* set timer */ ++ ++ apb_ns = 1000000000 / ( AHB_CLK_IN / 2 ); /* the time of APB clock */ ++ BSA = ( 50 + ( apb_ns - ( 50 % apb_ns))) / apb_ns; /* Based on the item tc( R) of BSA */ ++ BSMOW = 3; ++ BSIORW = 3; ++ BSM = ( 30 + ( apb_ns - ( 30 % apb_ns))) / apb_ns; /* Base on the item tw( WE) of BSM */ ++ BSIO = ( 35 + ( apb_ns - ( 35 % apb_ns))) / apb_ns; /* Base on the item tsuA( IORD,IOWR) of BSIO */ ++ ++ cfc->TimeCfgReg = ( ( BSMOW & 0x03) << 12) ++ | ( ( BSIORW & 0x03) << 14) ++ | ( ( BSA & 0x0f) << 0) ++ | ( ( BSM & 0x0f) << 4) ++ | ( ( BSIO & 0x0f) << 8); ++ ++ SetCFCardMode( CF_MEM_MAP_MODE); /* set memory mode read write access */ ++ ++ cfc->MultiSector = 0x1; /* enable multi sector read/write */ ++ ++ /* select drive */ ++ WriteCFCardByte( BLKMEM_DRIVE_REG, 0, COMMON_MEM); ++ ++ /* identify drive device */ ++ if( !CF_SendCommand( ATA_IDENTIFY_DRIVE)){ ++ ++ DEBUG( CF_DEBUG, 1, "Send Identify Drive command fail\n"); ++ return -1; ++ } ++ ++ SetTransferSize( BLKMEM_DATA_REG, COMMON_MEM, READ_OP, NOINCADR, SIZE_512_BYTE); ++ ++ for( i = 0; i < CF_SECTOR_SIZE / 4; i++){ ++ ++ while( !( cfc->HostStatus & BUF_DATA_RDY_BIT)) ++ ; ++ ++ *( ( u32*)&buff[ i*4]) = cfc->BufferData; ++ } ++ ++ /* clear command complete status */ ++ cfc->HostStatus = INTA_BIT; ++ ++ g_cf_sectors = ( ( u32)buff[ 15] << 24) | ( ( u32)buff[ 14] << 16) | ( ( u32)buff[ 17] << 8) | ( ( u32)buff[ 16]); ++ DEBUG( CF_DEBUG, 1, "Card identify - capicity: %d sectors, size: %d kbytes \n", g_cf_sectors, g_cf_sectors >> 1); ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ ++ return 0; ++} ++ ++static int cfc_read_block( cf_card_t *info, uint size, uint *buf) ++{ ++ /* ++ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 ( page 5-76) to set the timeout setting ++ */ ++ unsigned long timeout = jiffies + CFC_TIMEOUT_BASE *( ( size + 2048 + 511) >> 9); ++ uint count; ++ u8 data; ++ dmad_chreq *ch_req = (dmad_chreq *)info->private; ++ dmad_drb *drb = 0; ++ u32 drb_size = 0; ++ dma_addr_t addr_iter; ++ ++ if( info->DMAEnable){ ++ ++ DEBUG( CF_DEBUG, 1, "DMA Read - size: %d, buf: 0x%08lx, dma_buf: 0x%08lx\n", ++ size, ( unsigned long)buf, ( unsigned long)dma_buf); ++ ++ init_completion(&cf_dma_cmpl); ++ ++ if (dma_buf) ++ consistent_sync(__va(dma_buf), size, DMA_FROM_DEVICE); ++ else ++ consistent_sync(buf, size, DMA_FROM_DEVICE); ++ ++ //prepare parameter for add dma entry ++ dmad_config_channel_dir(ch_req, DMAD_DIR_A0_TO_A1); ++ ++ drb_size = dmad_max_size_per_drb(ch_req); ++ ++ if (dma_buf) ++ addr_iter = dma_buf; // given dest phy addr ++ else ++ addr_iter = __pa(buf); ++ ++ cfc->ControlReg |= ENDMA_BIT; ++ ++ while (size > 0) { ++ ++ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { ++ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); ++ return FALSE; ++ } ++ ++ drb->addr0 = FTCFC_PA_BASE + 0x10; ++ drb->addr1 = addr_iter; ++ ++ if (size <= drb_size) { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); ++ drb->sync = &cf_dma_cmpl; ++ size = 0; ++ } else { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); ++ drb->sync = 0; ++ size -= drb_size; ++ addr_iter += drb_size; ++ } ++ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); ++ ++ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { ++ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); ++ return FALSE; ++ } ++ } ++ ++ if (wait_for_completion_timeout(&cf_dma_cmpl, timeout - jiffies) == 0) ++ printk("%s: read timeout\n", __func__); ++ ++ DEBUG( CF_DEBUG, 1, "ControlReg: 0x%08x, HostStatus: 0x%08x, BufCtrl: 0x%08x\n", ++ cfc->ControlReg, cfc->HostStatus, cfc->BuffCtrlReg); ++ ++ while( !( cfc->HostStatus & INTA_BIT)) ++ ; ++ ++ cfc->HostStatus = INTA_BIT; ++ ++ /* Stop DMA */ ++ cfc->ControlReg &= ~ENDMA_BIT; ++ cfc->ControlReg &= ~MODE_BIT; ++ ++ do { ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ } while( data & BUSY_BIT); ++ } ++ else { ++ while( size > 0){ ++ ++ /* read data from FIFO */ ++ if( size >= ( CFC_READ_FIFO_LEN << 2)) ++ count = CFC_READ_FIFO_LEN; ++ else ++ count = size >> 2; ++ ++ /* read data from FIFO */ ++ DEBUG( CF_DEBUG, 0, "\n"); ++ size -= ( count << 2); ++ } ++ } ++ ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ while( 1){ ++ ++ if( data & ERR_BIT){ ++ ++ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF Read sector error.\n"); ++ return FALSE; ++ } ++ else if( data & DWF_BIT){ ++ ++ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF write fault error.\n"); ++ return FALSE; ++ } ++ else if( data & ( RDY_BIT | DSC_BIT)){ ++ ++ break; ++ } ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ } ++ ++ return TRUE; ++} ++ ++static int cfc_write_block( cf_card_t *info, uint size, uint *buf) ++{ ++ unsigned long timeout = jiffies + CFC_TIMEOUT_BASE * 3 *( ( size + 511) >> 9); ++ uint count; ++ u8 data; ++ dmad_chreq *ch_req = (dmad_chreq *)info->private; ++ dmad_drb *drb = 0; ++ u32 drb_size = 0; ++ dma_addr_t addr_iter; ++ ++ if( info->DMAEnable){ ++ ++ DEBUG( CF_DEBUG, 1, "size: %d, buf: %p) - DMA Write\n", size, buf); ++ ++ init_completion(&cf_dma_cmpl); ++ ++ if (dma_buf) ++ consistent_sync(__va(dma_buf), size, DMA_TO_DEVICE); ++ else ++ consistent_sync(buf, size, DMA_TO_DEVICE); ++ ++ //prepare parameter for add dma entry ++ dmad_config_channel_dir(ch_req, DMAD_DIR_A1_TO_A0); ++ ++ drb_size = dmad_max_size_per_drb(ch_req); ++ ++ if (dma_buf) ++ addr_iter = dma_buf; // given dest phy addr ++ else ++ addr_iter = __pa(buf); ++ ++ cfc->ControlReg |= ENDMA_BIT; ++ ++ while (size > 0) { ++ ++ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { ++ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); ++ return FALSE; ++ } ++ ++ drb->addr0 = FTCFC_PA_BASE + 0x10; ++ drb->addr1 = addr_iter; ++ ++ if (size <= drb_size) { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); ++ drb->sync = &cf_dma_cmpl; ++ size = 0; ++ } else { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); ++ drb->sync = 0; ++ size -= drb_size; ++ addr_iter += drb_size; ++ } ++ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); ++ ++ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { ++ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); ++ return FALSE; ++ } ++ } ++ ++ if (wait_for_completion_timeout(&cf_dma_cmpl, timeout - jiffies) == 0) ++ printk("write timeout\n"); ++ ++ while( !( cfc->HostStatus & INTA_BIT)) ++ ; ++ ++ cfc->HostStatus = INTA_BIT; ++ /* Stop DMA */ ++ cfc->ControlReg &= ~ENDMA_BIT; ++ cfc->ControlReg &= ~MODE_BIT; ++ ++ do{ ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ } while( data & BUSY_BIT); ++ } ++ else { ++ while( size > 0){ ++ ++ /* write data from FIFO */ ++ if( size >= ( CFC_WRITE_FIFO_LEN << 2)) ++ count = CFC_WRITE_FIFO_LEN; ++ else ++ count = ( size >> 2); ++ ++ size -= ( count << 2); ++ } ++ } ++ ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ while( 1){ ++ ++ if( data & ERR_BIT){ ++ ++ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF Read sector error.\n"); ++ return FALSE; ++ } ++ else if( data & DWF_BIT){ ++ ++ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF write fault error.\n"); ++ return FALSE; ++ } ++ else if( data & ( RDY_BIT | DSC_BIT)) ++ break; ++ ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ } ++ return TRUE; ++} ++ ++static int cf_card_insert( cf_card_t *info) ++{ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ CardReset(); ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ ++ return TRUE; ++} ++ ++/* Free IRQ and DMA resources */ ++static void cf_free( cf_dev_t *dev) ++{ ++ release_region( FTCFC_VA_BASE, 0x48); /* return ioport */ ++ free_irq( FTCFC_IRQ, dev); /* return Hotswapping irq */ ++ ++ if (cf_card_info.DMAEnable) { ++#if (CF_DEBUG) ++ if (dev->ch_req.controller == DMAD_DMAC_APB_CORE) ++ printk("%s: free APB dma channel (%d)\n", __func__, dev->ch_req.channel); ++ else ++ printk("%s: free AHB dma channel (%d)\n", __func__, dev->ch_req.channel); ++#endif ++ dmad_channel_free(&dev->ch_req); ++ cf_card_info.DMAEnable = FALSE; ++ } ++} ++ ++static int cf_card_remove( cf_card_t *info) ++{ ++ cf_err_code = ERR_NO_ERROR; ++ ++ info->ActiveState = FALSE; ++ info->WriteProtect = FALSE; ++ info->RCA = 0; ++ ++ /* reset host interface controller */ ++ cfc->ControlReg |= RESET_BIT; ++ ++ mdelay( 100); ++ cfc->ControlReg &= ~RESET_BIT; /* must manually clear reset bit */ ++ return TRUE; ++} ++ ++irqreturn_t cf_hotswap_interrupt_handler( int irq, void *dev_id) ++{ ++ cf_dev_t *dev = dev_id; ++ ++ DEBUG( CF_DEBUG, 1, "irq: %d\n", irq); ++ ++ /* ++ * When the card is inserted or removed, we must delay a short time to make sure ++ * the SDC_STATUS_REG_CARD_INSERT bit of status register is stable ++ */ ++ ++ if( cfc->HostStatus & INT_CD_BIT ){ ++ ++ mdelay( 100); /* wait 0.1 sec for card stable */ ++ ++ DEBUG( CF_DEBUG, 1, "Card %s\n", cfc->HostStatus & CARD_DETECT_BIT ? "Insert" : "Remove"); ++ if( cfc->HostStatus & CARD_DETECT_BIT ){ ++ ++ dev->card_state = CF_CARD_INSERT; ++ cf_card_insert( &cf_card_info); ++ } ++ else { ++ dev->card_state = CF_CARD_REMOVE; ++ cf_card_remove( &cf_card_info); ++ } ++ ++ cfc->HostStatus = INT_CD_BIT; ++ } ++ else{ ++ DEBUG( CF_DEBUG, 1, "cfc->HostStatus & INT_CD_BIT == 0\n"); ++ } ++ ++ DEBUG( CF_DEBUG, 1, "Exit: card state = %d\n", dev->card_state); ++ return IRQ_HANDLED; ++} ++ ++int cf_read_multiple_block( cf_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) ++{ ++ u8 data; ++ ++ DEBUG( CF_DEBUG, 1, "read block addr: 0x%x(%d) sectors: %d\n", addr, addr, count); ++ ++ cf_err_code = ERR_NO_ERROR; ++ Translate_Config_HCS( addr, count); ++ CF_SendCommand( ATA_READ_SECTOR); ++ ++ do{ ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ ++ } while( data & BUSY_BIT); ++ ++ SetTransferSizeEx( BLKMEM_DATA_REG, COMMON_MEM, READ_OP, NOINCADR, CF_SECTOR_SIZE * count); ++ ++ if( first_run == 0){ ++ ++ udelay( 100000); ++ ++ first_run = 1; ++ } ++ ++ if( !cfc_read_block( info, CF_SECTOR_SIZE * count, ( uint *)buf)) ++ return FALSE; ++ ++ if( cf_err_code != ERR_NO_ERROR){ ++ ++ DEBUG( CF_DEBUG, 1, "error = 0x%x\n", cf_err_code); ++ DEBUG( CF_DEBUG, 1, "r addr %d count %d\n", addr, count); ++ ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++int cf_write_multiple_block( cf_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) ++{ ++ u8 data; ++ ++ DEBUG( CF_DEBUG, 1, "write block addr: 0x%08lx, sectors: %x, sector: %x\n", ( unsigned long)addr, count, 512); ++ ++ cf_err_code = ERR_NO_ERROR; ++ Translate_Config_HCS( addr, count); ++ CF_SendCommand( ATA_WRITE_SECTOR); ++ do { ++ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); ++ } while( data & BUSY_BIT); ++ ++ SetTransferSizeEx( BLKMEM_DATA_REG, COMMON_MEM, WRITE_OP, NOINCADR, CF_SECTOR_SIZE * count); ++ ++ if( !cfc_write_block( info, CF_SECTOR_SIZE*count, ( uint *) buf)) ++ return FALSE; ++ ++ if( cf_err_code != ERR_NO_ERROR){ ++ ++ DEBUG( CF_DEBUG, 1, "error: 0x%08lx\n", ( unsigned long)cf_err_code); ++ DEBUG( CF_DEBUG, 1, "w addr: %d, count: %d\n", addr, count); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++ ++/*************************************************************************** ++ * SD Card Read/Write/Erase Function ++ ***************************************************************************/ ++int cf_read_sector( cf_card_t *info, uint addr, uint count, unchar *buf) ++{ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ if( !cf_read_multiple_block( info, addr + cf_devices->lba_sec_offset, count, ++ info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)){ ++ ++ DEBUG( CF_DEBUG, 1, "read failed\n"); ++ return FALSE; ++ } ++ ++ DEBUG( CF_DEBUG, 1, "read ok\n"); ++ ++ if( cf_devices->lba_sec_offset == 0){ ++ ++ if( !cf_read_multiple_block( info, 0, 1, info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)) ++ return FALSE; ++ ++ /* lba ( ??) sector offset */ ++ cf_devices->lba_sec_offset = ( *( buf + 0x1C6)) ++ | ( *( buf + 0x1C7)) << 8 ++ | ( *( buf + 0x1C8)) << 16 ++ | ( *( buf + 0x1C9)) << 24; ++ ++ /* device total sector number */ ++ g_cf_sectors = ( *( buf + 0x1CA)) ++ | ( *( buf + 0x1CB)) << 8 ++ | ( *( buf + 0x1CC)) << 16 ++ | ( *( buf + 0x1CD)) << 24; ++ ++ /* only for testing , it only to let format command ok */ ++ if( ( buf[ 0x1be] != 0x0) && ( buf[ 0x1be] != 0x80)) /* partition identify */ ++ cf_devices->lba_sec_offset = 0; /* sector 0 is PBR */ ++ else ++ cf_devices->lba_sec_offset = ( buf[ 0x1c6]) ++ | ( buf[ 0x1c7] << 8) ++ | ( buf[ 0x1c8] << 16) ++ | ( buf[ 0x1c9] << 24); ++ ++ DEBUG( CF_DEBUG, 1, "lba_sec_offet is %d\n", cf_devices->lba_sec_offset); ++ DEBUG( CF_DEBUG, 1, "the device( partition) total sector number is %d\n", g_cf_sectors); ++ } ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ return TRUE; ++} ++ ++int cf_write_sector( cf_card_t *info, uint addr, uint count, unchar *buf) ++{ ++ if( !cf_write_multiple_block( info, addr+cf_devices->lba_sec_offset, count, ++ info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)){ ++ ++ DEBUG( CF_DEBUG, 1, "write failed\n"); ++ ++ return FALSE; ++ } ++ ++ DEBUG( CF_DEBUG, 1, "write ok\n"); ++ ++ return TRUE; ++} ++ ++/* ++ * Perform an actual transfer: ++ * Returns: # of sectors transferred. 0 = error ++ */ ++int cf_transfer( cf_dev_t *device, const struct request *req) ++{ ++ int status = 0; ++ int count = 0; ++ ++ struct bio *bio = req->bio; ++ struct bio_vec *bvec; ++ struct req_iterator iter; ++ ++ DEBUG( CF_DEBUG, 1, "req sector: %d, phys_seg: %d, buf: 0x%08lx\n", ++ (int)req->__sector, req->nr_phys_segments, ++ (unsigned long)bio_data(bio)); ++ ++ spin_unlock_irq( &device->lock); ++ ++ rq_for_each_segment( bvec, req, iter){ ++ ++ unsigned char *buf = page_address( bvec->bv_page) + bvec->bv_offset; ++ int sectors = bio_cur_bytes( bio) >> 9; ++ ++ DEBUG( CF_DEBUG, 1, "bvec[%2d]: sector: %d, count: %d, curr: %d, buf: 0x%08lx\n", ++ iter.i, ( int)bio->bi_sector, count, ( int)sectors, ( unsigned long)buf); ++ ++ cf_card_info.private = (void *)&device->ch_req; ++ ++ if( rq_data_dir( req) == 0) /* Read */ ++ status = cf_read_sector( &cf_card_info, bio->bi_sector, sectors, buf); ++ else ++ status = cf_write_sector( &cf_card_info, bio->bi_sector, sectors, buf); ++ ++ DEBUG( CF_DEBUG, 1, "status: %d\n", status); ++ ++ if (status <= 0) { ++ spin_lock_irq( &device->lock); ++ return count; ++ } ++ ++ count += sectors; ++ bio->bi_sector += sectors; ++ } ++ ++ spin_lock_irq( &device->lock); ++ ++ if( status <= 0) ++ return 0; ++ else ++ return count; ++} ++ ++static int cf_card_setup(cf_dev_t *dev) ++{ ++ int i; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ first_run = 0; ++ cf_err_code = ERR_NO_ERROR; ++ ++ cf_card_info.ActiveState = FALSE; ++ cf_card_info.WriteProtect = FALSE; ++ cf_card_info.IOAddr = FTCFC_VA_BASE; ++ cf_card_info.DMAEnable = TRUE; ++ cf_card_info.DMAChannel = dev->ch_req.channel; ++ cf_card_info.SysFrequency = AHB_CLK_IN / 2; ++ cf_card_info.RCA = 0; ++ ++ DEBUG( CF_DEBUG, 1, "DMA Enable is %d, Sys frequency = %d\n", cf_card_info.DMAEnable, cf_card_info.SysFrequency); ++ ++ if( !cf_card_insert( &cf_card_info)) ++ return FALSE; ++ ++ /* Marketing MB is not 1048576 */ ++ DEBUG( CF_DEBUG, 1, "FTCFC010: CF Card Capacity = %d KBytes\n", g_cf_sectors >> 1); ++ ++ for( i = 0; i < CF_DEVS; i++) ++ cf_devices[i].size = g_cf_sectors; /* unit is block, not bytes */ ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ ++ return TRUE; ++} ++ ++int cf_ioctl( struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) ++{ ++ int size; ++ struct hd_geometry geo; ++ cf_dev_t *device = bdev->bd_disk->private_data; ++ ++ DEBUG( CF_DEBUG, 1, "ioctl 0x%x 0x%lx\n", cmd, arg); ++ ++ switch ( cmd){ ++ ++ case BLKGETSIZE: ++ /* ++ * Return the device size, expressed in sectors ++ * FIXME: distinguish between kernel sector size and media sector size ++ */ ++ size = device->size; ++ __copy_to_user ( ( long *) arg, &size, sizeof ( long)); ++ return 0; ++ ++ case HDIO_GETGEO: ++ /* ++ * get geometry: we have to fake one... trim the size to a ++ * multiple of 64 ( 32k): tell we have 16 sectors, 4 heads, ++ * whatever cylinders. Tell also that data starts at sector. 4. ++ */ ++ geo.cylinders = ( device->size / 4) / 8; /* ?? only for test */ ++ geo.heads = 4; ++ geo.sectors = 8; ++ geo.start = 0; ++ __copy_to_user ( ( void *) arg, &geo, sizeof ( geo)); ++ return 0; ++ ++ default: ++ /* For ioctls we don't understand, let the block layer handle them */ ++ return -ENOTTY; ++ } ++ ++ return -ENOTTY; /* unknown command */ ++} ++ ++static void cf_request( struct request_queue *q) ++{ ++ cf_dev_t *dev; ++ int ret = 0; ++ struct request *req; ++ static int act = 0; ++ ++ if( act) ++ return; ++ ++ act = 1; ++ ++ while( ( req = blk_fetch_request( q)) != NULL){ ++ ++ dev = req->rq_disk->private_data; ++ ++ if( !dev || dev->card_state == CF_CARD_REMOVE){ ++ ++ DEBUG( CF_DEBUG, 1, "CF: locating device error\n"); ++ __blk_end_request_cur( req, -EIO); ++ ++ act = 0; ++ return; ++ } ++ ++ ret = cf_transfer( dev, req); ++ __blk_end_request( req, 0, ret << 9); ++ } ++ ++ act = 0; ++} ++ ++static int cf_dma_ch_alloc(cf_dev_t *dev) ++{ ++ dmad_chreq *ch_req = &dev->ch_req; ++ ++ memset(ch_req, 0, sizeof(dmad_chreq)); ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++ ch_req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */ ++ ch_req->apb_req.addr0_reqn = APBBR_REQN_CFC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ ++ ch_req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */ ++ ch_req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ ++ ch_req->apb_req.burst_mode = 0; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */ ++ ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */ ++ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ ++ ++ ch_req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ ++ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ memset(ch_req, 0, sizeof(dmad_chreq)); ++ printk(KERN_INFO "%s: APB dma channel allocation failed\n", __func__); ++ goto _try_ahb; ++ } ++ ++#if (CF_DEBUG) ++ printk("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); ++#endif ++ ++ return 0; ++ ++_try_ahb: ++ ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ ++ ch_req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */ ++ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */ ++ ch_req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */ ++ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */ ++ ch_req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ ++ ch_req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ ++ ch_req->ahb_req.addr0_reqn = DMAC_REQN_CFC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ ++ ch_req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ ++ ch_req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ ++ ch_req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ ++ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ ++ ++ ch_req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ ++ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ memset(ch_req, 0, sizeof(dmad_chreq)); ++ printk(KERN_INFO "%s: AHB dma channel allocation failed\n", __func__); ++ goto _err_exit; ++ } ++ ++#if (CF_DEBUG) ++ printk("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); ++#endif ++ ++ return 0; ++ ++_err_exit: ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++ return -ENODEV; ++} ++ ++/* ++ * Note no locks taken out here. In a worst case scenario, we could drop ++ * a chunk of system memory. But that should never happen, since validation ++ * happens at open or mount time, when locks are held. ++ */ ++static int cf_revalidate( struct gendisk *gd) ++{ ++ cf_dev_t *dev = gd->private_data; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ dev->card_state = cfc->HostStatus & CARD_DETECT_BIT ? CF_CARD_INSERT : CF_CARD_REMOVE; ++ ++ DEBUG( CF_DEBUG, 1, "card state: %s\n", ++ dev->card_state == CF_CARD_INSERT ? "INSERT" : ++ dev->card_state == CF_CARD_WORK ? "WORK" : "REMOVE"); ++ ++ if( !dev->usage){ ++ ++ if( cf_card_setup(dev) != TRUE){ ++ ++ DEBUG( CF_DEBUG, 1, "cf_card_setup failed\n"); ++ dev->card_state = CF_CARD_REMOVE; ++ ++ return -1; ++ } ++ else { ++ DEBUG( CF_DEBUG, 1, "CFC Driver with DMA Mode\n"); ++ ++ if (cf_card_info.DMAEnable) { ++ /* acquire dma channel */ ++ if (cf_dma_ch_alloc(dev) != 0) { ++ cf_card_info.DMAEnable = FALSE; ++ cf_free( dev); ++ DEBUG( CF_DEBUG, 1, "Request DMA resource failed\n"); ++ return -1; ++ } ++ DEBUG( CF_DEBUG, 1, "Request DMA resource success\n"); ++ } ++ ++ /* SDC interrupt, currently only for HotSwap */ ++ DEBUG( CF_DEBUG, 1, "Request CFC IRQ: %d\n", FTCFC_IRQ); ++ ++ if( request_irq( FTCFC_IRQ, cf_hotswap_interrupt_handler, IRQF_DISABLED, "CF controller", dev) != 0){ ++ ++ DEBUG( CF_DEBUG, 1, "Unable to allocate CFC IRQ: 0x%x\n", FTCFC_IRQ); ++ cf_free( dev); ++ return -1; ++ } ++ ++ /* require io port address for sd controller */ ++ if( request_region( FTCFC_VA_BASE, 0x48, "CF Controller") == NULL){ ++ ++ DEBUG( CF_DEBUG, 1, "request io port of sd controller fail\n"); ++ cf_free( dev); ++ return -1; ++ } ++ ++ dev->card_state = CF_CARD_WORK; ++ } ++ } ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ ++ return 0; ++} ++ ++/* TODO: forbids open for write when WRITE_PROTECT = 1 */ ++static int cf_open( struct block_device *bdev, fmode_t mode) ++{ ++ cf_dev_t *dev= bdev->bd_disk->private_data; /* device information */ ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ if( ( cfc->HostStatus & CARD_DETECT_BIT) != CARD_DETECT_BIT){ ++ ++ DEBUG( CF_DEBUG, 1, "Error: ( ENOMEDIUM)\n"); ++ return -ENOMEDIUM; ++ } ++ ++ if( CFCardInit()){ ++ ++ DEBUG( CF_DEBUG, 1, "root initialize failed\n"); ++ return FALSE; ++ } ++ ++ if( !dev->usage){ ++ ++ dev->media_change = 1; ++ DEBUG( CF_DEBUG, 1, "forced check_disk_change check\n"); ++ check_disk_change( bdev); ++ } ++ else{ ++ dev->media_change = 0; ++ } ++ ++ DEBUG( CF_DEBUG, 1, "set_capacity() to %d blocks ( %d KBytes)\n", dev->size, dev->size >> 1); ++ set_capacity( dev->gd, dev->size); ++ dev->usage++; ++ cf_devices->lba_sec_offset = 0; ++ DEBUG( CF_DEBUG, 1, "dev: 0x%08lx, cf_devices: 0x%08lx\n", ( unsigned long)dev, ( unsigned long)cf_devices); ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ ++ return 0; /* success */ ++} ++ ++static int cf_release( struct gendisk *gd, fmode_t mode) ++{ ++ cf_dev_t *dev = gd->private_data; ++ ++ DEBUG( CF_DEBUG, 1, "Enter\n"); ++ ++ dev->usage--; ++ ++ if( !dev->usage) ++ cf_free( dev); ++ ++ DEBUG( CF_DEBUG, 1, "Exit\n"); ++ ++ return 0; ++} ++ ++static void setup_device( struct cf_dev *dev, int which) ++{ ++ memset ( dev, 0, sizeof ( struct cf_dev)); ++ dev->size = 0; ++ spin_lock_init( &dev->lock); ++ ++ dev->queue = blk_init_queue( cf_request, &dev->lock); ++ ++ if( !dev->queue) ++ goto out_vfree; ++ ++ blk_queue_logical_block_size( dev->queue, hardsect_size); ++ dev->queue->queuedata = dev; ++ ++ dev->card_state = CF_CARD_REMOVE; ++ ++ /* And the gendisk structure. */ ++ dev->gd = alloc_disk( CF_MINORS); ++ if( ! dev->gd){ ++ ++ DEBUG( CF_DEBUG, 1, "alloc_disk failure\n"); ++ goto out_vfree; ++ } ++ ++ dev->gd->flags = GENHD_FL_REMOVABLE | GENHD_FL_SUPPRESS_PARTITION_INFO; ++ dev->gd->major = cf_major; ++ dev->gd->first_minor = which * CF_MINORS; ++ dev->gd->minors = CF_MINORS; ++ dev->gd->fops = &cf_fops; ++ dev->gd->queue = dev->queue; ++ dev->gd->private_data = dev; ++ ++ snprintf ( dev->gd->disk_name, 32, "cpecf%c", which + 'a'); ++ set_capacity( dev->gd, 0); ++ add_disk( dev->gd); ++ ++ return; ++ ++out_vfree: ++ ++ return; ++} ++ ++static int cf_media_changed( struct gendisk *gd) ++{ ++ struct cf_dev *dev = gd->private_data; ++ ++ DEBUG( CF_DEBUG, 1, "cf_media_changed = %d\n", dev->media_change); ++ ++ return dev->media_change; ++} ++ ++struct block_device_operations cf_fops = { ++ ++ .owner = THIS_MODULE, ++ .open = cf_open, ++ .release = cf_release, ++ .ioctl = cf_ioctl, ++ .revalidate_disk = cf_revalidate, ++ .media_changed = cf_media_changed, ++}; ++ ++static int __init cf_module_init( void) ++{ ++ int result= -ENOMEM, i; ++ ++ DEBUG( 1, 0, "Faraday CF controller Driver (DMA mode)\n"); ++ ++ cf_major = register_blkdev( cf_major, DEVICE_NAME); ++ ++ if( cf_major <= 0){ ++ ++ DEBUG( CF_DEBUG, 1, ":unable to get major number\n"); ++ return -EBUSY; ++ } ++ ++ DEBUG( 1, 0, "CF: make node with 'mknod /dev/cpecf b %d 0'\n", cf_major); ++ ++ cf_devices = kzalloc( CF_DEVS * sizeof( cf_dev_t), GFP_KERNEL); ++ ++ if( !cf_devices) ++ goto fail_malloc; ++ ++ for( i = 0; i < CF_DEVS; i++) ++ setup_device( cf_devices + i, i); ++ ++ return 0; ++ ++fail_malloc: ++ ++ if( cf_devices) ++ kfree( cf_devices); ++ ++ unregister_blkdev( cf_major, DEVICE_NAME); ++ ++ return result; ++} ++ ++static void cf_module_cleanup( void) ++{ ++ int i; ++ ++ if( cf_devices){ ++ ++ for( i = 0; i < CF_DEVS; i++){ ++ ++ del_gendisk( cf_devices[i].gd); ++ put_disk( cf_devices[i].gd); ++ ++ if( cf_devices[i].queue) ++ blk_cleanup_queue( cf_devices[i].queue); ++ } ++ ++ kfree( cf_devices); ++ } ++ ++ unregister_blkdev( cf_major, DEVICE_NAME); ++} ++ ++module_init( cf_module_init); ++module_exit( cf_module_cleanup); ++ ++MODULE_AUTHOR( "Faraday Corp."); ++MODULE_LICENSE( "GPL"); +diff -Nur linux-3.4.110.orig/drivers/block/ftcfc010.h linux-3.4.110/drivers/block/ftcfc010.h +--- linux-3.4.110.orig/drivers/block/ftcfc010.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/block/ftcfc010.h 2016-04-07 10:20:51.022084119 +0200 +@@ -0,0 +1,438 @@ ++/* drivers/block/CPECF/ftcfc.h ++ * ++ * Faraday FTCFC010 Device Driver ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * All Rights Reserved ++ */ ++ ++#ifndef _FTCFC_H_ ++#define _FTCFC_H_ ++ ++#define CF_DEBUG 1 ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#define CF_DEVS 1 /* number of disks */ ++#define CF_MINORS 16 /* minors per disk */ ++#define CF_SECTOR_SIZE 512 /* sector size */ ++ ++/* SD Card State */ ++#define CF_CARD_REMOVE 0 ++#define CF_CARD_INSERT 1 ++#define CF_CARD_WORK 2 ++ ++/* data window register */ ++#define CFC_READ_FIFO_LEN 4 ++#define CFC_WRITE_FIFO_LEN 4 ++ ++/* card type, sd or mmc */ ++#define MEMORY_CARD_TYPE_SD 0 ++#define MEMORY_CARD_TYPE_MMC 1 ++ ++/***************************************************************************** ++ * SYSTEM ERROR_CODE ++ ****************************************************************************/ ++#define ERR_NO_ERROR 0x00000000 ++ ++/* command error */ ++#define ERR_DATA_CRC_ERROR 0x00000100 ++#define ERR_RSP_CRC_ERROR 0x00000200 ++#define ERR_DATA_TIMEOUT_ERROR 0x00000400 ++#define ERR_RSP_TIMEOUT_ERROR 0x00000800 ++ ++#define ERR_WAIT_OVERRUN_TIMEOUT 0x00001000 ++#define ERR_WAIT_UNDERRUN_TIMEOUT 0x00002000 ++#define ERR_WAIT_DATA_CRC_TIMEOUT 0x00004000 ++#define ERR_WAIT_TRANSFER_END_TIMEOUT 0x00008000 ++ ++#define ERR_SEND_COMMAND_TIMEOUT 0x00010000 ++ ++/* using APB DMA error */ ++#define ERR_APBDMA_RSP_ERROR 0x02000000 ++ ++/* ++ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting ++ */ ++#if CF_DEBUG ++#define CFC_TIMEOUT_BASE (HZ/2) /* Unit is 500 ms */ ++#else ++#define CFC_TIMEOUT_BASE (HZ/3) /* Unit is 333 ms */ ++#endif ++ ++typedef struct _cf_cid_t ++{ ++ uint ManufacturerID; ++ uint ApplicationID; ++ unchar ProductName[7]; ++ uint ProductRevisionHigh; ++ uint ProductRevisionLow; ++ uint ProductSerialNumber; ++ uint ManufactureMonth; ++ uint ManufactureYear; ++} cf_cid_t; ++ ++typedef struct _cf_ccf_t ++{ ++ uint CSDStructure; ++ uint MMCSpecVersion; ++ uint TAAC_u; ++ uint NSAC_u; ++ uint TransferSpeed; ++ uint CardCmdClass; ++ uint ReadBlockLength; ++ uint ReadBlockPartial; ++ uint WriteBlockMisalign; ++ uint ReadBlockMisalign; ++ uint DSRImplemant; ++ uint BlockNumber; ++ uint MemorySize; ++ uint VDDReadMin_u; ++ uint VDDReadMax_u; ++ uint VDDWriteMin_u; ++ uint VDDWriteMax_u; ++ uint EraseBlkEnable; ++ uint EraseSectorSize; ++ uint WriteProtectGroupSize; ++ uint WriteProtectGroupEnable; ++ uint WriteSpeedFactor; ++ uint WriteBlockLength; ++ unchar WriteBlockPartial; ++ unchar CopyFlag; ++ unchar PermanentWriteProtect; ++ unchar TemporaryWriteProtect; ++ unchar FileFormat; ++} cf_ccf_t; ++ ++/***************************************************************************** ++ * SD SCR register ++ ****************************************************************************/ ++typedef struct _cf_scr_t ++{ ++ uint Reserved:16; ++ uint SD_BUS_WIDTH:4; ++ uint SD_SECURITY:3; ++ uint DATA_STAT_AFTER_ERASE:1; ++ uint SD_SPEC:4; ++ uint SCR_STRUCTURE:4; ++ ++ uint ManufacturerReserved; ++} cf_scr_t; ++ ++/***************************************************************************** ++ * sd card structure ++ ****************************************************************************/ ++typedef struct _cf_card_t ++{ ++ /* host interface configuration */ ++ uint IOAddr; /* host controller register base address */ ++ uint DMAEnable; ++ uint DMAChannel; ++ ++ uint CardType; ++ ++ uint CIDWord[4]; ++ cf_cid_t CID; ++ ++ uint CSDWord[4]; ++ cf_ccf_t CSD; ++ ++ ushort RCA; ++ cf_scr_t SCR; ++ ++ /* access time out */ ++ uint ReadAccessTimoutCycle; ++ uint WriteAccessTimoutCycle; ++ ++ /* system configurations */ ++ uint SysFrequency; ++ ++ /* card status */ ++ int ActiveState; ++ int WriteProtect; ++ ++ void *private; ++} cf_card_t; ++ ++typedef struct _CF_Dev ++{ ++ u32 dev_size; /* used same as sect_num */ ++ u32 sect_num; /* sector num */ ++ u8 blksize_bit; /* It's not used */ ++ u32 blksize; /* size of block in file system, 1024 */ ++ ++ u32 phy_blksize; /* Physical size of block on the CF. It's not used */ ++ u32 phy_sectorsize; /* the size of erasable sector. It's not used */ ++ u32 wp_grp_size; /* the size of write protected group. It's not used */ ++ ++ spinlock_t lock; /* synchronization */ ++ struct semaphore sema; /* synchronization */ ++ u32 usage; ++ ++ u8 busy; ++ ++ wait_queue_head_t select_wait; /* Kernel thread blocked on it. It's not used */ ++ u8 cmd; /* What command being executed. */ ++ u32 result; /* set by tasklet */ ++ u8 *buff; ++ ++ u32 lba_sec_offset; ++ ++ /*APB_DMA */ ++ ++ u8 DMATransDir; /* 0: IDLE, 1:READ, 2:WRITE */ ++} CF_Dev; ++ ++#define CFC_R_IDLE 0x00 ++#define CFC_R_START_TRANSFER 0x01 ++#define CFC_R_SET_CFCARD_REG 0x02 ++#define CFC_R_SET_CFCARD_READ_CMD 0x03 ++#define CFC_R_CHK_CFCARD_READY 0x04 ++#define CFC_R_SET_DMA_REG 0x05 ++#define CFC_R_DMA_START 0x06 ++#define CFC_R_DMA_INT 0x07 ++#define CFC_R_DMA_FINISH 0x08 ++#define CFC_R_PIO_START 0x09 ++#define CFC_R_PIO_FINISH 0x0A ++#define CFC_R_CHECK_CFCARD_BUSY 0x0B ++#define CFC_R_CHECK_CFCARD_READY 0x0C ++ ++#define CFC_W_IDLE 0x00 ++#define CFC_W_START_TRANSFER 0x10 ++#define CFC_W_SET_CFCARD_REG 0x20 ++#define CFC_W_SET_CFCARD_READ_CMD 0x30 ++#define CFC_W_CHK_CFCARD_READY 0x40 ++#define CFC_W_SET_DMA_REG 0x50 ++#define CFC_W_DMA_START 0x60 ++#define CFC_W_DMA_INT 0x70 ++#define CFC_W_DMA_FINISH 0x80 ++#define CFC_W_PIO_START 0x90 ++#define CFC_W_PIO_FINISH 0xA0 ++#define CFC_W_CHECK_CFCARD_BUSY 0xB0 ++#define CFC_W_CHECK_CFCARD_READY 0xC0 ++ ++#define DMA_IDLE 0x00 ++#define DMA_READ 0x01 ++#define DMA_WRITE 0x02 ++ ++typedef struct CFCTYPE ++{ ++ u32 HostStatus; /* 0x00 */ ++ u32 ControlReg; /* 0x04 */ ++ u32 TimeCfgReg; /* 0x08 */ ++ u32 BuffCtrlReg; /* 0x0C */ ++ u32 BufferData; /* 0x10 */ ++ u32 MultiSector; /* 0x14 */ ++ ++ /* Enchanced Feature */ ++ u32 TransSzMode2En; /* 0x18 */ ++ u32 TransSzMode2Cnt; /* 0x1C */ ++ u32 Reserved[4]; /* 0x20~0x2F is reserved */ ++ u32 Revision; /* 0x30 */ ++ u32 Feature; /* 0x34 (define buffer size) */ ++ ++} CFCTYPE; ++ ++#define cfc ((volatile struct CFCTYPE *) (FTCFC_VA_BASE)) ++ ++typedef struct _tag_CFCardInfo ++{ ++ u32 SectTotal; ++ u8 ConfigOptionReg; ++ u8 ConfigAndStatusReg; ++ u8 PinReplaceReg; ++ u8 SocketCopyReg; ++ ++} CF_CARD_INFO; ++ ++#define CFC_C_Complete 0x00000400 ++#define CFC_B_Ready 0x00000200 ++#define CFC_8bit 0x00000040 ++#define CFC_16bit 0x00000000 ++#define CFC_Reset 0x00000020 ++#define CFC_T_2048 0x000C0000 ++#define CFC_T_1024 0x000B0000 ++#define CFC_T_512 0x000A0000 ++#define CFC_T_256 0x00090000 ++#define CFC_T_128 0x00080000 ++#define CFC_T_64 0x00070000 ++#define CFC_T_32 0x00060000 ++#define CFC_T_16 0x00050000 ++#define CFC_T_8 0x00040000 ++#define CFC_T_4 0x00030000 ++#define CFC_T_2 0x00020000 ++#define CFC_T_1 0x00010000 ++#define CFC_Read 0x00000000 ++#define CFC_Write 0x00008000 ++#define CFC_Increment 0x00004000 ++#define CFC_Attribute 0x00000000 ++#define CFC_Memory 0x00002000 ++#define CFC_IO 0x00003000 ++ ++/* CF status register bit mapping */ ++#define RDY_nIREQ_BIT 0x0001 ++#define CARD_DETECT_BIT 0x0002 ++#define VOL33_SENSE_BIT 0x0004 ++#define VOL40_SENSE_BIT 0x0008 ++#define STATUS_CHANGE_BIT 0x0010 ++#define SPKR_BIT 0x0020 ++#define BUF_ACTIVE_BIT 0x0100 ++#define BUF_DATA_RDY_BIT 0x0200 ++#define INTA_BIT 0x0400 ++#define BUF_SIZE_BITS 0xF000 ++#define INT_CD_BIT 0x10000 ++#define INT_IO_BIT 0x20000 ++ ++/* CF control register bit mapping */ ++#define POWER_CONTROL_BIT 0x000F ++#define FLOW_CONTROL_BIT 0x0010 ++#define RESET_BIT 0x0020 ++#define MODE_BIT 0x0040 ++#define DMA_BIT 0x0100 ++ ++#define PWR_ON 1 ++#define PWR_OFF 0 ++ ++#define SIGNAL_ON 0x0010 ++#define SIGNAL_OFF 0x0000 ++ ++#define BYTE_MODE 0x0040 ++#define WORD_MODE 0x0000 ++ ++#define ENDMA_BIT 0x0100 ++#define DISDMA_BIT 0x0000 ++ ++#define CARD_DETECT_INT_MASK 0x0200 ++#define DATA_CMP_INT_MASK 0x0400 ++#define IO_INT_MASK 0x0800 ++ ++/* active buffer control register bit mapping */ ++#define ADR_BIT 0x007FF ++#define TYPE_BIT 0x03000 ++#define INCADR_BIT 0x04000 ++#define RW_BIT 0x08000 ++#define TRANS_SIZE_CONTROL_BIT 0xF0000 ++ ++#define INCADR 0x04000 ++#define NOINCADR 0x00000 ++#define TRANS_SIZE_LOC 16 ++ ++#define SIZE_1_BYTE 0x01 ++#define SIZE_2_BYTE 0x02 ++#define SIZE_4_BYTE 0x03 ++#define SIZE_8_BYTE 0x04 ++#define SIZE_16_BYTE 0x05 ++#define SIZE_32_BYTE 0x06 ++#define SIZE_64_BYTE 0x07 ++#define SIZE_128_BYTE 0x08 ++#define SIZE_256_BYTE 0x09 ++#define SIZE_512_BYTE 0x0a ++#define SIZE_1024_BYTE 0x0b ++#define SIZE_2048_BYTE 0x0c ++ ++#define READ_OP 0x00000 ++#define WRITE_OP 0x08000 ++ ++/* type description */ ++#define ATTRIBUTE_MEM 0x00000 ++#define COMMON_MEM 0x02000 ++ ++/* ++ * CF card ++ * memory map register ++ * IO block register ++ */ ++#define BLKMEM_DATA_REG 0x000 ++#define BLKMEM_ERROR_REG ( BLKMEM_DATA_REG + 0x01) ++#define BLKMEM_FEATURE_REG ( BLKMEM_DATA_REG + 0x01) ++#define BLKMEM_SECTOR_COUNT_REG ( BLKMEM_DATA_REG + 0x02) ++#define BLKMEM_SECTOR_NUMBER_REG ( BLKMEM_DATA_REG + 0x03) ++#define BLKMEM_CYLINDER_LOW_REG ( BLKMEM_DATA_REG + 0x04) ++#define BLKMEM_CYLINDER_HIGH_REG ( BLKMEM_DATA_REG + 0x05) ++#define BLKMEM_DRIVE_REG ( BLKMEM_DATA_REG + 0x06) ++#define BLKMEM_STATUS_REG ( BLKMEM_DATA_REG + 0x07) ++#define BLKMEM_COMMAND_REG ( BLKMEM_DATA_REG + 0x07) ++ ++#define BLKMEM_EVEN_DATA_REG ( BLKMEM_DATA_REG + 0x08) ++#define BLKMEM_ODD_DATA_REG ( BLKMEM_DATA_REG + 0x09) ++#define BLKMEM_DUP_ERROR_REG ( BLKMEM_DATA_REG + 0x0d) ++#define BLKMEM_DUP_FEATURE_REG ( BLKMEM_DATA_REG + 0x0d) ++#define BLKMEM_DEV_CONTROL_REG ( BLKMEM_DATA_REG + 0x0e) ++#define BLKMEM_DRIVE_ADDR_REG ( BLKMEM_DATA_REG + 0x0f) ++#define BLKMEM_WINDOW_REG ( BLKMEM_DATA_REG + 0x400) ++#define BLKMEM_MAX_WINDOW_REG ( BLKMEM_DATA_REG + 0x7ff) ++ ++/* status register */ ++#define BUSY_BIT 0x80 ++#define RDY_BIT 0x40 ++#define DWF_BIT 0x20 ++#define DSC_BIT 0x10 ++#define DRQ_BIT 0x08 ++#define CORR_BIT 0x04 ++#define ERR_BIT 0x01 ++ ++/* CF ATA command */ ++#define ATA_CHECK_POWER_MODE 0xe5 ++#define ATA_EXECUTE_DRIVE_DIAG 0x90 ++#define ATA_ERASE_SECTOR 0xc0 ++#define ATA_FORMAT_TRACK 0x50 ++#define ATA_IDENTIFY_DRIVE 0xec ++#define ATA_IDLE 0xe3 ++#define ATA_IDLE_IMMEDIATE 0xe1 ++#define ATA_INIT_DRIVE_PARA 0x91 ++#define ATA_READ_BUFFER 0xe4 ++#define ATA_READ_LONG_SECTOR 0x22 ++#define ATA_READ_MULTIPLE 0xc4 ++#define ATA_READ_SECTOR 0x21 ++#define ATA_READ_VERIFY_SECTOR 0x40 ++#define ATA_RECALIBRATE 0x10 ++#define ATA_REQUEST_SENSE 0x03 ++#define ATA_SECURITY_DISABLE_PASSWORD 0xf6 ++#define ATA_SECURITY_EREASE_PREPARE 0xf3 ++#define ATA_SECURITY_ERASE_UNIT 0xf4 ++#define ATA_SECURITY_FREEZE_LOCK 0xf5 ++#define ATA_SECURITY_SET_PASSWORD 0xf1 ++#define ATA_SECURITY_UNLOCK 0xf2 ++#define ATA_SEEK 0x70 ++#define ATA_SET_FEATURE 0xef ++#define ATA_SET_MULTIPLE_MODE 0xc6 ++#define ATA_SET_SLEEP_MODE 0xe6 ++#define ATA_STANDBY 0xe2 ++#define ATA_STANDBY_IMMEDIATE 0xe0 ++#define ATA_TRANSFER_SECTOR 0x87 ++#define ATA_WEAR_LEVEL 0xf5 ++#define ATA_WRITE_BUFFER 0xe8 ++#define ATA_WRITE_LONG_SECTOR 0x32 ++#define ATA_WRITE_MULTIPLE 0xc5 ++#define ATA_WRITE_MULTIPLE_WO_ERASE 0xcd ++#define ATA_WRITE_SECTOR 0x30 ++#define ATA_WRITE_SECTOR_WO_ERASE 0x38 ++#define ATA_WRITE_VERIFY 0x3c ++ ++#define CF_MEM_MAP_MODE 0x0 ++/* attribute memory space register description */ ++#define ATTRIBUTE_MEM_BASE 0 ++#define ATTRIBUTE_MEM_CONFIG_BASE 0x200 ++#define CONFIG_OPTION_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x00) ++#define CARD_CONFIG_STATUS_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x02) ++#define PIN_REPLACE_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x04) ++#define SOCKET_COPY_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x06) ++ ++/* configuration option register */ ++#define CONF0_BIT 0x01 ++#define CONF1_BIT 0x02 ++#define CONF2_BIT 0x04 ++#define CONF3_BIT 0x08 ++#define CONF4_BIT 0x10 ++#define CONF5_BIT 0x20 ++#define LEVLREQ_BIT 0x40 ++#define SRESET_BIT 0x80 ++ ++#endif +diff -Nur linux-3.4.110.orig/drivers/block/ftsdc010.c linux-3.4.110/drivers/block/ftsdc010.c +--- linux-3.4.110.orig/drivers/block/ftsdc010.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/block/ftsdc010.c 2016-04-07 10:20:51.022084119 +0200 +@@ -0,0 +1,2206 @@ ++/* drivers/block/CPESD/ftsdc010.c ++ ******************************************************************************* ++ * Faraday FTSDC010 Device Driver ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * All Rights Reserved ++ * ++ * Porting to Linux 2.6 on 20050815 ++ * Author: Chris Lee, I-Jui Sung, Peter Liao (support APB DMA) ++ * Version: 0.2 ++ * History: ++ * 0.1 new creation ++ * 0.2 Porting to meet the style of linux dma ++ * 0.3 modify dma usage to virtual irq of dma interrupt ++ * 0.4 (20050701) Improve r/w performance ++ * 0.5 Porting to Linux 2.6 and replace busy_loop checking with timer's timeout ++ * Todo: ++ ******************************************************************************* ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* HDIO_GETGEO */ ++#include ++#include ++#include /* invalidate_bdev */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IPMODULE SDC ++#define IPNAME FTSDC010 ++ ++/* Define CONFIG_FTSDC010_USE_TIMER_DELAY if you want to use software timer instead of busy loop checking */ ++#define CONFIG_FTSDC010_USE_TIMER_DELAY ++#undef CONFIG_FTSDC010_USE_TIMER_DELAY ++#include "ftsdc010.h" ++#include ++MODULE_AUTHOR("Faraday Corp."); ++MODULE_LICENSE("Faraday License"); ++ ++/* options */ ++#define FORCE_PCI_CONSISTENCY 1 /* define it to 1 if met consistency problems */ ++#define KERNEL_SECTOR_SIZE 512 /* Use this when we refer to kernel related sector size */ ++ ++static int hardsect_size = 512; ++module_param(hardsect_size, int, 0); ++/*------------------------------------------------------------------------------ ++ * Predefine for block device ++ */ ++#define MAJOR_NR sd_major /* force definitions on in blk.h */ ++static int sd_major=0;//SD_MAJOR; /* must be declared before including blk.h */ ++#define SD_SHIFT 4 /* max 16 partitions */ ++#define DEVICE_NAME "Faraday SDC" /* name for messaging */ ++#define DEVICE_REQUEST sd_request ++#define DEVICE_NR(device) (MINOR(device) >> SD_SHIFT) ++//#define DEVICE_INTR sd_intrptr /* pointer to the bottom half */ ++#define DEVICE_NO_RANDOM /* no entropy to contribute */ ++#define DEVICE_OFF(d) /* do-nothing */ ++ ++/*#include ++#include */ /* blk_ioctl() */ ++ ++/*------------------------------------------------------------------------------ ++ * Macro definition ++ */ ++#define FTSDC_VA_BASE IP_VA_BASE(0) ++#define FTSDC_PA_BASE IP_PA_BASE(0) ++#define FTSDC_IRQ IP_IRQ(0) ++#define SDC_W_REG(offset, value) outl(value, IP_VA_BASE(0) + offset) ++#define SDC_R_REG(offset) inl(IP_VA_BASE(0) + offset) ++ ++ ++/*------------------------------------------------------------------------------ ++ * Global variable ++ */ ++ ++/* The following items are obtained through kmalloc() in sd_module_init() */ ++ ++struct block_device_operations sd_fops; ++/* our device structure */ ++struct sd_dev { ++ int size; /* device size in sectors */ ++ int usage; /* # of users currently */ ++ int media_change; /* Flag: media changed? */ ++ struct gendisk *gd; /* The gendisk structure */ ++ spinlock_t lock; /* For mutual exclusion */ ++ struct request_queue *queue; /* The device request queue */ ++ int card_state; ++ dmad_chreq ch_req; ++ bool dma_enable; ++}; ++static struct sd_dev *sd_devices = NULL; ++ ++static sd_card_t sd_card_info; ++static int sector_offset,Do_onetime; ++ ++dma_addr_t dma_buf = 0; /* ?? non-zero for for manually debug ?? */ ++struct completion sd_dma_cmpl; ++ ++static int sync_mode=0; ++ ++static uint first_run = 0; ++uint sd_err_code; ++ ++#define FILE_FORMAT_HARD_DISK_LIKE 0 ++#define FILE_FORMAT_FLOPPY_LIKE 1 ++#define FILE_FORMAT_UNIVERSAL 2 ++#define FILE_FORMAT_UNKNOW 3 ++#define FILE_FORMAT_RESERVED 4 ++ ++#define K 1000 ++ ++uint TAAC_TimeUnitTable[] = { // unit is ns ++ 1, 10, 100, 1 * K, 10 * K, 100 * K, 1 * K * K, 10 * K * K ++}; ++ ++uint TRANS_SPEED_RateUintTable[] = { ++ 100 * K, 1 * K * K, 10 * K * K, 100 * K * K ++}; ++ ++uint TRANS_SPEED_TimeValueTable_u[] = { // unit=1/10 ++ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 ++}; ++ ++uint VDD_CURR_MIN_Table_u[] = { // unit=1/10 ++ 5, 10, 50, 100, 250, 350, 600, 1000 ++}; ++ ++uint VDD_CURR_MAX_Table_u[] = { ++ 1, 5, 10, 25, 35, 45, 80, 200 ++}; ++ ++uint TAAC_TimeValueTable_u[] = { // unit=1/10 ++ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 ++}; ++ ++ ++unsigned int SDC_READ_FIFO_LEN; ++unsigned int SDC_WRITE_FIFO_LEN; ++ ++/*------------------------------------------------------------------------------ ++ * Local declaration of function ++ */ ++static int sd_revalidate(struct gendisk *gd); ++static int sd_media_changed(struct gendisk *gd); ++static int sd_card_setup(struct sd_dev *dev); ++int sd_check_err(uint status); ++int sd_get_scr(sd_card_t *info, uint *scr); ++int sd_set_transfer_state(sd_card_t *info); ++uint sd_block_size_convert(uint size); ++int sd_read_sector(sd_card_t *info, uint addr, uint count, unchar *buf); ++void sd_reset_host_controller(void); ++/*------------------------------------------------------------------------------ ++ * Local function ++ */ ++ ++/* ++ * SD host controller operation ++ */ ++int sdc_send_cmd(uint cmd, uint arg, uint *rsp) ++{ ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++ int count = 0; ++#else ++ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; ++#endif ++ int i; ++ uint status; ++ P_DEBUG("SD Cmd is %d\n",cmd); ++ ++ /* clear command relative bits of status register */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_FAIL | SDC_STATUS_REG_RSP_TIMEOUT | SDC_STATUS_REG_RSP_CRC_OK| SDC_STATUS_REG_CMD_SEND); ++ /* write argument to arugument register if necessary */ ++ SDC_W_REG(SDC_ARGU_REG, arg); ++ /* send command */ ++ SDC_W_REG(SDC_CMD_REG, cmd | SDC_CMD_REG_CMD_EN); ++ ++ /* wait for the CMD_SEND bit of status register is set */ ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { ++#else ++ while (time_before(jiffies, timeout)) { ++#endif ++ status = SDC_R_REG(SDC_STATUS_REG); ++ if (!(cmd & SDC_CMD_REG_NEED_RSP)) { ++ /* if this command does not need response, wait command sent flag */ ++ if (status & SDC_STATUS_REG_CMD_SEND) { ++ /* clear command sent bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CMD_SEND); ++ sd_err_code = ERR_NO_ERROR; ++ return TRUE; ++ } ++ } else { ++ /* if this command needs response */ ++ if (status & SDC_STATUS_REG_RSP_TIMEOUT) { ++ /* clear response timeout bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_TIMEOUT); ++ sd_err_code = ERR_RSP_TIMEOUT_ERROR; ++ printk("%s() ERR_RSP_TIMEOUT_ERROR\n", __func__); ++ return FALSE; ++ } else if (status & SDC_STATUS_REG_RSP_CRC_FAIL) { ++ /* clear response fail bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_FAIL); ++ sd_err_code = ERR_RSP_CRC_ERROR; ++ printk("%s() ERR_RSP_CRC_ERROR\n", __func__); ++ return FALSE; ++ } else if (status & SDC_STATUS_REG_RSP_CRC_OK) { ++ /* clear response OK bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_OK); ++ /* if it is long response */ ++ if (cmd & SDC_CMD_REG_LONG_RSP) ++ for (i = 0; i < 4; i++, rsp++) ++ *rsp = SDC_R_REG(SDC_RESPONSE0_REG + (i * 4)); ++ else ++ *rsp = SDC_R_REG(SDC_RESPONSE0_REG); ++ sd_err_code = ERR_NO_ERROR; ++ return TRUE; ++ } ++ } ++ } ++ sd_err_code = ERR_SEND_COMMAND_TIMEOUT; ++ P_DEBUG("%s() ERR_SEND_COMMAND_TIMEOUT\n", __func__); ++ return FALSE; ++} ++ ++int sdc_check_tx_ready(void) ++{ ++ uint status; ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++ int count = 0; ++ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { ++#else ++ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; ++ while (time_before(jiffies, timeout)) { ++#endif ++ status = SDC_R_REG(SDC_STATUS_REG); ++ if (status & SDC_STATUS_REG_FIFO_UNDERRUN) { ++ /* clear FIFO underrun bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_FIFO_UNDERRUN); ++ return TRUE; ++ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { ++ /* clear data timeout bit */ ++ printk("Wait Write FIFO TimeOut\n"); ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); ++ sd_err_code = ERR_DATA_TIMEOUT_ERROR; ++ return FALSE; ++ } ++ } ++ sd_err_code = ERR_WAIT_UNDERRUN_TIMEOUT; ++ P_DEBUG("%s() ERR_WAIT_UNDERRUN_TIMEOUT\n", __func__); ++ return FALSE; ++} ++ ++int sdc_check_rx_ready(void) ++{ ++ uint status; ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++ int count = 0; ++ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { ++#else ++ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; ++ while (time_before(jiffies, timeout)) { ++#endif ++ status = SDC_R_REG(SDC_STATUS_REG); ++ if (status & SDC_STATUS_REG_FIFO_OVERRUN) { ++ /* clear FIFO overrun bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_FIFO_OVERRUN); ++ return TRUE; ++ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { ++ /* clear data timeout bit */ ++ printk("Wait Read FIFO TimeOut\n"); ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); ++ sd_err_code = ERR_DATA_TIMEOUT_ERROR; ++ return FALSE; ++ } ++ } ++ sd_err_code = ERR_WAIT_OVERRUN_TIMEOUT; ++ P_DEBUG("%s() ERR_WAIT_OVERRUN_TIMEOUT\n", __func__); ++ return FALSE; ++} ++ ++int sdc_check_data_crc(void) ++{ ++ uint status=0; ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++ int count = 0; ++ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { ++#else ++ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; ++ while (time_before(jiffies, timeout)) { ++#endif ++ status = SDC_R_REG(SDC_STATUS_REG); ++ if (status & SDC_STATUS_REG_DATA_CRC_OK) { ++ P_DEBUGG("%s : receive data ok, status=0x%x\n", __func__, status); ++ /* clear data CRC OK bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_CRC_OK); ++ return TRUE; ++ } else if (status & SDC_STATUS_REG_DATA_CRC_FAIL) { ++ /* clear data CRC fail bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_CRC_FAIL); ++ sd_err_code = ERR_DATA_CRC_ERROR; ++ printk("%s() ERR_DATA_CRC_ERROR\n", __func__); ++ return FALSE; ++ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { ++ /* clear data timeout bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); ++ sd_err_code = ERR_DATA_TIMEOUT_ERROR; ++ printk("%s() ERR_DATA_TIMEOUT_ERROR\n", __func__); ++ return FALSE; ++ } ++ } ++ P_DEBUG("%s() ERR_WAIT_DATA_CRC_TIMEOUT, status=0x%x\n", __func__, status); ++ sd_err_code = ERR_WAIT_DATA_CRC_TIMEOUT; ++ return FALSE; ++} ++ ++static inline int sdc_check_data_end(void) ++{ ++ uint status; ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++ int count = 0; ++ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { ++#else ++ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; ++ while (time_before(jiffies, timeout)) { ++#endif ++ status = SDC_R_REG(SDC_STATUS_REG); ++ if (status & SDC_STATUS_REG_DATA_END) { ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_END); ++ return TRUE; ++ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { ++ /* clear data timeout bit */ ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); ++ sd_err_code = ERR_DATA_TIMEOUT_ERROR; ++ printk("%s() ERR_DATA_TIMEOUT_ERROR\n", __func__); ++ return FALSE; ++ } ++ } ++ sd_err_code = ERR_WAIT_TRANSFER_END_TIMEOUT; ++ P_DEBUG("%s() ERR_WAIT_TRANSFER_END_TIMEOUT\n", __func__); ++ return FALSE; ++} ++ ++int sdc_set_bus_width_cmd(sd_card_t *info, uint width) ++{ ++ uint status; ++ ++ /* send CMD55 to indicate to the card that the next command is an application specific command */ ++ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, (((uint)info->RCA) << 16), &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ /* send ACMD6 to set bus width */ ++ if (!sdc_send_cmd(SD_SET_BUS_WIDTH_CMD | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, width, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++int sdc_set_bus_width(sd_card_t *info) ++{ ++ uint width; ++ ++ /* if it is not SD card, it does not support wide bus */ ++ if (info->CardType != MEMORY_CARD_TYPE_SD) ++ return TRUE; ++ /* get SCR register */ ++ if (!sd_get_scr(info, (uint *) &info->SCR)) ++ return FALSE; ++ /* if host controller does not support wide bus, return */ ++ if ((SDC_R_REG(SDC_BUS_WIDTH_REG) & SDC_WIDE_BUS_SUPPORT) != SDC_WIDE_BUS_SUPPORT) ++ return TRUE; ++ if (!sd_set_transfer_state(info)) ++ return FALSE; ++ if (info->SCR.SD_BUS_WIDTH & SD_SCR_4_BIT_BIT) ++ width = SD_BUS_WIDTH_4_BIT; ++ else ++ width = SD_BUS_WIDTH_1_BIT; ++ if (!sdc_set_bus_width_cmd(info, width)) ++ return FALSE; ++ if (width == SD_BUS_WIDTH_1_BIT) ++ SDC_W_REG(SDC_BUS_WIDTH_REG, SDC_BUS_WIDTH_REG_SINGLE_BUS); ++ else ++ SDC_W_REG(SDC_BUS_WIDTH_REG, SDC_BUS_WIDTH_REG_WIDE_BUS); ++ ++ return TRUE; ++} ++ ++static inline int sdc_pre_erase_cmd(uint nr_blocks) ++{ ++ uint status; ++ sd_card_t *info=&sd_card_info; ++ /* send CMD55 to indicate to the card that the next command is an application specific command */ ++ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, (((uint)info->RCA) << 16), &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ /* send ACMD6 to set bus width */ ++ if (!sdc_send_cmd(23 | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, nr_blocks, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++ ++uint sdc_set_bus_clock(sd_card_t *info, uint clock) ++{ ++ uint div = 0, reg; ++ ++ while (clock < (info->SysFrequency / (2 * (div + 1)))) ++ div++; ++ /* write clock divided */ ++ reg = SDC_R_REG(SDC_CLOCK_CTRL_REG); ++ reg &= (~SDC_CLOCK_REG_CLK_DIV | 0x80); //ijsung: preserv SD or MMC ++ reg += div & SDC_CLOCK_REG_CLK_DIV; ++ SDC_W_REG(SDC_CLOCK_CTRL_REG, reg); ++ P_DEBUG("%s: SD clock=%d, info->SysFrequency=%d, div=%d\n",__func__,clock, info->SysFrequency, div); ++ return info->SysFrequency / (2 * (div + 1)); ++} ++ ++static inline int sdc_set_block_size(uint size) ++{ ++ uint status; ++ static uint last_size=0; ++ if (size == last_size) ++ return TRUE; ++ else ++ last_size=size; ++ ++ if (!sdc_send_cmd(SD_SET_BLOCKLEN_CMD | SDC_CMD_REG_NEED_RSP, size, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ return TRUE; ++} ++ ++void sdc_set_card_type(int type) ++{ ++ uint reg; ++ ++ reg = SDC_R_REG(SDC_CLOCK_CTRL_REG); ++ reg &= ~SDC_CLOCK_REG_CARD_TYPE; ++ ++ if (type == MEMORY_CARD_TYPE_SD) { ++ reg |= SDC_CARD_TYPE_SD; ++ } ++ else { ++ reg |= SDC_CARD_TYPE_MMC; ++ } ++ ++ SDC_W_REG(SDC_CLOCK_CTRL_REG, reg); ++} ++ ++int sdc_read_block(sd_card_t *info, uint size, uint *buf) ++{ ++ /* ++ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting ++ */ ++ unsigned long timeout = jiffies + SDC_TIMEOUT_BASE*((size+511)>>9); ++ uint count, i; ++ dmad_chreq *ch_req = (dmad_chreq *)info->private; ++ dmad_drb *drb = 0; ++ u32 drb_size = 0; ++ dma_addr_t addr_iter; ++ ++ //if (info->DMAEnable) { ++ if ((info->DMAEnable) && ((size & 0xf) == 0)) { ++ P_DEBUG("%s:size=%d, buf=%p) - DMA Read\n", __func__, size,buf ); ++ P_DEBUG("dma_buf = %d\n", dma_buf); ++ ++ init_completion(&sd_dma_cmpl); ++ ++ if (dma_buf) ++ consistent_sync(__va(dma_buf), size, DMA_FROM_DEVICE); ++ else ++ consistent_sync(buf, size, DMA_FROM_DEVICE); ++ ++ //prepare parameter for add dma entry ++ dmad_config_channel_dir(ch_req, DMAD_DIR_A0_TO_A1); ++ ++ drb_size = dmad_max_size_per_drb(ch_req); ++ ++ if (dma_buf) ++ addr_iter = dma_buf; // given dest phy addr ++ else ++ addr_iter = __pa(buf); ++ ++ while (size > 0) { ++ ++ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { ++ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); ++ return FALSE; ++ } ++ ++ drb->addr0 = FTSDC_PA_BASE + SDC_DATA_WINDOW_REG; ++ drb->addr1 = addr_iter; ++ ++ if (size <= drb_size) { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); ++ drb->sync = &sd_dma_cmpl; ++ size = 0; ++ } else { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); ++ drb->sync = 0; ++ size -= drb_size; ++ addr_iter += drb_size; ++ } ++ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); ++ ++ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { ++ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); ++ return FALSE; ++ } ++ } ++ ++ if (wait_for_completion_timeout(&sd_dma_cmpl, timeout - jiffies) == 0) ++ printk("%s: read timeout\n", __func__); ++ } else { ++ while (size > 0) { ++ if (!sdc_check_rx_ready()) { ++ printk("error...........\n"); ++ return FALSE; ++ } ++ /* read data from FIFO */ ++ if (size >= (SDC_READ_FIFO_LEN << 2)) ++ count = SDC_READ_FIFO_LEN; ++ else ++ count = size >> 2; ++ /* read data from FIFO */ ++ P_DEBUG("\n"); ++ for (i = 1; i <= count; i++, buf++) ++ { ++ *buf = SDC_R_REG(SDC_DATA_WINDOW_REG); ++ P_DEBUG("%.8x ",*buf); ++ } ++ size -= (count << 2); ++ } ++ } ++ return sdc_check_data_crc(); ++} ++ ++int sdc_write_block(sd_card_t *info, uint size, uint *buf) ++{ ++ unsigned long timeout = jiffies + SDC_TIMEOUT_BASE*3*((size+511)>>9); ++ uint count, i; ++ dmad_chreq *ch_req = (dmad_chreq *)info->private; ++ dmad_drb *drb = 0; ++ u32 drb_size = 0; ++ dma_addr_t addr_iter; ++ ++ //if (info->DMAEnable) { ++ if ((info->DMAEnable) && ((size & 0xf) == 0)) { ++ P_DEBUG("%s:size=%d, buf=%p) - DMA Write\n", __func__, size,buf ); ++ ++ init_completion(&sd_dma_cmpl); ++ ++ if (dma_buf) ++ consistent_sync(__va(dma_buf), size, DMA_TO_DEVICE); ++ else ++ consistent_sync(buf, size, DMA_TO_DEVICE); ++ ++ //prepare parameter for add dma entry ++ dmad_config_channel_dir(ch_req, DMAD_DIR_A1_TO_A0); ++ ++ drb_size = dmad_max_size_per_drb(ch_req); ++ ++ if (dma_buf) ++ addr_iter = dma_buf; // given dest phy addr ++ else ++ addr_iter = __pa(buf); ++ ++ while (size > 0) { ++ ++ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { ++ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); ++ return FALSE; ++ } ++ ++ drb->addr0 = FTSDC_PA_BASE + SDC_DATA_WINDOW_REG; ++ drb->addr1 = addr_iter; ++ ++ if (size <= drb_size) { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); ++ drb->sync = &sd_dma_cmpl; ++ size = 0; ++ } else { ++ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); ++ drb->sync = 0; ++ size -= drb_size; ++ addr_iter += drb_size; ++ } ++ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); ++ ++ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { ++ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); ++ return FALSE; ++ } ++ } ++ ++ if (wait_for_completion_timeout(&sd_dma_cmpl, timeout - jiffies) == 0) ++ printk("write timeout\n"); ++ } else { ++ while (size > 0) { ++ if (!sdc_check_tx_ready()) ++ return FALSE; ++ /* write data from FIFO */ ++ if (size >= (SDC_WRITE_FIFO_LEN << 2)) ++ count = SDC_WRITE_FIFO_LEN; ++ else ++ count = (size >> 2) ; ++ /* write data from FIFO */ ++ for (i = 0; i < count; i++, buf++) ++ SDC_W_REG(SDC_DATA_WINDOW_REG, *buf); ++ size -= (count << 2); ++ } ++ } ++ return sdc_check_data_crc(); ++} ++ ++void sdc_config_transfer(sd_card_t *SDCard, uint len, uint size, uint rw, uint timeout) ++{ ++ u32 con; ++ /* write timeout */ ++ SDC_W_REG(SDC_DATA_TIMER_REG, timeout * 2); ++ /* set data length */ ++ SDC_W_REG(SDC_DATA_LEN_REG, len); ++ ++ /* set data block */ ++ if (SDCard->DMAEnable) { ++ con = sd_block_size_convert(size) | SDC_DATA_CTRL_REG_DMA_EN | rw | SDC_DATA_CTRL_REG_DATA_EN; ++ con |= SDC_DMA_TYPE_4; ++ P_DEBUG("%s() transfer DMA mode\n", __func__); ++ SDC_W_REG(SDC_DATA_CTRL_REG, con); ++ } else { ++ P_DEBUG("%s() transfer nonDMA mode\n", __func__); ++ SDC_W_REG(SDC_DATA_CTRL_REG, sd_block_size_convert(size) | rw | SDC_DATA_CTRL_REG_DATA_EN); ++ } ++} ++ ++/* Note: This funciton may be called by interrupt handler */ ++void sdc_reset(void) ++{ ++ uint ret; ++ unsigned long delay = jiffies + (HZ/10)*3; //Delay 300ms ++ ++ /* reset host interface */ ++ SDC_W_REG(SDC_CMD_REG, SDC_CMD_REG_SDC_RST); ++ ++ /* loop, until the reset bit is clear */ ++ do { ++ ret = SDC_R_REG(SDC_CMD_REG); ++ } while ((ret & SDC_CMD_REG_SDC_RST) != 0); ++ #if 0 ++ udelay(1000); ++ #else ++ while(time_before(jiffies, delay)); ++ #endif ++} ++ ++/* ++ * SD card operation ++ */ ++void sd_endian_change(uint *dt, int len) ++{ ++ uint ul; ++ ++ for(; len > 0; len--, dt++) { ++ ul = *dt; ++ ((unchar *)dt)[0] = ((unchar *)&ul)[3]; ++ ((unchar *)dt)[1] = ((unchar *)&ul)[2]; ++ ((unchar *)dt)[2] = ((unchar *)&ul)[1]; ++ ((unchar *)dt)[3] = ((unchar *)&ul)[0]; ++ } ++} ++ ++int sd_get_ocr(sd_card_t *info, uint hocr, uint *cocr) ++{ ++ uint status; ++ int count = 0; ++ ++ do { ++ if (info->CardType == MEMORY_CARD_TYPE_SD) { ++ /* send CMD55 to indicate to the card that the next command is an application specific command */ ++ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ /* send ACMD41 to get OCR register */ ++ if (!sdc_send_cmd(SD_APP_OP_COND | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, (uint) hocr, (uint *) cocr)) ++ return FALSE; ++ } else { ++ /* send CMD1 to get OCR register */ ++ if (!sdc_send_cmd(SD_MMC_OP_COND | SDC_CMD_REG_NEED_RSP, (uint) hocr, (uint *) cocr)) ++ return FALSE; ++ } ++ if (count++ > SD_CARD_GET_OCR_RETRY_COUNT) { ++ sd_err_code = ERR_SD_CARD_IS_BUSY; ++ printk("%s : ERR_SD_CARD_IS_BUSY\n", __func__); ++ return FALSE; ++ } ++ udelay(1000); /* According to spec, at most 1 msec or 74 clock cycles */ ++ } while ((*cocr & SD_OCR_BUSY_BIT) != SD_OCR_BUSY_BIT); ++ ++ return TRUE; ++} ++ ++int sd_get_scr(sd_card_t *info, uint *scr) ++{ ++ uint status; ++ ++ if (!sd_set_transfer_state(info)) ++ return FALSE; ++ if (!sdc_set_block_size(8)) ++ return FALSE; ++ sdc_config_transfer(info, 8, 8, SDC_DATA_CTRL_REG_DATA_READ, 0xFFFFFFFF); ++ /* send CMD55 to indicate to the card that the next command is an application specific command */ ++ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ /* send ACMD51 to get SCR */ ++ if (!sdc_send_cmd(SD_SEND_SCR_CMD | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, 0, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ if (!sdc_read_block(info, 8, (uint *) scr)) ++ return FALSE; ++ if (!sdc_check_data_end()) ++ return FALSE; ++ sd_endian_change(scr, 2); ++ ++ return TRUE; ++} ++ ++int sd_check_err(uint status) ++{ ++ if (status & SD_STATUS_ERROR_BITS) { ++ sd_err_code = ERR_SD_CARD_STATUS_ERROR; ++ printk("%s() ERR_SD_CARD_STATUS_ERROR %X\n", __func__, status); ++ return FALSE; ++ } ++ sd_err_code = ERR_NO_ERROR; ++ return TRUE; ++} ++ ++int sd_get_card_state(sd_card_t *info, uint *ret) ++{ ++ uint status; ++ ++ /* send CMD13 to get card status */ ++ if (!sdc_send_cmd(SD_SEND_STATUS_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ *ret = (status & SD_STATUS_CURRENT_STATE) >> SD_STATUS_CURRENT_STATE_LOC; ++ return TRUE; ++} ++ ++int sd_operation_complete(sd_card_t *info, uint finish) ++{ ++ uint state; ++ int count = 0; ++ while (count++ < SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT) { ++ if (!sd_get_card_state(info, &state)) ++ return FALSE; ++ if (state == finish) ++ return TRUE; ++ } ++ P_DEBUG("%s() error\n", __func__); ++ return FALSE; ++} ++ ++int sd_stop_transmission(void) ++{ ++ uint status; ++ ++ /* send CMD12 to stop transmission */ ++ if (!sdc_send_cmd(SD_STOP_TRANSMISSION_CMD | SDC_CMD_REG_NEED_RSP, 0, &status)) ++ return FALSE; ++ ++ if (!sd_check_err(status)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++int sd_set_card_standby(sd_card_t *info) ++{ ++ uint state; ++ int count = 0; ++ while (count++ < SD_CARD_STATE_CHANGE_RETRY_COUNT) { ++ if (!sd_get_card_state(info, &state)) ++ return FALSE; ++ ++ switch (state) { ++ case SD_IDLE_STATE: ++ case SD_READY_STATE: ++ case SD_IDENT_STATE: ++ printk("%s() error\n", __func__); ++ return FALSE; ++ case SD_DIS_STATE: ++ return sd_operation_complete(info, SD_STBY_STATE); ++ case SD_TRAN_STATE: ++ if (!sdc_send_cmd(SD_SELECT_CARD_CMD, 0, NULL)) ++ return FALSE; ++ break; ++ case SD_DATA_STATE: ++ if (sd_operation_complete(info, SD_TRAN_STATE)) ++ return TRUE; ++ if (sd_err_code != ERR_NO_ERROR) ++ return FALSE; ++ if (!sd_stop_transmission()) ++ return FALSE; ++ break; ++ case SD_RCV_STATE: ++ if (sd_operation_complete(info, SD_TRAN_STATE)) ++ return TRUE; ++ if (sd_err_code != ERR_NO_ERROR) ++ return FALSE; ++ if (!sd_stop_transmission()) ++ return FALSE; ++ break; ++ case SD_PRG_STATE: ++ if (!sd_operation_complete(info, SD_TRAN_STATE)) ++ return FALSE; ++ break; ++ case SD_STBY_STATE: ++ return TRUE; ++ } ++ } ++ P_DEBUG("%s() error\n", __func__); ++ return FALSE; ++} ++ ++uint two_power(uint n) ++{ ++ uint pow = 1; ++ ++ for (; n > 0; n--) ++ pow <<= 1; ++ return pow; ++} ++ ++int sd_csd_parse(sd_csd_t *csd, uint *csd_word) ++{ ++ sd_csd_bit_t *csd_bit; ++ uint mult, blocks, len; ++ ++ if ((csd_word[0] & 0x00000001) != 1) { ++ sd_err_code = ERR_CSD_REGISTER_ERROR; ++ printk("%s() ERR_CSD_REGISTER_ERROR\n", __func__); ++ return FALSE; ++ } ++ ++ csd_bit = (sd_csd_bit_t *) csd_word; ++ csd->CSDStructure = csd_bit->CSD_STRUCTURE; ++ csd->MMCSpecVersion = csd_bit->MMC_SPEC_VERS; ++ csd->TAAC_u = TAAC_TimeValueTable_u[csd_bit->TAAC_TimeValue] * TAAC_TimeUnitTable[csd_bit->TAAC_TimeUnit] / 10; ++ csd->NSAC_u = csd_bit->NSAC * 100; ++ csd->TransferSpeed = TRANS_SPEED_RateUintTable[csd_bit->TRAN_SPEED_RateUnit] * TRANS_SPEED_TimeValueTable_u[csd_bit->TRAN_SPEED_TimeValue] / 10; ++ csd->CardCmdClass = csd_bit->CCC; ++ csd->ReadBlockLength = two_power(csd_bit->READ_BL_LEN); ++ csd->ReadBlockPartial = csd_bit->READ_BL_PARTIAL; ++ csd->WriteBlockMisalign = csd_bit->WRITE_BLK_MISALIGN; ++ csd->ReadBlockMisalign = csd_bit->READ_BLK_MISALIGN; ++ csd->DSRImplemant = csd_bit->DSR_IMP; ++ mult = 1 << (csd_bit->C_SIZE_MULT + 2); ++ blocks = ((csd_bit->C_SIZE_1 | (csd_bit->C_SIZE_2 << 2)) + 1) * mult; ++ len = 1 << (csd_bit->READ_BL_LEN); ++ csd->BlockNumber = blocks; ++ csd->MemorySize = blocks * len; ++ csd->VDDReadMin_u = VDD_CURR_MIN_Table_u[csd_bit->VDD_R_CURR_MIN]; ++ csd->VDDReadMax_u = VDD_CURR_MAX_Table_u[csd_bit->VDD_R_CURR_MAX]; ++ csd->VDDWriteMin_u = VDD_CURR_MIN_Table_u[csd_bit->VDD_W_CURR_MIN]; ++ csd->VDDWriteMax_u = VDD_CURR_MAX_Table_u[csd_bit->VDD_W_CURR_MAX]; ++ csd->EraseBlkEnable = csd_bit->ERASE_BLK_ENABLE; ++ csd->EraseSectorSize = csd_bit->ERASE_SECTOR_SIZE + 1; ++ csd->WriteProtectGroupSize = csd_bit->WP_GRP_SIZE + 1; ++ csd->WriteProtectGroupEnable = csd_bit->WP_GRP_ENABLE; ++ csd->WriteSpeedFactor = two_power(csd_bit->R2W_FACTOR); ++ csd->WriteBlockLength = two_power(csd_bit->WRITE_BL_LEN); ++ csd->WriteBlockPartial = csd_bit->WRITE_BL_PARTIAL; ++ csd->CopyFlag = csd_bit->COPY; ++ csd->PermanentWriteProtect = csd_bit->PERM_WRITE_PROTECT; ++ csd->TemporaryWriteProtect = csd_bit->TMP_WRITE_PROTECT; ++ ++ if (csd_bit->FILE_FORMAT_GRP == 0) ++ csd->FileFormat = csd_bit->FILE_FORMAT; ++ else ++ csd->FileFormat = FILE_FORMAT_RESERVED; ++ ++ return TRUE; ++} ++ ++int sd_cid_parse(sd_cid_t *cid, uint *cid_word) ++{ ++ unchar *ptr; ++ int i; ++ ++ if ((cid_word[0] & 0x00000001) != 1) ++ { ++ sd_err_code = ERR_CID_REGISTER_ERROR; ++ printk("%s() ERR_CID_REGISTER_ERROR\n", __func__); ++ return FALSE; ++ } ++ ++ cid->ManufacturerID = (cid_word[3] & 0xFF000000) >> 24; ++ cid->ApplicationID = (cid_word[3] & 0x00FFFF00) >> 8; ++ ++ ptr = (unchar *) cid_word; ++ ptr += 15 - 3; ++ for (i = 0; i < 6; i++, ptr--) ++ cid->ProductName[i] = *ptr; ++ cid->ProductName[6] = '\0' ; ++ ++ cid->ProductRevisionLow = (cid_word[1] & 0x00F00000) >> 20; ++ cid->ProductRevisionHigh = (cid_word[1] & 0x000F0000) >> 16; ++ cid->ProductSerialNumber = ((cid_word[1] & 0x0000FFFF) << 16) + ((cid_word[0] & 0xFFFF0000) >> 16); ++ cid->ManufactureMonth = ((cid_word[0] & 0x00000F00) >> 8); ++ cid->ManufactureYear = ((cid_word[0] & 0x0000F000) >> 12) + SD_DEFAULT_YEAR_CODE; ++ ++ return TRUE; ++} ++ ++uint sd_read_timeout_cycle(uint clock, sd_csd_t *csd) ++{ ++#if 1 //ivan for 100ms maximux from document "ProdManualIndGradeSDv1.0[1].pdf" chapter A-2 ++ return clock/10; // /10; ++#else ++ uint ret, total, per; ++ ++ per = 1000000000 / clock; ++ total = (csd->TAAC_u + (csd->NSAC_u * 100 * per)) * 100; ++ ++ if (total > (100 * 1000 * 1000)) ++ total = 100 * 1000 * 1000; ++ ret = total / per; ++ ++ return ret; ++#endif ++} ++ ++uint sd_block_size_convert(uint size) ++{ ++ uint ret = 0; ++ ++ while (size >= 2) { ++ size >>= 1; ++ ret++; ++ } ++ return ret; ++} ++ ++int sd_select_card(sd_card_t *info) ++{ ++ uint status; ++ ++ /* send CMD7 with valid RCA to select */ ++ if (!sdc_send_cmd(SD_SELECT_CARD_CMD | SDC_CMD_REG_NEED_RSP, ((uint)info->RCA) << 16, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ return TRUE; ++} ++ ++int sd_set_transfer_state(sd_card_t *info) ++{ ++ uint state; ++ int count = 0; ++ while (count++ < SD_CARD_STATE_CHANGE_RETRY_COUNT) { ++ if (!sd_get_card_state(info, &state)) ++ return FALSE; ++ ++ switch (state) { ++ case SD_IDLE_STATE: ++ case SD_READY_STATE: ++ case SD_IDENT_STATE: ++ printk("%s() error\n", __func__); ++ return FALSE; ++ case SD_DIS_STATE: ++ if (!sd_operation_complete(info, SD_STBY_STATE)) ++ return FALSE; ++ break; ++ case SD_TRAN_STATE: ++ return TRUE; ++ case SD_DATA_STATE: ++ if (sd_operation_complete(info, SD_TRAN_STATE)) ++ return TRUE; ++ if (sd_err_code != ERR_NO_ERROR) ++ return FALSE; ++ if (!sd_stop_transmission()) ++ return FALSE; ++ break; ++ case SD_RCV_STATE: ++ if (sd_operation_complete(info, SD_TRAN_STATE)) ++ return TRUE; ++ if (sd_err_code != ERR_NO_ERROR) ++ return FALSE; ++ if (!sd_stop_transmission()) ++ return FALSE; ++ break; ++ case SD_PRG_STATE: ++ if (!sd_operation_complete(info, SD_TRAN_STATE)) ++ return FALSE; ++ break; ++ case SD_STBY_STATE: ++ if (!sd_select_card(info)) ++ return FALSE; ++ } ++ } ++ P_DEBUG("%s() error\n", __func__); ++ return FALSE; ++} ++ ++uint sd_write_timeout_cycle(uint clock, sd_csd_t *CSD) ++{ ++#if 1 //ivan for 250ms maximux from document ++ return clock/4; //ijsung hack ++#else ++ uint ret, total, pre; ++ ++ pre = 1000000000 / clock; ++ total = CSD->WriteSpeedFactor * 100 * (CSD->TAAC_u + (CSD->NSAC_u * 100 * pre)); ++ ++ if (total > (100 * 1000 * 1000)) ++ total = 100 * 1000 * 1000; ++ ret = total / pre; ++ ++ return ret; ++#endif ++} ++ ++int sd_card_identify(sd_card_t *info) ++{ ++ uint rca, status, cid[4]; ++ ++ /* reset all cards */ ++ if (!sdc_send_cmd(SD_GO_IDLE_STATE_CMD, 0, NULL)) ++ return FALSE; ++ udelay(1000); ++ /* Do operating voltage range validation */ ++ /* get OCR register */ ++ if (!sd_get_ocr(info, SDC_OCR, (uint *) &info->OCR)) ++ return FALSE; ++ /* ckeck the operation conditions */ ++ if ((info->OCR & SDC_OCR) == 0) { ++ sd_err_code = ERR_OUT_OF_VOLF_RANGE; ++ return FALSE; ++ } ++ ++ /* send CMD2 to get CID register */ ++ if (!sdc_send_cmd(SD_ALL_SEND_CID_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, 0, cid)) ++ return FALSE; ++ if (info->CardType == MEMORY_CARD_TYPE_SD) { ++ /* send CMD3 to get RCA register */ ++ if (!sdc_send_cmd(SD_SEND_RELATIVE_ADDR_CMD | SDC_CMD_REG_NEED_RSP, 0, &rca)) ++ return FALSE; ++ info->RCA = (ushort) (rca >> 16); ++ } else { ++ /* so far, we only support one interface, so we can give RCA any value */ ++ info->RCA = 0x1; ++ /* send CMD3 to set RCA register */ ++ if (!sdc_send_cmd(SD_SEND_RELATIVE_ADDR_CMD | SDC_CMD_REG_NEED_RSP, (info->RCA << 16), &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++int sd_card_init(sd_card_t *info) ++{ ++ uint clock; ++ ++ P_DEBUG("--> %s\n", __func__); ++ if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) ++ return FALSE; ++ sd_err_code = ERR_NO_ERROR; ++ /* At first, set card type to SD */ ++ info->CardType = MEMORY_CARD_TYPE_SD; ++ /* set memory card type */ ++ sdc_set_card_type(info->CardType); ++ /* start card idenfication process */ ++ if (!sd_card_identify(info)) { ++ printk("this is not SD card\n"); ++ sd_err_code = ERR_NO_ERROR; ++ info->CardType = MEMORY_CARD_TYPE_MMC; ++ /* set memory card type */ ++ sdc_set_card_type(info->CardType); ++ if (!sd_card_identify(info)) ++ return FALSE; ++ } ++ ++ /* get CSD */ ++ if (!sd_set_card_standby(info)) ++ return FALSE; ++ /* send CMD9 to get CSD register */ ++ if (!sdc_send_cmd(SD_SEND_CSD_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, ((uint) info->RCA) << 16, info->CSDWord)) ++ return FALSE; ++ sd_csd_parse(&info->CSD, info->CSDWord); ++ ++ if (info->CSD.ReadBlockLength != SD_SECTOR_SIZE) { ++ printk("Sector size is mis-matched (SD CSD report=0x%X,SD_SECTOR_SIZE=0x%X)\n", info->CSD.ReadBlockLength, SD_SECTOR_SIZE); ++ info->CSD.ReadBlockLength = SD_SECTOR_SIZE; ++// return FALSE; ++ } ++ ++ /* get CID */ ++ /* send CMD10 to get CID register */ ++ if (!sdc_send_cmd(SD_SEND_CID_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, ((uint) info->RCA) << 16, info->CIDWord)) ++ return FALSE; ++ sd_cid_parse(&info->CID, info->CIDWord); ++ ++ /* Set card bus clock. sdc_set_bus_clock() will give the real card bus clock has been set. */ ++ clock = sdc_set_bus_clock(info, info->CSD.TransferSpeed); ++ info->ReadAccessTimoutCycle = sd_read_timeout_cycle(clock, &(info->CSD)); ++ info->WriteAccessTimoutCycle = sd_write_timeout_cycle(clock, &(info->CSD)); ++ /* set bus width */ ++ if (!sdc_set_bus_width(info)) ++ return FALSE; ++ ++ /* check write protect */ ++ info->WriteProtect = ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_LOCK) == SDC_STATUS_REG_CARD_LOCK) ? TRUE : FALSE; ++ if(info->WriteProtect == TRUE) ++ printk("SD/MMC Card is Write Protected\n"); ++ info->ActiveState = TRUE; ++ P_DEBUG("<-- %s\n", __func__); ++ ++ return TRUE; ++} ++ ++int sd_card_insert(sd_card_t *info) ++{ ++ P_DEBUG("--> %s\n", __func__); ++ /* reset host interface controller */ ++ sdc_reset(); ++ /* turn on clock using default clock*/ ++ SDC_W_REG(SDC_CLOCK_CTRL_REG, SDC_R_REG(SDC_CLOCK_CTRL_REG)&0xff); ++ ++ if (!sd_card_init(info)) { ++ printk("root initialize failed\n"); ++ return FALSE; ++ } ++ /* set interrupt mask register */ ++ SDC_W_REG(SDC_INT_MASK_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); ++ P_DEBUG("<-- %s\n", __func__); ++ ++ return TRUE; ++} ++ ++int sd_card_remove(sd_card_t *info) ++{ ++ sd_err_code = ERR_NO_ERROR; ++ ++ info->ActiveState = FALSE; ++ info->WriteProtect = FALSE; ++ info->RCA = 0; ++ /* reset host interface controller */ ++ sdc_reset(); ++ /* set interrupt mask register */ ++ SDC_W_REG(SDC_INT_MASK_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); ++ sd_err_code = ERR_CARD_NOT_EXIST; ++ /* turn off clock */ ++ SDC_W_REG(SDC_CLOCK_CTRL_REG, SDC_R_REG(SDC_CLOCK_CTRL_REG) | 0x100); ++ return TRUE; ++} ++ ++irqreturn_t sd_hotswap_interrupt_handler(int irq, void *dev_id) ++{ ++ uint status; ++ struct sd_dev *dev = dev_id; ++ ++ P_DEBUG("--> %s, irq=%d\n", __func__, irq); ++ /* When the card is inserted or removed, we must delay a short time to make sure */ ++ /* the SDC_STATUS_REG_CARD_INSERT bit of status register is stable */ ++ udelay(1000); ++ status = SDC_R_REG(SDC_STATUS_REG); ++ if ((status & SDC_STATUS_REG_CARD_CHANGE) == SDC_STATUS_REG_CARD_CHANGE) { ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); ++ if ((status & SDC_STATUS_REG_CARD_INSERT) == SDC_CARD_INSERT) { ++ dev->card_state = SD_CARD_INSERT; ++ printk("Card Insert\n"); ++ sd_card_insert(&sd_card_info); ++ } else { ++ dev->card_state = SD_CARD_REMOVE; ++ printk("Card Remove\n"); ++ sd_card_remove(&sd_card_info); ++ /* remove all current transfers as I/O error*/ ++#if 0 //ASYNC ++ spin_lock_irqsave(&io_request_lock, status); ++ INIT_REQUEST; ++ while(!QUEUE_EMPTY) ++ end_request(0); ++ bh_busy=0; ++ spin_unlock_irqrestore(&io_request_lock, status); ++#endif ++ } ++ } else if ((status & SDC_STATUS_REG_DATA_TIMEOUT) == SDC_STATUS_REG_DATA_TIMEOUT) { ++ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); ++ ++#if 0 //ASYNC ++ printk("Data timeout. Retry.\n"); ++ sd_clustered_bh(2); ++#else ++ printk("Data timeout. Retry.\n"); ++#endif ++ } ++ P_DEBUGG("card state=%d\n", dev->card_state); ++ P_DEBUG("<-- %s\n", __func__); ++ return IRQ_HANDLED; ++} ++ ++/*------------------------------------ ++ * Block-driver specific functions ++ */ ++/* ++ * Find the device for this request. ++ */ ++#if 0 ++static inline struct sd_dev *sd_locate_device(const struct request *req) ++{ ++ int devno; ++ struct sd_dev *dev; ++ ++ P_DEBUG("--> %s\n", __func__); ++#if 0 ++ /* Check if the minor number is in range */ ++ devno = DEVICE_NR(req->rq_dev); ++ P_DEBUGG("minor=%d\n", devno); ++ if (devno >= SD_DEVS) { ++ static int count = 0; ++ ++ if (count++ < 5) /* print the message at most five times */ ++ P_DEBUG("request for unknown device\n"); ++ return NULL; ++ } ++#endif ++ dev = sd_devices + devno; ++ P_DEBUGG("card_state=%d\n", dev->card_state); ++ P_DEBUG("<-- %s\n", __func__); ++ return dev; ++} ++ ++int sd_card_check_exist(sd_card_t *info) ++{ ++ /* if card is not exist */ ++ if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) { ++ sd_card_remove(info); ++ return FALSE; ++ } ++ /* if card is not active */ ++ if (!info->ActiveState) ++ { ++ return sd_card_insert(info); ++ } ++ return TRUE; ++} ++#endif ++ ++void sd_reset_host_controller(void) ++{ ++ uint clock, mask, width; ++ ++ /* read register */ ++ clock = SDC_R_REG(SDC_CLOCK_CTRL_REG); ++ width = SDC_R_REG(SDC_BUS_WIDTH_REG); ++ mask = SDC_R_REG(SDC_INT_MASK_REG); ++ /* reset host interface */ ++ sdc_reset(); ++ /* restore register */ ++ SDC_W_REG(SDC_CLOCK_CTRL_REG, clock); ++ SDC_W_REG(SDC_BUS_WIDTH_REG, width); ++ SDC_W_REG(SDC_INT_MASK_REG, mask); ++} ++ ++int sd_read_single_block(sd_card_t *info, uint addr, uint size, uint timeout, unchar *buf) ++{ ++ uint status; ++ ++ if (!sdc_set_block_size(size)) ++ return FALSE; ++ ++ sdc_config_transfer(info, size, size, SDC_DATA_CTRL_REG_DATA_READ, timeout); ++ ++ if (!sdc_send_cmd(SD_READ_SINGLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ ++#ifdef DELAY_FOR_DMA_READ ++ if (first_run==0) { ++ int i=0; ++ for(i=0;i<10;i++) ++ udelay(1000); ++ first_run=1; ++ } ++#endif ++ if (!sdc_read_block(info, size, (uint *) buf)) ++ return FALSE; ++ ++ if (sd_err_code != ERR_NO_ERROR) { ++ printk("%s() error=0x%X\n", __func__, sd_err_code); ++ sd_reset_host_controller(); ++ return FALSE; ++ } else { ++ if (!sdc_check_data_end()) { ++ sd_stop_transmission(); ++ printk("%s()2 error=0x%X\n", __func__, sd_err_code); ++ return FALSE; ++ } ++ } ++ ++ return TRUE; ++} ++ ++int sd_write_single_block(sd_card_t *info, uint addr, uint size, uint timeout, unchar *buf) ++{ ++ uint status; ++ ++ if (!sdc_set_block_size(size)) ++ return FALSE; ++ ++ sdc_config_transfer(info, size, size, SDC_DATA_CTRL_REG_DATA_WRITE, timeout); ++ ++ if (!sdc_send_cmd(SD_WRITE_SINGLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ ++ if (!sdc_write_block(info, size, (uint *) buf)) ++ return FALSE; ++ if (sd_err_code != ERR_NO_ERROR) { ++ printk("%s() error=0x%X\n", __func__, sd_err_code); ++ sd_reset_host_controller(); ++ return FALSE; ++ } else { ++ if (!sdc_check_data_end()) { ++ sd_stop_transmission(); ++ printk("%s()2 error=0x%X\n", __func__, sd_err_code); ++ return FALSE; ++ } ++ } ++ ++ return TRUE; ++} ++ ++int sd_read_multiple_block(sd_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) ++{ ++ uint err, status; ++ ++ if (!sdc_set_block_size(size)) ++ return FALSE; ++ ++ sdc_config_transfer(info, count * size, size, SDC_DATA_CTRL_REG_DATA_READ, timeout); ++ ++ if (!sdc_send_cmd(SD_READ_MULTIPLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++ ++#ifdef DELAY_FOR_DMA_READ ++ if (first_run==0) { ++ int i=0; ++ for(i=0;i<10;i++) ++ udelay(1000); ++ first_run=1; ++ } ++#endif ++#if 0 //ijsung: Sometimes this will cause IRQ lost, and is slower. Use method below ++ while (count > 0) { ++ if (!sdc_read_block(info, size, (uint *) buf)) ++ return FALSE; ++ count--; ++ buf += size; ++ } ++#else //ijsung: DMA at once. ++ if (!sdc_read_block(info, size*count, (uint *) buf)) ++ return FALSE; ++#endif ++ if (sd_err_code != ERR_NO_ERROR) { ++ err = sd_err_code; ++ sd_stop_transmission(); ++ sd_reset_host_controller(); ++ sd_err_code |= err; ++ printk("%s() error=0x%X\n", __func__, sd_err_code); ++ return FALSE; ++ } else { ++ if (!sdc_check_data_end()) { ++ err = sd_err_code; ++ sd_stop_transmission(); ++ sd_err_code |= err; ++ printk("%s()2 error=0x%X\n", __func__, sd_err_code); ++ return FALSE; ++ } ++ if (!sd_stop_transmission()) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++int sd_write_multiple_block(sd_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) ++{ ++ uint ErrorCode, status; ++ ++ if(!sdc_set_block_size(size)) ++ return FALSE; ++ ++ sdc_config_transfer(info, count * size, size, SDC_DATA_CTRL_REG_DATA_WRITE, timeout); ++ sdc_pre_erase_cmd(count); //ijsung: pre-erase ++ if (!sdc_send_cmd(SD_WRITE_MULTIPLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) ++ return FALSE; ++ if (!sd_check_err(status)) ++ return FALSE; ++#if 0 //ijsung: Sometimes this will cause IRQ lost, and is slower. Use method below ++ while (count > 0) { ++ if (!sdc_write_block(info, size, (uint *) buf)) ++ return FALSE; ++ count--; ++ buf += size; ++ } ++#else //ijsung: DMA at once. ++ if (!sdc_write_block(info, size*count, (uint *) buf)) ++ return FALSE; ++#endif ++ ++ if (sd_err_code != ERR_NO_ERROR) ++ { ++ ErrorCode = sd_err_code; ++ sd_stop_transmission(); ++ sd_reset_host_controller(); ++ sd_err_code |= ErrorCode; ++ printk("%s() error=0x%X\n", __func__, sd_err_code); ++ return FALSE; ++ } else { ++ if (!sdc_check_data_end()) { ++ ErrorCode = sd_err_code; ++ sd_stop_transmission(); ++ sd_err_code |= ErrorCode; ++ printk("%s()2 error=0x%X\n", __func__, sd_err_code); ++ return FALSE; ++ } ++ if (!sd_stop_transmission()) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++int sd_wait_transfer_state(sd_card_t *info) ++{ ++ uint state; ++ int count = 0; ++ while (count++ < SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT) { ++ if (!sd_get_card_state(info, &state)) ++ return FALSE; ++ ++ switch (state) { ++ case SD_IDLE_STATE: ++ case SD_READY_STATE: ++ case SD_IDENT_STATE: ++ case SD_DIS_STATE: ++ case SD_STBY_STATE: ++ printk("%s() error\n", __func__); ++ return FALSE; ++ case SD_TRAN_STATE: ++ return TRUE; ++ case SD_DATA_STATE: ++ case SD_RCV_STATE: ++ case SD_PRG_STATE: ++ break; ++ } ++ } ++ sd_err_code = ERR_SD_CARD_IS_BUSY; ++ P_DEBUG("%s() ERR_SD_CARD_IS_BUSY\n", __func__); ++ return FALSE; ++} ++ ++/*************************************************************************** ++SD Card Read/Write/Erase Function ++***************************************************************************/ ++int sd_read_sector(sd_card_t *info, uint addr, uint count, unchar *buf) ++{ ++ int cnt; ++ uint start; ++ sync_mode=1; ++ P_DEBUG("%s : sector = %d,count = %d\n",__func__,addr,count); ++ if (count > MAX_READ_SECTOR_NR) { ++ P_DEBUG("Readable Block Number Per Commands is 0x%X\n",MAX_READ_SECTOR_NR); ++ return FALSE; ++ } ++ ++ sd_err_code = ERR_NO_ERROR; ++ ++ if (!info->ActiveState) { ++ P_DEBUG("%s : SD card not active!!\n", __func__); ++ return FALSE; ++ } ++ ++ if (!sd_set_transfer_state(info)) ++ return FALSE; ++ ++ start = addr * info->CSD.ReadBlockLength; ++ cnt = (int) count; ++ ++ while (cnt > 0) { ++ if (cnt > 1) { ++ if (!sd_read_multiple_block(info, start, (cnt > MAX_MULTI_BLOCK_NUM) ? MAX_MULTI_BLOCK_NUM : cnt, ++ info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)) ++ return FALSE; ++ } else { ++ if (!sd_read_single_block(info, start, info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)) ++ return FALSE; ++ return TRUE; ++ } ++ ++ if (!sd_wait_transfer_state(info)) ++ return FALSE; ++ ++ cnt -= MAX_MULTI_BLOCK_NUM; ++ start += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; ++ buf += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; ++ } ++ ++ return TRUE; ++} ++ ++int sd_write_sector(sd_card_t *info, uint addr, uint count, unchar *buf) ++{ ++ int cnt; ++ uint start; ++ ++ if (count > MAX_WRITE_SECTOR_NR) { ++ P_DEBUG("Writable Block Number Per Commands is 0x%X\n",MAX_WRITE_SECTOR_NR); ++ return FALSE; ++ } ++ ++ sd_err_code = ERR_NO_ERROR; ++ ++ if (!info->ActiveState) { ++ P_DEBUG("%s : SD card not active!!\n", __func__); ++ return FALSE; ++ } ++ ++ if (info->WriteProtect == TRUE) { ++ sd_err_code = ERR_SD_CARD_IS_LOCK; ++ printk("Write Protected!!\n"); ++ return FALSE; ++ } ++ if (!sd_set_transfer_state(info)) ++ return FALSE; ++ ++ start = addr * info->CSD.ReadBlockLength; ++ cnt = (int) count; ++ ++ while (cnt > 0) { ++ if (cnt > 1) { ++ if (!sd_write_multiple_block(info, start, (cnt > MAX_MULTI_BLOCK_NUM) ? MAX_MULTI_BLOCK_NUM : cnt, ++ info->CSD.ReadBlockLength, info->WriteAccessTimoutCycle, buf)) ++ return FALSE; ++ } else { ++ if (!sd_write_single_block(info, start, info->CSD.ReadBlockLength, info->WriteAccessTimoutCycle, buf)) ++ return FALSE; ++ return TRUE; ++ } ++ ++ if (!sd_wait_transfer_state(info)) ++ return FALSE; ++ ++ cnt -= MAX_MULTI_BLOCK_NUM; ++ start += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; ++ buf += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; ++ } ++ ++ return TRUE; ++} ++/*---------------------------------------------- ++ * Perform an actual transfer: ++ * Returns: # of sectors transferred. 0 = error ++ */ ++static int sd_transfer(struct sd_dev *device, const struct request *req) ++{ ++ int status = 0; ++ int count = 0; ++ ++ struct bio *bio = req->bio; ++ struct bio_vec *bvec; ++ struct req_iterator iter; ++ ++ spin_unlock_irq( &device->lock); ++ ++#if 0 ++ P_DEBUG("\nreq sector: %d, nr_sectors: %d, hard_cur_sectors: %d phys_seg: %d, buf: 0x%08lx\n", ++ (int)req->sector, (int)req->nr_sectors, (int)req->hard_cur_sectors, ++ (int)req->nr_phys_segments, (ulong)bio_data( bio)); ++#endif ++ ++ rq_for_each_segment( bvec, req, iter) { ++ ++ unsigned char *buf = page_address( bvec->bv_page) + bvec->bv_offset; ++ int sectors = bio_cur_bytes(bio) >> 9; ++ ++ P_DEBUG("bvec[%2d]: sector: %d, count: %d, curr: %d, buf: 0x%08lx, ", ++ iter.i, (int)bio->bi_sector, count, (int)sectors, (unsigned long)buf); ++ ++ sd_card_info.private = (void *)&device->ch_req; ++ ++ if( rq_data_dir(req) == 0) /* Read */ ++ status = sd_read_sector( &sd_card_info, sector_offset + bio->bi_sector, sectors, buf); ++ else ++ status = sd_write_sector( &sd_card_info, sector_offset + bio->bi_sector, sectors, buf); ++ ++ P_DEBUG("status: %d\n", status); ++ ++ if (status <= 0) { ++ spin_lock_irq( &device->lock); ++ return count; ++ } ++ ++ count += sectors; ++ bio->bi_sector += sectors; ++ } ++ ++ if( ( req->__sector == 0) && !Do_onetime){ ++ ++ unsigned char *buf = bio_data( bio); ++ ++ if( ( buf[ 0x1be] != 0x0) && ( buf[ 0x1be] != 0x80)) /* partition identify */ ++ sector_offset = 0; //sector 0 is PBR ++ else ++ sector_offset = ( buf[ 0x1c6]) | ( buf[ 0x1c7] << 8) | ( buf[ 0x1c8] <<16) |( buf[ 0x1c9] << 24); ++ ++ P_DEBUG( "sector_offset = %d\n", sector_offset); ++ Do_onetime = 1; ++ } ++ ++ spin_lock_irq( &device->lock); ++ ++ if( status <= 0) ++ return 0; ++ else ++ return count; ++} ++ ++#ifdef SD_DEBUG ++uint sd_dev_info(void) ++{ ++ sd_csd_t *CSD; ++ sd_cid_t *CID; ++ ++ P_DEBUG("============SDCard=====================================\n"); ++#if 0 ++ if (!sd_card_check_exist(&sd_card_info)) ++ { ++ P_DEBUG("SD Card does not exist!!!"); ++ return FALSE; ++ } ++#else ++ if (!sd_card_info.ActiveState) { ++ P_DEBUG("%s : SD card not active!!\n", __func__); ++ return FALSE; ++ } ++#endif ++ ++ /* print OCR, RCA register */ ++ P_DEBUG("OCR>> 0x%08X RCA>> 0x%04X\n", (uint) sd_card_info.OCR, sd_card_info.RCA); ++ /* print CID register */ ++ P_DEBUG("CID>> 0x%08X 0x%08X 0x%08X 0x%08X\n", sd_card_info.CIDWord[0], sd_card_info.CIDWord[1], sd_card_info.CIDWord[2], sd_card_info.CIDWord[3]); ++ CID = &(sd_card_info.CID); ++ P_DEBUG(" MID:0x%02X OID:0x%04X PNM:%s PRV:%d.%d PSN:0x%08X\n", CID->ManufacturerID, CID->ApplicationID, CID->ProductName, ++ CID->ProductRevisionHigh, CID->ProductRevisionLow, CID->ProductSerialNumber); ++ P_DEBUG(" MDT:%d/%d\n", CID->ManufactureMonth, CID->ManufactureYear); ++ /* print CSD register */ ++ P_DEBUG("CSD>> 0x%08X 0x%08X 0x%08X 0x%08X\n", sd_card_info.CSDWord[0], sd_card_info.CSDWord[1], sd_card_info.CSDWord[2], sd_card_info.CSDWord[3]); ++ CSD = &(sd_card_info.CSD); ++ P_DEBUG(" CSDStructure:%d Spec.Version:%d\n", CSD->CSDStructure, CSD->MMCSpecVersion); ++ P_DEBUG(" TAAC:%dns NSAC:%d clock cycles\n", CSD->TAAC_u, CSD->NSAC_u); ++ P_DEBUG(" TransferSpeed:%d bit/s CardCommandClass:0x%03X\n", CSD->TransferSpeed, CSD->CardCmdClass); ++ P_DEBUG(" ReadBlLen:%d ReadBlPartial:%X WriteBlkMisalign:%X ReadBlkMisalign:%X\n", CSD->ReadBlockLength, CSD->ReadBlockPartial, CSD->WriteBlockMisalign, CSD->ReadBlockMisalign); ++ P_DEBUG(" DSP:%X BlockNumber:%d MemorySize:%d \n", CSD->DSRImplemant, CSD->BlockNumber, CSD->MemorySize); ++ P_DEBUG(" VDD_R_MIN:%d/10mA VDD_R_MAX:%dmA\n", (uint) CSD->VDDReadMin_u, (uint) CSD->VDDReadMax_u); ++ P_DEBUG(" VDD_W_MIN:%d/10mA VDD_W_MAX:%dmA\n", (uint) CSD->VDDWriteMin_u, (uint) CSD->VDDWriteMax_u); ++ P_DEBUG(" EraseBlkEnable:%d EraseSectorSize:%d WpGrpSize:%d WpGrpEnable:%X\n", CSD->EraseBlkEnable, CSD->EraseSectorSize, CSD->WriteProtectGroupSize, CSD->WriteProtectGroupEnable); ++ P_DEBUG(" WriteSpeedFactor:%d WriteBlLen:%d WriteBlPartial:%X\n", CSD->WriteSpeedFactor, CSD->WriteBlockLength, CSD->WriteBlockPartial); ++ P_DEBUG(" Copy:%X PermWrProtect:%X TmpWrProtect:%X FileFormat:%X\n", CSD->CopyFlag, CSD->PermanentWriteProtect, CSD->TemporaryWriteProtect, CSD->FileFormat); ++ P_DEBUG(" ReadTimoutCycle:0x%08X WriteTimoutCycle:0x%08X\n", sd_card_info.ReadAccessTimoutCycle, sd_card_info.WriteAccessTimoutCycle); ++ /* print SCR register */ ++ P_DEBUG("SCR>> 0x%08X 0x%08X \n", *(((uint *) &sd_card_info.SCR)), *(((uint *) &sd_card_info.SCR) + 1)); ++ P_DEBUG(" SCR_STRUCTURE:%d, SD_SPEC:%d, Data_status_after_erase:%d\n", sd_card_info.SCR.SCR_STRUCTURE, sd_card_info.SCR.SD_SPEC, sd_card_info.SCR.DATA_STAT_AFTER_ERASE); ++ P_DEBUG(" sd_security:%d, SD_BUS_WIDTH:%X\n", sd_card_info.SCR.SD_SECURITY, sd_card_info.SCR.SD_BUS_WIDTH); ++ ++ return TRUE; ++} ++#endif ++ ++static int sd_card_setup(struct sd_dev *dev) ++{ ++ uint sd_card_size; ++ int i; ++ ++ P_DEBUG("--> %s\n", __func__); ++ first_run = 0; ++ sd_err_code = ERR_NO_ERROR; ++ ++ sd_card_info.ActiveState = FALSE; ++ sd_card_info.WriteProtect = FALSE; ++ sd_card_info.IOAddr = FTSDC_VA_BASE; ++ sd_card_info.DMAEnable = FALSE; ++ ++ sd_card_info.SysFrequency = AHB_CLK_IN/2; ++ P_DEBUG("DMA Enable is %d, Sys frequency = %d\n", sd_card_info.DMAEnable, sd_card_info.SysFrequency); ++ sd_card_info.RCA = 0; ++ sd_card_info.Drive = 'S'; ++ ++ if (!sd_card_insert(&sd_card_info)) ++ return FALSE; ++#ifdef SD_DEBUG ++ if (!sd_dev_info()) ++ return FALSE; ++#endif ++ sd_card_size = sd_card_info.CSD.MemorySize; ++ printk(KERN_NOTICE "FTSDC010: SD Card Capacity=%d MB\n", sd_card_size/1000000); /* Marketing MB is not 1048576 */ ++ ++ for (i = 0; i < SD_DEVS; i++) { ++ sd_devices[i].size = sd_card_size / SD_SECTOR_SIZE; //unit is block, not bytes ++ ++#if 0 ++ sd_partitions[i << SD_SHIFT].nr_sects =sd_size * (SD_BLKSIZE / SD_SECTOR_SIZE); ++ P_DEBUG ("%s() %d-th device, size=%d blks(blks=%d),nr_sects=%ld\n", __func__, i, sd_size, SD_BLKSIZE, sd_partitions[i << SD_SHIFT].nr_sects); ++#endif ++ //sd_devices[i].card_state = SD_CARD_WORK; ++ //sema_init(&(sd_devices[i].sema), 1); // add by Charles Tsai*/ ++ } ++ ++ sd_card_info.DMAEnable = dev->dma_enable; ++ ++ P_DEBUG("<-- %s\n", __func__); ++ return TRUE; ++} ++ ++/* ++ * Driver stuff ++ */ ++/*------------------------------------ ++ * The ioctl implementation ++ */ ++int sd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) ++{ ++ int size; ++ struct hd_geometry geo; ++ struct sd_dev *device=bdev->bd_disk->private_data; ++ P_DEBUG ("ioctl 0x%x 0x%lx\n", cmd, arg); ++ switch (cmd) { ++ case BLKGETSIZE: ++ /* Return the device size, expressed in sectors */ ++ /* FIXME: distinguish between kernel sector size and media sector size */ ++ size = device->size; ++ __copy_to_user ((long *) arg, &size, sizeof (long)); ++ return 0; ++#if 0 ++ case BLKFLSBUF: /* flush */ ++ return blk_ioctl(inode->i_rdev, cmd, arg); ++ case BLKRAGET: /* return the readahead value */ ++ return blk_ioctl(inode->i_rdev, cmd, arg); ++ case BLKRASET: /* set the readahead value */ ++ if (!capable (CAP_SYS_RAWIO)) ++ return -EACCES; ++ if (arg > 0xff) ++ return -EINVAL; /* limit it */ ++ return 0; ++// case BLKRRPART: /* re-read partition table */ ++// return sd_revalidate (inode->i_rdev); ++#endif ++ case HDIO_GETGEO: ++ /* ++ * get geometry: we have to fake one... trim the size to a ++ * multiple of 64 (32k): tell we have 16 sectors, 4 heads, ++ * whatever cylinders. Tell also that data starts at sector. 4. ++ */ ++ geo.cylinders = (device->size/4)/8; /* ?? only for test */ ++ geo.heads = 4; ++ geo.sectors = 8; ++ geo.start = 0; ++ __copy_to_user ((void *) arg, &geo, sizeof (geo)); ++ return 0; ++ default: ++ /* ++ * For ioctls we don't understand, let the block layer handle them. ++ */ ++ return -ENOTTY;//blk_ioctl (inode->i_rdev, cmd, arg); ++ } ++ ++ return -ENOTTY; /* unknown command */ ++} ++ ++static void sd_request(struct request_queue *q) ++{ ++ struct sd_dev *dev; ++ static int active; ++#ifndef A320_SD_USE_ASYNC_DMA ++ int ret; ++ struct request *req; ++#else ++ if(bh_busy) ++ return; ++#endif ++ if(active) ++ return; ++ active = 1; ++ P_DEBUG("--> %s\n", __func__); ++repeat: ++ /* Locate the device */ ++ if((req=blk_fetch_request(q))==NULL) { ++ active = 0; ++ return; ++ } ++ dev = req->rq_disk->private_data; ++ if (!dev||dev->card_state == SD_CARD_REMOVE) { ++ if(!dev) ++ printk(KERN_NOTICE"SD: locating device error\n"); ++ __blk_end_request_cur(req, -EIO); ++ goto repeat; ++ } ++#ifndef A320_SD_USE_ASYNC_DMA ++ sync_mode=1; ++ //spin_unlock_irq(&io_request_lock); ++ ret = sd_transfer(dev, req); ++ __blk_end_request(req, 0, ret << 9); ++ //spin_lock_irq(&io_request_lock); ++ goto repeat; ++ ++#else ++ sync_mode=0; //Use new async DMA machanism ++ //printk("%s: set up initial DMA, from sector %d to buffer 0x%X\n", __func__, CURRENT->sector+sector_offset, CURRENT->buffer); ++ //sd_init_async_dma(); ++ sd_clustered_bh(1); ++ //bh_busy=1; ++#endif ++ P_DEBUG("<-- %s\n", __func__); ++} ++ ++#if 0 ++/*----------------------------------------- ++ * Support for removable devices ++ */ ++int sd_check_change(kdev_t i_rdev) ++{ ++ int minor = DEVICE_NR(i_rdev); ++ struct sd_dev *dev = sd_devices + minor; ++ ++ P_DEBUG("--> %s\n", __func__); ++ P_DEBUG("minor=%d\n", minor); ++ if (minor >= SD_DEVS) /* paranoid */ ++ return 0; ++ P_DEBUG("check change for dev %d\n", minor); ++ if (dev->usage) { ++ P_DEBUG("disk not change\n"); ++ P_DEBUG("<-- %s\n", __func__); ++ return 0; /* still valid */ ++ } ++ P_DEBUG("disk changed\n"); ++ P_DEBUG("<-- %s\n", __func__); ++ return 1; /* expired */ ++} ++#endif ++ ++static int sd_dma_ch_alloc(struct sd_dev *dev) ++{ ++ dmad_chreq *ch_req = &dev->ch_req; ++ ++ memset(ch_req, 0, sizeof(dmad_chreq)); ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++ ch_req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */ ++/* for amerald */ ++ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID){ ++ ch_req->apb_req.addr0_reqn = APBBR_REQN_SDC_AMERALD; ++ }else ++ ch_req->apb_req.addr0_reqn = APBBR_REQN_SDC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ ++ ch_req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */ ++ ch_req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ ++ ch_req->apb_req.burst_mode = 1; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */ ++ ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */ ++ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ ++ ++ ch_req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ ++ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ memset(ch_req, 0, sizeof(dmad_chreq)); ++ printk(KERN_INFO "%s: APB dma channel allocation failed\n", __func__); ++ goto _try_ahb; ++ } ++ ++ P_DEBUG("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); ++ //printk("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); ++ ++ return 0; ++ ++_try_ahb: ++ ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ ++ ch_req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */ ++ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */ ++ ch_req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */ ++ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */ ++ ch_req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ ++ ch_req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ ++ ch_req->ahb_req.addr0_reqn = DMAC_REQN_SDC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ ++ ch_req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ ++ ch_req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ ++ ch_req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ ++ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ ++ ++ ch_req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ ++ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ memset(ch_req, 0, sizeof(dmad_chreq)); ++ printk(KERN_INFO "%s: AHB dma channel allocation failed\n", __func__); ++ goto _err_exit; ++ } ++ ++ P_DEBUG("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); ++ //printk("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); ++ ++ return 0; ++ ++_err_exit: ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++ return -ENODEV; ++} ++ ++/*-------------------------------- ++ * Note no locks taken out here. In a worst case scenario, we could drop ++ * a chunk of system memory. But that should never happen, since validation ++ * happens at open or mount time, when locks are held. ++ */ ++static int sd_revalidate(struct gendisk *gd) ++{ ++ struct sd_dev *dev = gd->private_data; ++ ++ P_DEBUG("--> %s\n", __func__); ++ P_DEBUG("card state=%s\n", dev->card_state == SD_CARD_INSERT ? "INSERT" : dev->card_state == SD_CARD_WORK ? "WORK" : "REMOVE"); ++ ++ if (dev->usage == 0) { ++ if (sd_card_setup(dev) != TRUE) { ++ dev->card_state = SD_CARD_REMOVE; ++ return -1; ++ } else { ++ enable_irq(FTSDC_IRQ); ++ dev->card_state = SD_CARD_WORK; ++ } ++ } ++ P_DEBUG("<-- %s\n", __func__); ++ ++ return 0; ++} ++ ++/* ++ * Device open and close ++ * TODO: forbids open for write when WRITE_PROTECT=1 ++ */ ++int sd_open(struct block_device *bdev, fmode_t mode) ++{ ++ struct sd_dev *dev= bdev->bd_disk->private_data; /* device information */ ++ P_DEBUG("--> %s\n", __func__); ++ /* Early return if there's nothing in the card slot */ ++ if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) { ++ P_DEBUG("<-- %s (ENOMEDIUM)\n", __func__); ++ return -ENOMEDIUM; ++ } ++ //spin_lock(&dev->lock); ++ if (!dev->usage) { ++ dev->media_change=1; ++ P_DEBUG("%s: forced check_disk_change check\n", __func__); ++ check_disk_change(bdev); ++ sector_offset=0; ++ Do_onetime=0; ++ } else ++ dev->media_change=0; ++ ++ /* Set size HERE: ++ * must rely on sd_revalidate to set correct size ++ * (seems on check_disk_change()) */ ++ P_DEBUG("%s: set_capacity() to %d blocks (%d bytes)\n",__func__, dev->size, dev->size*SD_SECTOR_SIZE); ++ set_capacity(dev->gd, dev->size); ++ dev->usage++; ++ P_DEBUG("<-- %s\n", __func__); ++ ++ return 0; /* success */ ++} ++ ++int sd_release(struct gendisk *gd, fmode_t mode) ++{ ++ struct sd_dev *dev = gd->private_data; ++ ++ disable_irq(FTSDC_IRQ); ++ printk(" + sd_release : umount SD\n"); ++ ++ P_DEBUG("--> %s\n", __func__); ++ dev->usage--; ++ P_DEBUG("<-- %s\n", __func__); ++ ++ return 0; ++} ++ ++/*-------------------------------------- ++ * The file operations ++ */ ++struct block_device_operations sd_fops = { ++ owner: THIS_MODULE, ++ open: sd_open, ++ release: sd_release, ++ ioctl: sd_ioctl, ++ revalidate_disk: sd_revalidate, ++ media_changed: sd_media_changed, ++}; ++ ++void init_sd_pmu(void) ++{ ++ ++#ifdef CONFIG_FIE8100_PLATFORM ++ unsigned int u32temp; ++ u32temp = *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x14); ++ u32temp &= ~0x3000; ++ u32temp |= 0x2000; ++ *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x14)=u32temp; ++#endif ++ ++#ifdef CONFIG_FIE7000_PLATFORM ++ *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x114) = (*(volatile unsigned int *)(A320_PMU_VA_BASE + 0x114) & 0xFFFF0FFF) | 0x00002000; ++#endif ++} ++ ++/* ++ * Set up our internal device. ++ */ ++static int setup_device(struct sd_dev *dev) ++{ ++ /* ++ * Get some memory. ++ */ ++ memset (dev, 0, sizeof (struct sd_dev)); ++ dev->size = 0;//SD_DUMMY_SIZE/SD_SECTOR_SIZE; /* We'll fill this with correct size later*/ ++ spin_lock_init(&dev->lock); ++ /* Request Queue */ ++ dev->queue = blk_init_queue(sd_request, &dev->lock); ++ if (dev->queue == NULL) ++ return -EFAULT; ++ ++ blk_queue_logical_block_size(dev->queue, hardsect_size); ++ dev->queue->queuedata = dev; ++ ++ dev->card_state = SD_CARD_REMOVE; ++ ++ /* ++ * And the gendisk structure. ++ */ ++ dev->gd = alloc_disk(SD_MINORS); ++ if (! dev->gd) { ++ printk (KERN_NOTICE "alloc_disk failure\n"); ++ return -EFAULT; ++ } ++ ++ dev->gd->flags = GENHD_FL_REMOVABLE|GENHD_FL_SUPPRESS_PARTITION_INFO; ++ dev->gd->major = sd_major; ++ dev->gd->first_minor = 0; ++ dev->gd->minors = SD_MINORS; ++ dev->gd->fops = &sd_fops; ++ dev->gd->queue = dev->queue; ++ dev->gd->private_data = dev; ++ snprintf (dev->gd->disk_name, 32, "cpesd%c", 'a'); ++ set_capacity(dev->gd, 0); //SD_DUMMY_SIZE/SD_SECTOR_SIZE*(hardsect_size/KERNEL_SECTOR_SIZE)); ++ add_disk(dev->gd); ++ ++ /* ++ * dma alloc ++ */ ++ if (sd_dma_ch_alloc(dev) == 0) { ++ printk(KERN_NOTICE "Faraday SD controller Driver (DMA mode)\n"); ++ dev->dma_enable = true; ++ } else { ++ printk(KERN_NOTICE "Faraday SD controller Driver (PIO mode)\n"); ++ } ++ ++ return 0; ++} ++/* ++ * Look for a media change. ++ */ ++static int sd_media_changed(struct gendisk *gd) ++{ ++ struct sd_dev *dev = gd->private_data; ++ return dev->media_change; ++} ++ ++/* ++ * module stuff ++ */ ++static int __init sd_module_init(void) ++{ ++ int result=-ENOMEM; ++ spinlock_t complete_lock; ++ unsigned long iflags; ++ spin_lock_init(&complete_lock); ++ ++#ifdef CONFIG_PLAT_QEMU ++ SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(0x44) & 0xff; ++#else ++ if(SDC_R_REG(0xa0) == 0x00030101) ++ SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(0x9c) & 0xff; ++ else ++ SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(SDC_FEATURE_REG) & 0xff; ++#endif ++ /* Register SD driver */ ++ sd_major = register_blkdev(sd_major, DEVICE_NAME); ++ if (sd_major <= 0) { ++ printk(KERN_WARNING DEVICE_NAME ":unable to get major number\n"); ++ return -EBUSY; ++ } ++ init_sd_pmu(); /* Power on SDC */ ++ P_DEBUG("SD Major Number = %d\n", sd_major); ++ printk(KERN_ALERT "SD: make node with 'mknod /dev/cpesd b %d 0'\n", sd_major); ++ ++ sd_devices = kmalloc(sizeof(struct sd_dev), GFP_KERNEL); ++ if (!sd_devices) ++ goto fail_malloc; ++ memset(sd_devices, 0, sizeof(struct sd_dev)); ++ ++ if (setup_device(sd_devices)) ++ goto fail_malloc; ++ ++ P_DEBUG("Request SDC IRQ=%d\n", FTSDC_IRQ); ++ spin_lock_irqsave(&complete_lock, iflags); ++ if (request_irq(FTSDC_IRQ, sd_hotswap_interrupt_handler, IRQF_DISABLED, "SD controller", sd_devices) != 0) { ++ printk(KERN_ERR "Unable to allocate SDC IRQ=0x%X\n", FTSDC_IRQ); ++ goto fail_malloc; ++ } ++ disable_irq(FTSDC_IRQ); ++ spin_unlock_irqrestore(&complete_lock, iflags); ++ if (request_region(FTSDC_VA_BASE, 0x48, "SD Controller") == NULL) { ++ printk(KERN_ERR "request io port of sd controller fail\n"); ++ goto fail_mem; ++ } ++ ++ return 0; /* succeed */ ++ ++fail_mem: ++ free_irq(FTSDC_IRQ, sd_devices); ++ ++fail_malloc: ++ if (sd_devices) ++ kfree(sd_devices); ++ unregister_blkdev(sd_major, DEVICE_NAME); ++ return result; ++} ++ ++static void sd_module_cleanup(void) ++{ ++ P_DEBUG("--> %s\n", __func__); ++ ++ /* unregister the device now to avoid further operations during cleanup */ ++ ++ if (sd_devices) { ++ del_gendisk(sd_devices->gd); ++ put_disk(sd_devices->gd); ++ if(sd_devices->queue) ++ blk_cleanup_queue(sd_devices->queue); ++ ++ if (sd_devices->dma_enable) ++ dmad_channel_free(&sd_devices->ch_req); ++ ++ kfree(sd_devices); ++ } ++ ++ release_region(FTSDC_VA_BASE, 0x48); ++ free_irq(FTSDC_IRQ, sd_devices); ++ ++ unregister_blkdev(sd_major, DEVICE_NAME); ++ P_DEBUG("<-- %s\n", __func__); ++} ++ ++module_init(sd_module_init); ++module_exit(sd_module_cleanup); +diff -Nur linux-3.4.110.orig/drivers/block/ftsdc010.h linux-3.4.110/drivers/block/ftsdc010.h +--- linux-3.4.110.orig/drivers/block/ftsdc010.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/block/ftsdc010.h 2016-04-07 10:20:51.022084119 +0200 +@@ -0,0 +1,477 @@ ++/* drivers/block/CPESD/ftsdc010.h ++ * ++ * Faraday FTSDC010 Device Driver ++ * ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * All Rights Reserved ++ */ ++ ++#ifndef _FTSDC010_H_ ++#define _FTSDC010_H_ ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++//#define SD_DEBUG ++#define DELAY_FOR_DMA_READ ++ ++#ifdef SD_DEBUG ++ #define P_DEBUG(fmt, args...) printk(KERN_ALERT "SD: " fmt, ## args) ++#else ++ #define P_DEBUG(a...) ++#endif ++#define P_DEBUGG(a...) ++ ++#define MAX_READ_SECTOR_NR 96 //16 ++#define MAX_WRITE_SECTOR_NR MAX_READ_SECTOR_NR ++ ++#define SD_MAJOR 6 /* default major number, if zero, it means dynamic allocate */ ++#define SD_DEVS 1 /* number of disks */ ++#define SD_MINORS 16 /* minors per disk */ ++#define SD_RAHEAD 2 /* number of sectors */ ++#define SD_BLKSIZE 1024 /* block size */ ++#define SD_SECTOR_SIZE 512 /* sector size */ ++#define SD_DUMMY_SIZE (256*1024*1024) // for sake of hotswap/hotplug ++#if 0 ++typedef struct _sd_dev_t { ++ int size; ++ int usage; ++ //struct timer_list timer; ++ spinlock_t lock; ++ struct semaphore sema; // synchronization ++ int card_state; ++} sd_dev_t; ++#endif ++//---------SD Card State ++#define SD_CARD_REMOVE 0 ++#define SD_CARD_INSERT 1 ++#define SD_CARD_WORK 2 ++ ++/* so far, SD controller support 3.2-3.3 VDD */ ++#define SDC_OCR 0x00FF8000 ++ ++/* sd controller register */ ++#define SDC_CMD_REG 0x00000000 ++#define SDC_ARGU_REG 0x00000004 ++#define SDC_RESPONSE0_REG 0x00000008 ++#define SDC_RESPONSE1_REG 0x0000000C ++#define SDC_RESPONSE2_REG 0x00000010 ++#define SDC_RESPONSE3_REG 0x00000014 ++#define SDC_RSP_CMD_REG 0x00000018 ++#define SDC_DATA_CTRL_REG 0x0000001C ++#define SDC_DATA_TIMER_REG 0x00000020 ++#define SDC_DATA_LEN_REG 0x00000024 ++#define SDC_STATUS_REG 0x00000028 ++#define SDC_CLEAR_REG 0x0000002C ++#define SDC_INT_MASK_REG 0x00000030 ++#define SDC_POWER_CTRL_REG 0x00000034 ++#define SDC_CLOCK_CTRL_REG 0x00000038 ++#define SDC_BUS_WIDTH_REG 0x0000003C ++#define SDC_DATA_WINDOW_REG 0x00000040 ++#ifdef A320D_BUILDIN_SDC ++#define SDC_FEATURE_REG 0x00000044 ++#define SDC_REVISION_REG 0x00000048 ++#else ++#define SDC_MMC_INT_RSP_REG 0x00000044 ++#define SDC_GP_OUTPUT_REG 0x00000048 ++#define SDC_FEATURE_REG 0x0000009C ++#define SDC_REVISION_REG 0x000000A0 ++#endif ++ ++/* bit mapping of command register */ ++#define SDC_CMD_REG_INDEX 0x0000003F ++#define SDC_CMD_REG_NEED_RSP 0x00000040 ++#define SDC_CMD_REG_LONG_RSP 0x00000080 ++#define SDC_CMD_REG_APP_CMD 0x00000100 ++#define SDC_CMD_REG_CMD_EN 0x00000200 ++#define SDC_CMD_REG_SDC_RST 0x00000400 ++ ++/* bit mapping of response command register */ ++#define SDC_RSP_CMD_REG_INDEX 0x0000003F ++#define SDC_RSP_CMD_REG_APP 0x00000040 ++ ++/* bit mapping of data control register */ ++#define SDC_DATA_CTRL_REG_BLK_SIZE 0x0000000F ++#define SDC_DATA_CTRL_REG_DATA_WRITE 0x00000010 ++#define SDC_DATA_CTRL_REG_DATA_READ 0x00000000 ++#define SDC_DATA_CTRL_REG_DMA_EN 0x00000020 ++#define SDC_DATA_CTRL_REG_DATA_EN 0x00000040 ++ ++#define SDC_DMA_TYPE_1 0x00000000 ++#define SDC_DMA_TYPE_4 0x00000100 ++#define SDC_DMA_TYPE_8 0x00000200 ++ ++/* bit mapping of status/clear/mask register */ ++#define SDC_STATUS_REG_RSP_CRC_FAIL 0x00000001 ++#define SDC_STATUS_REG_DATA_CRC_FAIL 0x00000002 ++#define SDC_STATUS_REG_RSP_TIMEOUT 0x00000004 ++#define SDC_STATUS_REG_DATA_TIMEOUT 0x00000008 ++#define SDC_STATUS_REG_RSP_CRC_OK 0x00000010 ++#define SDC_STATUS_REG_DATA_CRC_OK 0x00000020 ++#define SDC_STATUS_REG_CMD_SEND 0x00000040 ++#define SDC_STATUS_REG_DATA_END 0x00000080 ++#define SDC_STATUS_REG_FIFO_UNDERRUN 0x00000100 ++#define SDC_STATUS_REG_FIFO_OVERRUN 0x00000200 ++#define SDC_STATUS_REG_CARD_CHANGE 0x00000400 ++#define SDC_STATUS_REG_CARD_INSERT 0x00000800 ++#define SDC_STATUS_REG_CARD_LOCK 0x00001000 ++ ++#define SDC_CARD_INSERT 0x0 ++#define SDC_CARD_REMOVE SDC_STATUS_REG_CARD_INSERT ++ ++/* bit mapping of power control register */ ++#define SDC_POWER_REG_POWER_ON 0x00000010 ++#define SDC_POWER_REG_POWER_BITS 0x0000000F ++ ++/* bit mapping of clock control register */ ++#define SDC_CLOCK_REG_CARD_TYPE 0x00000080 ++#define SDC_CLOCK_REG_CLK_DIV 0x0000007F ++ ++/* card type */ ++#define SDC_CARD_TYPE_SD SDC_CLOCK_REG_CARD_TYPE ++#define SDC_CARD_TYPE_MMC 0x0 ++ ++/* bit mapping of bus width register */ ++#define SDC_BUS_WIDTH_REG_SINGLE_BUS 0x00000001 ++#define SDC_BUS_WIDTH_REG_WIDE_BUS 0x00000004 ++#define SDC_WIDE_BUS_SUPPORT 0x00000008 ++ ++/* data window register */ ++//#define SDC_READ_FIFO_LEN 4 ++//#define SDC_WRITE_FIFO_LEN 4 ++ ++/* card type, sd or mmc */ ++#define MEMORY_CARD_TYPE_SD 0 ++#define MEMORY_CARD_TYPE_MMC 1 ++ ++/********************************************************************/ ++/* SYSTEM ERROR_CODE */ ++/********************************************************************/ ++#define ERR_NO_ERROR 0x00000000 ++ ++/* general error */ ++#define ERR_CARD_NOT_EXIST 0x00000001 ++#define ERR_OUT_OF_VOLF_RANGE 0x00000002 ++#define ERR_SD_PARTITIAL_READ_ERROR 0x00000004 ++#define ERR_SD_PARTITIAL_WRITE_ERROR 0x00000008 ++ ++#define ERR_SD_CARD_IS_LOCK 0x00000010 ++ ++/* command error */ ++#define ERR_DATA_CRC_ERROR 0x00000100 ++#define ERR_RSP_CRC_ERROR 0x00000200 ++#define ERR_DATA_TIMEOUT_ERROR 0x00000400 ++#define ERR_RSP_TIMEOUT_ERROR 0x00000800 ++ ++#define ERR_WAIT_OVERRUN_TIMEOUT 0x00001000 ++#define ERR_WAIT_UNDERRUN_TIMEOUT 0x00002000 ++#define ERR_WAIT_DATA_CRC_TIMEOUT 0x00004000 ++#define ERR_WAIT_TRANSFER_END_TIMEOUT 0x00008000 ++ ++#define ERR_SEND_COMMAND_TIMEOUT 0x00010000 ++ ++/* sd error */ ++#define ERR_SD_CARD_IS_BUSY 0x00100000 ++#define ERR_CID_REGISTER_ERROR 0x00200000 ++#define ERR_CSD_REGISTER_ERROR 0x00400000 ++ ++/* sd card status error */ ++#define ERR_SD_CARD_STATUS_ERROR 0x01000000 ++/* SDC using APB DMA error */ ++#define ERR_DMA_RSP_ERROR 0x02000000 ++ ++#define SD_SCR_1_BIT_BIT 0x0001 ++#define SD_SCR_4_BIT_BIT 0x0004 ++ ++/********************************************************************/ ++/* The bit mapping of SD Status register */ ++/********************************************************************/ ++#define SD_STATUS_OUT_OF_RANGE 0x80000000 ++#define SD_STATUS_ADDRESS_ERROR 0x40000000 ++#define SD_STATUS_BLOCK_LEN_ERROR 0x20000000 ++#define SD_STATUS_ERASE_SEQ_ERROR 0x10000000 ++#define SD_STATUS_ERASE_PARAM 0x08000000 ++#define SD_STATUS_WP_VIOLATION 0x04000000 ++#define SD_STATUS_CARD_IS_LOCK 0x02000000 ++#define SD_STATUS_LOCK_UNLOCK_FILED 0x01000000 ++#define SD_STATUS_COM_CRC_ERROR 0x00800000 ++#define SD_STATUS_ILLEGAL_COMMAND 0x00400000 ++#define SD_STATUS_CARD_ECC_FAILED 0x00200000 ++#define SD_STATUS_CC_ERROR 0x00100000 ++#define SD_STATUS_ERROR 0x00080000 ++#define SD_STATUS_UNDERRUN 0x00040000 ++#define SD_STATUS_OVERRUN 0x00020000 ++#define SD_STATUS_CID_CSD_OVERWRITE 0x00010000 ++#define SD_STATUS_WP_ERASE_SKIP 0x00008000 ++#define SD_STATUS_CARD_ECC_DISABLE 0x00004000 ++#define SD_STATUS_ERASE_RESET 0x00002000 ++#define SD_STATUS_CURRENT_STATE 0x00001E00 ++#define SD_STATUS_READY_FOR_DATA 0x00000100 ++#define SD_STATUS_APP_CMD 0x00000020 ++#define SD_STATUS_AKE_SEQ_ERROR 0x00000008 ++#define SD_STATUS_ERROR_BITS (SD_STATUS_ADDRESS_ERROR | SD_STATUS_BLOCK_LEN_ERROR | SD_STATUS_ERASE_SEQ_ERROR | SD_STATUS_ERASE_PARAM | SD_STATUS_WP_VIOLATION | SD_STATUS_LOCK_UNLOCK_FILED | SD_STATUS_CARD_ECC_FAILED | SD_STATUS_CC_ERROR | SD_STATUS_ERROR | SD_STATUS_UNDERRUN | SD_STATUS_OVERRUN | SD_STATUS_CID_CSD_OVERWRITE | SD_STATUS_WP_ERASE_SKIP | SD_STATUS_AKE_SEQ_ERROR) ++#define SD_STATUS_CURRENT_STATE_LOC 9 ++ ++/********************************************************************/ ++/* SD command response type */ ++/********************************************************************/ ++#define SD_NO_RESPONSE 0 ++#define SD_RESPONSE_R1 1 ++#define SD_RESPONSE_R1b 2 ++#define SD_RESPONSE_R2 3 ++#define SD_RESPONSE_R3 4 ++#define SD_RESPONSE_R6 5 ++ ++/********************************************************************/ ++/* SD command */ ++/********************************************************************/ ++#define SD_GO_IDLE_STATE_CMD 0 ++#define SD_MMC_OP_COND 1 ++#define SD_ALL_SEND_CID_CMD 2 ++#define SD_SEND_RELATIVE_ADDR_CMD 3 ++#define SD_SET_DSR_CMD 4 ++#define SD_SET_BUS_WIDTH_CMD 6 ++#define SD_SELECT_CARD_CMD 7 ++#define SD_SEND_CSD_CMD 9 ++#define SD_SEND_CID_CMD 10 ++#define SD_STOP_TRANSMISSION_CMD 12 ++#define SD_SEND_STATUS_CMD 13 ++#define SD_GO_INACTIVE_STATE_CMD 15 ++#define SD_SET_BLOCKLEN_CMD 16 ++#define SD_READ_SINGLE_BLOCK_CMD 17 ++#define SD_READ_MULTIPLE_BLOCK_CMD 18 ++#define SD_WRITE_SINGLE_BLOCK_CMD 24 ++#define SD_WRITE_MULTIPLE_BLOCK_CMD 25 ++#define SD_PROGRAM_CSD_CMD 27 ++#define SD_ERASE_SECTOR_START_CMD 32 ++#define SD_ERASE_SECTOR_END_CMD 33 ++#define SD_ERASE_CMD 38 ++#define SD_APP_OP_COND 41 ++#define SD_LOCK_UNLOCK_CMD 42 ++#define SD_SEND_SCR_CMD 51 ++#define SD_APP_CMD 55 ++#define SD_GET_CMD 56 ++ ++/* retry count */ ++#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY ++#define SD_CARD_GET_OCR_RETRY_COUNT 0x1000 ++#define SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT 8000 ++#define SD_CARD_STATE_CHANGE_RETRY_COUNT 30000 ++#define SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT 30000 ++#define SDC_GET_STATUS_RETRY_COUNT 0x300000 ++#else ++#define SD_CARD_GET_OCR_RETRY_COUNT 0x1000 ++#define SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT 8000 ++#define SD_CARD_STATE_CHANGE_RETRY_COUNT 10000 ++#define SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT 10000 ++#endif ++ ++/* ++ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting ++ */ ++#ifdef SD_DEBUG ++#define SDC_TIMEOUT_BASE (HZ/2) // Unit is 500 ms ++#else ++#define SDC_TIMEOUT_BASE (HZ/3) // Unit is 333 ms ++#endif ++#define SDC_GET_STATUS_RETRY_TIMEOUT_COUNT (HZ*4) ++ ++/* sd card standby state */ ++#define SD_IDLE_STATE 0 ++#define SD_READY_STATE 1 ++#define SD_IDENT_STATE 2 ++#define SD_STBY_STATE 3 ++#define SD_TRAN_STATE 4 ++#define SD_DATA_STATE 5 ++#define SD_RCV_STATE 6 ++#define SD_PRG_STATE 7 ++#define SD_DIS_STATE 8 ++ ++#define SD_BUS_WIDTH_1_BIT 0 ++#define SD_BUS_WIDTH_4_BIT 2 ++ ++/********************************************************************/ ++/* SD card OCR register */ ++/********************************************************************/ ++#define SD_OCR_BUSY_BIT 0x80000000 ++ ++/********************************************************************/ ++/* SD CID register */ ++/********************************************************************/ ++#define SD_DEFAULT_MONTH_CODE 1 ++#define SD_DEFAULT_YEAR_CODE 2000 ++#define MAX_MULTI_BLOCK_NUM 126 ++ ++typedef struct _sd_cid_t ++{ ++ uint ManufacturerID; ++ uint ApplicationID; ++ unchar ProductName[7]; ++ uint ProductRevisionHigh; ++ uint ProductRevisionLow; ++ uint ProductSerialNumber; ++ uint ManufactureMonth; ++ uint ManufactureYear; ++} sd_cid_t; ++ ++/********************************************************************/ ++/* SD CSD register */ ++/********************************************************************/ ++#define SD_CSD_STRUCTURE_1_0 0 ++#define SD_CSD_STRUCTURE_1_1 1 ++ ++#define SD_CSD_SPEC_VERS_1_0_1_2 0 ++#define SD_CSD_SPEC_VERS_1_4 1 ++#define SD_CSD_SPEC_VERS_2_1 2 ++ ++#define SD_TAAC_TIME_UINT_BITS 0x07 ++#define SD_TAAC_TIME_VALUE_BITS 0x78 ++ ++typedef struct _sd_csd_t ++{ ++ uint CSDStructure; ++ uint MMCSpecVersion; ++ uint TAAC_u; ++ uint NSAC_u; ++ uint TransferSpeed; ++ uint CardCmdClass; ++ uint ReadBlockLength; ++ uint ReadBlockPartial; ++ uint WriteBlockMisalign; ++ uint ReadBlockMisalign; ++ uint DSRImplemant; ++ uint BlockNumber; ++ uint MemorySize; ++ uint VDDReadMin_u; ++ uint VDDReadMax_u; ++ uint VDDWriteMin_u; ++ uint VDDWriteMax_u; ++ uint EraseBlkEnable; ++ uint EraseSectorSize; ++ uint WriteProtectGroupSize; ++ uint WriteProtectGroupEnable; ++ uint WriteSpeedFactor; ++ uint WriteBlockLength; ++ unchar WriteBlockPartial; ++ unchar CopyFlag; ++ unchar PermanentWriteProtect; ++ unchar TemporaryWriteProtect; ++ unchar FileFormat; ++} sd_csd_t; ++ ++typedef struct _sd_csd_bit_t ++{ ++ uint NotUsed:1; ++ uint CRC:7; ++ uint MMCardReserved1:2; ++ uint FILE_FORMAT:2; ++ uint TMP_WRITE_PROTECT:1; ++ uint PERM_WRITE_PROTECT:1; ++ uint COPY:1; ++ uint FILE_FORMAT_GRP:1; ++ ++ uint Reserved2:5; ++ uint WRITE_BL_PARTIAL:1; ++ uint WRITE_BL_LEN:4; ++ uint R2W_FACTOR:3; ++ uint MMCardReserved0:2; ++ uint WP_GRP_ENABLE:1; ++ ++ uint WP_GRP_SIZE:7; ++ uint ERASE_SECTOR_SIZE:7; ++ uint ERASE_BLK_ENABLE:1; ++ uint C_SIZE_MULT:3; ++ uint VDD_W_CURR_MAX:3; ++ uint VDD_W_CURR_MIN:3; ++ uint VDD_R_CURR_MAX:3; ++ uint VDD_R_CURR_MIN:3; ++ ++ uint C_SIZE_1:2; ++ uint C_SIZE_2:10; // divide its into 2, 10bits ++ ++ uint Reserved1:2; ++ uint DSR_IMP:1; ++ uint READ_BLK_MISALIGN:1; ++ uint WRITE_BLK_MISALIGN:1; ++ uint READ_BL_PARTIAL:1; ++ ++ uint READ_BL_LEN:4; ++ uint CCC:12; ++ ++ uint TRAN_SPEED_RateUnit:3; ++ uint TRAN_SPEED_TimeValue:4; ++ uint TRAN_SPEED_Reserved:1; ++ ++ uint NSAC:8; ++ ++ uint TAAC_TimeUnit:3; ++ uint TAAC_TimeValue:4; ++ uint TAAC_Reserved:1; ++ ++ uint Reserved0:2; ++ uint MMC_SPEC_VERS:4; ++ uint CSD_STRUCTURE:2; ++} sd_csd_bit_t; ++ ++/********************************************************************/ ++/* SD SCR register */ ++/********************************************************************/ ++typedef struct _sd_scr_t ++{ ++ uint Reserved:16; ++ uint SD_BUS_WIDTH:4; ++ uint SD_SECURITY:3; ++ uint DATA_STAT_AFTER_ERASE:1; ++ uint SD_SPEC:4; ++ uint SCR_STRUCTURE:4; ++ ++ uint ManufacturerReserved; ++} sd_scr_t; ++ ++/********************************************************************/ ++/* sd card structure */ ++/********************************************************************/ ++typedef struct _sd_card_t ++{ ++ /* host interface configuration */ ++ uint IOAddr; /* host controller register base address */ ++ uint DMAEnable; ++ ++ uint CardType; ++ ++ /* card register */ ++ uint OCR; ++ ++ uint CIDWord[4]; ++ sd_cid_t CID; ++ ++ uint CSDWord[4]; ++ sd_csd_t CSD; ++ ++ ushort RCA; ++ sd_scr_t SCR; ++ ++ /* access time out */ ++ uint ReadAccessTimoutCycle; ++ uint WriteAccessTimoutCycle; ++ ++ /* Drive Name */ ++ uint Drive; ++ ++ /* system configurations */ ++ uint SysFrequency; ++ ++ /* card status */ ++ int ActiveState; ++ int WriteProtect; ++ ++ void *private; ++} sd_card_t; ++ ++#endif +diff -Nur linux-3.4.110.orig/drivers/block/Kconfig linux-3.4.110/drivers/block/Kconfig +--- linux-3.4.110.orig/drivers/block/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/block/Kconfig 2016-04-07 10:20:51.022084119 +0200 +@@ -498,6 +498,14 @@ + block device driver. It communicates with a back-end driver + in another domain which drives the actual block device. + ++config FTSDC010 ++ tristate "Faraday FTSDC010 driver" ++ depends on NDS32 ++ ++config FTCFC010 ++ tristate "Faraday FTCFC010 driver" ++ depends on NDS32 ++ + config XEN_BLKDEV_BACKEND + tristate "Xen block-device backend driver" + depends on XEN_BACKEND +diff -Nur linux-3.4.110.orig/drivers/block/Makefile linux-3.4.110/drivers/block/Makefile +--- linux-3.4.110.orig/drivers/block/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/block/Makefile 2016-04-07 10:20:51.050085202 +0200 +@@ -43,3 +43,5 @@ + obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx/ + + swim_mod-y := swim.o swim_asm.o ++obj-$(CONFIG_FTSDC010) += ftsdc010.o ++obj-$(CONFIG_FTCFC010) += ftcfc010.o +diff -Nur linux-3.4.110.orig/drivers/gpio/gpio-ftgpio010.c linux-3.4.110/drivers/gpio/gpio-ftgpio010.c +--- linux-3.4.110.orig/drivers/gpio/gpio-ftgpio010.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/gpio/gpio-ftgpio010.c 2016-04-07 10:20:51.050085202 +0200 +@@ -0,0 +1,218 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#define GPIO_DATA_OUT 0x00 ++#define GPIO_DATA_IN 0x04 ++#define PIN_DIR 0x08 ++#define PIN_BYPASS 0x0C ++#define GPIO_DATA_SET 0x10 ++#define GPIO_DATA_CLEAR 0x14 ++#define PIN_PULL_ENABLE 0x18 ++#define PIN_PULL_TYPE 0x1C ++#define INT_ENABLE 0x20 ++#define INT_RAW_STATE 0x24 ++#define INT_MASKED_STATE 0x28 ++#define INT_MASK 0x2C ++#define INT_CLEAR 0x30 ++#define INT_TRIGGER 0x34 ++#define INT_BOTH 0x38 ++#define INT_RISE_NEG 0x3C ++#define BOUNCE_ENABLE 0x40 ++#define BOUNCE_PRE_SCALE 0x44 ++ ++#define GPIO_READL(offset) \ ++ readl(GPIO_FTGPIO010_VA_BASE + (offset)) ++ ++#define GPIO_WRITEL(val, offset) \ ++ writel((val), GPIO_FTGPIO010_VA_BASE + (offset)) ++ ++#define FTGPIO010_VIRTUAL_IRQ_BASE 100 ++ ++static int irq_to_gpio(unsigned int irq) ++{ ++ return irq - FTGPIO010_VIRTUAL_IRQ_BASE; ++} ++ ++static int ftgpio_to_irq(struct gpio_chip *gc, unsigned int offset) ++{ ++ return FTGPIO010_VIRTUAL_IRQ_BASE + offset; ++} ++ ++static int ftgpio_get(struct gpio_chip *gc, unsigned int gpio) ++{ ++ return (GPIO_READL(GPIO_DATA_IN) >> gpio & 1); ++} ++ ++static void ftgpio_set(struct gpio_chip *gc, unsigned int gpio, int data) ++{ ++ unsigned long val; ++ ++ if (data) ++ val = GPIO_READL(GPIO_DATA_OUT) | (0x1UL << gpio); ++ else ++ val = GPIO_READL(GPIO_DATA_OUT) & ~(0x1UL << gpio); ++ ++ GPIO_WRITEL(val, GPIO_DATA_OUT); ++} ++ ++static int ftgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) ++{ ++ unsigned long val; ++ ++ val = GPIO_READL(PIN_DIR) & ~(0x1UL << gpio); ++ GPIO_WRITEL(val, PIN_DIR); ++ ++ return 0; ++} ++ ++static int ftgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int data) ++{ ++ unsigned long val; ++ ++ val = GPIO_READL(PIN_DIR) | (0x1UL << gpio); ++ GPIO_WRITEL(val, PIN_DIR); ++ ++ gc->set(gc, gpio, data); ++ ++ return 0; ++} ++ ++static struct gpio_chip ftgpio_chip = { ++ ++ .label = "FTGPIO010", ++ .base = 0, ++ .ngpio = 16, ++ .direction_input = ftgpio_dir_in, ++ .direction_output = ftgpio_dir_out, ++ .get = ftgpio_get, ++ .set = ftgpio_set, ++ .to_irq = ftgpio_to_irq, ++}; ++ ++static void ftgpio_irq_ack(struct irq_data *data) ++{ ++ GPIO_WRITEL(0x1UL << irq_to_gpio(data->irq), INT_CLEAR); ++} ++ ++static void ftgpio_irq_mask(struct irq_data *data) ++{ ++ unsigned long val; ++ ++ val = GPIO_READL(INT_MASK) | (0x1UL << irq_to_gpio(data->irq)); ++ GPIO_WRITEL(val, INT_MASK); ++} ++ ++static void ftgpio_irq_unmask(struct irq_data *data) ++{ ++ unsigned long val; ++ val = GPIO_READL(INT_MASK) & ~(0x1UL << irq_to_gpio(data->irq)); ++ GPIO_WRITEL(val, INT_MASK); ++} ++ ++static int ftgpio_irq_set_type(struct irq_data *data, unsigned int flow_type) ++{ ++ unsigned long bit = 0x1UL << irq_to_gpio(data->irq); ++ unsigned long val; ++ val = GPIO_READL(INT_BOTH); ++ ++ if (flow_type & IRQF_TRIGGER_RISING && flow_type & IRQF_TRIGGER_FALLING) ++ GPIO_WRITEL(val | bit, INT_BOTH); ++ else ++ GPIO_WRITEL(val & ~bit, INT_BOTH); ++ ++ val = GPIO_READL(INT_RISE_NEG); ++ ++ if (flow_type & IRQF_TRIGGER_FALLING) ++ GPIO_WRITEL(val | bit, INT_RISE_NEG); ++ else if (flow_type & IRQF_TRIGGER_RISING) ++ GPIO_WRITEL(val & ~bit, INT_RISE_NEG); ++ ++ return 0; ++} ++ ++static struct irq_chip ftgpio_irq_chip = { ++ ++ .name = "FTGPIO010_irq", ++ .irq_ack = ftgpio_irq_ack, ++ .irq_mask = ftgpio_irq_mask, ++ .irq_unmask = ftgpio_irq_unmask, ++ .irq_set_type = ftgpio_irq_set_type, ++}; ++ ++static void gpio_irq_router(unsigned int irq, struct irq_desc *desc) ++{ ++ unsigned long status; ++ int i = 0; ++ ++ status = GPIO_READL(INT_RAW_STATE); ++ status &= ~((1 << 22) | (1 << 25) | (1 << 26)); ++ ++ while (status) { ++ ++ if (status & 0x1UL) ++ generic_handle_irq(gpio_to_irq(i)); ++ ++ status >>= 1; ++ i++; ++ } ++} ++ ++static int gpio_init(void) ++{ ++ int i; ++ ++ /* disable interrupt */ ++ GPIO_WRITEL(0x00000000UL, INT_ENABLE); ++ ++ /* mask interrupt */ ++ GPIO_WRITEL(0x0000FFFFUL, INT_MASK); ++ ++ /* triggered interrupt on both edge */ ++ GPIO_WRITEL(0x0000FFFFUL, INT_BOTH); ++ ++ /* clear interrupt */ ++ GPIO_WRITEL(0x0000FFFFUL, INT_CLEAR); ++ ++ /* enable de-bouncing */ ++ GPIO_WRITEL(0x0000FFFFUL, BOUNCE_ENABLE); ++ ++ /* enable interrupt */ ++ GPIO_WRITEL(0x0000FFFFUL, INT_ENABLE); ++ ++ gpiochip_add(&ftgpio_chip); ++ ++ for (i = 0; i < ftgpio_chip.ngpio; i++) { ++ ++ irq_set_chip(gpio_to_irq(i), &ftgpio_irq_chip); ++ irq_set_handler(gpio_to_irq(i), handle_level_irq); ++ } ++ ++ irq_set_chained_handler(GPIO_FTGPIO010_IRQ, gpio_irq_router); ++ ++ pr_info("GPIO module inserted\n"); ++ ++ return 0; ++} ++ ++static void __exit gpio_exit(void) ++{ ++ int i=0; ++ /* disable interrupt */ ++ GPIO_WRITEL(0x00000000UL, INT_ENABLE); ++ while(i ++#include ++#include ++#include ++ ++#include ++#include "cpe_ts.h" ++ ++ ++#include ++ ++#include ++#include ++ ++#define TOUCHSCREEN_IRQ 28 ++ ++#define ads_dbg( enabled, tagged, ...) \ ++ do{ \ ++ if( enabled){ \ ++ if( tagged) \ ++ printk( "[ %30s() ] ", __func__); \ ++ printk( __VA_ARGS__); \ ++ } \ ++ } while( 0) ++ ++#define TS_POLL_DELAY ( 1 * 1000000) /* ns delay before the first sample */ ++#define TS_POLL_PERIOD ( delay * 1000000) /* ns delay between samples */ ++ ++static int debug = 0; ++static int delay = 25; ++ ++module_param(debug, int, 0); ++module_param(delay, int, 0); ++ ++struct ads7846 ++{ ++ void __iomem * regs; ++ struct input_dev *input; ++ char phys[32]; ++ struct hrtimer timer; ++ int irq; ++ spinlock_t lock; ++ bool disabled; ++}; ++ ++struct ts_event ++{ ++ int x; ++ int y; ++ int z1, z2; ++ int Rt; ++}; ++ ++struct ads7846 touchscreen; ++ ++#define ADS_START ( 0x1UL << 7) ++#define ADS_A2A1A0_d_y ( 0x1UL << 4) /* differential */ ++#define ADS_A2A1A0_d_z1 ( 0x3UL << 4) /* differential */ ++#define ADS_A2A1A0_d_z2 ( 0x4UL << 4) /* differential */ ++#define ADS_A2A1A0_d_x ( 0x5UL << 4) /* differential */ ++#define ADS_12_BIT ( 0x0UL << 3) ++#define ADS_SER ( 0x1UL << 2) /* non-differential */ ++#define ADS_DFR ( 0x0UL << 2) /* differential */ ++#define ADS_PD10_PDOWN ( 0x0UL << 0) /* lowpower mode + penirq */ ++#define ADS_PD10_ADC_ON ( 0x1UL << 0) /* ADC on */ ++#define ADS_PD10_REF_ON ( 0x2UL << 0) /* vREF on + penirq */ ++#define ADS_PD10_ALL_ON ( 0x3UL << 0) /* ADC + vREF on */ ++ ++#define MAX_12BIT ( ( 0x1UL << 12) - 1) ++ ++#define READ_X ( ADS_A2A1A0_d_x | ADS_12_BIT | ADS_DFR) ++#define READ_Y ( ADS_A2A1A0_d_y | ADS_12_BIT | ADS_DFR) ++#define READ_Z1 ( ADS_A2A1A0_d_z1 | ADS_12_BIT | ADS_DFR) ++#define READ_Z2 ( ADS_A2A1A0_d_z2 | ADS_12_BIT | ADS_DFR) ++ ++static int ++read_val(struct ads7846 *ts, unsigned long cmd) ++{ ++ unsigned long data = 0; ++ int repeat = 5; ++ int i; ++ ++ ads_dbg(0, 1, "Queuing data: 0x%08lx\n", cmd << 16); ++ ++ for (i = 0; i < repeat; i++) ++ { ++ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskTFNF)); ++ REG32(ts->regs + SSP_REG_DR) = (ADS_START | cmd | ADS_PD10_ALL_ON) << 16; ++ } ++ ++ for (i = 0; i < repeat; i++) ++ { ++ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskRFVE)); ++ data = (REG32(ts->regs + SSP_REG_DR) >> 3) & 0xFFF; ++ } ++ ++ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskTFNF)); ++ REG32(ts->regs + SSP_REG_DR) = (ADS_START | cmd) << 16; ++ ++ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskRFVE)); ++ ++ data = (REG32(ts->regs + SSP_REG_DR) >> 3) & 0xFFF; ++ ads_dbg(0, 1, "CMD <%02lx> data: 0x%08lx( %ld)\n", cmd, data, data); ++ ++ return data; ++} ++ ++static int pendown(struct ads7846 *ts) ++{ ++ return read_val(ts, READ_Z1) > 40; ++} ++ ++static void report(struct ads7846 *ts, struct ts_event *e) ++{ ++ e->x = read_val(ts, READ_X); ++ e->y = read_val(ts, READ_Y); ++ e->z1 = read_val(ts, READ_Z1); ++ e->z2 = read_val(ts, READ_Z2); ++ ++ ads_dbg(debug, 1, "x: %4d, y: %4d, z1: %4d, z2: %4d\n", e->x, e->y, e->z1, e->z2); ++} ++ ++#define FILTER_LIMIT 35 ++ ++static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) ++{ ++ struct ads7846 *ts = container_of(handle, struct ads7846, timer); ++ struct ts_event e; ++ struct irq_desc *desc = (struct irq_desc *)irq_get_irq_data((unsigned int)ts->irq); ++ static int xp = 0, yp = 0; ++ ++ if (ts->disabled) ++ return HRTIMER_NORESTART; ++ ++ if (!pendown(ts)) ++ { ++ ads_dbg(debug, 1, "Release\n"); ++ ++ input_report_key(ts->input, BTN_TOUCH, 0); ++ input_report_abs(ts->input, ABS_PRESSURE, 0); ++ input_sync(ts->input); ++ ++ if(desc->irq_data.chip->irq_ack) ++ desc->irq_data.chip->irq_ack(&desc->irq_data); ++ enable_irq(ts->irq); ++ return HRTIMER_NORESTART; ++ } ++ report(ts, &e); ++ ++#ifdef CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER ++ if (abs(xp - e.x) > FILTER_LIMIT || abs(yp - e.y) > FILTER_LIMIT) ++ { ++#endif ++ input_report_key(ts->input, BTN_TOUCH, 1); ++ input_report_abs(ts->input, ABS_X, e.x); ++ input_report_abs(ts->input, ABS_Y, e.y); ++ input_report_abs(ts->input, ABS_PRESSURE, 50); ++ xp = e.x; ++ yp = e.y; ++#ifdef CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER ++ } ++#endif ++ input_sync(ts->input); ++ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); ++ ads_dbg(0, 1, "Leave\n"); ++ return HRTIMER_NORESTART; ++} ++ ++static irqreturn_t ads7846_irq(int irq, void *handle) ++{ ++ struct ads7846 *ts = handle; ++ ++ if (ts->disabled) ++ return IRQ_HANDLED; ++ ++ disable_irq_nosync(irq); ++ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), HRTIMER_MODE_REL); ++ ++ return IRQ_HANDLED; ++} ++ ++static int xspi_init_hw(void __iomem *regs_base) ++{ ++ int rev = REG32(regs_base + SSP_REG_REV); ++ int reva = REG32(regs_base + SSP_REG_REV-0x20); ++ ++ if ((((rev & SSP_REV_mskMAJOR_REV) >> SSP_REV_offMAJOR_REV) != 1)&& ++ (((reva & SSP_REV_mskMAJOR_REV) >> SSP_REV_offMAJOR_REV) != 1)) ++ { ++ ads_dbg(1, 0, "ADS7846 Touchscreen controller initialized failed:\n" ++ "\tcannot detect Faraday SSP Controller\n"); ++ return -ENXIO; ++ } ++ REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offSSPRST); ++ ++ REG32(regs_base + SSP_REG_CR1) = ++ (0UL << SSP_CR1_offPDL) | /* Padding Data Length */ ++ (23UL << SSP_CR1_offSDL) | /* Serial Data Length */ ++ (5UL << SSP_CR1_offSCLKDIV); /* SCLK Divider */ ++ ++ REG32(regs_base + SSP_REG_CR0) = ++ (1UL << SSP_CR0_offFFMT) | /* Frame Format */ ++ (3UL << SSP_CR0_offOPM) | /* Operation Mode */ ++ (0UL << SSP_CR0_offSCLKPO) | /* SCLK Polarity */ ++ (0UL << SSP_CR0_offSCLKPH); /* SCLK Phase */ ++ ++ REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offTXFCLR) | (1UL << SSP_CR2_offRXFCLR); ++ REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offSSPEN) | (1UL << SSP_CR2_offTXDOE); ++ return 0; ++} ++ ++static int ads7846_probe(struct platform_device *pdev) ++{ ++ struct ads7846 *ts = &touchscreen; ++ struct input_dev *input_dev; ++ int err = 0; ++ platform_set_drvdata(pdev, ts); ++ ++ ts->regs = ioremap(0x98b00000, 44); ++ err = xspi_init_hw(ts->regs); ++ if (err) ++ goto err_unmap; ++ input_dev = input_allocate_device(); ++ if (!input_dev) ++ { ++ err = -ENOMEM; ++ goto err_free_mem; ++ } ++ ++ ts->input = input_dev; ++ ++ hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); ++ ts->timer.function = ads7846_timer; ++ ++ input_dev->name = "ADS7846 Touchscreen"; ++ input_dev->phys = ts->phys; ++ ++ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); ++ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); ++ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); ++ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); ++ input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); ++ ++ ts->irq = TOUCHSCREEN_IRQ; ++ ++ if (request_irq(ts->irq, ads7846_irq, IRQF_TRIGGER_RISING, "touch screen", ts)) ++ goto err_free_mem; ++ ++ err = input_register_device(input_dev); ++ if (err) ++ goto err_free_irq; ++ ++ spin_lock_init(&ts->lock); ++ return 0; ++err_free_irq: ++ free_irq(ts->irq, ts); ++err_free_mem: ++ input_free_device(input_dev); ++err_unmap: ++ iounmap(ts->regs); ++ ++ return err; ++} ++ ++static int __devexit ads7846_remove(struct platform_device *pdev) ++{ ++ struct ads7846 *ts = platform_get_drvdata(pdev); ++ ++ disable_irq(ts->irq); ++ free_irq(ts->irq, ts); ++ iounmap(ts->regs); ++ input_unregister_device(ts->input); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int ads7846_suspend( struct platform_device *pdev, pm_message_t message) ++{ ++ struct ads7846 *ts = platform_get_drvdata(pdev); ++ ++ spin_lock_irq(&ts->lock); ++ ts->disabled = true; ++ disable_irq(ts->irq); ++ spin_unlock_irq(&ts->lock); ++ ++ return 0; ++} ++ ++static int ads7846_resume( struct platform_device *pdev) ++{ ++ struct ads7846 *ts = platform_get_drvdata(pdev); ++ ++ spin_lock_irq(&ts->lock); ++ ++ enable_irq(ts->irq); ++ ts->disabled = false; ++ ++ spin_unlock_irq(&ts->lock); ++ ++ return 0; ++} ++#else ++#define ads7846_suspend NULL ++#define ads7846_resume NULL ++#endif ++ ++static void platform_device_release(struct device *dev){ ++} ++ ++static struct resource ads7846_resources[] = ++{ ++ [0] = { ++ .start = SSP_FTSSP010_PA_BASE, ++ .end = SSP_FTSSP010_PA_LIMIT, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = TOUCHSCREEN_IRQ, //feed me! SSP_FTSSP010_IRQ in spec.h ++ .end = TOUCHSCREEN_IRQ, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_device ads7846_device = ++{ ++ .name = "ads7846", ++ .id = -1, ++ .resource = ads7846_resources, ++ .num_resources = ARRAY_SIZE(ads7846_resources), ++ .dev = { ++ .release = platform_device_release, ++ }, ++}; ++ ++#if 0 ++static struct platform_driver ads7846_driver = ++{ ++ .driver = { ++ .name = "ads7846", ++ .owner = THIS_MODULE, ++ }, ++ .probe = ads7846_probe, ++ .remove = __devexit_p(ads7846_remove), ++ .suspend = ads7846_suspend, ++ .resume = ads7846_resume, ++}; ++#else ++static struct platform_driver ads7846_driver = ++{ ++ .driver = { ++ .name = "ads7846", ++ }, ++ .probe = ads7846_probe, ++ .remove = __devexit_p(ads7846_remove), ++ .suspend = ads7846_suspend, ++ .resume = ads7846_resume, ++}; ++#endif ++ ++static int __init ads7846_init(void) ++{ ++ platform_device_register(&ads7846_device); ++ return platform_driver_register(&ads7846_driver); ++} ++ ++static void __exit ads7846_exit(void) ++{ ++ platform_device_unregister(&ads7846_device); ++ platform_driver_unregister(&ads7846_driver); ++} ++ ++module_init(ads7846_init); ++module_exit(ads7846_exit); ++MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); ++MODULE_LICENSE("GPL"); +diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.h linux-3.4.110/drivers/input/touchscreen/cpe_ts/cpe_ts.h +--- linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/input/touchscreen/cpe_ts/cpe_ts.h 2016-04-07 10:20:51.050085202 +0200 +@@ -0,0 +1,218 @@ ++#ifndef SSP_FARADAY_H ++#define SSP_FARADAY_H ++ ++#define XILINX_SPI_NAME "faraday-spi" ++ ++/* ++ * Register definitions as per "OPB Serial Peripheral Interface ( SPI) ( v1.00e) ++ * Product Specification", DS464 ++ */ ++#define XSPI_CR_OFFSET 0x62 /* 16-bit Control Register */ ++ ++#define XSPI_CR_ENABLE 0x02 ++#define XSPI_CR_MASTER_MODE 0x04 ++#define XSPI_CR_CPOL 0x08 ++#define XSPI_CR_CPHA 0x10 ++#define XSPI_CR_MODE_MASK ( XSPI_CR_CPHA | XSPI_CR_CPOL) ++#define XSPI_CR_TXFIFO_RESET 0x20 ++#define XSPI_CR_RXFIFO_RESET 0x40 ++#define XSPI_CR_MANUAL_SSELECT 0x80 ++#define XSPI_CR_TRANS_INHIBIT 0x100 ++ ++#define XSPI_SR_OFFSET 0x67 /* 8-bit Status Register */ ++ ++#define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */ ++#define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */ ++#define XSPI_SR_TX_EMPTY_MASK 0x04 /* Transmit FIFO is empty */ ++#define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */ ++#define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */ ++ ++#define XSPI_TXD_OFFSET 0x6b /* 8-bit Data Transmit Register */ ++#define XSPI_RXD_OFFSET 0x6f /* 8-bit Data Receive Register */ ++ ++#define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */ ++ ++/* Register definitions as per "OPB IPIF ( v3.01c) Product Specification", DS414 ++ * IPIF registers are 32 bit ++ */ ++#define XIPIF_V123B_DGIER_OFFSET 0x1c /* IPIF global int enable reg */ ++#define XIPIF_V123B_GINTR_ENABLE 0x80000000 ++ ++#define XIPIF_V123B_IISR_OFFSET 0x20 /* IPIF interrupt status reg */ ++#define XIPIF_V123B_IIER_OFFSET 0x28 /* IPIF interrupt enable reg */ ++ ++#define XSPI_INTR_MODE_FAULT 0x01 /* Mode fault error */ ++#define XSPI_INTR_SLAVE_MODE_FAULT 0x02 /* Selected as slave while disabled */ ++#define XSPI_INTR_TX_EMPTY 0x04 /* TxFIFO is empty */ ++#define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */ ++#define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */ ++#define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */ ++ ++#define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */ ++#define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */ ++ ++/*************************************************************************/ ++#if 0 ++#define SSP_REG_CR0 ( SSP_FTSSP010_VA_BASE + 0x00) /* SSP Control Register 0 */ ++#define SSP_REG_CR1 ( SSP_FTSSP010_VA_BASE + 0x04) /* SSP Control Register 1 */ ++#define SSP_REG_CR2 ( SSP_FTSSP010_VA_BASE + 0x08) /* SSP Control Register 2 */ ++#define SSP_REG_SR ( SSP_FTSSP010_VA_BASE + 0x0c) /* SSP Status Register */ ++#define SSP_REG_ICR ( SSP_FTSSP010_VA_BASE + 0x10) /* SSP Interrupt Control Register */ ++#define SSP_REG_ISR ( SSP_FTSSP010_VA_BASE + 0x14) /* SSP Interrupt Status Register */ ++#define SSP_REG_DR ( SSP_FTSSP010_VA_BASE + 0x18) /* SSP Data Register */ ++#define SSP_REG_ACL ( SSP_FTSSP010_VA_BASE + 0x20) /* AC-Link Slot Valid Register */ ++#define SSP_REG_REV ( SSP_FTSSP010_VA_BASE + 0x40) /* SSP Revision Register */ ++#define SSP_REG_FEA ( SSP_FTSSP010_VA_BASE + 0x44) /* SSP Feature Register */ ++#endif ++#define SSP_REG_CR0 0x00 /* SSP Control Register 0 */ ++#define SSP_REG_CR1 0x04 /* SSP Control Register 1 */ ++#define SSP_REG_CR2 0x08 /* SSP Control Register 2 */ ++#define SSP_REG_SR 0x0C /* SSP Status Register */ ++#define SSP_REG_ICR 0x10 /* SSP Interrupt Control Register */ ++#define SSP_REG_ISR 0x14 /* SSP Interrupt Status Register */ ++#define SSP_REG_DR 0x18 /* SSP Data Register */ ++#define SSP_REG_ACL 0x20 /* AC-Link Slot Valid Register */ ++#define SSP_REG_REV 0x60 /* SSP Revision Register */ ++#define SSP_REG_FEA 0x64 /* SSP Feature Register */ ++ ++#define SSP_CR0_offFFMT 12 /* Frame Format */ ++#define SSP_CR0_offFSDIST 8 /* Frame/Sync and Data Distance */ ++#define SSP_CR0_offLBM 7 /* Loopback Mode */ ++#define SSP_CR0_offLSB 6 /* Bit Sequence Indicator */ ++#define SSP_CR0_offFSPO 5 /* Frame/Sync Polarity */ ++#define SSP_CR0_offFSJSFY 4 /* Data Justify */ ++#define SSP_CR0_offOPM 2 /* Operation Mode */ ++#define SSP_CR0_offSCLKPO 1 /* SCLK Polarity */ ++#define SSP_CR0_offSCLKPH 0 /* SCLK Phase */ ++ ++#define SSP_CR0_mskFFMT ( 0x07UL << SSP_CR0_offFFMT) ++#define SSP_CR0_mskFSDIST ( 0x03UL << SSP_CR0_offFSDIST) ++#define SSP_CR0_mskLBM ( 0x01UL << SSP_CR0_offLBM) ++#define SSP_CR0_mskLSB ( 0x01UL << SSP_CR0_offLSB) ++#define SSP_CR0_mskFSPO ( 0x01UL << SSP_CR0_offFSPO) ++#define SSP_CR0_mskFSJSFY ( 0x01UL << SSP_CR0_offFSJSFY) ++#define SSP_CR0_mskOPM ( 0x03UL << SSP_CR0_offOPM) ++#define SSP_CR0_mskSCLKPO ( 0x01UL << SSP_CR0_offSCLKPO) ++#define SSP_CR0_mskSCLKPH ( 0x01UL << SSP_CR0_offSCLKPH) ++ ++#define SSP_CR1_offPDL 24 /* Padding Data Length */ ++#define SSP_CR1_offSDL 16 /* Serial Data Length */ ++#define SSP_CR1_offSCLKDIV 0 /* SCLK Divider */ ++ ++#define SSP_CR1_mskPDL ( 0xFFUL << SSP_CR1_offPDL) ++#define SSP_CR1_mskSDL ( 0x1FUL << SSP_CR1_offSDL) ++#define SSP_CR1_mskSCLKDIV ( 0xFFUL << SSP_CR1_offSCLKDIV) ++ ++#define SSP_CR2_offSSPRST 6 /* SSP Reset */ ++#define SSP_CR2_offACCRST 5 /* AC-Link Cold Reset Enable */ ++#define SSP_CR2_offACWRST 4 /* AC-Link Warm Reset Enable */ ++#define SSP_CR2_offTXFCLR 3 /* Transmit FIFO Clear */ ++#define SSP_CR2_offRXFCLR 2 /* Recieve FIFO clear */ ++#define SSP_CR2_offTXDOE 1 /* Transmit Data Output Enable */ ++#define SSP_CR2_offSSPEN 0 /* The SSP Enable */ ++ ++#define SSP_CR2_mskSSPRST ( 0x01UL << SSP_CR2_offSSPRST) ++#define SSP_CR2_mskACCRST ( 0x01UL << SSP_CR2_offACCRST) ++#define SSP_CR2_mskACWRST ( 0x01UL << SSP_CR2_offACWRST) ++#define SSP_CR2_mskTXFCLR ( 0x01UL << SSP_CR2_offTXFCLR) ++#define SSP_CR2_mskRXFCLR ( 0x01UL << SSP_CR2_offRXFCLR) ++#define SSP_CR2_mskTXDOE ( 0x01UL << SSP_CR2_offTXDOE) ++#define SSP_CR2_mskSSPEN ( 0x01UL << SSP_CR2_offSSPEN) ++ ++#define SSP_SR_offTFVE 12 /* Transmit FIFO Valid Entries */ ++#define SSP_SR_offRFVE 4 /* Recieve FIFO Valid Entries */ ++#define SSP_SR_offBUSY 2 /* Busy Indicator */ ++#define SSP_SR_offTFNF 1 /* Transmit FIFO not full */ ++#define SSP_SR_offRFF 0 /* Recieve FIFO full */ ++ ++#define SSP_SR_mskTFVE ( 0x1FUL << SSP_SR_offTFVE) ++#define SSP_SR_mskRFVE ( 0x1FUL << SSP_SR_offRFVE) ++#define SSP_SR_mskBUSY ( 0x01UL << SSP_SR_offBUSY) ++#define SSP_SR_mskTFNF ( 0x01UL << SSP_SR_offTFNF) ++#define SSP_SR_mskRFF ( 0x01UL << SSP_SR_offRFF) ++ ++#define SSP_ICR_offTFTHOD 12 /* Transmit FIFO Threshold */ ++#define SSP_ICR_offRFTHOD 8 /* Recieve FIFO Threshold */ ++#define SSP_ICR_offAC97FCEN 6 /* AC97 Frame Complete */ ++#define SSP_ICR_offTFDMAEN 5 /* Transmit DMA Request Enable */ ++#define SSP_ICR_offRFDMAEN 4 /* Recieve DMA Request Enable */ ++#define SSP_ICR_offTFTHIEN 3 /* Transmit FIFO Threshold Interrupt */ ++#define SSP_ICR_offRFTHIEN 2 /* Recieve FIFO Threshold Interrupt */ ++#define SSP_ICR_offTFURIEN 1 /* Transmit FIFO Underrun Interrupt Enable */ ++#define SSP_ICR_offRFORIEN 0 /* Recieve FIFO Overrun Interrupt Enable */ ++ ++#define SSP_ICR_mskTFTHOD ( 0x0FUL << SSP_ICR_offTFTHOD) ++#define SSP_ICR_mskRFTHOD ( 0x0FUL << SSP_ICR_offRFTHOD) ++#define SSP_ICR_mskAC97FCEN ( 0x01UL << SSP_ICR_offAC97FCEN) ++#define SSP_ICR_mskTFDMAEN ( 0x01UL << SSP_ICR_offTFDMAEN) ++#define SSP_ICR_mskRFDMAEN ( 0x01UL << SSP_ICR_offRFDMAEN) ++#define SSP_ICR_mskTFTHIEN ( 0x01UL << SSP_ICR_offTFTHIEN) ++#define SSP_ICR_mskRFTHIEN ( 0x01UL << SSP_ICR_offRFTHIEN) ++#define SSP_ICR_mskTFURIEN ( 0x01UL << SSP_ICR_offTFURIEN) ++#define SSP_ICR_mskRFORIEN ( 0x01UL << SSP_ICR_offRFORIEN) ++ ++#define SSP_ISR_offAC97FCI 4 /* AC97 Frame Complete Interrupt */ ++#define SSP_ISR_offTFTHI 3 /* Transmit FIFO Threshold Interrupt */ ++#define SSP_ISR_offRFTHI 2 /* Recieve FIFO Threshold Interrupt */ ++#define SSP_ISR_offTFURI 1 /* Transmit FIFO underrun Interrupt */ ++#define SSP_ISR_offRFORI 0 /* Recieve FIFO Overun Interrupt */ ++ ++#define SSP_ISR_mskAC97FCI ( 0x01UL << SSP_ISR_offAC97FCI) ++#define SSP_ISR_mskTFTHI ( 0x01UL << SSP_ISR_offTFTHI) ++#define SSP_ISR_mskRFTHI ( 0x01UL << SSP_ISR_offRFTHI) ++#define SSP_ISR_mskTFURI ( 0x01UL << SSP_ISR_offTFURI) ++#define SSP_ISR_mskRFORI ( 0x01UL << SSP_ISR_offRFORI) ++ ++#define SSP_ACL_offSLOT1V 14 /* The 1st Slot is Valid */ ++#define SSP_ACL_offSLOT2V 13 /* The 2nd Slot is Valid */ ++#define SSP_ACL_offSLOT3V 12 /* The 3th Slot is Valid */ ++#define SSP_ACL_offSLOT4V 11 /* The 4th Slot is Valid */ ++#define SSP_ACL_offSLOT5V 10 /* The 5th Slot is Valid */ ++#define SSP_ACL_offSLOT6V 9 /* The 6th Slot is Valid */ ++#define SSP_ACL_offSLOT7V 8 /* The 7th Slot is Valid */ ++#define SSP_ACL_offSLOT8V 7 /* The 8th Slot is Valid */ ++#define SSP_ACL_offSLOT9V 6 /* The 9th Slot is Valid */ ++#define SSP_ACL_offSLOT10V 5 /* The 10th Slot is Valid */ ++#define SSP_ACL_offSLOT11V 4 /* The 11th Slot is Valid */ ++#define SSP_ACL_offSLOT12V 3 /* The 12th Slot is Valid */ ++#define SSP_ACL_offCODECID 0 /* Codec ID, which will be shifted out as tag slot */ ++ ++#define SSP_ACL_mskSLOT1V ( 0x01UL << SSP_ACL_offSLOT1V) ++#define SSP_ACL_mskSLOT2V ( 0x01UL << SSP_ACL_offSLOT2V) ++#define SSP_ACL_mskSLOT3V ( 0x01UL << SSP_ACL_offSLOT3V) ++#define SSP_ACL_mskSLOT4V ( 0x01UL << SSP_ACL_offSLOT4V) ++#define SSP_ACL_mskSLOT5V ( 0x01UL << SSP_ACL_offSLOT5V) ++#define SSP_ACL_mskSLOT6V ( 0x01UL << SSP_ACL_offSLOT6V) ++#define SSP_ACL_mskSLOT7V ( 0x01UL << SSP_ACL_offSLOT7V) ++#define SSP_ACL_mskSLOT8V ( 0x01UL << SSP_ACL_offSLOT8V) ++#define SSP_ACL_mskSLOT9V ( 0x01UL << SSP_ACL_offSLOT9V) ++#define SSP_ACL_mskSLOT10V ( 0x01UL << SSP_ACL_offSLOT10V) ++#define SSP_ACL_mskSLOT11V ( 0x01UL << SSP_ACL_offSLOT11V) ++#define SSP_ACL_mskSLOT12V ( 0x01UL << SSP_ACL_offSLOT12V) ++#define SSP_ACL_mskCODECID ( 0x03UL << SSP_ACL_offCODECID) ++ ++#define SSP_REV_offMAJOR_REV 16 /* Major Revision Number */ ++#define SSP_REV_offMINOR_REV 8 /* Minor Revision Number */ ++#define SSP_REV_offREL_REV 0 /* Release Number */ ++ ++#define SSP_REV_mskMAJOR_REV ( 0xFFUL << SSP_REV_offMAJOR_REV) ++#define SSP_REV_mskMINOR_REV ( 0xFFUL << SSP_REV_offMINOR_REV) ++#define SSP_REV_mskREL_REV ( 0xFFUL << SSP_REV_offREL_REV) ++ ++#define SSP_FEA_offSSP_FCFG 27 /* The SSP Functional Configurations */ ++#define SSP_FEA_offSPIMWR_FCFG 26 /* Motorola's SPI and National Semiconductor's Microwire Configurations */ ++#define SSP_FEA_offI2S_FCFG 25 /* Philips's I2S Functional Configurations */ ++#define SSP_FEA_offAC97_FCFG 24 /* Intel's AC-Link Functional Configurations */ ++#define SSP_FEA_offTXFIFO_WIDTH 16 /* Transmit FIFO Size Configurations */ ++#define SSP_FEA_offRXFIFO_WIDTH 8 /* Recieve FIFO Size Configuration */ ++#define SSP_FEA_offFIFO_WIDTH 0 /* Transmit/Recieve FIFO Width */ ++ ++#define SSP_FEA_mskSSP_FCFG ( 0x01UL << SSP_FEA_offSSP_FCFG) ++#define SSP_FEA_mskSPIMWR_FCFG ( 0x01UL << SSP_FEA_offSPIMWR_FCFG) ++#define SSP_FEA_mskI2S_FCFG ( 0x01UL << SSP_FEA_offI2S_FCFG) ++#define SSP_FEA_mskAC97_FCFG ( 0x01UL << SSP_FEA_offAC97_FCFG) ++#define SSP_FEA_mskTXFIFO_WIDTH ( 0xFFUL << SSP_FEA_offTXFIFO_WIDTH) ++#define SSP_FEA_mskRXFIFO_WIDTH ( 0xFFUL << SSP_FEA_offRXFIFO_WIDTH) ++#define SSP_FEA_mskFIFO_WIDTH ( 0xFFUL << SSP_FEA_offFIFO_WIDTH) ++ ++#endif /* SSP_FARADAY */ +diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/Makefile linux-3.4.110/drivers/input/touchscreen/cpe_ts/Makefile +--- linux-3.4.110.orig/drivers/input/touchscreen/cpe_ts/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/input/touchscreen/cpe_ts/Makefile 2016-04-07 10:20:51.050085202 +0200 +@@ -0,0 +1 @@ ++obj-$(CONFIG_TOUCHSCREEN_CPE_TS) += cpe_ts.o +diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/Kconfig linux-3.4.110/drivers/input/touchscreen/Kconfig +--- linux-3.4.110.orig/drivers/input/touchscreen/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/input/touchscreen/Kconfig 2016-04-07 10:20:51.050085202 +0200 +@@ -86,6 +86,26 @@ + To compile this driver as a module, choose M here: the + module will be called ad7879-spi. + ++config TOUCHSCREEN_CPE_TS ++ tristate "Touchscreen Driver for AG101/XC5" ++ help ++ This driver directly accesses SPI controller to communicate with ++ the ads7846 chip. ++ ++ Once we have a SPI controller driver ++ , we can adopt to the SPI ++ framework that kernel provides. ++ ++config TOUCHSCREEN_CPE_TS_DEJITTER ++ bool "Dejitter Detection" ++ depends on TOUCHSCREEN_CPE_TS ++ default y ++ help ++ Say Y here to enable dejitter detection in AG101/Leopard Touchscreen Driver. ++ ++ If unsure, say y. ++ ++ + config TOUCHSCREEN_ATMEL_MXT + tristate "Atmel mXT I2C Touchscreen" + depends on I2C +diff -Nur linux-3.4.110.orig/drivers/input/touchscreen/Makefile linux-3.4.110/drivers/input/touchscreen/Makefile +--- linux-3.4.110.orig/drivers/input/touchscreen/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/input/touchscreen/Makefile 2016-04-07 10:20:51.050085202 +0200 +@@ -69,3 +69,4 @@ + obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o + obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o + obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o ++obj-$(CONFIG_TOUCHSCREEN_CPE_TS) += cpe_ts/ +diff -Nur linux-3.4.110.orig/drivers/mmc/core/bus.c linux-3.4.110/drivers/mmc/core/bus.c +--- linux-3.4.110.orig/drivers/mmc/core/bus.c 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/mmc/core/bus.c 2016-04-07 10:20:51.050085202 +0200 +@@ -26,7 +26,9 @@ + #include "bus.h" + + #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) +- ++#ifdef CONFIG_MMC_TEST ++static struct mmc_driver *mmc_test_drv; ++#endif + static ssize_t mmc_type_show(struct device *dev, + struct device_attribute *attr, char *buf) + { +@@ -109,6 +111,11 @@ + struct mmc_driver *drv = to_mmc_driver(dev->driver); + struct mmc_card *card = mmc_dev_to_card(dev); + ++ #ifdef CONFIG_MMC_TEST ++ mmc_test_drv->probe(card); ++ printk("debug mmc_bus_probe\n"); ++ #endif ++ + return drv->probe(card); + } + +@@ -200,6 +207,11 @@ + int mmc_register_driver(struct mmc_driver *drv) + { + drv->drv.bus = &mmc_bus_type; ++ #ifdef CONFIG_MMC_TEST ++ printk("debug defined config_mmc_test in mmc_register_driver\n"); ++ if(!strcmp(drv->drv.name,"mmc_test")) ++ mmc_test_drv = drv; ++ #endif + return driver_register(&drv->drv); + } + +diff -Nur linux-3.4.110.orig/drivers/mmc/host/ftsdc010.c linux-3.4.110/drivers/mmc/host/ftsdc010.c +--- linux-3.4.110.orig/drivers/mmc/host/ftsdc010.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/mmc/host/ftsdc010.c 2016-04-07 10:20:51.050085202 +0200 +@@ -0,0 +1,1586 @@ ++/* drivers/mmc/host/ftsdc010.c ++ * Copyright (C) 2010 Andestech ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "ftsdc010.h" ++ ++#define DRIVER_NAME "ftsdc010" ++ ++#define REG_READ(addr) readl((host->base + addr)) ++#define REG_WRITE(data, addr) writel((data), (host->base + addr)) ++ ++#define APB_CLK_IN (AHB_CLK_IN / 2) ++ ++enum dbg_channels { ++ dbg_err = (1 << 0), ++ dbg_debug = (1 << 1), ++ dbg_info = (1 << 2), ++ dbg_irq = (1 << 3), ++ dbg_sg = (1 << 4), ++ dbg_dma = (1 << 5), ++ dbg_pio = (1 << 6), ++ dbg_fail = (1 << 7), ++ dbg_conf = (1 << 8), ++}; ++ ++static struct workqueue_struct *mywq; ++ ++static const int dbgmap_err = dbg_fail; ++static const int dbgmap_info = dbg_info | dbg_conf; ++static const int dbgmap_debug = dbg_err | dbg_debug | dbg_info | dbg_conf; ++#if 1 ++#define dbg(host, channels, args...) \ ++ do { \ ++ if (dbgmap_err & channels) \ ++ dev_err(&host->pdev->dev, args); \ ++ else if (dbgmap_info & channels) \ ++ dev_info(&host->pdev->dev, args); \ ++ else if (dbgmap_debug & channels) \ ++ dev_dbg(&host->pdev->dev, args); \ ++ } while (0) ++#endif ++#if 0 ++#define dbg(host, channels, args...) \ ++ do { \ ++ printk(KERN_INFO "%s: ", "ftsdc");\ ++ printk(args); \ ++ } while(0) ++#endif ++ ++static void finalize_request(struct ftsdc_host *host); ++static void ftsdc_send_request(struct mmc_host *mmc); ++ ++#ifdef CONFIG_MMC_DEBUG ++ ++static void dbg_dumpregs(struct ftsdc_host *host, char *prefix) ++{ ++ u32 con, cmdarg, r0, r1, r2, r3, rcmd, dcon, dtimer, ++ dlen, sta, clr, imask, pcon, ccon, bwidth, scon1, ++ scon2, ssta, fea; ++ ++ con = REG_READ(SDC_CMD_REG); ++ cmdarg = REG_READ(SDC_ARGU_REG); ++ r0 = REG_READ(SDC_RESPONSE0_REG); ++ r1 = REG_READ(SDC_RESPONSE1_REG); ++ r2 = REG_READ(SDC_RESPONSE2_REG); ++ r3 = REG_READ(SDC_RESPONSE3_REG); ++ rcmd = REG_READ(SDC_RSP_CMD_REG); ++ dcon = REG_READ(SDC_DATA_CTRL_REG); ++ dtimer = REG_READ(SDC_DATA_TIMER_REG); ++ dlen = REG_READ(SDC_DATA_LEN_REG); ++ sta = REG_READ(SDC_STATUS_REG); ++ clr = REG_READ(SDC_CLEAR_REG); ++ imask = REG_READ(SDC_INT_MASK_REG); ++ pcon = REG_READ(SDC_POWER_CTRL_REG); ++ ccon = REG_READ(SDC_CLOCK_CTRL_REG); ++ bwidth = REG_READ(SDC_BUS_WIDTH_REG); ++ scon1 = REG_READ(SDC_SDIO_CTRL1_REG); ++ scon2 = REG_READ(SDC_SDIO_CTRL2_REG); ++ ssta = REG_READ(SDC_SDIO_STATUS_REG); ++ fea = REG_READ(SDC_FEATURE_REG); ++ ++ dbg(host, dbg_debug, "%s CON:[%08x] STA:[%08x] INT:[%08x], PWR:[%08x], CLK:[%08x]\n", ++ prefix, con, sta, imask, pcon, ccon); ++ ++ dbg(host, dbg_debug, "%s DCON:[%08x] DTIME:[%08x]" ++ " DLEN:[%08x] DWIDTH:[%08x]\n", ++ prefix, dcon, dtimer, dlen, bwidth); ++ ++ dbg(host, dbg_debug, "%s R0:[%08x] R1:[%08x]" ++ " R2:[%08x] R3:[%08x]\n", ++ prefix, r0, r1, r2, r3); ++ ++ dbg(host, dbg_debug, "%s SCON1:[%08x] SCON2:[%08x]" ++ " SSTA:[%08x] FEA:[%08x]\n", ++ prefix, scon1, scon2, ssta, fea); ++} ++ ++static void prepare_dbgmsg(struct ftsdc_host *host, struct mmc_command *cmd, ++ int stop) ++{ ++ snprintf(host->dbgmsg_cmd, 300, ++ "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u", ++ host->ccnt, (stop ? " (STOP)" : ""), ++ cmd->opcode, cmd->arg, cmd->flags, cmd->retries); ++ ++ if (cmd->data) { ++ snprintf(host->dbgmsg_dat, 300, ++ "#%u bsize:%u blocks:%u bytes:%u", ++ host->dcnt, cmd->data->blksz, ++ cmd->data->blocks, ++ cmd->data->blocks * cmd->data->blksz); ++ } else { ++ host->dbgmsg_dat[0] = '\0'; ++ } ++} ++ ++static void dbg_dumpcmd(struct ftsdc_host *host, struct mmc_command *cmd, ++ int fail) ++{ ++ unsigned int dbglvl = fail ? dbg_fail : dbg_debug; ++ ++ if (!cmd) ++ return; ++ ++ if (cmd->error == 0) { ++ dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n", ++ host->dbgmsg_cmd, cmd->resp[0]); ++ } else { ++ dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n", ++ cmd->error, host->dbgmsg_cmd, host->status); ++ } ++ ++ if (!cmd->data) ++ return; ++ ++ if (cmd->data->error == 0) { ++ dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat); ++ } else { ++ dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n", ++ cmd->data->error, host->dbgmsg_dat, ++ REG_READ(SDC_DATA_LEN_REG)); ++ } ++} ++#else ++static void dbg_dumpcmd(struct ftsdc_host *host, ++ struct mmc_command *cmd, int fail) { } ++ ++static void prepare_dbgmsg(struct ftsdc_host *host, struct mmc_command *cmd, ++ int stop) { } ++ ++static void dbg_dumpregs(struct ftsdc_host *host, char *prefix) { } ++ ++#endif /* CONFIG_MMC_DEBUG */ ++ ++static inline bool ftsdc_dmaexist(struct ftsdc_host *host) ++{ ++ return (host->dma_req != NULL); ++} ++ ++static inline u32 enable_imask(struct ftsdc_host *host, u32 imask) ++{ ++ u32 newmask; ++ ++#ifdef CONFIG_MMC_DEBUG ++ if (imask & SDC_STATUS_REG_SDIO_INTR) printk("\n*** E ***\n"); ++#endif ++ newmask = REG_READ(SDC_INT_MASK_REG); ++ newmask |= imask; ++ ++ REG_WRITE(newmask, SDC_INT_MASK_REG); ++ ++ return newmask; ++} ++ ++static inline u32 disable_imask(struct ftsdc_host *host, u32 imask) ++{ ++ u32 newmask; ++ ++#ifdef CONFIG_MMC_DEBUG ++ if (imask & SDC_STATUS_REG_SDIO_INTR) printk("\n*** D ***\n"); ++#endif ++ newmask = REG_READ(SDC_INT_MASK_REG); ++ newmask &= ~imask; ++ ++ REG_WRITE(newmask, SDC_INT_MASK_REG); ++ ++ return newmask; ++} ++ ++static inline void clear_imask(struct ftsdc_host *host) ++{ ++ u32 mask = REG_READ(SDC_INT_MASK_REG); ++ ++ /* preserve the SDIO IRQ mask state */ ++ mask &= (SDC_INT_MASK_REG_SDIO_INTR | SDC_INT_MASK_REG_CARD_CHANGE); ++ REG_WRITE(mask, SDC_INT_MASK_REG); ++} ++ ++//static void ftsdc_check_sdio_irq(struct ftsdc_host *host) ++//{ ++// if (host->sdio_irqen) { ++// u32 con = REG_READ(SDC_STATUS_REG); ++// if (con & SDC_STATUS_REG_SDIO_INTR) { ++// printk(KERN_DEBUG "%s: signalling irq\n", __func__); ++// mmc_signal_sdio_irq(host->mmc); ++// } ++// } ++//} ++ ++static inline void get_data_buffer(struct ftsdc_host *host) ++{ ++ struct scatterlist *sg; ++ ++ BUG_ON(host->buf_sgptr >= host->mrq->data->sg_len); ++ ++ sg = &host->mrq->data->sg[host->buf_sgptr]; ++ ++ host->buf_bytes = sg->length; ++ host->buf_ptr = host->dodma ? (u32 *)sg->dma_address : sg_virt(sg); ++ host->buf_sgptr++; ++} ++ ++static inline u32 cal_blksz(unsigned int blksz) ++{ ++ u32 blksztwo = 0; ++ ++ while (blksz >>= 1) ++ blksztwo++; ++ ++ return blksztwo; ++} ++ ++/** ++ * ftsdc_enable_irq - enable IRQ, after having disabled it. ++ * @host: The device state. ++ * @more: True if more IRQs are expected from transfer. ++ * ++ * Enable the main IRQ if needed after it has been disabled. ++ * ++ * The IRQ can be one of the following states: ++ * - enable after data read/write ++ * - disable when handle data read/write ++ */ ++static void ftsdc_enable_irq(struct ftsdc_host *host, bool enable) ++{ ++ unsigned long flags; ++ local_irq_save(flags); ++ ++ host->irq_enabled = enable; ++ ++ if (enable) ++ enable_irq(host->irq); ++ else ++ disable_irq(host->irq); ++ ++ local_irq_restore(flags); ++} ++ ++static void do_pio_read(struct ftsdc_host *host) ++{ ++ u32 fifo; ++ u32 fifo_words; ++ u32 *ptr; ++ u32 status; ++ u32 retry = 0; ++ ++ ++ BUG_ON(host->buf_bytes != 0); ++ ++ while (host->buf_sgptr < host->mrq->data->sg_len) { ++ get_data_buffer(host); ++ ++ dbg(host, dbg_pio, ++ "pio_read(): new target: [%i]@[%p]\n", ++ host->buf_bytes, host->buf_ptr); ++ ++ while (host->buf_bytes) { ++ status = REG_READ(SDC_STATUS_REG); ++ ++ if (status & SDC_STATUS_REG_FIFO_OVERRUN) { ++ fifo = host->fifo_len > host->buf_bytes ? ++ host->buf_bytes : host->fifo_len; ++ ++#if 1 ++ dbg(host, dbg_pio, ++ "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", ++ fifo, host->buf_bytes, ++ REG_READ(SDC_DATA_LEN_REG)); ++#endif ++ ++ host->buf_bytes -= fifo; ++ host->buf_count += fifo; ++ ++ fifo_words = fifo >> 2; ++ ptr = host->buf_ptr; ++ while (fifo_words--) ++ *ptr++ = REG_READ(SDC_DATA_WINDOW_REG); ++ ++ host->buf_ptr = ptr; ++ //ADD by river 2010.10.26 for adding some delays for SD card to put data into FIFO again ++ //mdelay(1); ++ udelay(800); ++ //End ADD by river 2010.10.26 for adding some delays for SD card to put data into FIFO again ++ ++ /* sdio allow non-power-of-2 blksz */ ++ if (fifo & 3) { ++ u32 n = fifo & 3; ++ u32 data = REG_READ(SDC_DATA_WINDOW_REG); ++ u8 *p = (u8 *)host->buf_ptr; ++ ++ while (n--) { ++ *p++ = data; ++ data >>= 8; ++ } ++ } ++ } else { ++ udelay(1); ++ if (++retry >= SDC_PIO_RETRY) { ++ host->mrq->data->error = -EIO; ++ goto err; ++ } ++ } ++ } ++ } ++ ++err: ++ ++ host->buf_active = XFER_NONE; ++ host->complete_what = COMPLETION_FINALIZE; ++} ++ ++static void do_pio_write(struct ftsdc_host *host) ++{ ++ u32 fifo; ++ u32 *ptr; ++ u32 status; ++ u32 retry = 0; ++ ++ BUG_ON(host->buf_bytes != 0); ++ ++ while (host->buf_sgptr < host->mrq->data->sg_len) { ++ get_data_buffer(host); ++ ++ dbg(host, dbg_pio, ++ "pio_write(): new source: [%i]@[%p]\n", ++ host->buf_bytes, host->buf_ptr); ++ ++ while (host->buf_bytes) { ++ status = REG_READ(SDC_STATUS_REG); ++ if (status & SDC_STATUS_REG_FIFO_UNDERRUN) { ++ fifo = host->fifo_len > host->buf_bytes ? ++ host->buf_bytes : host->fifo_len; ++ ++ dbg(host, dbg_pio, ++ "pio_write(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", ++ fifo, host->buf_bytes, ++ REG_READ(SDC_DATA_LEN_REG)); ++ ++ host->buf_bytes -= fifo; ++ host->buf_count += fifo; ++ ++ fifo = (fifo + 3) >> 2; ++ ptr = host->buf_ptr; ++ while (fifo--) { ++ REG_WRITE(*ptr, SDC_DATA_WINDOW_REG); ++ ptr++; ++ } ++ host->buf_ptr = ptr; ++ } else { ++ udelay(1); ++ if (++retry >= SDC_PIO_RETRY) { ++ host->mrq->data->error = -EIO; ++ goto err; ++ } ++ } ++ } ++ } ++ ++err: ++ host->buf_active = XFER_NONE; ++ host->complete_what = COMPLETION_FINALIZE; ++} ++ ++static void do_dma_access(struct ftsdc_host *host) ++{ ++ int res; ++ unsigned long timeout; ++ dmad_chreq *req = host->dma_req; ++ dmad_drb *drb = 0; ++ ++ while (host->buf_sgptr < host->mrq->data->sg_len) { ++ ++ INIT_COMPLETION(host->dma_complete); ++ get_data_buffer(host); ++ ++ dbg(host, dbg_dma, ++ "dma_%s(): new target: [%i]@[%p]\n", ++ host->buf_active == XFER_READ ? "read" : "write", ++ host->buf_bytes, host->buf_ptr); ++ ++ res = dmad_alloc_drb(req, &drb); ++ if (res != 0 || (drb == 0)) { ++ dbg(host, dbg_err, "%s() Failed to allocate dma request block!\n", __func__); ++ host->mrq->data->error = -ENODEV; ++ goto err; ++ } ++ ++ drb->addr0 = SDC_FTSDC010_0_PA_BASE + SDC_DATA_WINDOW_REG; ++ drb->addr1 = (dma_addr_t)host->buf_ptr; ++ drb->req_cycle = dmad_bytes_to_cycles(req, host->buf_bytes); ++ drb->sync = &host->dma_complete; ++ ++ timeout = SDC_TIMEOUT_BASE*((host->buf_bytes+511)>>9); ++ ++ res = dmad_submit_request(req, drb, 1); ++ if (res != 0) { ++ dbg(host, dbg_err, "%s() Failed to submit dma request block!\n", __func__); ++ host->mrq->data->error = -ENODEV; ++ goto err; ++ } ++ ++ dbg(host, dbg_err, "reach here!\n"); ++ if (wait_for_completion_timeout(&host->dma_complete, timeout) == 0) { ++ dbg(host, dbg_err, "%s: read timeout\n", __func__); ++ host->mrq->data->error = -ETIMEDOUT; ++ goto err; ++ } ++ } ++ ++ host->dma_finish = true; ++err: ++ host->buf_active = XFER_NONE; ++ host->complete_what = COMPLETION_FINALIZE; ++} ++ ++static void ftsdc_work(struct work_struct *work) ++{ ++ struct ftsdc_host *host = ++ container_of(work, struct ftsdc_host, work); ++ ++ ftsdc_enable_irq(host, false); ++ ++ if (host->dodma) { ++ do_dma_access(host); ++ } else { ++ if (host->buf_active == XFER_WRITE) ++ do_pio_write(host); ++ ++ if (host->buf_active == XFER_READ) ++ do_pio_read(host); ++ } ++ ++ tasklet_schedule(&host->pio_tasklet); ++ ftsdc_enable_irq(host, true); ++} ++ ++ ++static void pio_tasklet(unsigned long data) ++{ ++ struct ftsdc_host *host = (struct ftsdc_host *) data; ++ ++ if (host->complete_what == COMPLETION_XFER_PROGRESS) { ++ queue_work(mywq, (struct work_struct *)&host->work); ++ return; ++ } ++ ++ if (host->complete_what == COMPLETION_FINALIZE) { ++ clear_imask(host); ++ if (host->buf_active != XFER_NONE) { ++ dbg(host, dbg_err, "unfinished %s " ++ "- buf_count:[%u] buf_bytes:[%u]\n", ++ (host->buf_active == XFER_READ) ? "read" : "write", ++ host->buf_count, host->buf_bytes); ++ ++ if (host->mrq->data) ++ host->mrq->data->error = -EINVAL; ++ } ++ ++ finalize_request(host); ++ } ++} ++ ++ ++static void finalize_request(struct ftsdc_host *host) ++{ ++ struct mmc_request *mrq = host->mrq; ++ struct mmc_command *cmd; ++ u32 con; ++ int debug_as_failure = 0; ++ ++ if (host->complete_what != COMPLETION_FINALIZE) ++ return; ++ ++ if (!mrq) ++ return; ++ ++ cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; ++ ++ if (cmd->data && (cmd->error == 0) && ++ (cmd->data->error == 0)) { ++ if (host->dodma && (!host->dma_finish)) { ++ dbg(host, dbg_dma, "DMA Missing (%d)!\n", ++ host->dma_finish); ++ return; ++ } ++ host->dodma = false; ++ } ++ ++ /* Read response from controller. */ ++ if (cmd->flags & MMC_RSP_136) { ++ cmd->resp[3] = REG_READ(SDC_RESPONSE0_REG); ++ cmd->resp[2] = REG_READ(SDC_RESPONSE1_REG); ++ cmd->resp[1] = REG_READ(SDC_RESPONSE2_REG); ++ cmd->resp[0] = REG_READ(SDC_RESPONSE3_REG); ++ } else if (cmd->flags & MMC_RSP_PRESENT) { ++ cmd->resp[0] = REG_READ(SDC_RESPONSE0_REG); ++ } ++ ++ if (cmd->error) ++ debug_as_failure = 1; ++ ++ if (cmd->data && cmd->data->error) ++ debug_as_failure = 1; ++ ++ dbg_dumpcmd(host, cmd, debug_as_failure); ++ ++ clear_imask(host); ++ con = REG_READ(SDC_STATUS_REG); ++ con &= ~SDC_CLEAR_REG_SDIO_INTR; ++ REG_WRITE(con, SDC_CLEAR_REG); ++ ++ if (cmd->data && cmd->error) ++ cmd->data->error = cmd->error; ++ ++ if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) { ++ host->cmd_is_stop = 1; ++ ftsdc_send_request(host->mmc); ++ return; ++ } ++ ++ /* If we have no data transfer we are finished here */ ++ if (!mrq->data) ++ goto request_done; ++ ++ /* Calulate the amout of bytes transfer if there was no error */ ++ if (mrq->data->error == 0) { ++ mrq->data->bytes_xfered = ++ (mrq->data->blocks * mrq->data->blksz); ++ } else { ++ mrq->data->bytes_xfered = 0; ++ } ++ ++request_done: ++ host->complete_what = COMPLETION_NONE; ++ host->mrq = NULL; ++ ++ host->last_opcode = mrq->cmd->opcode; ++ mmc_request_done(host->mmc, mrq); ++} ++ ++static void ftsdc_send_command(struct ftsdc_host *host, ++ struct mmc_command *cmd) ++{ ++ u32 ccon = 0; ++ u32 newmask = 0; ++ u32 scon; ++ ++ if (cmd->data) { ++ host->complete_what = COMPLETION_XFER_PROGRESS; ++ newmask |= SDC_INT_MASK_REG_RSP_TIMEOUT; ++ } else if (cmd->flags & MMC_RSP_PRESENT) { ++ host->complete_what = COMPLETION_RSPFIN; ++ newmask |= SDC_INT_MASK_REG_RSP_TIMEOUT; ++ } else { ++ host->complete_what = COMPLETION_CMDSENT; ++ newmask |= SDC_INT_MASK_REG_CMD_SEND; ++ } ++ ++ ccon |= cmd->opcode & SDC_CMD_REG_INDEX; ++ ccon |= SDC_CMD_REG_CMD_EN; ++ ++ if (cmd->flags & MMC_RSP_PRESENT) { ++ ccon |= SDC_CMD_REG_NEED_RSP; ++ newmask |= SDC_INT_MASK_REG_RSP_CRC_OK | ++ SDC_INT_MASK_REG_RSP_CRC_FAIL; ++ } ++ ++ if (cmd->flags & MMC_RSP_136) ++ ccon |= SDC_CMD_REG_LONG_RSP; ++ ++ /* applicatiion specific cmd must follow an MMC_APP_CMD. The ++ * value will be updated in finalize_request function */ ++ if (host->last_opcode == MMC_APP_CMD) ++ ccon |= SDC_CMD_REG_APP_CMD; ++ ++ enable_imask(host, newmask); ++ REG_WRITE(cmd->arg, SDC_ARGU_REG); ++ ++ scon = REG_READ(SDC_SDIO_CTRL1_REG); ++ if (host->mmc->card != NULL && mmc_card_sdio(host->mmc->card)) ++ scon |= SDC_SDIO_CTRL1_REG_SDIO_ENABLE; ++ else ++ scon &= ~SDC_SDIO_CTRL1_REG_SDIO_ENABLE; ++ REG_WRITE(scon, SDC_SDIO_CTRL1_REG); ++ ++ dbg_dumpregs(host, ""); ++ dbg(host, dbg_debug, "CON[%x]\n", ccon); ++ ++ REG_WRITE(ccon, SDC_CMD_REG); ++} ++ ++static int ftsdc_setup_data(struct ftsdc_host *host, struct mmc_data *data) ++{ ++ u32 dcon, newmask = 0; ++ ++ /* configure data transfer paramter */ ++ ++ if (!data) ++ return 0; ++ if(host->mmc->card && host->mmc->card->type==(unsigned int)MMC_TYPE_SD){ ++ if (((data->blksz - 1) & data->blksz) != 0) { ++ pr_warning("%s: can't do non-power-of 2 sized block transfers (blksz %d)\n", __func__, data->blksz); ++ return -EINVAL; ++ } ++ } ++ ++ if (data->blksz <= 2) { ++ /* We cannot deal with unaligned blocks with more than ++ * one block being transfered. */ ++ ++ if (data->blocks > 1) { ++ pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz); ++ return -EINVAL; ++ } ++ } ++ ++ /* data length */ ++ dcon = data->blksz * data->blocks; ++ REG_WRITE(dcon, SDC_DATA_LEN_REG); ++ ++ /* write data control */ ++ dcon = 0; ++ dcon = cal_blksz(data->blksz); ++ ++ /* enable UNDERFUN will trigger interrupt immediatedly ++ * So setup it when rsp is received successfully ++ */ ++ if (data->flags & MMC_DATA_WRITE) { ++ dcon |= SDC_DATA_CTRL_REG_DATA_WRITE; ++ } else { ++ dcon &= ~SDC_DATA_CTRL_REG_DATA_WRITE; ++ newmask |= SDC_INT_MASK_REG_FIFO_OVERRUN; ++ } ++ ++ /* always reset fifo since last transfer may fail */ ++ dcon |= SDC_DATA_CTRL_REG_FIFO_RST; ++ ++ /* enable data transfer which will be pended until cmd is send */ ++ dcon |= SDC_DATA_CTRL_REG_DATA_EN; ++ ++ if (ftsdc_dmaexist(host) && ++ ((data->blksz * data->blocks) & 0xf) == 0) { ++ newmask &= ~SDC_INT_MASK_REG_FIFO_OVERRUN; ++ dcon |= SDC_DATA_CTRL_REG_DMA_EN; ++ dcon |= SDC_DMA_TYPE_4; ++ host->dodma = true; ++ ++ } ++ ++ REG_WRITE(dcon, SDC_DATA_CTRL_REG); ++ ++ /* add to IMASK register */ ++ newmask |= SDC_INT_MASK_REG_DATA_CRC_FAIL | ++ SDC_INT_MASK_REG_DATA_TIMEOUT; ++ ++ enable_imask(host, newmask); ++ ++ /* handle sdio */ ++ dcon = SDC_SDIO_CTRL1_REG_READ_WAIT_ENABLE & REG_READ(SDC_SDIO_CTRL1_REG); ++ dcon |= data->blksz | data->blocks << 15; ++ if (1 < data->blocks) ++ dcon |= SDC_SDIO_CTRL1_REG_SDIO_BLK_MODE; ++ REG_WRITE(dcon, SDC_SDIO_CTRL1_REG); ++ ++ return 0; ++} ++ ++#define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ) ++ ++static int ftsdc_prepare_buffer(struct ftsdc_host *host, struct mmc_data *data) ++{ ++ int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; ++ ++ if ((!host->mrq) || (!host->mrq->data)) ++ return -EINVAL; ++ ++ BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); ++ ++ host->buf_sgptr = 0; ++ host->buf_bytes = 0; ++ host->buf_count = 0; ++ host->buf_active = rw ? XFER_WRITE : XFER_READ; ++ ++ if (host->dodma) { ++ u32 dma_len; ++ u32 drb_size; ++ dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, ++ rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ if (dma_len == 0) ++ return -ENOMEM; ++ ++ ++ dmad_config_channel_dir(host->dma_req, ++ rw ? DMAD_DIR_A1_TO_A0 : DMAD_DIR_A0_TO_A1); ++ ++ drb_size = dmad_max_size_per_drb(host->dma_req); ++ if (drb_size < (data->blksz & data->blocks)) ++ return -ENODEV; ++ ++ host->dma_finish = false; ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t ftsdc_irq(int irq, void *dev_id) ++{ ++ struct ftsdc_host *host = dev_id; ++ struct mmc_command *cmd; ++ u32 mci_status; ++ u32 mci_clear; ++ u32 mci_imsk; ++ unsigned long iflags; ++ ++ mci_status = REG_READ(SDC_STATUS_REG); ++ mci_imsk = REG_READ(SDC_INT_MASK_REG); ++ ++ dbg(host, dbg_debug, "irq: status:0x%08x, mask : %08x\n", mci_status, mci_imsk); ++ ++ if (mci_status & SDC_STATUS_REG_SDIO_INTR) { ++ if (mci_imsk & SDC_INT_MASK_REG_SDIO_INTR) { ++ mci_clear = SDC_CLEAR_REG_SDIO_INTR; ++ REG_WRITE(mci_clear, SDC_CLEAR_REG); ++ ++ mmc_signal_sdio_irq(host->mmc); ++ return IRQ_HANDLED; ++ } ++ } ++ ++ spin_lock_irqsave(&host->complete_lock, iflags); ++ ++ mci_status = REG_READ(SDC_STATUS_REG); ++ mci_clear = 0; ++ ++ if (mci_status & SDC_STATUS_REG_CARD_CHANGE) { ++ if ((mci_status & SDC_STATUS_REG_CARD_DETECT) ++ == SDC_CARD_INSERT) { ++ host->status = "card insert"; ++ mmc_detect_change(host->mmc, msecs_to_jiffies(500)); ++ } else { ++ host->status = "card remove"; ++ } ++ ++ mci_clear |= SDC_CLEAR_REG_CARD_CHANGE; ++ dbg(host, dbg_irq, "%s\n", host->status); ++ ++ if (host->complete_what != COMPLETION_NONE) { ++ host->mrq->cmd->error = -EIO; ++ goto close_transfer; ++ } ++ ++ goto irq_out; ++ } ++ ++ if ((host->complete_what == COMPLETION_NONE) || ++ (host->complete_what == COMPLETION_FINALIZE)) { ++ host->status = "nothing to complete"; ++ mci_clear = -1u; ++ goto irq_out; ++ } ++ ++ if (!host->mrq) { ++ host->status = "no active mrq"; ++ clear_imask(host); ++ goto irq_out; ++ } ++ ++ cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd; ++ ++ if (!cmd) { ++ host->status = "no active cmd"; ++ clear_imask(host); ++ goto irq_out; ++ } ++ ++ if (mci_status & SDC_STATUS_REG_CMD_SEND) { ++ mci_clear |= SDC_CLEAR_REG_CMD_SEND; ++ ++ if (host->complete_what == COMPLETION_CMDSENT) { ++ host->status = "ok: command sent"; ++ goto close_transfer; ++ } else { ++ host->status = "error: command sent(status not match)"; ++ cmd->error = -EINVAL; ++ goto fail_transfer; ++ } ++ } ++ ++ /* handle error status */ ++ if (mci_status & SDC_STATUS_REG_RSP_TIMEOUT) { ++ dbg(host, dbg_err, "CMDSTAT: error RSP TIMEOUT\n"); ++ mci_clear |= SDC_CLEAR_REG_RSP_TIMEOUT; ++ cmd->error = -ETIMEDOUT; ++ host->status = "error: response timeout"; ++ goto fail_transfer; ++ } ++ ++ if (mci_status & SDC_STATUS_REG_RSP_CRC_FAIL) { ++ mci_clear |= SDC_CLEAR_REG_RSP_CRC_FAIL; ++ /* This is wierd hack */ ++ if (cmd->flags & MMC_RSP_CRC) { ++ dbg(host, dbg_err, "CMDSTAT: error RSP CRC\n"); ++ cmd->error = -EILSEQ; ++ host->status = "error: RSP CRC failed"; ++ goto fail_transfer; ++ } else { ++ host->status = "R3 or R4 type command"; ++ goto close_transfer; ++ } ++ } ++ ++ if (mci_status & SDC_STATUS_REG_RSP_CRC_OK) { ++ mci_clear |= SDC_CLEAR_REG_RSP_CRC_OK; ++ ++ if (host->complete_what == COMPLETION_XFER_PROGRESS) { ++ REG_WRITE(mci_clear, SDC_CLEAR_REG); ++ ++ host->status = "RSP recv OK"; ++ if (!cmd->data) ++ goto close_transfer; ++ ++ if (host->dodma) { ++ tasklet_schedule(&host->pio_tasklet); ++ host->status = "dma access"; ++ goto irq_out; ++ } ++ ++ if (host->buf_active == XFER_WRITE) ++ enable_imask(host, SDC_INT_MASK_REG_FIFO_UNDERRUN); ++ } else if (host->complete_what == COMPLETION_RSPFIN) { ++ goto close_transfer; ++ } ++ } ++ ++ /* handler data transfer */ ++ if (mci_status & SDC_STATUS_REG_DATA_TIMEOUT) { ++ dbg(host, dbg_err, "CMDSTAT: error DATA TIMEOUT\n"); ++ mci_clear |= SDC_CLEAR_REG_DATA_TIMEOUT; ++ cmd->error = -ETIMEDOUT; ++ host->status = "error: data timeout"; ++ goto fail_transfer; ++ } ++ ++ if (mci_status & SDC_STATUS_REG_DATA_CRC_FAIL) { ++ dbg(host, dbg_err, "CMDSTAT: error DATA CRC\n"); ++ mci_clear |= SDC_CLEAR_REG_DATA_CRC_FAIL; ++ cmd->error = -EILSEQ; ++ host->status = "error: data CRC fail"; ++ goto fail_transfer; ++ } ++ ++ if ((mci_status & SDC_STATUS_REG_FIFO_UNDERRUN) || ++ mci_status & SDC_STATUS_REG_FIFO_OVERRUN) { ++ ++ disable_imask(host, SDC_INT_MASK_REG_FIFO_OVERRUN | ++ SDC_INT_MASK_REG_FIFO_UNDERRUN); ++ ++ if (!host->dodma) { ++ if (host->buf_active == XFER_WRITE) { ++ tasklet_schedule(&host->pio_tasklet); ++ host->status = "pio tx"; ++ } else if (host->buf_active == XFER_READ) { ++ ++ tasklet_schedule(&host->pio_tasklet); ++ host->status = "pio rx"; ++ } ++ } ++ } ++ ++ goto irq_out; ++ ++fail_transfer: ++ host->buf_active = XFER_NONE; ++ ++close_transfer: ++ host->complete_what = COMPLETION_FINALIZE; ++ ++ clear_imask(host); ++ tasklet_schedule(&host->pio_tasklet); ++ ++irq_out: ++ REG_WRITE(mci_clear, SDC_CLEAR_REG); ++ ++ dbg(host, dbg_debug, "irq: %s\n", host->status); ++ spin_unlock_irqrestore(&host->complete_lock, iflags); ++ return IRQ_HANDLED; ++} ++ ++static void ftsdc_send_request(struct mmc_host *mmc) ++{ ++ struct ftsdc_host *host = mmc_priv(mmc); ++ struct mmc_request *mrq = host->mrq; ++ struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; ++ ++ host->ccnt++; ++ prepare_dbgmsg(host, cmd, host->cmd_is_stop); ++ dbg(host, dbg_debug, "%s\n", host->dbgmsg_cmd); ++ ++ if (cmd->data) { ++ int res = ftsdc_setup_data(host, cmd->data); ++ ++ host->dcnt++; ++ ++ if (res) { ++ dbg(host, dbg_err, "setup data error %d\n", res); ++ cmd->error = res; ++ cmd->data->error = res; ++ ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ ++ res = ftsdc_prepare_buffer(host, cmd->data); ++ ++ if (res) { ++ dbg(host, dbg_err, "data prepare error %d\n", res); ++ cmd->error = res; ++ cmd->data->error = res; ++ ++ mmc_request_done(mmc, mrq); ++ return; ++ } ++ } ++ ++ /* Send command */ ++ ftsdc_send_command(host, cmd); ++} ++ ++static int ftsdc_get_cd(struct mmc_host *mmc) ++{ ++ struct ftsdc_host *host = mmc_priv(mmc); ++ ++ u32 con = REG_READ(SDC_STATUS_REG); ++ dbg(host, dbg_debug, "get_cd status:%.8x\n\n", con); ++ ++ return (con & SDC_STATUS_REG_CARD_DETECT) ? 0 : 1; ++} ++ ++static void ftsdc_request(struct mmc_host *mmc, struct mmc_request *mrq) ++{ ++ struct ftsdc_host *host = mmc_priv(mmc); ++ ++/* work_around_for_amerald(mrq);*/ ++ host->status = "mmc request"; ++ host->cmd_is_stop = 0; ++ host->mrq = mrq; ++ if (ftsdc_get_cd(mmc) == 0) { ++ dbg(host, dbg_err, "%s: no medium present\n", __func__); ++ host->mrq->cmd->error = -ENOMEDIUM; ++ mmc_request_done(mmc, mrq); ++ } else { ++ ftsdc_send_request(mmc); ++ } ++ ++ dbg(host, dbg_debug, "send request \n"); ++} ++ ++static void ftsdc_set_clk(struct ftsdc_host *host, struct mmc_ios *ios) ++{ ++ u32 clk_div = 0; ++ u32 con; ++ ++ dbg(host, dbg_debug, "request clk : %u \n", ios->clock); ++ con = REG_READ(SDC_CLOCK_CTRL_REG); ++ if (ios->clock == 0) { ++ host->real_rate = 0; ++ con |= SDC_CLOCK_CTRL_REG_CLK_DIS; ++ } else { ++ clk_div = (APB_CLK_IN / (ios->clock << 1)) - 1; ++ host->real_rate = APB_CLK_IN / ((clk_div+1)<<1); ++ if (host->real_rate > ios->clock) { ++ ++clk_div; ++ host->real_rate = APB_CLK_IN / ((clk_div+1)<<1); ++ } ++ if (clk_div > 127) ++ dbg(host, dbg_err, "%s: no match clock rate, %u\n", __func__, ios->clock); ++ ++ con = (con & ~SDC_CLOCK_CTRL_REG_CLK_DIV) | (clk_div & SDC_CLOCK_CTRL_REG_CLK_DIV); ++ con &= ~SDC_CLOCK_CTRL_REG_CLK_DIS; ++ } ++ ++ REG_WRITE(con, SDC_CLOCK_CTRL_REG); ++} ++ ++static void ftsdc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ struct ftsdc_host *host = mmc_priv(mmc); ++ u32 con; ++ ++ con = REG_READ(SDC_POWER_CTRL_REG); ++ switch (ios->power_mode) { ++ case MMC_POWER_ON: ++ case MMC_POWER_UP: ++ con |= SDC_POWER_CTRL_REG_POWER_ON; ++ break; ++ case MMC_POWER_OFF: ++ default: ++ con &= ~SDC_POWER_CTRL_REG_POWER_ON; ++ break; ++ } ++ ++ REG_WRITE(con, SDC_POWER_CTRL_REG); ++ ++ ftsdc_set_clk(host, ios); ++ ++ if ((ios->power_mode == MMC_POWER_ON) || ++ (ios->power_mode == MMC_POWER_UP)) { ++ dbg(host, dbg_debug, "running at %ukHz (requested: %ukHz).\n", ++ host->real_rate/1000, ios->clock/1000); ++ } else { ++ dbg(host, dbg_debug, "powered down.\n"); ++ } ++ ++ host->bus_width = ios->bus_width; ++ /* write bus configure */ ++ con = REG_READ(SDC_BUS_WIDTH_REG); ++ ++ con &= ~(SDC_BUS_WIDTH_REG_SINGLE_BUS | ++ SDC_BUS_WIDTH_REG_WIDE_4_BUS | ++ SDC_BUS_WIDTH_REG_WIDE_8_BUS); ++ if (host->bus_width == MMC_BUS_WIDTH_1) ++ con |= SDC_BUS_WIDTH_REG_SINGLE_BUS; ++ else if (host->bus_width == MMC_BUS_WIDTH_4) ++ con |= SDC_BUS_WIDTH_REG_WIDE_4_BUS; ++ else if (host->bus_width == MMC_BUS_WIDTH_8) ++ con |= SDC_BUS_WIDTH_REG_WIDE_8_BUS; ++ else { ++ dbg(host, dbg_err, "set_ios: can't support bus mode"); ++ } ++ REG_WRITE(con, SDC_BUS_WIDTH_REG); ++ ++ /*set rsp and data timeout */ ++ con = -1; ++ REG_WRITE(con, SDC_DATA_TIMER_REG); ++} ++ ++static int ftsdc_get_ro(struct mmc_host *mmc) ++{ ++ struct ftsdc_host *host = mmc_priv(mmc); ++ u32 con = REG_READ(SDC_STATUS_REG); ++ dbg(host, dbg_debug, "get_ro status:%.8x\n", con); ++ ++ return (con & SDC_STATUS_REG_CARD_LOCK) ? 1 : 0; ++} ++ ++ ++static void ftsdc_enable_sdio_irq(struct mmc_host *mmc, int enable) ++{ ++ struct ftsdc_host *host = mmc_priv(mmc); ++ unsigned long flags; ++ u32 con; ++#ifdef CONFIG_MMC_DEBUG ++ u32 ena; ++#endif ++ ++ local_irq_save(flags); ++ ++ con = REG_READ(SDC_INT_MASK_REG); ++#ifdef CONFIG_MMC_DEBUG ++ ena = (con & SDC_STATUS_REG_SDIO_INTR) ? 1:0; ++ if (ena == enable) ++ printk("\n*** XXX ***\n"); ++#endif ++ ++ con = enable ? (con | SDC_STATUS_REG_SDIO_INTR) : (con & ~SDC_STATUS_REG_SDIO_INTR); ++ REG_WRITE(con, SDC_INT_MASK_REG); ++ ++#ifdef CONFIG_MMC_DEBUG ++ //check and ensure data out to SD host controller ++ ena = (REG_READ(SDC_INT_MASK_REG) & SDC_STATUS_REG_SDIO_INTR) ? 1:0; ++ if (ena != enable) { ++ printk("\n*** YYY ***\n"); ++ } ++#endif ++ ++ local_irq_restore(flags); ++} ++ ++static struct mmc_host_ops ftsdc_ops = { ++ .request = ftsdc_request, ++ .set_ios = ftsdc_set_ios, ++ .get_ro = ftsdc_get_ro, ++ .get_cd = ftsdc_get_cd, ++ .enable_sdio_irq = ftsdc_enable_sdio_irq, ++}; ++ ++#ifdef CONFIG_DEBUG_FS ++ ++static int ftsdc_state_show(struct seq_file *seq, void *v) ++{ ++ struct ftsdc_host *host = seq->private; ++ ++ seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base); ++ seq_printf(seq, "Clock rate = %u\n", host->real_rate); ++ seq_printf(seq, "host status = %s\n", host->status); ++ seq_printf(seq, "IRQ = %d\n", host->irq); ++ seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled); ++ seq_printf(seq, "complete what = %d\n", host->complete_what); ++ seq_printf(seq, "dma support = %d\n", ftsdc_dmaexist(host)); ++ seq_printf(seq, "use dma = %d\n", host->dodma); ++ ++ return 0; ++} ++ ++static int ftsdc_state_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, ftsdc_state_show, inode->i_private); ++} ++ ++static const struct file_operations ftsdc_fops_state = { ++ .owner = THIS_MODULE, ++ .open = ftsdc_state_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++#define DBG_REG(_r) { .addr = SDC_## _r ## _REG, .name = #_r } ++ ++struct ftsdc_reg { ++ unsigned short addr; ++ unsigned char *name; ++} debug_regs[] = { ++ DBG_REG(CMD), ++ DBG_REG(ARGU), ++ DBG_REG(RESPONSE0), ++ DBG_REG(RESPONSE1), ++ DBG_REG(RESPONSE2), ++ DBG_REG(RESPONSE3), ++ DBG_REG(RSP_CMD), ++ DBG_REG(DATA_CTRL), ++ DBG_REG(DATA_TIMER), ++ DBG_REG(DATA_LEN), ++ DBG_REG(STATUS), ++ DBG_REG(CLEAR), ++ DBG_REG(INT_MASK), ++ DBG_REG(POWER_CTRL), ++ DBG_REG(CLOCK_CTRL), ++ DBG_REG(BUS_WIDTH), ++ DBG_REG(SDIO_CTRL1), ++ DBG_REG(SDIO_CTRL2), ++ DBG_REG(SDIO_STATUS), ++ DBG_REG(FEATURE), ++ DBG_REG(REVISION), ++ {} ++}; ++ ++static int ftsdc_regs_show(struct seq_file *seq, void *v) ++{ ++ struct ftsdc_host *host = seq->private; ++ struct ftsdc_reg *rptr = debug_regs; ++ ++ for (; rptr->name; rptr++) ++ seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name, ++ REG_READ(rptr->addr)); ++ ++ return 0; ++} ++ ++static int ftsdc_regs_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, ftsdc_regs_show, inode->i_private); ++} ++ ++static const struct file_operations ftsdc_fops_regs = { ++ .owner = THIS_MODULE, ++ .open = ftsdc_regs_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static void ftsdc_debugfs_attach(struct ftsdc_host *host) ++{ ++ struct device *dev = &host->pdev->dev; ++ ++ host->debug_root = debugfs_create_dir(dev_name(dev), NULL); ++ if (IS_ERR(host->debug_root)) { ++ dev_err(dev, "failed to create debugfs root\n"); ++ return; ++ } ++ ++ host->debug_state = debugfs_create_file("state", 0444, ++ host->debug_root, host, ++ &ftsdc_fops_state); ++ ++ if (IS_ERR(host->debug_state)) ++ dev_err(dev, "failed to create debug state file\n"); ++ ++ host->debug_regs = debugfs_create_file("regs", 0444, ++ host->debug_root, host, ++ &ftsdc_fops_regs); ++ ++ if (IS_ERR(host->debug_regs)) ++ dev_err(dev, "failed to create debug regs file\n"); ++} ++ ++static void ftsdc_debugfs_remove(struct ftsdc_host *host) ++{ ++ debugfs_remove(host->debug_regs); ++ debugfs_remove(host->debug_state); ++ debugfs_remove(host->debug_root); ++} ++ ++#else ++static inline void ftsdc_debugfs_attach(struct ftsdc_host *host) { } ++static inline void ftsdc_debugfs_remove(struct ftsdc_host *host) { } ++ ++#endif /* CONFIG_DEBUG_FS */ ++ ++#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) ++static int ftsdc_alloc_dma(struct ftsdc_host *host) ++{ ++ dmad_chreq *req = host->dma_req; ++ ++ req = kzalloc(sizeof(dmad_chreq), GFP_KERNEL); ++#ifdef CONFIG_PLATFORM_APBDMA ++#ifdef CONFIG_PLAT_AG102 ++ //ADD by river 2010.10.20 ++ outl(inl(PCU_VA_BASE + 0x38) | 0x00000300, PCU_VA_BASE + 0x38); ++ //End ADD by river 2010.10.20 ++#endif ++ req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */ ++/* for amerald */ ++ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID){ ++ req->apb_req.addr0_reqn = APBBR_REQN_SDC_AMERALD; ++ }else ++ { ++ req->apb_req.addr0_reqn = APBBR_REQN_SDC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ ++ } ++ req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */ ++ req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ ++ req->apb_req.burst_mode = 1; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */ ++ req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */ ++ req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ ++ req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ ++ req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; ++ ++ if (dmad_channel_alloc(req) == 0) { ++ dbg(host, dbg_debug, "%s: APB dma channel allocated (ch: %d)\n", __func__, req->channel); ++ host->dma_req = req; ++ return 0; ++ } ++ ++ memset(req, 0, sizeof(dmad_chreq)); ++ dbg(host, dbg_info, "%s: APB dma channel allocation failed\n", __func__); ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */ ++ req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */ ++ req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */ ++ req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */ ++ req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ ++ req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ ++ req->ahb_req.addr0_reqn = DMAC_REQN_SDC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ ++ req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ ++ req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ ++ req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ ++ req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ ++ ++ req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ ++ req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; ++ ++ if (dmad_channel_alloc(req) == 0) { ++ dbg(host, dbg_debug, "%s: AHB dma channel allocated (ch: %d)\n", __func__, req->channel); ++ host->dma_req = req; ++ return 0; ++ } ++ ++ dbg(host, dbg_info, "%s: AHB dma channel allocation failed\n", __func__); ++#endif ++ ++ kfree(req); ++ return -ENODEV; ++ ++} ++#endif ++ ++static int __devinit ftsdc_probe(struct platform_device *pdev) ++{ ++ struct ftsdc_host *host; ++ struct mmc_host *mmc; ++ int ret = -ENOMEM; ++ u32 con; ++ ++ mmc = mmc_alloc_host(sizeof(struct ftsdc_host), &pdev->dev); ++ if (!mmc) { ++// ret = -ENOMEM; ++ goto probe_out; ++ } ++ ++ host = mmc_priv(mmc); ++ host->mmc = mmc; ++ host->pdev = pdev; ++ ++ mywq = create_workqueue("atcsdc_queue"); ++ if (NULL == mywq) ++ goto probe_free_host; ++ ++ spin_lock_init(&host->complete_lock); ++ tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); ++ init_completion(&host->dma_complete); ++ INIT_WORK(&host->work, ftsdc_work); ++ ++ host->complete_what = COMPLETION_NONE; ++ host->buf_active = XFER_NONE; ++ ++#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) ++ ftsdc_alloc_dma(host); ++#endif ++ ++ host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!host->mem) { ++ dev_err(&pdev->dev, ++ "failed to get io memory region resouce.\n"); ++ ++ ret = -ENOENT; ++ goto probe_free_host; ++ } ++ ++ host->mem = request_mem_region(host->mem->start, ++ resource_size(host->mem), pdev->name); ++ ++ if (!host->mem) { ++ dev_err(&pdev->dev, "failed to request io memory region.\n"); ++ ret = -ENOENT; ++ goto probe_free_wq; ++ } ++ ++ host->base = (void __iomem *) SDC_FTSDC010_0_VA_BASE; ++ host->irq = SDC_FTSDC010_IRQ; ++ if (request_irq(host->irq, ftsdc_irq, IRQF_DISABLED, DRIVER_NAME, host)) { ++ dev_err(&pdev->dev, "failed to request mci interrupt.\n"); ++ ret = -ENOENT; ++ goto probe_free_mem_region; ++ } ++ host->irq_enabled = true; ++ ++ /* enable card change interruption */ ++ con = REG_READ(SDC_INT_MASK_REG); ++ con |= SDC_INT_MASK_REG_CARD_CHANGE; ++ REG_WRITE(con, SDC_INT_MASK_REG); ++ ++ con = REG_READ(SDC_BUS_WIDTH_REG); ++ ++ mmc->ops = &ftsdc_ops; ++ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; ++ ++ if (con & SDC_WIDE_4_BUS_SUPPORT) ++ mmc->caps |= MMC_CAP_4_BIT_DATA; ++ else if (con & SDC_WIDE_8_BUS_SUPPORT) ++ mmc->caps |= MMC_CAP_8_BIT_DATA; ++ ++#ifndef A320D_BUILDIN_SDC ++ mmc->caps |= MMC_CAP_SDIO_IRQ; ++#endif ++ ++ mmc->f_min = APB_CLK_IN / (2 * 128); ++ mmc->f_max = APB_CLK_IN / 2; ++ ++ /* limit SDIO mode max size */ ++ mmc->max_req_size = 128 * 1024 * 1024 - 1; ++ mmc->max_blk_size = 2047; ++ mmc->max_req_size = (mmc->max_req_size + 1) / (mmc->max_blk_size + 1); ++ mmc->max_seg_size = mmc->max_req_size; ++ mmc->max_blk_count = (1<<17)-1; ++ ++ /* kernel default value. see Doc/block/biodocs.txt */ ++ /* ++ 'struct mmc_host' has no member named 'max_phys_segs' ++ 'struct mmc_host' has no member named 'max_hw_segs' ++ */ ++// mmc->max_phys_segs = 128; ++// mmc->max_hw_segs = 128; ++ ++ /* set fifo lenght and default threshold half */ ++ con = REG_READ(SDC_FEATURE_REG); ++ host->fifo_len = (con & SDC_FEATURE_REG_FIFO_DEPTH) * sizeof(u32); ++ ++ dbg(host, dbg_debug, ++ "probe: mapped mci_base:%p irq:%u.\n", ++ host->base, host->irq); ++ ++ dbg_dumpregs(host, ""); ++ ++ ret = mmc_add_host(mmc); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to add mmc host.\n"); ++ goto probe_free_irq; ++ } ++ ++ ftsdc_debugfs_attach(host); ++ ++ platform_set_drvdata(pdev, mmc); ++ dev_info(&pdev->dev, "%s - using %s SDIO IRQ\n", mmc_hostname(mmc), ++ mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw"); ++ ++ return 0; ++ ++ probe_free_irq: ++ free_irq(host->irq, host); ++ ++ probe_free_mem_region: ++ release_mem_region(host->mem->start, resource_size(host->mem)); ++ ++probe_free_wq: ++ destroy_workqueue(mywq); ++ ++ probe_free_host: ++ mmc_free_host(mmc); ++ ++ probe_out: ++ return ret; ++} ++ ++static void ftsdc_shutdown(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(pdev); ++ struct ftsdc_host *host = mmc_priv(mmc); ++ ++ flush_workqueue(mywq); ++ destroy_workqueue(mywq); ++ ++ ftsdc_debugfs_remove(host); ++ mmc_remove_host(mmc); ++} ++ ++static int __devexit ftsdc_remove(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(pdev); ++ struct ftsdc_host *host = mmc_priv(mmc); ++ ++ ftsdc_shutdown(pdev); ++ ++ tasklet_disable(&host->pio_tasklet); ++ ++ if (ftsdc_dmaexist(host)) ++ kfree(host->dma_req); ++ ++ free_irq(host->irq, host); ++ ++ release_mem_region(host->mem->start, resource_size(host->mem)); ++ ++ mmc_free_host(mmc); ++ return 0; ++} ++ ++ ++#ifdef CONFIG_PM ++static int ftsdc_free_dma(struct ftsdc_host *host) ++{ ++ dmad_channel_free(host->dma_req); ++ return 0; ++} ++ ++static int ftsdc_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(pdev); ++ struct ftsdc_host *host = mmc_priv(mmc); ++ int ret = 0; ++ if (mmc) { ++ ftsdc_free_dma(host); ++ ret = mmc_suspend_host(mmc); ++ } ++ return ret; ++ ++} ++ ++static int ftsdc_resume(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc = platform_get_drvdata(pdev); ++ int ret = 0; ++ struct ftsdc_host *host = mmc_priv(mmc); ++ if (mmc) { ++#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) ++ ftsdc_alloc_dma(host); ++#endif ++ ret = mmc_resume_host(mmc); ++ } ++ return ret; ++} ++ ++static void platform_device_release(struct device *dev){ ++} ++ ++ ++#else ++#define ftsdc_suspend NULL ++#define ftsdc_resume NULL ++#endif ++ ++ ++static struct platform_driver ftsdc_driver = { ++ .driver = { ++ .name = "ftsdc010", ++ .owner = THIS_MODULE, ++ }, ++ .probe = ftsdc_probe, ++ .remove = __devexit_p(ftsdc_remove), ++ .shutdown = ftsdc_shutdown, ++ .suspend = ftsdc_suspend, ++ .resume = ftsdc_resume, ++}; ++ ++static struct resource sdc_resource[] = { ++ [0] = { ++ .start = SDC_FTSDC010_0_VA_BASE, ++ .end = SDC_FTSDC010_0_VA_BASE + 0x1000 - 1, ++ .flags = IORESOURCE_MEM, ++ }, ++ [1] = { ++ .start = SDC_FTSDC010_0_IRQ, ++ .flags = IORESOURCE_IRQ, ++ } ++ ++}; ++ ++struct platform_device sdc_device = { ++ .name = "ftsdc010", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(sdc_resource), ++ .resource = sdc_resource, ++ .dev = { ++ .release = platform_device_release, ++ }, ++}; ++ ++static int __init ftsdc_init(void) ++{ ++ platform_device_register(&sdc_device); ++ return platform_driver_register(&ftsdc_driver); ++} ++ ++static void __exit ftsdc_exit(void) ++{ ++ platform_driver_unregister(&ftsdc_driver); ++ platform_device_unregister(&sdc_device); ++} ++module_init(ftsdc_init); ++module_exit(ftsdc_exit); ++ ++MODULE_DESCRIPTION("Andestech Leopard MMC/SD Card Interface driver"); ++MODULE_LICENSE("GPL v2"); +diff -Nur linux-3.4.110.orig/drivers/mmc/host/ftsdc010.h linux-3.4.110/drivers/mmc/host/ftsdc010.h +--- linux-3.4.110.orig/drivers/mmc/host/ftsdc010.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/mmc/host/ftsdc010.h 2016-04-07 10:20:51.050085202 +0200 +@@ -0,0 +1,240 @@ ++/* ++ * linux/driver/mmc/ftsdc010.h - Andestech MMC/SD driver ++ * Andestech FTSDC010 Device Driver ++ * ++ * Andestech (C) 2005 Faraday Corp. (http://www.Andestech.com) ++ * ++ * All Rights Reserved ++ */ ++ ++#ifndef _FTSDC010_H_ ++#define _FTSDC010_H_ ++ ++//#define SD_DEBUG ++#define DELAY_FOR_DMA_READ ++ ++#ifdef SD_DEBUG ++ #define P_DEBUG(fmt, args...) printk(KERN_ALERT "SD: " fmt, ## args) ++#else ++ #define P_DEBUG(a...) ++#endif ++#define P_DEBUGG(a...) ++ ++/* used for dma timeout */ ++#define SDC_TIMEOUT_BASE (HZ/2) // Unit is 500 ms ++ ++/* used for pio retry times */ ++#define SDC_PIO_RETRY 0x300000 ++ ++/* sd controller register */ ++#define SDC_CMD_REG 0x00000000 ++#define SDC_ARGU_REG 0x00000004 ++#define SDC_RESPONSE0_REG 0x00000008 ++#define SDC_RESPONSE1_REG 0x0000000C ++#define SDC_RESPONSE2_REG 0x00000010 ++#define SDC_RESPONSE3_REG 0x00000014 ++#define SDC_RSP_CMD_REG 0x00000018 ++#define SDC_DATA_CTRL_REG 0x0000001C ++#define SDC_DATA_TIMER_REG 0x00000020 ++#define SDC_DATA_LEN_REG 0x00000024 ++#define SDC_STATUS_REG 0x00000028 ++#define SDC_CLEAR_REG 0x0000002C ++#define SDC_INT_MASK_REG 0x00000030 ++#define SDC_POWER_CTRL_REG 0x00000034 ++#define SDC_CLOCK_CTRL_REG 0x00000038 ++#define SDC_BUS_WIDTH_REG 0x0000003C ++#define SDC_DATA_WINDOW_REG 0x00000040 ++ ++#ifdef A320D_BUILDIN_SDC ++#define SDC_FEATURE_REG 0x00000044 ++#define SDC_REVISION_REG 0x00000048 ++#else ++#define SDC_MMC_INT_RSP_REG 0x00000044 ++#define SDC_GP_OUTPUT_REG 0x00000048 ++#define SDC_FEATURE_REG 0x0000009C ++#define SDC_REVISION_REG 0x000000A0 ++#endif ++ ++#define SDC_SDIO_CTRL1_REG 0x0000006C ++#define SDC_SDIO_CTRL2_REG 0x00000070 ++#define SDC_SDIO_STATUS_REG 0x00000074 ++ ++/* bit mapping of command register */ ++#define SDC_CMD_REG_INDEX 0x0000003F ++#define SDC_CMD_REG_NEED_RSP 0x00000040 ++#define SDC_CMD_REG_LONG_RSP 0x00000080 ++#define SDC_CMD_REG_APP_CMD 0x00000100 ++#define SDC_CMD_REG_CMD_EN 0x00000200 ++#define SDC_CMD_REG_SDC_RST 0x00000400 ++#define SDC_CMD_MMC_INT_STOP 0x00000800 ++ ++/* bit mapping of response command register */ ++#define SDC_RSP_CMD_REG_INDEX 0x0000003F ++#define SDC_RSP_CMD_REG_APP 0x00000040 ++ ++/* bit mapping of data control register */ ++#define SDC_DATA_CTRL_REG_BLK_SIZE 0x0000000F ++#define SDC_DATA_CTRL_REG_DATA_WRITE 0x00000010 ++#define SDC_DATA_CTRL_REG_DMA_EN 0x00000020 ++#define SDC_DATA_CTRL_REG_DATA_EN 0x00000040 ++#define SDC_DATA_CTRL_REG_FIFOTH 0x00000080 ++#define SDC_DATA_CTRL_REG_DMA_TYPE 0x00000300 ++#define SDC_DATA_CTRL_REG_FIFO_RST 0x00000400 ++#define SDC_CPRM_DATA_CHANGE_ENDIAN_EN 0x00000800 ++#define SDC_CPRM_DATA_SWAP_HL_EN 0x00001000 ++ ++#define SDC_DMA_TYPE_1 0x00000000 ++#define SDC_DMA_TYPE_4 0x00000100 ++#define SDC_DMA_TYPE_8 0x00000200 ++ ++/* bit mapping of status register */ ++#define SDC_STATUS_REG_RSP_CRC_FAIL 0x00000001 ++#define SDC_STATUS_REG_DATA_CRC_FAIL 0x00000002 ++#define SDC_STATUS_REG_RSP_TIMEOUT 0x00000004 ++#define SDC_STATUS_REG_DATA_TIMEOUT 0x00000008 ++#define SDC_STATUS_REG_RSP_CRC_OK 0x00000010 ++#define SDC_STATUS_REG_DATA_CRC_OK 0x00000020 ++#define SDC_STATUS_REG_CMD_SEND 0x00000040 ++#define SDC_STATUS_REG_DATA_END 0x00000080 ++#define SDC_STATUS_REG_FIFO_UNDERRUN 0x00000100 ++#define SDC_STATUS_REG_FIFO_OVERRUN 0x00000200 ++#define SDC_STATUS_REG_CARD_CHANGE 0x00000400 ++#define SDC_STATUS_REG_CARD_DETECT 0x00000800 ++#define SDC_STATUS_REG_CARD_LOCK 0x00001000 ++#define SDC_STATUS_REG_CP_READY 0x00002000 ++#define SDC_STATUS_REG_CP_BUF_READY 0x00004000 ++#define SDC_STATUS_REG_PLAIN_TEXT_READY 0x00008000 ++#define SDC_STATUS_REG_SDIO_INTR 0x00010000 ++ ++/* bit mapping of clear register */ ++#define SDC_CLEAR_REG_RSP_CRC_FAIL 0x00000001 ++#define SDC_CLEAR_REG_DATA_CRC_FAIL 0x00000002 ++#define SDC_CLEAR_REG_RSP_TIMEOUT 0x00000004 ++#define SDC_CLEAR_REG_DATA_TIMEOUT 0x00000008 ++#define SDC_CLEAR_REG_RSP_CRC_OK 0x00000010 ++#define SDC_CLEAR_REG_DATA_CRC_OK 0x00000020 ++#define SDC_CLEAR_REG_CMD_SEND 0x00000040 ++#define SDC_CLEAR_REG_DATA_END 0x00000080 ++#define SDC_CLEAR_REG_CARD_CHANGE 0x00000400 ++#define SDC_CLEAR_REG_SDIO_INTR 0x00010000 ++ ++/* bit mapping of int_mask register */ ++#define SDC_INT_MASK_REG_RSP_CRC_FAIL 0x00000001 ++#define SDC_INT_MASK_REG_DATA_CRC_FAIL 0x00000002 ++#define SDC_INT_MASK_REG_RSP_TIMEOUT 0x00000004 ++#define SDC_INT_MASK_REG_DATA_TIMEOUT 0x00000008 ++#define SDC_INT_MASK_REG_RSP_CRC_OK 0x00000010 ++#define SDC_INT_MASK_REG_DATA_CRC_OK 0x00000020 ++#define SDC_INT_MASK_REG_CMD_SEND 0x00000040 ++#define SDC_INT_MASK_REG_DATA_END 0x00000080 ++#define SDC_INT_MASK_REG_FIFO_UNDERRUN 0x00000100 ++#define SDC_INT_MASK_REG_FIFO_OVERRUN 0x00000200 ++#define SDC_INT_MASK_REG_CARD_CHANGE 0x00000400 ++#define SDC_INT_MASK_REG_CARD_LOCK 0x00001000 ++#define SDC_INT_MASK_REG_CP_READY 0x00002000 ++#define SDC_INT_MASK_REG_CP_BUF_READY 0x00004000 ++#define SDC_INT_MASK_REG_PLAIN_TEXT_READY 0x00008000 ++#define SDC_INT_MASK_REG_SDIO_INTR 0x00010000 ++ ++ ++#define SDC_CARD_INSERT 0x0 ++#define SDC_CARD_REMOVE SDC_STATUS_REG_CARD_DETECT ++ ++/* bit mapping of power control register */ ++#define SDC_POWER_CTRL_REG_POWER_ON 0x00000010 ++#define SDC_POWER_CTRL_REG_POWER_BITS 0x0000000F ++ ++/* bit mapping of clock control register */ ++#define SDC_CLOCK_CTRL_REG_CLK_DIV 0x0000007F ++#define SDC_CLOCK_CTRL_REG_CARD_TYPE 0x00000080 ++#define SDC_CLOCK_CTRL_REG_CLK_DIS 0x00000100 ++ ++/* card type */ ++#define SDC_CARD_TYPE_SD SDC_CLOCK_REG_CARD_TYPE ++#define SDC_CARD_TYPE_MMC 0x0 ++ ++/* bit mapping of bus width register */ ++#define SDC_BUS_WIDTH_REG_SINGLE_BUS 0x00000001 ++#define SDC_BUS_WIDTH_REG_WIDE_8_BUS 0x00000002 ++#define SDC_BUS_WIDTH_REG_WIDE_4_BUS 0x00000004 ++#define SDC_BUS_WIDTH_REG_WIDE_BUS_SUPPORT 0x00000018 ++#define SDC_BUS_WIDTH_REG_CARD_DETECT 0x00000020 ++ ++#define SDC_WIDE_4_BUS_SUPPORT 0x00000008 ++#define SDC_WIDE_8_BUS_SUPPORT 0x00000010 ++ ++/* bit mapping of feature register */ ++#define SDC_FEATURE_REG_FIFO_DEPTH 0x000000FF ++#define SDC_FEATURE_REG_CPRM_FUNCTION 0x00000100 ++ ++/* bit mapping of sdio control register */ ++#define SDC_SDIO_CTRL1_REG_SDIO_BLK_NO 0xFFFF8000 ++#define SDC_SDIO_CTRL1_REG_SDIO_ENABLE 0x00004000 ++#define SDC_SDIO_CTRL1_REG_READ_WAIT_ENABLE 0x00002000 ++#define SDC_SDIO_CTRL1_REG_SDIO_BLK_MODE 0x00001000 ++#define SDC_SDIO_CTRL1_REG_SDIO_BLK_SIZE 0x00000FFF ++ ++/* bit mapping of sdio status register */ ++#define SDC_SDIO_SDIO_STATUS_REG_FIFO_REMAIN_NO 0x00FE0000 ++#define SDC_SDIO_SDIO_STATUS_REG_SDIO_BLK_CNT 0x0001FFFF ++ ++enum ftsdc_waitfor { ++ COMPLETION_NONE, ++ COMPLETION_FINALIZE, ++ COMPLETION_CMDSENT, ++ COMPLETION_RSPFIN, ++ COMPLETION_XFER_PROGRESS, ++}; ++ ++struct ftsdc_host { ++ struct platform_device *pdev; ++ struct mmc_host *mmc; ++ struct resource *mem; ++ struct clk *clk; ++ void __iomem *base; ++ int irq; ++ ++ unsigned int real_rate; ++ bool irq_enabled; ++ unsigned int fifo_len; /* bytes */ ++ unsigned int last_opcode; /* keep last successful cmd to judge application specific command */ ++ ++ struct mmc_request *mrq; ++ int cmd_is_stop; ++ ++ spinlock_t complete_lock; ++ enum ftsdc_waitfor complete_what; ++ ++ struct completion dma_complete; ++ dmad_chreq *dma_req; ++ bool dodma; ++ bool dma_finish; ++ ++ ++ u32 buf_sgptr; /* keep next scallterlist buffer index */ ++ u32 buf_bytes; /* keep current total scallterlist buffer length */ ++ u32 buf_count; /* keep real data size rw from sd */ ++ u32 *buf_ptr; /* keep current scallterlist buffer address */ ++#define XFER_NONE 0 ++#define XFER_READ 1 ++#define XFER_WRITE 2 ++ u32 buf_active; /* keep current transfer mode */ ++ ++ int bus_width; ++ ++ char dbgmsg_cmd[301]; ++ char dbgmsg_dat[301]; ++ char *status; ++ ++ unsigned int ccnt, dcnt; ++ struct tasklet_struct pio_tasklet; ++ struct work_struct work; ++ ++#ifdef CONFIG_DEBUG_FS ++ struct dentry *debug_root; ++ struct dentry *debug_state; ++ struct dentry *debug_regs; ++#endif ++}; ++ ++#endif +diff -Nur linux-3.4.110.orig/drivers/mmc/host/Kconfig linux-3.4.110/drivers/mmc/host/Kconfig +--- linux-3.4.110.orig/drivers/mmc/host/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/mmc/host/Kconfig 2016-04-07 10:20:51.050085202 +0200 +@@ -609,3 +609,8 @@ + + Note: These controllers only support SDIO cards and do not + support MMC or SD memory cards. ++ ++config MMC_FTSDC010 ++ tristate "Andestech MMC/SD function support" ++ depends on NDS32 && !FTSDC010 ++ +diff -Nur linux-3.4.110.orig/drivers/mmc/host/Makefile linux-3.4.110/drivers/mmc/host/Makefile +--- linux-3.4.110.orig/drivers/mmc/host/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/mmc/host/Makefile 2016-04-07 10:20:51.050085202 +0200 +@@ -45,6 +45,7 @@ + obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o + obj-$(CONFIG_MMC_VUB300) += vub300.o + obj-$(CONFIG_MMC_USHC) += ushc.o ++obj-$(CONFIG_MMC_FTSDC010) += ftsdc010.o + + obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o + obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o +diff -Nur linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.c linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.c +--- linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.c 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.c 2016-04-07 10:20:51.054085357 +0200 +@@ -1,1202 +1,1210 @@ + /* +- * Faraday FTMAC100 10/100 Ethernet ++ * drivers/net/ftmac100.c + * +- * (C) Copyright 2009-2011 Faraday Technology +- * Po-Yu Chuang ++ * Faraday FTMAC100 Device Driver + * +- * 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. ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * All Rights Reserved + * +- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include ++#include + #include ++#include ++ ++#include ++#include /* printk() */ ++#include /* kmalloc() */ ++#include /* error codes */ ++#include /* size_t */ + #include +-#include +-#include +-#include +-#include ++ ++#include + #include ++#include /* struct device, and other headers */ ++#include /* eth_type_trans */ ++#include /* struct iphdr */ ++#include /* struct tcphdr */ ++#include ++ ++#include ++#include ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + ++#include // dma_clean_range ++#include + #include "ftmac100.h" + +-#define DRV_NAME "ftmac100" +-#define DRV_VERSION "0.2" +- +-#define RX_QUEUE_ENTRIES 128 /* must be power of 2 */ +-#define TX_QUEUE_ENTRIES 16 /* must be power of 2 */ ++#define IPMODULE MAC ++#define IPNAME FTMAC100 + +-#define MAX_PKT_SIZE 1518 +-#define RX_BUF_SIZE 2044 /* must be smaller than 0x7ff */ ++#define ENABLE_BOTTOM_HALF 0 ++#define ZERO_COPY 1 + +-#if MAX_PKT_SIZE > 0x7ff +-#error invalid MAX_PKT_SIZE +-#endif +- +-#if RX_BUF_SIZE > 0x7ff || RX_BUF_SIZE > PAGE_SIZE +-#error invalid RX_BUF_SIZE +-#endif +- +-/****************************************************************************** +- * private data +- *****************************************************************************/ +-struct ftmac100_descs { +- struct ftmac100_rxdes rxdes[RX_QUEUE_ENTRIES]; +- struct ftmac100_txdes txdes[TX_QUEUE_ENTRIES]; +-}; +- +-struct ftmac100 { +- struct resource *res; +- void __iomem *base; +- int irq; +- +- struct ftmac100_descs *descs; +- dma_addr_t descs_dma_addr; +- +- unsigned int rx_pointer; +- unsigned int tx_clean_pointer; +- unsigned int tx_pointer; +- unsigned int tx_pending; +- +- spinlock_t tx_lock; +- +- struct net_device *netdev; +- struct device *dev; +- struct napi_struct napi; ++#define FTMAC100_DEBUG 0 ++#define CARDNAME "FTMAC100" + +- struct mii_if_info mii; +-}; +- +-static int ftmac100_alloc_rx_page(struct ftmac100 *priv, +- struct ftmac100_rxdes *rxdes, gfp_t gfp); +- +-/****************************************************************************** +- * internal functions (hardware register access) +- *****************************************************************************/ +-#define INT_MASK_ALL_ENABLED (FTMAC100_INT_RPKT_FINISH | \ +- FTMAC100_INT_NORXBUF | \ +- FTMAC100_INT_XPKT_OK | \ +- FTMAC100_INT_XPKT_LOST | \ +- FTMAC100_INT_RPKT_LOST | \ +- FTMAC100_INT_AHB_ERR | \ +- FTMAC100_INT_PHYSTS_CHG) ++MODULE_AUTHOR("Faraday Corp."); ++MODULE_LICENSE("GPL"); + +-#define INT_MASK_ALL_DISABLED 0 ++static const char version[] = "Faraday FTMAC100 Driver (Linux 2.6) 09/28/05 - (C) 2005 Faraday Corp.\n"; ++static volatile int trans_busy = 0; ++static const char mac_string[] = "Faraday MAC"; + +-static void ftmac100_enable_all_int(struct ftmac100 *priv) +-{ +- iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTMAC100_OFFSET_IMR); +-} ++#if FTMAC100_DEBUG > 2 ++static void print_packet( unsigned char * buf, int length ); ++#endif + +-static void ftmac100_disable_all_int(struct ftmac100 *priv) +-{ +- iowrite32(INT_MASK_ALL_DISABLED, priv->base + FTMAC100_OFFSET_IMR); +-} ++#if FTMAC100_DEBUG > 0 ++#define PRINTK printk ++#else ++#define PRINTK(x...) ++#endif + +-static void ftmac100_set_rx_ring_base(struct ftmac100 *priv, dma_addr_t addr) +-{ +- iowrite32(addr, priv->base + FTMAC100_OFFSET_RXR_BADR); ++static int ftmac100_open(struct net_device *dev); ++static void ftmac100_timeout (struct net_device *dev); ++static int ftmac100_close(struct net_device *dev); ++static struct net_device_stats * ftmac100_query_statistics( struct net_device *dev); ++#ifdef HAVE_MULTICAST ++static void ftmac100_set_multicast_list(struct net_device *dev); ++#endif ++static void ftmac100_phy_configure(struct net_device* dev) {}; ++static irqreturn_t ftmac100_interrupt(int irq, void * dev_id); ++static void ftmac100_rcv(void *dev); ++static int ftmac100_setup(struct net_device *dev); ++static int ftmac100_reset( struct net_device* dev ); ++static void ftmac100_enable( struct net_device *dev ); ++ ++static void put_mac(int base, unsigned char *mac_addr) ++{ ++ int val; ++ ++ val = ((u32)mac_addr[0])<<8 | (u32)mac_addr[1]; ++ outl(val, base); ++ val = ((((u32)mac_addr[2])<<24)&0xff000000) | ++ ((((u32)mac_addr[3])<<16)&0xff0000) | ++ ((((u32)mac_addr[4])<<8)&0xff00) | ++ ((((u32)mac_addr[5])<<0)&0xff); ++ outl(val, base+4); ++} ++ ++static void get_mac(int base, unsigned char *mac_addr) ++{ ++ int val; ++ ++ //printk("+get_mac\n"); ++ ++ val = inl(base); ++ mac_addr[0] = (val>>8)&0xff; ++ mac_addr[1] = val&0xff; ++ val = inl(base+4); //john add +4 ++ mac_addr[2] = (val>>24)&0xff; ++ mac_addr[3] = (val>>16)&0xff; ++ mac_addr[4] = (val>>8)&0xff; ++ mac_addr[5] = val&0xff; ++} ++ ++static void auto_get_mac(int id,unsigned char *mac_addr) ++{ ++ get_mac(MAC_FTMAC100_0_VA_BASE + MAC_MADR_REG, mac_addr); ++ ++ if (memcmp(mac_addr, "\0\0\0\0\0\0", 6) == 0) { ++ mac_addr[0]=0; ++ mac_addr[1]=0x23; ++ mac_addr[2]=0x96; ++ mac_addr[3]=0x00; ++ mac_addr[4]=0xff; ++ mac_addr[5]=0x00; ++ } + } + +-static void ftmac100_set_tx_ring_base(struct ftmac100 *priv, dma_addr_t addr) ++/* ++ * Print the Ethernet address ++ */ ++static void ft_print_mac(unsigned char *mac_addr) + { +- iowrite32(addr, priv->base + FTMAC100_OFFSET_TXR_BADR); ++ printk("ADDR: %pM\n", mac_addr); + } + +-static void ftmac100_txdma_start_polling(struct ftmac100 *priv) +-{ +- iowrite32(1, priv->base + FTMAC100_OFFSET_TXPD); +-} + +-static int ftmac100_reset(struct ftmac100 *priv) ++#ifdef HAVE_MULTICAST ++/* ++ * Finds the CRC32 of a set of bytes. ++ * Again, from Peter Cammaert's code. ++ */ ++static int crc32( char * s, int length ) + { +- struct net_device *netdev = priv->netdev; +- int i; +- +- /* NOTE: reset clears all registers */ +- iowrite32(FTMAC100_MACCR_SW_RST, priv->base + FTMAC100_OFFSET_MACCR); +- +- for (i = 0; i < 5; i++) { +- unsigned int maccr; +- +- maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR); +- if (!(maccr & FTMAC100_MACCR_SW_RST)) { +- /* +- * FTMAC100_MACCR_SW_RST cleared does not indicate +- * that hardware reset completed (what the f*ck). +- * We still need to wait for a while. +- */ +- udelay(500); +- return 0; ++ /* indices */ ++ int perByte; ++ int perBit; ++ /* crc polynomial for Ethernet */ ++ const unsigned long poly = 0xedb88320; ++ /* crc value - preinitialized to all 1's */ ++ unsigned long crc_value = 0xffffffff; ++ ++ //printk("+crc32\n"); ++ ++ for ( perByte = 0; perByte < length; perByte ++ ) { ++ unsigned char c; ++ ++ c = *(s++); ++ for ( perBit = 0; perBit < 8; perBit++ ) { ++ crc_value = (crc_value>>1)^ ++ (((crc_value^c)&0x01)?poly:0); ++ c >>= 1; + } +- +- udelay(1000); + } +- +- netdev_err(netdev, "software reset failed\n"); +- return -EIO; +-} +- +-static void ftmac100_set_mac(struct ftmac100 *priv, const unsigned char *mac) +-{ +- unsigned int maddr = mac[0] << 8 | mac[1]; +- unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; +- +- iowrite32(maddr, priv->base + FTMAC100_OFFSET_MAC_MADR); +- iowrite32(laddr, priv->base + FTMAC100_OFFSET_MAC_LADR); ++ return crc_value; + } ++#endif + +-#define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \ +- FTMAC100_MACCR_RCV_EN | \ +- FTMAC100_MACCR_XDMA_EN | \ +- FTMAC100_MACCR_RDMA_EN | \ +- FTMAC100_MACCR_CRC_APD | \ +- FTMAC100_MACCR_FULLDUP | \ +- FTMAC100_MACCR_RX_RUNT | \ +- FTMAC100_MACCR_RX_BROADPKT) +- +-static int ftmac100_start_hw(struct ftmac100 *priv) ++static int ftmac100_reset( struct net_device* dev ) + { +- struct net_device *netdev = priv->netdev; ++ unsigned ioaddr = dev->base_addr; ++ int rcount; + +- if (ftmac100_reset(priv)) +- return -EIO; ++ PRINTK("+ftmac100_reset:I/O addr=%X\n", ioaddr); + +- /* setup ring buffer base registers */ +- ftmac100_set_rx_ring_base(priv, +- priv->descs_dma_addr + +- offsetof(struct ftmac100_descs, rxdes)); +- ftmac100_set_tx_ring_base(priv, +- priv->descs_dma_addr + +- offsetof(struct ftmac100_descs, txdes)); ++ outl( SW_RST_bit, ioaddr + MACCR_REG ); + +- iowrite32(FTMAC100_APTC_RXPOLL_CNT(1), priv->base + FTMAC100_OFFSET_APTC); ++ /* this should pause enough for the chip to be happy */ ++ for (rcount = 0; (inl( ioaddr + MACCR_REG ) & SW_RST_bit) != 0; rcount++) { ++ //mdelay(10); ++ msleep_interruptible(10); ++ if (rcount > 5) // Retry 5 times ++ return -ENODEV; ++ } + +- ftmac100_set_mac(priv, netdev->dev_addr); ++ outl( 0, ioaddr + IMR_REG ); /* Disable all interrupts */ ++ if (inl(ioaddr+IMR_REG)!=0) ++ return -ENODEV; + +- iowrite32(MACCR_ENABLE_ALL, priv->base + FTMAC100_OFFSET_MACCR); +- return 0; ++ return 0; + } + +-static void ftmac100_stop_hw(struct ftmac100 *priv) +-{ +- iowrite32(0, priv->base + FTMAC100_OFFSET_MACCR); +-} + +-/****************************************************************************** +- * internal functions (receive descriptor) +- *****************************************************************************/ +-static bool ftmac100_rxdes_first_segment(struct ftmac100_rxdes *rxdes) +-{ +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FRS); +-} +- +-static bool ftmac100_rxdes_last_segment(struct ftmac100_rxdes *rxdes) ++/* ++ . Function: ftmac100_enable ++ . Purpose: let the chip talk to the outside work ++ . Method: ++ . 1. Enable the transmitter ++ . 2. Enable the receiver ++ . 3. Enable interrupts ++*/ ++static void ftmac100_enable( struct net_device *dev ) + { +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_LRS); +-} ++ unsigned int ioaddr = dev->base_addr; ++ int i; ++ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); ++ char mac_addr[6]; + +-static bool ftmac100_rxdes_owned_by_dma(struct ftmac100_rxdes *rxdes) +-{ +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN); +-} ++ //printk("+ftmac100_enable\n"); ++ PRINTK("%s:ftmac100_enable ioaddr=%X\n", dev->name, ioaddr); + +-static void ftmac100_rxdes_set_dma_own(struct ftmac100_rxdes *rxdes) +-{ +- /* clear status bits */ +- rxdes->rxdes0 = cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN); ++ for (i=0; irx_descs[i].RXDMA_OWN = OWNBY_FTMAC100; // owned by FTMAC100 ++ } ++ priv->rx_idx = 0; ++ ++ for (i=0; itx_descs[i].TXDMA_OWN = OWNBY_SOFTWARE; // owned by software ++ } ++ priv->tx_idx = 0; ++ ++ ++ /* set the MAC address */ ++ put_mac(ioaddr + MAC_MADR_REG, dev->dev_addr); ++ ++ //john add ++ get_mac(ioaddr + MAC_MADR_REG, mac_addr); ++ ft_print_mac(mac_addr); ++ ++ outl( priv->rx_descs_dma, ioaddr + RXR_BADR_REG); ++ outl( priv->tx_descs_dma, ioaddr + TXR_BADR_REG); ++ outl( 0x00001010, ioaddr + ITC_REG); // TODO: threshold too small ++ outl( (0UL<maccr_val, ioaddr + MACCR_REG ); ++ PRINTK("%s:ftmac100_enable DONE\n", dev->name); + } + +-static bool ftmac100_rxdes_rx_error(struct ftmac100_rxdes *rxdes) ++/* ++ . Function: ftmac100_shutdown ++ . Purpose: closes down the SMC91xxx chip. ++ . Method: ++ . 1. zero the interrupt mask ++ . 2. clear the enable receive flag ++ . 3. clear the enable xmit flags ++ . ++ . TODO: ++ . (1) maybe utilize power down mode. ++ . Why not yet? Because while the chip will go into power down mode, ++ . the manual says that it will wake up in response to any I/O requests ++ . in the register space. Empirical results do not show this working. ++*/ ++static void ftmac100_shutdown( unsigned int ioaddr ) + { +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ERR); +-} ++ //printk("+ftmac100_shutdown\n"); + +-static bool ftmac100_rxdes_crc_error(struct ftmac100_rxdes *rxdes) +-{ +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_CRC_ERR); ++ outl( 0, ioaddr + IMR_REG ); ++ outl( 0, ioaddr + MACCR_REG ); + } + +-static bool ftmac100_rxdes_frame_too_long(struct ftmac100_rxdes *rxdes) ++/* ++ * Function: ftmac100_wait_to_send_packet( struct sk_buff * skb, struct device * ) ++ * Purpose: ++ * Attempt to allocate memory for a packet, if chip-memory is not ++ * available, then tell the card to generate an interrupt when it ++ * is available* ++ * ++ * Algorithm: ++ * ++ * o if the saved_skb is not currently null, then drop this packet ++ * on the floor. This should never happen, because of TBUSY. ++ * o if the saved_skb is null, then replace it with the current packet, ++ * o See if I can sending it now. ++ * o (NO): Enable interrupts and let the interrupt handler deal with it. ++ * o (YES):Send it now. ++ */ ++static int ftmac100_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev ) + { +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FTL); +-} ++ struct ftmac100_local *priv=(struct ftmac100_local *)netdev_priv(dev); ++ unsigned int ioaddr=dev->base_addr; ++ volatile TX_DESC *cur_desc; ++ int length; ++ unsigned long flags; ++ ++ //printk("+ftmac100_wait_to_send_packet\n"); ++ ++ spin_lock_irqsave(&priv->lock, flags); ++ if (skb==NULL) { ++ printk("%s(%d): NULL skb???\n", __FILE__,__LINE__); ++ spin_unlock_irqrestore(&priv->lock, flags); ++ return 0; ++ } ++ ++ cur_desc = &priv->tx_descs[priv->tx_idx]; ++#if ZERO_COPY ++ /* Record buffer address to be freed later */ ++ priv->tx_skbuff[priv->tx_idx] = skb; ++#endif ++ ++#ifdef not_complete_yet ++ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor ++ { ++ DO_PRINT("no empty transmit descriptor\n"); ++ DO_PRINT("jiffies = %d\n", jiffies); ++ lp->stats.tx_dropped++; ++ netif_stop_queue(dev); /// waiting to do: ++ spin_unlock_irqrestore(&lp->lock, flags); ++ ++ return 1; ++ } ++#endif /* end_of_not */ ++ ++ for (; cur_desc->TXDMA_OWN != OWNBY_SOFTWARE; ) { ++ PRINTK( KERN_WARNING "NO empty TX\n"); //printk("no empty TX descriptor:0x%x:0x%x\n",(unsigned)cur_desc,(unsigned)cur_desc[0]); ++ udelay(1); ++ } ++ length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; ++ length = min(length, TX_BUF_SIZE); // truncate jumbo packets ++ ++#if FTMAC100_DEBUG > 2 ++ printk("Transmitting Packet at 0x%x\n",(unsigned int)cur_desc->VIR_TXBUF_BADR); ++ print_packet( skb->data, length ); ++#endif + +-static bool ftmac100_rxdes_runt(struct ftmac100_rxdes *rxdes) +-{ +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RUNT); +-} ++#if ZERO_COPY ++ cur_desc->VIR_TXBUF_BADR = (unsigned)skb->data; ++ cur_desc->TXBUF_BADR = virt_to_phys(skb->data); ++ cpu_dma_wb_range((unsigned)skb->data, ((unsigned)(skb->data) + length + CACHE_LINE_SIZE( DCACHE) - 1 )&(~(CACHE_LINE_SIZE( DCACHE)-1)) ); + +-static bool ftmac100_rxdes_odd_nibble(struct ftmac100_rxdes *rxdes) +-{ +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ODD_NB); +-} ++#else ++ memcpy((char *)cur_desc->VIR_TXBUF_BADR, skb->data, length); ++#endif + +-static unsigned int ftmac100_rxdes_frame_length(struct ftmac100_rxdes *rxdes) +-{ +- return le32_to_cpu(rxdes->rxdes0) & FTMAC100_RXDES0_RFL; ++ cur_desc->TXBUF_Size = length; ++ cur_desc->LTS = 1; ++ cur_desc->FTS = 1; ++ ++ cur_desc->TX2FIC = 0; ++ cur_desc->TXIC = 0; ++ ++ cur_desc->TXDMA_OWN = OWNBY_FTMAC100; ++ ++ outl( 0xffffffff, ioaddr + TXPD_REG ); ++ ++ priv->tx_idx = (priv->tx_idx + 1) & (TXDES_NUM-1); ++ priv->stats.tx_packets++; ++ priv->stats.tx_bytes += skb->len; ++#if !ZERO_COPY ++ dev_kfree_skb_any (skb); ++#endif ++ dev->trans_start = jiffies; ++ spin_unlock_irqrestore(&priv->lock, flags); ++ return 0; + } + +-static bool ftmac100_rxdes_multicast(struct ftmac100_rxdes *rxdes) +-{ +- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_MULTICAST); +-} ++//#define dma_allocate(x,y,z,w) dma_alloc_coherent((x),(y),(dma_addr_t*)(z),(w)) ++#define dma_allocate(x,y,z,w) dma_alloc_writecombine((x),(y),(dma_addr_t*)(z),(w)) + +-static void ftmac100_rxdes_set_buffer_size(struct ftmac100_rxdes *rxdes, +- unsigned int size) ++static int ftmac100_ringbuf_alloc(struct net_device *dev,struct ftmac100_local *priv) + { +- rxdes->rxdes1 &= cpu_to_le32(FTMAC100_RXDES1_EDORR); +- rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_RXBUF_SIZE(size)); +-} ++ int i; + +-static void ftmac100_rxdes_set_end_of_ring(struct ftmac100_rxdes *rxdes) +-{ +- rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_EDORR); +-} ++ //printk("+ftmac100_ringbuf_alloc\n"); + +-static void ftmac100_rxdes_set_dma_addr(struct ftmac100_rxdes *rxdes, +- dma_addr_t addr) +-{ +- rxdes->rxdes2 = cpu_to_le32(addr); +-} ++ priv->rx_descs = dma_allocate( NULL, sizeof(RX_DESC)*RXDES_NUM, &(priv->rx_descs_dma), GFP_KERNEL ); ++ if (priv->rx_descs == NULL || (( (u32)priv->rx_descs & 0xf)!=0)) { ++ printk("Receive Ring Buffer allocation error\n"); ++ return -ENOMEM; ++ } ++#if FTMAC100_DEBUG > 2 ++ else ++ printk( KERN_INFO "* Allocated RX descs=%X, bus addr=%X, size=%d*%d=%d\n", ++ (unsigned)priv->rx_descs, (unsigned)priv->rx_descs_dma, ++ sizeof(RX_DESC),RXDES_NUM,sizeof(RX_DESC)*RXDES_NUM ); ++#endif ++ memset((unsigned int *)priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM); + +-static dma_addr_t ftmac100_rxdes_get_dma_addr(struct ftmac100_rxdes *rxdes) +-{ +- return le32_to_cpu(rxdes->rxdes2); ++ priv->rx_buf = dma_allocate( NULL, RX_BUF_SIZE*RXDES_NUM, &(priv->rx_buf_dma), GFP_KERNEL ); ++ if (priv->rx_buf == NULL || (( (u32)priv->rx_buf & 3)!=0)) { ++ printk("Receive Ring Buffer allocation error\n"); ++ return -ENOMEM; ++ } ++#if FTMAC100_DEBUG > 2 ++ else ++ printk( KERN_INFO "* Allocated RX buf=%X, bus addr=%X, size=%d*%d=%d\n", ++ (unsigned)priv->rx_buf, (unsigned)priv->rx_buf_dma, ++ RX_BUF_SIZE, RXDES_NUM, RX_BUF_SIZE*RXDES_NUM ); ++#endif ++ ++ memset((void *)priv->rx_buf,0,sizeof(RX_BUF_SIZE)*RXDES_NUM); ++ ++ for (i=0; irx_descs[i].RXBUF_Size = RX_BUF_SIZE; ++ priv->rx_descs[i].EDOTR = 0; // not last descriptor ++ priv->rx_descs[i].RXBUF_BADR = priv->rx_buf_dma+RX_BUF_SIZE*i; ++ priv->rx_descs[i].VIR_RXBUF_BADR=(unsigned int)priv->rx_buf+RX_BUF_SIZE*i; ++ } ++ priv->rx_descs[RXDES_NUM-1].EDOTR = 1; // is last descriptor ++ ++ priv->tx_descs = dma_allocate( NULL, sizeof(TX_DESC)*TXDES_NUM, &(priv->tx_descs_dma), GFP_KERNEL ); ++ if (priv->tx_descs == NULL || (( (u32)priv->tx_descs & 0xf)!=0)) { ++ printk("Transmit Ring Buffer allocation error\n"); ++ return -ENOMEM; ++ } ++#if FTMAC100_DEBUG > 2 ++ else ++ printk( KERN_INFO "* Allocated TX descs=%X, bus addr=%X, size=%d*%d=%d\n", ++ (unsigned)priv->tx_descs, (unsigned)priv->tx_descs_dma, sizeof(TX_DESC),TXDES_NUM,sizeof(TX_DESC)*TXDES_NUM); ++#endif ++ memset((void *)priv->tx_descs,0,sizeof(TX_DESC)*TXDES_NUM); ++ ++ priv->tx_buf = dma_allocate( NULL, TX_BUF_SIZE*TXDES_NUM, &(priv->tx_buf_dma), GFP_KERNEL ); ++ if (priv->tx_buf == NULL || (( (u32)priv->tx_buf & 0x3)!=0)) { ++ printk("Transmit Ring Buffer allocation error\n"); ++ return -ENOMEM; ++ } ++#if FTMAC100_DEBUG > 2 ++ else ++ printk( KERN_INFO "* Allocated TX buf=%X, bus addr=%X, size=%d*%d=%d\n", ++ (unsigned)priv->tx_buf, (unsigned)priv->tx_buf_dma, ++ TX_BUF_SIZE, TXDES_NUM, TX_BUF_SIZE*TXDES_NUM ); ++#endif ++ ++ memset((void *)priv->tx_buf,0,sizeof(TX_BUF_SIZE)*TXDES_NUM); ++ ++ for (i=0; itx_descs[i].EDOTR = 0; // not last descriptor ++ priv->tx_descs[i].TXBUF_BADR=priv->tx_buf_dma+TX_BUF_SIZE*i; ++ priv->tx_descs[i].VIR_TXBUF_BADR=(unsigned int)priv->tx_buf+TX_BUF_SIZE*i; ++ } ++ priv->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor ++ return 0; + } + + /* +- * rxdes3 is not used by hardware. We use it to keep track of page. +- * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). ++ * Function: ftmac100_poll( struct net_device *dev ) ++ * ++ * Purpose: ++ * poll interface callback function. + */ +-static void ftmac100_rxdes_set_page(struct ftmac100_rxdes *rxdes, struct page *page) ++void ftmac100_poll(struct net_device *dev) + { +- rxdes->rxdes3 = (unsigned int)page; ++ disable_irq(dev->irq); ++ ftmac100_interrupt(dev->irq, dev); ++ enable_irq(dev->irq); + } + +-static struct page *ftmac100_rxdes_get_page(struct ftmac100_rxdes *rxdes) +-{ +- return (struct page *)rxdes->rxdes3; +-} +- +-/****************************************************************************** +- * internal functions (receive) +- *****************************************************************************/ +-static int ftmac100_next_rx_pointer(int pointer) ++/* ++ * Function: ftmac100_setup( struct net_device *dev ) ++ * ++ * Purpose: ++ * Tests to see if the device 'dev' points to an ftmac100 chip. ++ * Returns a 0 on success ++ */ ++static const struct net_device_ops ftmac100_ops = { ++ .ndo_init = ftmac100_setup, ++ .ndo_open = ftmac100_open, ++ .ndo_stop = ftmac100_close, ++ .ndo_start_xmit = ftmac100_wait_to_send_packet, ++ .ndo_get_stats = ftmac100_query_statistics, ++ .ndo_tx_timeout = ftmac100_timeout, ++#ifdef HAVE_MULTICAST ++ .ndo_set_multicast_list = ftmac100_set_multicast_list, ++#endif ++ .ndo_set_mac_address = eth_mac_addr, ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = ftmac100_poll, ++#endif ++}; ++static int ftmac100_setup(struct net_device *dev) + { +- return (pointer + 1) & (RX_QUEUE_ENTRIES - 1); +-} ++ int retval; ++ static unsigned version_printed = 0; ++ struct ftmac100_local *priv; ++ ++ if (version_printed++ == 0) ++ printk(KERN_INFO "%s", version); ++ ++ /* Now, print out the card info, in a short format.. */ ++ printk(KERN_INFO "%s: device at %#3x IRQ:%d NOWAIT:%d\n",dev->name, ++ (unsigned)dev->base_addr, dev->irq, dev->dma); ++ ++ /* Initialize priviate data */ ++ priv = (struct ftmac100_local *)netdev_priv(dev); ++ memset(priv, 0, sizeof(struct ftmac100_local)); ++ spin_lock_init(&priv->lock); ++ priv->maccr_val = FULLDUP_bit ++ | CRC_APD_bit ++ | MDC_SEL_bit ++ | RCV_EN_bit ++ | XMT_EN_bit ++ | RDMA_EN_bit ++ | XDMA_EN_bit ; ++ retval = ftmac100_ringbuf_alloc(dev,priv); ++ if (retval) ++ goto err_out; ++ ++ /* now, reset the chip, and put it into a known state */ ++ retval = ftmac100_reset( dev ); ++ if (retval) { ++ printk( "%s: unable to reset.\n", dev->name ); ++ goto err_out; ++ } ++ ++ /* Fill in the fields of the device structure with ethernet values. */ ++ ether_setup(dev); ++ ++ /* Grab the IRQ */ ++ retval = request_irq(dev->irq, &ftmac100_interrupt, IRQF_DISABLED, dev->name, dev); ++ if (retval) { ++ printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, retval); ++ goto err_out; ++ } ++ ++#if 0 ++ if ((proc_ftmac100 = create_proc_entry( "ftmac100", 0, 0 ))) { ++ proc_ftmac100->read_proc = ftmac100_read_proc; ++ proc_ftmac100->data = dev; ++ proc_ftmac100->owner = THIS_MODULE; ++ } ++#endif + +-static void ftmac100_rx_pointer_advance(struct ftmac100 *priv) +-{ +- priv->rx_pointer = ftmac100_next_rx_pointer(priv->rx_pointer); +-} ++ return 0; + +-static struct ftmac100_rxdes *ftmac100_current_rxdes(struct ftmac100 *priv) +-{ +- return &priv->descs->rxdes[priv->rx_pointer]; ++err_out: ++ dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma ); ++ dma_free_coherent( NULL, RX_BUF_SIZE*RXDES_NUM, (void*)priv->rx_buf, (dma_addr_t)priv->rx_buf_dma ); ++ dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma ); ++ dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma ); ++ priv->rx_descs = NULL; priv->rx_descs_dma = 0; ++ priv->rx_buf = NULL; priv->rx_buf_dma = 0; ++ priv->tx_descs = NULL; priv->tx_descs_dma = 0; ++ priv->tx_buf = NULL; priv->tx_buf_dma = 0; ++ return retval; + } + +-static struct ftmac100_rxdes * +-ftmac100_rx_locate_first_segment(struct ftmac100 *priv) +-{ +- struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv); + +- while (!ftmac100_rxdes_owned_by_dma(rxdes)) { +- if (ftmac100_rxdes_first_segment(rxdes)) +- return rxdes; ++#if FTMAC100_DEBUG > 2 ++static void print_packet( unsigned char * buf, int length ) ++{ ++#if FTMAC100_DEBUG > 3 ++ int i; ++ int remainder; ++ int lines; ++#endif + +- ftmac100_rxdes_set_dma_own(rxdes); +- ftmac100_rx_pointer_advance(priv); +- rxdes = ftmac100_current_rxdes(priv); +- } ++// printk("Packet of length %d \n", length ); + +- return NULL; ++#if FTMAC100_DEBUG > 3 ++ lines = length >> 4; ++ remainder = length & 15; ++ ++ for ( i = 0; i < lines ; i ++ ) { ++ int cur; ++ for ( cur = 0; cur < 8; cur ++ ) { ++ unsigned char a, b; ++ a = *(buf ++ ); ++ b = *(buf ++ ); ++ printk("%02x%02x ", a, b ); ++ } ++ printk("\n"); ++ } ++ for ( i = 0; i < remainder/2 ; i++ ) { ++ unsigned char a, b; ++ ++ a = *(buf ++ ); ++ b = *(buf ++ ); ++ printk("%02x%02x ", a, b ); ++ } ++ printk("\n"); ++#endif + } ++#endif + +-static bool ftmac100_rx_packet_error(struct ftmac100 *priv, +- struct ftmac100_rxdes *rxdes) +-{ +- struct net_device *netdev = priv->netdev; +- bool error = false; +- +- if (unlikely(ftmac100_rxdes_rx_error(rxdes))) { +- if (net_ratelimit()) +- netdev_info(netdev, "rx err\n"); +- +- netdev->stats.rx_errors++; +- error = true; +- } +- +- if (unlikely(ftmac100_rxdes_crc_error(rxdes))) { +- if (net_ratelimit()) +- netdev_info(netdev, "rx crc err\n"); +- +- netdev->stats.rx_crc_errors++; +- error = true; +- } +- +- if (unlikely(ftmac100_rxdes_frame_too_long(rxdes))) { +- if (net_ratelimit()) +- netdev_info(netdev, "rx frame too long\n"); +- +- netdev->stats.rx_length_errors++; +- error = true; +- } else if (unlikely(ftmac100_rxdes_runt(rxdes))) { +- if (net_ratelimit()) +- netdev_info(netdev, "rx runt\n"); +- +- netdev->stats.rx_length_errors++; +- error = true; +- } else if (unlikely(ftmac100_rxdes_odd_nibble(rxdes))) { +- if (net_ratelimit()) +- netdev_info(netdev, "rx odd nibble\n"); +- +- netdev->stats.rx_length_errors++; +- error = true; +- } +- +- return error; +-} + +-static void ftmac100_rx_drop_packet(struct ftmac100 *priv) ++/* ++ * Open and Initialize the board ++ * ++ * Set up everything, reset the card, etc .. ++ * ++ */ ++static int ftmac100_open(struct net_device *dev) + { +- struct net_device *netdev = priv->netdev; +- struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv); +- bool done = false; +- +- if (net_ratelimit()) +- netdev_dbg(netdev, "drop packet %p\n", rxdes); ++ int retval = 0; ++ PRINTK("+%s:ftmac100_open\n", dev->name); + +- do { +- if (ftmac100_rxdes_last_segment(rxdes)) +- done = true; ++ //netif_start_queue(dev); + +- ftmac100_rxdes_set_dma_own(rxdes); +- ftmac100_rx_pointer_advance(priv); +- rxdes = ftmac100_current_rxdes(priv); +- } while (!done && !ftmac100_rxdes_owned_by_dma(rxdes)); +- +- netdev->stats.rx_dropped++; ++ /* reset the hardware */ ++ ftmac100_reset( dev ); ++ retval = ftmac100_reset( dev ); ++ if (retval) { ++ printk( "%s: unable to reset.\n", dev->name ); ++ retval = -ENODEV; ++ } else { ++ ftmac100_enable( dev ); ++ ++ /* Configure the PHY */ ++ ftmac100_phy_configure(dev); ++ ++ netif_start_queue(dev); ++ ++ PRINTK("+%s:ftmac100_open DONE\n", dev->name); ++ } ++ ++ return retval; + } + +-static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed) +-{ +- struct net_device *netdev = priv->netdev; +- struct ftmac100_rxdes *rxdes; +- struct sk_buff *skb; +- struct page *page; +- dma_addr_t map; +- int length; + +- rxdes = ftmac100_rx_locate_first_segment(priv); +- if (!rxdes) +- return false; +- +- if (unlikely(ftmac100_rx_packet_error(priv, rxdes))) { +- ftmac100_rx_drop_packet(priv); +- return true; +- } +- +- /* +- * It is impossible to get multi-segment packets +- * because we always provide big enough receive buffers. +- */ +- if (unlikely(!ftmac100_rxdes_last_segment(rxdes))) +- BUG(); +- +- /* start processing */ +- skb = netdev_alloc_skb_ip_align(netdev, 128); +- if (unlikely(!skb)) { +- if (net_ratelimit()) +- netdev_err(netdev, "rx skb alloc failed\n"); +- +- ftmac100_rx_drop_packet(priv); +- return true; +- } +- +- if (unlikely(ftmac100_rxdes_multicast(rxdes))) +- netdev->stats.multicast++; +- +- map = ftmac100_rxdes_get_dma_addr(rxdes); +- dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); +- +- length = ftmac100_rxdes_frame_length(rxdes); +- page = ftmac100_rxdes_get_page(rxdes); +- skb_fill_page_desc(skb, 0, page, 0, length); +- skb->len += length; +- skb->data_len += length; +- +- /* page might be freed in __pskb_pull_tail() */ +- if (length > 64) +- skb->truesize += PAGE_SIZE; +- __pskb_pull_tail(skb, min(length, 64)); +- +- ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC); +- +- ftmac100_rx_pointer_advance(priv); +- +- skb->protocol = eth_type_trans(skb, netdev); +- +- netdev->stats.rx_packets++; +- netdev->stats.rx_bytes += skb->len; ++/* ++ * Called by the kernel to send a packet out into the void ++ * of the net. This routine is largely based on ++ * skeleton.c, from Becker. ++ * ++ */ ++static void ftmac100_timeout (struct net_device *dev) ++{ ++ /* If we get here, some higher level has decided we are broken. ++ There should really be a "kick me" function call instead. */ ++ printk(KERN_WARNING "%s: transmit timed out?\n",dev->name); + +- /* push packet to protocol stack */ +- netif_receive_skb(skb); ++ //printk("+ftmac100_timeout\n"); + +- (*processed)++; +- return true; ++ ftmac100_reset( dev ); ++ ftmac100_enable( dev ); ++ ftmac100_phy_configure(dev); ++ netif_wake_queue(dev); ++ dev->trans_start = jiffies; + } + +-/****************************************************************************** +- * internal functions (transmit descriptor) +- *****************************************************************************/ +-static void ftmac100_txdes_reset(struct ftmac100_txdes *txdes) ++#if ZERO_COPY ++/* ++ * Free transmitted skb buffer when it's safe. ++ */ ++static void ftmac100_free_tx (struct net_device *dev, int irq) + { +- /* clear all except end of ring bit */ +- txdes->txdes0 = 0; +- txdes->txdes1 &= cpu_to_le32(FTMAC100_TXDES1_EDOTR); +- txdes->txdes2 = 0; +- txdes->txdes3 = 0; +-} ++ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); ++ //volatile TX_DESC *cur_desc; ++ int entry = priv->old_tx & (TXDES_NUM-1); ++ ++ //enter spinlock ++ if (!irq) ++ spin_lock(&priv->lock); ++ ++ /* Free used tx skbuffs */ ++ while (entry != priv->tx_idx) { ++ struct sk_buff *skb; ++ ++ skb = priv->tx_skbuff[entry]; ++ if(skb) { ++ dev_kfree_skb_any (skb); ++ priv->tx_skbuff[entry] = 0; ++ } + +-static bool ftmac100_txdes_owned_by_dma(struct ftmac100_txdes *txdes) +-{ +- return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN); +-} ++ entry = (entry + 1) & (TXDES_NUM-1); ++ } + +-static void ftmac100_txdes_set_dma_own(struct ftmac100_txdes *txdes) +-{ +- /* +- * Make sure dma own bit will not be set before any other +- * descriptor fields. +- */ +- wmb(); +- txdes->txdes0 |= cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN); +-} ++ if (!irq) ++ spin_unlock(&priv->lock); ++ //exit spinloc + +-static bool ftmac100_txdes_excessive_collision(struct ftmac100_txdes *txdes) +-{ +- return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_EXSCOL); ++ priv->old_tx = entry; ++ netif_wake_queue (dev); + } ++#endif + +-static bool ftmac100_txdes_late_collision(struct ftmac100_txdes *txdes) +-{ +- return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_LATECOL); +-} ++/* ++ . ++ . This is the main routine of the driver, to handle the net_device when ++ . it needs some attention. ++ . ++ . So: ++ . first, save state of the chipset ++ . branch off into routines to handle each case, and acknowledge ++ . each to the interrupt register ++ . and finally restore state. ++ . ++ */ + +-static void ftmac100_txdes_set_end_of_ring(struct ftmac100_txdes *txdes) +-{ +- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_EDOTR); +-} ++#if FTMAC100_DEBUG > 2 + +-static void ftmac100_txdes_set_first_segment(struct ftmac100_txdes *txdes) ++static void dump_intc(void) + { +- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_FTS); ++ printk( " INTC[0] IRQSRC=%08X,MASK=%08X,MOD=%08X,LEV=%08X,STAT=%08X\n", ++ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0)), ++ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x4)), ++ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0xc)), ++ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x10)), ++ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x14)) ); ++ printk( " INTC[1] IRQSRC=%08X,MASK=%08X,MOD=%08X,LEV=%08X,STAT=%08X\n", ++ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0)), ++ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x4)), ++ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0xc)), ++ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x10)), ++ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x14)) ); + } ++#else ++#define dump_intc() ++#endif + +-static void ftmac100_txdes_set_last_segment(struct ftmac100_txdes *txdes) ++#if FTMAC100_DEBUG > 2 ++static void show_intstatus(unsigned char status) + { +- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_LTS); ++ static int count = 0; ++ if (status & PHYSTS_CHG_bit) ++ printk( "[%d]%s ", count, "PHYSTS_CHG" ); ++ if (status & AHB_ERR_bit) ++ printk( "[%d]%s ", count, "AHB_ERR" ); ++ if (status & RPKT_LOST_bit) ++ printk( "[%d]%s ", count, "RPKT_LOST" ); ++ if (status & RPKT_SAV_bit) ++ printk( "[%d]%s ", count, "RPKT_SAV" ); ++ if (status & XPKT_LOST_bit) ++ printk( "[%d]%s ", count, "XPKT_LOST" ); ++ if (status & XPKT_OK_bit) ++ printk( "[%d]%s ", count, "XPKT_OK" ); ++ if (status & NOTXBUF_bit) ++ printk( "[%d]%s ", count, "NOTXBUF" ); ++ if (status & XPKT_FINISH_bit) ++ printk( "[%d]%s ", count, "XPKT_FINISH" ); ++ if (status & NORXBUF_bit) ++ printk( "[%d]%s ", count, "NORXBUF" ); ++ if (status & RPKT_FINISH_bit) ++ printk( "[%d]%s ", count, "RPKT_FINISH" ); ++ if (status & ~(PHYSTS_CHG_bit | AHB_ERR_bit | RPKT_LOST_bit | RPKT_SAV_bit ++ | XPKT_LOST_bit | XPKT_OK_bit | NOTXBUF_bit | XPKT_FINISH_bit ++ | NORXBUF_bit | RPKT_FINISH_bit)) ++ printk( "[%d]%s ", count, "" ); ++ count++; + } ++#else ++#define show_intstatus(x) ++#endif ++ + +-static void ftmac100_txdes_set_txint(struct ftmac100_txdes *txdes) ++/* ++ * The interrupt handler ++ */ ++static irqreturn_t ftmac100_interrupt(int irq, void * dev_id) + { +- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXIC); +-} ++ struct net_device *dev = dev_id; ++ unsigned int ioaddr = dev->base_addr; ++ unsigned status; // interrupt status ++ unsigned char mask; // interrupt mask ++ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&priv->lock,flags); // Luke 08/18/2005 ins ++ PRINTK(KERN_INFO "+ftmac100_interrupt\n"); ++ dump_intc(); ++ ++ if (dev == NULL||priv == NULL) { ++ printk(KERN_WARNING "%s: irq %d for unknown device.\n", "ftmac100_interrupt", irq); ++ return IRQ_HANDLED; ++ } ++ ++ /* read the interrupt status register */ ++ mask = inl( ioaddr + IMR_REG ); ++ ++ /* read the status flag, and mask it */ ++ status = inl( ioaddr + ISR_REG ) & mask; ++ ++ show_intstatus(status); ++ ++ if ( status & RPKT_FINISH_bit ) ++ ftmac100_rcv(dev); ++ ++ if (status & NORXBUF_bit) { ++ //printk("<0x%x:NORXBUF>",status); ++ outl( mask & ~NORXBUF_bit, ioaddr + IMR_REG); ++ trans_busy = 1; ++ ++#if ENABLE_BOTTOM_HALF ++ priv->rcv_tq.sync = 0; ++ priv->rcv_tq.routine=ftmac100_rcv; ++ priv->rcv_tq.data = dev; ++ queue_task(&priv->rcv_tq, &tq_timer); ++ //queue_task(&priv->rcv_tq, &tq_immediate); ++#else ++ ftmac100_rcv( dev ); ++#endif ++ } ++ ++ if (status & AHB_ERR_bit) ++ printk("<0x%x:AHB_ERR>",status); ++ ++ if (status & XPKT_FINISH_bit) ++ printk( "[XPKT_FINISH]" ); ++ ++ /* ++ if (status & PHYSTS_CHG_bit) { ++ } ++ */ ++ if (status & XPKT_OK_bit) { ++#if ZERO_COPY ++ ftmac100_free_tx(dev,1); ++#endif ++ } ++ /* ++ if (status & NOTXBUF_bit) { ++ } ++ */ ++ ++ if (status & RPKT_LOST_bit) ++ priv->stats.rx_errors++; ++ ++ if (status & XPKT_LOST_bit) { ++#if ZERO_COPY ++ ftmac100_free_tx(dev,1); ++#endif ++ priv->stats.tx_errors++; ++ } ++ ++ PRINTK(KERN_INFO "+ftmac100_interrupt DONE\n"); ++ dump_intc(); ++ PRINTK(KERN_INFO "\n"); ++ spin_unlock_irqrestore(&priv->lock,flags); // Luke 08/18/2005 ins + +-static void ftmac100_txdes_set_buffer_size(struct ftmac100_txdes *txdes, +- unsigned int len) +-{ +- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXBUF_SIZE(len)); ++ return IRQ_HANDLED; + } + +-static void ftmac100_txdes_set_dma_addr(struct ftmac100_txdes *txdes, +- dma_addr_t addr) +-{ +- txdes->txdes2 = cpu_to_le32(addr); +-} + +-static dma_addr_t ftmac100_txdes_get_dma_addr(struct ftmac100_txdes *txdes) +-{ +- return le32_to_cpu(txdes->txdes2); +-} + + /* +- * txdes3 is not used by hardware. We use it to keep track of socket buffer. +- * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). ++ . ftmac100_rcv - receive a packet from the card ++ . ++ . There is ( at least ) a packet waiting to be read from ++ . chip-memory. ++ . ++ . o Read the status ++ . o If an error, record it ++ . o otherwise, read in the packet + */ +-static void ftmac100_txdes_set_skb(struct ftmac100_txdes *txdes, struct sk_buff *skb) +-{ +- txdes->txdes3 = (unsigned int)skb; +-} + +-static struct sk_buff *ftmac100_txdes_get_skb(struct ftmac100_txdes *txdes) ++static void ftmac100_rcv(void *devp) + { +- return (struct sk_buff *)txdes->txdes3; ++ struct net_device *dev=(struct net_device *)devp; ++ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); ++ unsigned int ioaddr=dev->base_addr; ++ int packet_length; ++ int rcv_cnt; ++ volatile RX_DESC *cur_desc; ++ int cpy_length; ++ int cur_idx; ++ int seg_length; ++ int have_package; ++ int have_frs; ++ int start_idx; ++ ++ struct sk_buff * skb; ++ unsigned char * data; ++ ++ PRINTK("+ ftmac100_rcv\n"); ++ ++ start_idx = priv->rx_idx; ++ ++ for (rcv_cnt=0; rcv_cnt<8 ; ++rcv_cnt) { ++ packet_length = 0; ++ cur_idx = priv->rx_idx; ++ ++ have_package = 0; ++ have_frs = 0; ++ for (; (cur_desc = &priv->rx_descs[priv->rx_idx])->RXDMA_OWN==0; ) { ++ have_package = 1; ++ priv->rx_idx = (priv->rx_idx+1) & (RXDES_NUM-1); ++ if (cur_desc->FRS) { ++ have_frs = 1; ++ if (cur_desc->RX_ERR || cur_desc->CRC_ERR || cur_desc->FTL ++ || cur_desc->RUNT || cur_desc->RX_ODD_NB) { ++ priv->stats.rx_errors++; // error frame.... ++ break; ++ } ++ if (cur_desc->MULTICAST) ++ priv->stats.multicast++; ++ packet_length = cur_desc->ReceiveFrameLength; // normal frame ++ } ++ if ( cur_desc->LRS ) // packet's last frame ++ break; ++ } ++ if (have_package==0) ++ goto done; ++ if (have_frs == 0) ++ priv->stats.rx_over_errors++; ++ ++ if (packet_length>0) { ++ // Allocate enough memory for entire receive frame, to be safe ++ skb = dev_alloc_skb( packet_length + 2 ); ++ ++ if ( skb == NULL ) { ++ printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", dev->name); ++ priv->stats.rx_dropped++; ++ goto done; ++ } ++ ++ skb_reserve( skb, 2 ); /* 16 bit alignment */ ++ skb->dev = dev; ++ ++ data = skb_put( skb, packet_length ); ++ cpy_length = 0; ++ for (; cur_idx!=priv->rx_idx; cur_idx = (cur_idx+1) & (RXDES_NUM-1)) { ++ seg_length = min(packet_length - cpy_length, RX_BUF_SIZE); ++ memcpy(data+cpy_length, (char *)priv->rx_descs[cur_idx].VIR_RXBUF_BADR, seg_length); ++ cpy_length += seg_length; ++ } ++ ++ skb->protocol = eth_type_trans(skb, dev); ++ netif_rx(skb); ++ dev->last_rx = jiffies; ++ priv->stats.rx_packets++; ++ priv->stats.rx_bytes += skb->len; ++ } ++ } ++ ++done: ++ if (start_idx != priv->rx_idx) { ++ for (cur_idx = (start_idx+1)%RXDES_NUM; cur_idx != priv->rx_idx; cur_idx = (cur_idx+1)%RXDES_NUM) { ++ priv->rx_descs[cur_idx].RXDMA_OWN = 1; ++ } ++ priv->rx_descs[start_idx].RXDMA_OWN = 1; ++ } ++ if (trans_busy == 1) { ++ outl( priv->maccr_val, ioaddr + MACCR_REG ); ++ outl( inl(ioaddr + IMR_REG) | NORXBUF_bit, ioaddr + IMR_REG); ++ } ++ ++ PRINTK("+ ftmac100_rcv DONE\n"); ++ ++ return; + } + +-/****************************************************************************** +- * internal functions (transmit) +- *****************************************************************************/ +-static int ftmac100_next_tx_pointer(int pointer) ++/* ++ . ftmac100_close ++ . ++ . this makes the board clean up everything that it can ++ . and not talk to the outside world. Caused by ++ . an 'ifconfig ethX down' ++ . ++ */ ++static int ftmac100_close(struct net_device *dev) + { +- return (pointer + 1) & (TX_QUEUE_ENTRIES - 1); +-} ++ //printk("+ftmac100_close\n"); + +-static void ftmac100_tx_pointer_advance(struct ftmac100 *priv) +-{ +- priv->tx_pointer = ftmac100_next_tx_pointer(priv->tx_pointer); ++ netif_stop_queue(dev); ++ ++ ftmac100_shutdown( dev->base_addr ); ++#if ZERO_COPY ++ ftmac100_free_tx(dev,0); ++#endif ++ return 0; + } + +-static void ftmac100_tx_clean_pointer_advance(struct ftmac100 *priv) ++/* ++ . Get the current statistics. ++ . This may be called with the card open or closed. ++ */ ++static struct net_device_stats* ftmac100_query_statistics(struct net_device *dev) + { +- priv->tx_clean_pointer = ftmac100_next_tx_pointer(priv->tx_clean_pointer); +-} ++ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); + +-static struct ftmac100_txdes *ftmac100_current_txdes(struct ftmac100 *priv) +-{ +- return &priv->descs->txdes[priv->tx_pointer]; +-} ++ PRINTK("+ftmac100_query_statistics\n"); + +-static struct ftmac100_txdes *ftmac100_current_clean_txdes(struct ftmac100 *priv) +-{ +- return &priv->descs->txdes[priv->tx_clean_pointer]; ++ return &priv->stats; + } + +-static bool ftmac100_tx_complete_packet(struct ftmac100 *priv) +-{ +- struct net_device *netdev = priv->netdev; +- struct ftmac100_txdes *txdes; +- struct sk_buff *skb; +- dma_addr_t map; +- +- if (priv->tx_pending == 0) +- return false; + +- txdes = ftmac100_current_clean_txdes(priv); +- +- if (ftmac100_txdes_owned_by_dma(txdes)) +- return false; +- +- skb = ftmac100_txdes_get_skb(txdes); +- map = ftmac100_txdes_get_dma_addr(txdes); +- +- if (unlikely(ftmac100_txdes_excessive_collision(txdes) || +- ftmac100_txdes_late_collision(txdes))) { +- /* +- * packet transmitted to ethernet lost due to late collision +- * or excessive collision +- */ +- netdev->stats.tx_aborted_errors++; +- } else { +- netdev->stats.tx_packets++; +- netdev->stats.tx_bytes += skb->len; +- } ++#ifdef HAVE_MULTICAST + +- dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); +- dev_kfree_skb(skb); +- +- ftmac100_txdes_reset(txdes); +- +- ftmac100_tx_clean_pointer_advance(priv); +- +- spin_lock(&priv->tx_lock); +- priv->tx_pending--; +- spin_unlock(&priv->tx_lock); +- netif_wake_queue(netdev); +- +- return true; +-} ++/* ++ . Function: ftmac100_setmulticast( unsigned int ioaddr, int count, dev_mc_list * adds ) ++ . Purpose: ++ . This sets the internal hardware table to filter out unwanted multicast ++ . packets before they take up memory. ++ */ + +-static void ftmac100_tx_complete(struct ftmac100 *priv) ++static void ftmac100_setmulticast( unsigned int ioaddr, int count, struct dev_mc_list * addrs ) + { +- while (ftmac100_tx_complete_packet(priv)) +- ; ++ struct dev_mc_list * cur_addr; ++ int crc_val; ++ ++ //printk("+ftmac100_setmulticast\n"); ++ ++ for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next ) { ++ if ( !( *cur_addr->dmi_addr & 1 ) ) ++ continue; ++ crc_val = crc32( cur_addr->dmi_addr, 6 ); ++ crc_val = (crc_val>>26)&0x3f; // ¨ú MSB 6 bit ++ if (crc_val >= 32) ++ outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG); ++ else ++ outl(inl(ioaddr+MAHT0_REG) | (1UL<netdev; +- struct ftmac100_txdes *txdes; +- unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; +- +- txdes = ftmac100_current_txdes(priv); +- ftmac100_tx_pointer_advance(priv); +- +- /* setup TX descriptor */ +- ftmac100_txdes_set_skb(txdes, skb); +- ftmac100_txdes_set_dma_addr(txdes, map); +- +- ftmac100_txdes_set_first_segment(txdes); +- ftmac100_txdes_set_last_segment(txdes); +- ftmac100_txdes_set_txint(txdes); +- ftmac100_txdes_set_buffer_size(txdes, len); + +- spin_lock(&priv->tx_lock); +- priv->tx_pending++; +- if (priv->tx_pending == TX_QUEUE_ENTRIES) +- netif_stop_queue(netdev); +- +- /* start transmit */ +- ftmac100_txdes_set_dma_own(txdes); +- spin_unlock(&priv->tx_lock); ++/* ++ . ftmac100_set_multicast_list ++ . ++ . This routine will, depending on the values passed to it, ++ . either make it accept multicast packets, go into ++ . promiscuous mode ( for TCPDUMP and cousins ) or accept ++ . a select set of multicast packets ++*/ ++static void ftmac100_set_multicast_list(struct net_device *dev) ++{ ++ unsigned int ioaddr = dev->base_addr; ++ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); ++ ++ //printk("+ftmac100_set_multicast_list\n"); ++ ++ if (dev->flags & IFF_PROMISC) ++ priv->maccr_val |= RCV_ALL_bit; ++ else ++ priv->maccr_val &= ~RCV_ALL_bit; ++ ++ if ( !(dev->flags & IFF_ALLMULTI) ) ++ priv->maccr_val |= RX_MULTIPKT_bit; ++ else ++ priv->maccr_val &= ~RX_MULTIPKT_bit; ++ ++ if (dev->mc_count) { ++ priv->maccr_val |= HT_MULTI_EN_bit; ++ ftmac100_setmulticast( ioaddr, dev->mc_count, dev->mc_list ); ++ } ++ else ++ priv->maccr_val &= ~HT_MULTI_EN_bit; + +- ftmac100_txdma_start_polling(priv); +- return NETDEV_TX_OK; ++ outl( priv->maccr_val, ioaddr + MACCR_REG ); + } ++#endif + +-/****************************************************************************** +- * internal functions (buffer) +- *****************************************************************************/ +-static int ftmac100_alloc_rx_page(struct ftmac100 *priv, +- struct ftmac100_rxdes *rxdes, gfp_t gfp) +-{ +- struct net_device *netdev = priv->netdev; +- struct page *page; +- dma_addr_t map; +- +- page = alloc_page(gfp); +- if (!page) { +- if (net_ratelimit()) +- netdev_err(netdev, "failed to allocate rx page\n"); +- return -ENOMEM; +- } +- +- map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE); +- if (unlikely(dma_mapping_error(priv->dev, map))) { +- if (net_ratelimit()) +- netdev_err(netdev, "failed to map rx page\n"); +- __free_page(page); +- return -ENOMEM; +- } +- +- ftmac100_rxdes_set_page(rxdes, page); +- ftmac100_rxdes_set_dma_addr(rxdes, map); +- ftmac100_rxdes_set_buffer_size(rxdes, RX_BUF_SIZE); +- ftmac100_rxdes_set_dma_own(rxdes); +- return 0; +-} ++/* ++ * Module initialization function ++ */ + +-static void ftmac100_free_buffers(struct ftmac100 *priv) ++static int ftmac100_probe(struct platform_device *pdev) + { +- int i; ++ int result,thisresult; ++ struct net_device *dev; ++ struct resource *iores; + +- for (i = 0; i < RX_QUEUE_ENTRIES; i++) { +- struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; +- struct page *page = ftmac100_rxdes_get_page(rxdes); +- dma_addr_t map = ftmac100_rxdes_get_dma_addr(rxdes); ++ PRINTK("+init_module\n"); + +- if (!page) +- continue; ++ result = -ENODEV; + +- dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); +- __free_page(page); ++ dev = alloc_etherdev(sizeof(struct ftmac100_local)); ++ if (!dev) { ++ printk(KERN_ERR "Fail allocating ethernet device"); ++ return -ENODEV; + } +- +- for (i = 0; i < TX_QUEUE_ENTRIES; i++) { +- struct ftmac100_txdes *txdes = &priv->descs->txdes[i]; +- struct sk_buff *skb = ftmac100_txdes_get_skb(txdes); +- dma_addr_t map = ftmac100_txdes_get_dma_addr(txdes); +- +- if (!skb) +- continue; +- +- dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); +- dev_kfree_skb(skb); ++ iores = platform_get_resource(pdev, IORESOURCE_IO, 0); ++ /* Copy the parameters from the platform specification */ ++ dev->base_addr = iores->start; ++ dev->irq = platform_get_irq(pdev, 0); ++ dev->netdev_ops = &ftmac100_ops; ++ ++ //dev->dma = nowait; // Use DMA field for nowait ++ /* Setup initial mac address */ ++ auto_get_mac(pdev->id,dev->dev_addr); ++ ++ if ((thisresult = register_netdev(dev)) != 0) { ++ free_irq( dev->irq, dev ); ++ free_netdev(dev); ++ } else { ++ platform_set_drvdata(pdev, dev); + } ++ if (thisresult == 0) // any of the devices initialized, run ++ result = 0; + +- dma_free_coherent(priv->dev, sizeof(struct ftmac100_descs), +- priv->descs, priv->descs_dma_addr); ++ return result; + } + +-static int ftmac100_alloc_buffers(struct ftmac100 *priv) +-{ +- int i; +- +- priv->descs = dma_alloc_coherent(priv->dev, sizeof(struct ftmac100_descs), +- &priv->descs_dma_addr, GFP_KERNEL); +- if (!priv->descs) +- return -ENOMEM; +- +- memset(priv->descs, 0, sizeof(struct ftmac100_descs)); +- +- /* initialize RX ring */ +- ftmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]); +- +- for (i = 0; i < RX_QUEUE_ENTRIES; i++) { +- struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; +- +- if (ftmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL)) +- goto err; +- } +- +- /* initialize TX ring */ +- ftmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]); +- return 0; +- +-err: +- ftmac100_free_buffers(priv); +- return -ENOMEM; +-} + +-/****************************************************************************** +- * struct mii_if_info functions +- *****************************************************************************/ +-static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg) ++/* ++ * Cleanup when module is removed with rmmod ++ */ ++ ++static int ftmac100_remove(struct platform_device *pdev) + { +- struct ftmac100 *priv = netdev_priv(netdev); +- unsigned int phycr; +- int i; +- +- phycr = FTMAC100_PHYCR_PHYAD(phy_id) | +- FTMAC100_PHYCR_REGAD(reg) | +- FTMAC100_PHYCR_MIIRD; +- +- iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR); +- +- for (i = 0; i < 10; i++) { +- phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR); +- +- if ((phycr & FTMAC100_PHYCR_MIIRD) == 0) +- return phycr & FTMAC100_PHYCR_MIIRDATA; +- +- udelay(100); +- } +- +- netdev_err(netdev, "mdio read timed out\n"); ++ struct net_device *dev; ++ struct ftmac100_local *priv; ++ PRINTK("+cleanup_module\n"); ++ ++ dev = platform_get_drvdata(pdev); ++ ++ priv = (struct ftmac100_local *)netdev_priv(dev); ++ if (priv->rx_descs) ++ dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma ); ++ if (priv->rx_buf) ++ dma_free_coherent( NULL, RX_BUF_SIZE*RXDES_NUM, (void*)priv->rx_buf, (dma_addr_t)priv->rx_buf_dma ); ++ if (priv->tx_descs) ++ dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma ); ++ if (priv->tx_buf) ++ dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma ); ++ priv->rx_descs = NULL; priv->rx_descs_dma = 0; ++ priv->rx_buf = NULL; priv->rx_buf_dma = 0; ++ priv->tx_descs = NULL; priv->tx_descs_dma = 0; ++ priv->tx_buf = NULL; priv->tx_buf_dma = 0; ++ ++ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ ++ unregister_netdev(dev); ++ ++ free_irq(dev->irq, dev); ++ //TODO: where is the request_region ? ++ //release_region(devFMAC.base_addr, SMC_IO_EXTENT); ++ free_netdev(dev); + return 0; + } + +-static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg, +- int data) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- unsigned int phycr; +- int i; +- +- phycr = FTMAC100_PHYCR_PHYAD(phy_id) | +- FTMAC100_PHYCR_REGAD(reg) | +- FTMAC100_PHYCR_MIIWR; +- +- data = FTMAC100_PHYWDATA_MIIWDATA(data); +- +- iowrite32(data, priv->base + FTMAC100_OFFSET_PHYWDATA); +- iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR); +- +- for (i = 0; i < 10; i++) { +- phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR); +- +- if ((phycr & FTMAC100_PHYCR_MIIWR) == 0) +- return; +- +- udelay(100); +- } +- +- netdev_err(netdev, "mdio write timed out\n"); +-} +- +-/****************************************************************************** +- * struct ethtool_ops functions +- *****************************************************************************/ +-static void ftmac100_get_drvinfo(struct net_device *netdev, +- struct ethtool_drvinfo *info) +-{ +- strcpy(info->driver, DRV_NAME); +- strcpy(info->version, DRV_VERSION); +- strcpy(info->bus_info, dev_name(&netdev->dev)); +-} +- +-static int ftmac100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- return mii_ethtool_gset(&priv->mii, cmd); +-} +- +-static int ftmac100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- return mii_ethtool_sset(&priv->mii, cmd); +-} +- +-static int ftmac100_nway_reset(struct net_device *netdev) ++static int ftmac100_suspend(struct platform_device *pdev, pm_message_t state) + { +- struct ftmac100 *priv = netdev_priv(netdev); +- return mii_nway_restart(&priv->mii); +-} +- +-static u32 ftmac100_get_link(struct net_device *netdev) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- return mii_link_ok(&priv->mii); +-} +- +-static const struct ethtool_ops ftmac100_ethtool_ops = { +- .set_settings = ftmac100_set_settings, +- .get_settings = ftmac100_get_settings, +- .get_drvinfo = ftmac100_get_drvinfo, +- .nway_reset = ftmac100_nway_reset, +- .get_link = ftmac100_get_link, +-}; +- +-/****************************************************************************** +- * interrupt handler +- *****************************************************************************/ +-static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) +-{ +- struct net_device *netdev = dev_id; +- struct ftmac100 *priv = netdev_priv(netdev); +- +- if (likely(netif_running(netdev))) { +- /* Disable interrupts for polling */ +- ftmac100_disable_all_int(priv); +- napi_schedule(&priv->napi); +- } +- +- return IRQ_HANDLED; +-} +- +-/****************************************************************************** +- * struct napi_struct functions +- *****************************************************************************/ +-static int ftmac100_poll(struct napi_struct *napi, int budget) +-{ +- struct ftmac100 *priv = container_of(napi, struct ftmac100, napi); +- struct net_device *netdev = priv->netdev; +- unsigned int status; +- bool completed = true; +- int rx = 0; +- +- status = ioread32(priv->base + FTMAC100_OFFSET_ISR); +- +- if (status & (FTMAC100_INT_RPKT_FINISH | FTMAC100_INT_NORXBUF)) { +- /* +- * FTMAC100_INT_RPKT_FINISH: +- * RX DMA has received packets into RX buffer successfully +- * +- * FTMAC100_INT_NORXBUF: +- * RX buffer unavailable +- */ +- bool retry; +- +- do { +- retry = ftmac100_rx_packet(priv, &rx); +- } while (retry && rx < budget); ++ struct net_device *ndev = platform_get_drvdata(pdev); + +- if (retry && rx == budget) +- completed = false; +- } +- +- if (status & (FTMAC100_INT_XPKT_OK | FTMAC100_INT_XPKT_LOST)) { +- /* +- * FTMAC100_INT_XPKT_OK: +- * packet transmitted to ethernet successfully +- * +- * FTMAC100_INT_XPKT_LOST: +- * packet transmitted to ethernet lost due to late +- * collision or excessive collision +- */ +- ftmac100_tx_complete(priv); +- } +- +- if (status & (FTMAC100_INT_NORXBUF | FTMAC100_INT_RPKT_LOST | +- FTMAC100_INT_AHB_ERR | FTMAC100_INT_PHYSTS_CHG)) { +- if (net_ratelimit()) +- netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status, +- status & FTMAC100_INT_NORXBUF ? "NORXBUF " : "", +- status & FTMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "", +- status & FTMAC100_INT_AHB_ERR ? "AHB_ERR " : "", +- status & FTMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : ""); +- +- if (status & FTMAC100_INT_NORXBUF) { +- /* RX buffer unavailable */ +- netdev->stats.rx_over_errors++; +- } +- +- if (status & FTMAC100_INT_RPKT_LOST) { +- /* received packet lost due to RX FIFO full */ +- netdev->stats.rx_fifo_errors++; +- } +- +- if (status & FTMAC100_INT_PHYSTS_CHG) { +- /* PHY link status change */ +- mii_check_link(&priv->mii); ++ if (ndev) { ++ if (netif_running(ndev)) { ++ netif_device_detach(ndev); ++ ftmac100_shutdown(ndev->base_addr); + } + } +- +- if (completed) { +- /* stop polling */ +- napi_complete(napi); +- ftmac100_enable_all_int(priv); +- } +- +- return rx; +-} +- +-/****************************************************************************** +- * struct net_device_ops functions +- *****************************************************************************/ +-static int ftmac100_open(struct net_device *netdev) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- int err; +- +- err = ftmac100_alloc_buffers(priv); +- if (err) { +- netdev_err(netdev, "failed to allocate buffers\n"); +- goto err_alloc; +- } +- +- err = request_irq(priv->irq, ftmac100_interrupt, 0, netdev->name, netdev); +- if (err) { +- netdev_err(netdev, "failed to request irq %d\n", priv->irq); +- goto err_irq; +- } +- +- priv->rx_pointer = 0; +- priv->tx_clean_pointer = 0; +- priv->tx_pointer = 0; +- priv->tx_pending = 0; +- +- err = ftmac100_start_hw(priv); +- if (err) +- goto err_hw; +- +- napi_enable(&priv->napi); +- netif_start_queue(netdev); +- +- ftmac100_enable_all_int(priv); +- +- return 0; +- +-err_hw: +- free_irq(priv->irq, netdev); +-err_irq: +- ftmac100_free_buffers(priv); +-err_alloc: +- return err; +-} +- +-static int ftmac100_stop(struct net_device *netdev) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- +- ftmac100_disable_all_int(priv); +- netif_stop_queue(netdev); +- napi_disable(&priv->napi); +- ftmac100_stop_hw(priv); +- free_irq(priv->irq, netdev); +- ftmac100_free_buffers(priv); +- + return 0; + } + +-static int ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) ++static int ftmac100_resume(struct platform_device *pdev) + { +- struct ftmac100 *priv = netdev_priv(netdev); +- dma_addr_t map; +- +- if (unlikely(skb->len > MAX_PKT_SIZE)) { +- if (net_ratelimit()) +- netdev_dbg(netdev, "tx packet too big\n"); +- +- netdev->stats.tx_dropped++; +- dev_kfree_skb(skb); +- return NETDEV_TX_OK; +- } ++ struct net_device *ndev = platform_get_drvdata(pdev); + +- map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); +- if (unlikely(dma_mapping_error(priv->dev, map))) { +- /* drop packet */ +- if (net_ratelimit()) +- netdev_err(netdev, "map socket buffer failed\n"); +- +- netdev->stats.tx_dropped++; +- dev_kfree_skb(skb); +- return NETDEV_TX_OK; ++ if (ndev) { ++ if (netif_running(ndev)) { ++ ftmac100_reset(ndev); ++ ftmac100_enable(ndev); ++ netif_device_attach(ndev); ++ } + } +- +- return ftmac100_xmit(priv, skb, map); ++ return 0; + } + +-/* optional */ +-static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +-{ +- struct ftmac100 *priv = netdev_priv(netdev); +- struct mii_ioctl_data *data = if_mii(ifr); +- +- return generic_mii_ioctl(&priv->mii, data, cmd, NULL); ++static void platform_device_release(struct device *dev){ + } + +-static const struct net_device_ops ftmac100_netdev_ops = { +- .ndo_open = ftmac100_open, +- .ndo_stop = ftmac100_stop, +- .ndo_start_xmit = ftmac100_hard_start_xmit, +- .ndo_set_mac_address = eth_mac_addr, +- .ndo_validate_addr = eth_validate_addr, +- .ndo_do_ioctl = ftmac100_do_ioctl, ++static struct platform_driver ftmac100_driver = { ++ .probe = ftmac100_probe, ++ .remove = ftmac100_remove, ++ .suspend = ftmac100_suspend, ++ .resume = ftmac100_resume, ++ .driver = { ++ .name = "ftmac100", ++ }, + }; + +-/****************************************************************************** +- * struct platform_driver functions +- *****************************************************************************/ +-static int ftmac100_probe(struct platform_device *pdev) +-{ +- struct resource *res; +- int irq; +- struct net_device *netdev; +- struct ftmac100 *priv; +- int err; +- +- if (!pdev) +- return -ENODEV; +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -ENXIO; +- +- irq = platform_get_irq(pdev, 0); +- if (irq < 0) +- return irq; +- +- /* setup net_device */ +- netdev = alloc_etherdev(sizeof(*priv)); +- if (!netdev) { +- err = -ENOMEM; +- goto err_alloc_etherdev; +- } +- +- SET_NETDEV_DEV(netdev, &pdev->dev); +- SET_ETHTOOL_OPS(netdev, &ftmac100_ethtool_ops); +- netdev->netdev_ops = &ftmac100_netdev_ops; +- +- platform_set_drvdata(pdev, netdev); +- +- /* setup private data */ +- priv = netdev_priv(netdev); +- priv->netdev = netdev; +- priv->dev = &pdev->dev; +- +- spin_lock_init(&priv->tx_lock); +- +- /* initialize NAPI */ +- netif_napi_add(netdev, &priv->napi, ftmac100_poll, 64); +- +- /* map io memory */ +- priv->res = request_mem_region(res->start, resource_size(res), +- dev_name(&pdev->dev)); +- if (!priv->res) { +- dev_err(&pdev->dev, "Could not reserve memory region\n"); +- err = -ENOMEM; +- goto err_req_mem; +- } +- +- priv->base = ioremap(res->start, resource_size(res)); +- if (!priv->base) { +- dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); +- err = -EIO; +- goto err_ioremap; +- } +- +- priv->irq = irq; +- +- /* initialize struct mii_if_info */ +- priv->mii.phy_id = 0; +- priv->mii.phy_id_mask = 0x1f; +- priv->mii.reg_num_mask = 0x1f; +- priv->mii.dev = netdev; +- priv->mii.mdio_read = ftmac100_mdio_read; +- priv->mii.mdio_write = ftmac100_mdio_write; +- +- /* register network device */ +- err = register_netdev(netdev); +- if (err) { +- dev_err(&pdev->dev, "Failed to register netdev\n"); +- goto err_register_netdev; +- } +- +- netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base); +- +- if (!is_valid_ether_addr(netdev->dev_addr)) { +- eth_hw_addr_random(netdev); +- netdev_info(netdev, "generated random MAC address %pM\n", +- netdev->dev_addr); +- } +- +- return 0; +- +-err_register_netdev: +- iounmap(priv->base); +-err_ioremap: +- release_resource(priv->res); +-err_req_mem: +- netif_napi_del(&priv->napi); +- platform_set_drvdata(pdev, NULL); +- free_netdev(netdev); +-err_alloc_etherdev: +- return err; +-} +- +-static int __exit ftmac100_remove(struct platform_device *pdev) +-{ +- struct net_device *netdev; +- struct ftmac100 *priv; +- +- netdev = platform_get_drvdata(pdev); +- priv = netdev_priv(netdev); +- +- unregister_netdev(netdev); +- +- iounmap(priv->base); +- release_resource(priv->res); +- +- netif_napi_del(&priv->napi); +- platform_set_drvdata(pdev, NULL); +- free_netdev(netdev); +- return 0; +-} ++static struct resource ftmac100_resources_a320[] = { ++ [0] = { ++ .start = MAC_FTMAC100_0_VA_BASE, ++ .end = MAC_FTMAC100_0_VA_LIMIT, ++ .flags = IORESOURCE_IO, ++ }, ++ [1] = { ++ .start = MAC_FTMAC100_0_IRQ, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; + +-static struct platform_driver ftmac100_driver = { +- .probe = ftmac100_probe, +- .remove = __exit_p(ftmac100_remove), +- .driver = { +- .name = DRV_NAME, +- .owner = THIS_MODULE, ++static struct platform_device ftmac100_device_a320 = { ++ .name = "ftmac100", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(ftmac100_resources_a320), ++ .resource = ftmac100_resources_a320, ++ .dev = { ++ .release = platform_device_release, + }, + }; + +-/****************************************************************************** +- * initialization / finalization +- *****************************************************************************/ ++ + static int __init ftmac100_init(void) + { +- pr_info("Loading version " DRV_VERSION " ...\n"); ++ platform_device_register(&ftmac100_device_a320); + return platform_driver_register(&ftmac100_driver); + } + + static void __exit ftmac100_exit(void) + { + platform_driver_unregister(&ftmac100_driver); ++ platform_device_unregister(&ftmac100_device_a320); + } + + module_init(ftmac100_init); + module_exit(ftmac100_exit); +- +-MODULE_AUTHOR("Po-Yu Chuang "); +-MODULE_DESCRIPTION("FTMAC100 driver"); +-MODULE_LICENSE("GPL"); +diff -Nur linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.h linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.h +--- linux-3.4.110.orig/drivers/net/ethernet/faraday/ftmac100.h 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/net/ethernet/faraday/ftmac100.h 2016-04-07 10:20:51.054085357 +0200 +@@ -1,180 +1,267 @@ + /* +- * Faraday FTMAC100 10/100 Ethernet ++ * drivers/net/ftmac100.h + * +- * (C) Copyright 2009-2011 Faraday Technology +- * Po-Yu Chuang ++ * Faraday FTMAC100 Device Driver + * +- * 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. ++ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) ++ * ++ * All Rights Reserved + * +- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. +- */ +- +-#ifndef __FTMAC100_H +-#define __FTMAC100_H +- +-#define FTMAC100_OFFSET_ISR 0x00 +-#define FTMAC100_OFFSET_IMR 0x04 +-#define FTMAC100_OFFSET_MAC_MADR 0x08 +-#define FTMAC100_OFFSET_MAC_LADR 0x0c +-#define FTMAC100_OFFSET_MAHT0 0x10 +-#define FTMAC100_OFFSET_MAHT1 0x14 +-#define FTMAC100_OFFSET_TXPD 0x18 +-#define FTMAC100_OFFSET_RXPD 0x1c +-#define FTMAC100_OFFSET_TXR_BADR 0x20 +-#define FTMAC100_OFFSET_RXR_BADR 0x24 +-#define FTMAC100_OFFSET_ITC 0x28 +-#define FTMAC100_OFFSET_APTC 0x2c +-#define FTMAC100_OFFSET_DBLAC 0x30 +-#define FTMAC100_OFFSET_MACCR 0x88 +-#define FTMAC100_OFFSET_MACSR 0x8c +-#define FTMAC100_OFFSET_PHYCR 0x90 +-#define FTMAC100_OFFSET_PHYWDATA 0x94 +-#define FTMAC100_OFFSET_FCR 0x98 +-#define FTMAC100_OFFSET_BPR 0x9c +-#define FTMAC100_OFFSET_TS 0xc4 +-#define FTMAC100_OFFSET_DMAFIFOS 0xc8 +-#define FTMAC100_OFFSET_TM 0xcc +-#define FTMAC100_OFFSET_TX_MCOL_SCOL 0xd4 +-#define FTMAC100_OFFSET_RPF_AEP 0xd8 +-#define FTMAC100_OFFSET_XM_PG 0xdc +-#define FTMAC100_OFFSET_RUNT_TLCC 0xe0 +-#define FTMAC100_OFFSET_CRCER_FTL 0xe4 +-#define FTMAC100_OFFSET_RLC_RCC 0xe8 +-#define FTMAC100_OFFSET_BROC 0xec +-#define FTMAC100_OFFSET_MULCA 0xf0 +-#define FTMAC100_OFFSET_RP 0xf4 +-#define FTMAC100_OFFSET_XP 0xf8 +- +-/* +- * Interrupt status register & interrupt mask register +- */ +-#define FTMAC100_INT_RPKT_FINISH (1 << 0) +-#define FTMAC100_INT_NORXBUF (1 << 1) +-#define FTMAC100_INT_XPKT_FINISH (1 << 2) +-#define FTMAC100_INT_NOTXBUF (1 << 3) +-#define FTMAC100_INT_XPKT_OK (1 << 4) +-#define FTMAC100_INT_XPKT_LOST (1 << 5) +-#define FTMAC100_INT_RPKT_SAV (1 << 6) +-#define FTMAC100_INT_RPKT_LOST (1 << 7) +-#define FTMAC100_INT_AHB_ERR (1 << 8) +-#define FTMAC100_INT_PHYSTS_CHG (1 << 9) +- +-/* +- * Interrupt timer control register + */ +-#define FTMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0) +-#define FTMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4) +-#define FTMAC100_ITC_RXINT_TIME_SEL (1 << 7) +-#define FTMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8) +-#define FTMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12) +-#define FTMAC100_ITC_TXINT_TIME_SEL (1 << 15) + +-/* +- * Automatic polling timer control register +- */ +-#define FTMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0) +-#define FTMAC100_APTC_RXPOLL_TIME_SEL (1 << 4) +-#define FTMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8) +-#define FTMAC100_APTC_TXPOLL_TIME_SEL (1 << 12) ++#ifndef _FTMAC100_H_ ++#define _FTMAC100_H_ + +-/* +- * DMA burst length and arbitration control register +- */ +-#define FTMAC100_DBLAC_INCR4_EN (1 << 0) +-#define FTMAC100_DBLAC_INCR8_EN (1 << 1) +-#define FTMAC100_DBLAC_INCR16_EN (1 << 2) +-#define FTMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 3) +-#define FTMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 6) +-#define FTMAC100_DBLAC_RX_THR_EN (1 << 9) ++#define ISR_REG 0x00 // interrups status register ++#define IMR_REG 0x04 // interrupt maks register ++#define MAC_MADR_REG 0x08 // MAC address (Most significant) ++#define MAC_LADR_REG 0x0c // MAC address (Least significant) ++ ++#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register ++#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register ++#define TXPD_REG 0x18 // Transmit Poll Demand register ++#define RXPD_REG 0x1c // Receive Poll Demand register ++#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register ++#define RXR_BADR_REG 0x24 // Receive Ring Base Address register ++#define ITC_REG 0x28 // interrupt timer control register ++#define APTC_REG 0x2c // Automatic Polling Timer control register ++#define DBLAC_REG 0x30 // DMA Burst Length and Arbitration control register ++ ++ ++ ++#define MACCR_REG 0x88 // MAC control register ++#define MACSR_REG 0x8c // MAC status register ++#define PHYCR_REG 0x90 // PHY control register ++#define PHYWDATA_REG 0x94 // PHY Write Data register ++#define FCR_REG 0x98 // Flow Control register ++#define BPR_REG 0x9c // back pressure register ++#define WOLCR_REG 0xa0 // Wake-On-Lan control register ++#define WOLSR_REG 0xa4 // Wake-On-Lan status register ++#define WFCRC_REG 0xa8 // Wake-up Frame CRC register ++#define WFBM1_REG 0xb0 // wake-up frame byte mask 1st double word register ++#define WFBM2_REG 0xb4 // wake-up frame byte mask 2nd double word register ++#define WFBM3_REG 0xb8 // wake-up frame byte mask 3rd double word register ++#define WFBM4_REG 0xbc // wake-up frame byte mask 4th double word register ++#define TM_REG 0xcc // test mode register ++ ++#define PHYSTS_CHG_bit (1UL<<9) ++#define AHB_ERR_bit (1UL<<8) ++#define RPKT_LOST_bit (1UL<<7) ++#define RPKT_SAV_bit (1UL<<6) ++#define XPKT_LOST_bit (1UL<<5) ++#define XPKT_OK_bit (1UL<<4) ++#define NOTXBUF_bit (1UL<<3) ++#define XPKT_FINISH_bit (1UL<<2) ++#define NORXBUF_bit (1UL<<1) ++#define RPKT_FINISH_bit (1UL<<0) ++ ++ ++#ifdef __NDS32_EB__ ++typedef struct ++{ ++ unsigned int Reserved2:19; ++ unsigned int TXPOLL_TIME_SEL:1; ++ unsigned int TXPOLL_CNT:4; ++ unsigned int Reserved1:3; ++ unsigned int RXPOLL_TIME_SEL:1; ++ unsigned int RXPOLL_CNT:4; ++}FTMAC100_APTCR_Status; ++#else ++typedef struct ++{ ++ unsigned int RXPOLL_CNT:4; ++ unsigned int RXPOLL_TIME_SEL:1; ++ unsigned int Reserved1:3; ++ unsigned int TXPOLL_CNT:4; ++ unsigned int TXPOLL_TIME_SEL:1; ++ unsigned int Reserved2:19; ++} FTMAC100_APTCR_Status; ++#endif ++ ++#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet ++#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet ++#define FULLDUP_bit (1UL<<15) // full duplex ++#define CRC_APD_bit (1UL<<14) // append crc to transmit packet ++#define MDC_SEL_bit (1UL<<13) // set MDC as TX_CK/10 ++#define RCV_ALL_bit (1UL<<12) // not check incoming packet's destination address ++#define RX_FTL_bit (1UL<<11) // Store incoming packet even its length is great than 1518 byte ++#define RX_RUNT_bit (1UL<<10) // Store incoming packet even its length is les than 64 byte ++#define HT_MULTI_EN_bit (1UL<<9) ++#define RCV_EN_bit (1UL<<8) // receiver enable ++#define XMT_EN_bit (1UL<<5) // transmitter enable ++#define CRC_DIS_bit (1UL<<4) ++#define LOOP_EN_bit (1UL<<3) // Internal loop-back ++#define SW_RST_bit (1UL<<2) // software reset/ ++#define RDMA_EN_bit (1UL<<1) // enable DMA receiving channel ++#define XDMA_EN_bit (1UL<<0) // enable DMA transmitting channel ++ ++ ++// -------------------------------------------------------------------- ++// Receive Ring descriptor structure ++// -------------------------------------------------------------------- ++#ifdef __NDS32_EB__ ++typedef struct ++{ ++ // RXDES0 ++ unsigned int RXDMA_OWN:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software ++ unsigned int Reserved3:1; ++ unsigned int FRS:1; ++ unsigned int LRS:1; ++ unsigned int Reserved2:5; ++ unsigned int RX_ODD_NB:1; ++ unsigned int RUNT:1; ++ unsigned int FTL:1; ++ unsigned int CRC_ERR:1; //19 ++ unsigned int RX_ERR:1; //18 ++ unsigned int BROARDCAST:1; //17 ++ unsigned int MULTICAST:1; //16 ++ unsigned int Reserved1:5; //11~15 ++ unsigned int ReceiveFrameLength:11;//0~10 ++ ++ // RXDES1 ++ unsigned int EDOTR:1; ++ unsigned int Reserved:20; ++ unsigned int RXBUF_Size:11; ++ ++ // RXDES2 ++ unsigned int RXBUF_BADR; ++ ++ unsigned int VIR_RXBUF_BADR; // not defined, §Ú­Ì®³¨Ó©ñ receive buffer ªº virtual address ++ ++}RX_DESC; ++ ++ ++typedef struct ++{ ++ // TXDES0 ++ unsigned int TXDMA_OWN:1; ++ unsigned int Reserved1:29; ++ unsigned int TXPKT_EXSCOL:1; ++ unsigned int TXPKT_LATECOL:1; ++ ++ // TXDES1 ++ unsigned int EDOTR:1; ++ unsigned int TXIC:1; ++ unsigned int TX2FIC:1; ++ unsigned int FTS:1; ++ unsigned int LTS:1; ++ unsigned int Reserved2:16; ++ unsigned int TXBUF_Size:11; ++ ++ // RXDES2 ++ unsigned int TXBUF_BADR; ++ unsigned int VIR_TXBUF_BADR; ++}TX_DESC; ++#else ++typedef struct ++{ ++ // RXDES0 ++ unsigned int ReceiveFrameLength:11;//0~10 ++ unsigned int Reserved1:5; //11~15 ++ unsigned int MULTICAST:1; //16 ++ unsigned int BROARDCAST:1; //17 ++ unsigned int RX_ERR:1; //18 ++ unsigned int CRC_ERR:1; //19 ++ unsigned int FTL:1; ++ unsigned int RUNT:1; ++ unsigned int RX_ODD_NB:1; ++ unsigned int Reserved2:5; ++ unsigned int LRS:1; ++ unsigned int FRS:1; ++ unsigned int Reserved3:1; ++ unsigned int RXDMA_OWN:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software ++ ++ // RXDES1 ++ unsigned int RXBUF_Size:11; ++ unsigned int Reserved:20; ++ unsigned int EDOTR:1; ++ ++ // RXDES2 ++ unsigned int RXBUF_BADR; ++ ++ unsigned int VIR_RXBUF_BADR; // not defined, §Ú­Ì®³¨Ó©ñ receive buffer ªº virtual address ++ ++} RX_DESC; ++ ++ ++typedef struct ++{ ++ // TXDES0 ++ unsigned int TXPKT_LATECOL:1; ++ unsigned int TXPKT_EXSCOL:1; ++ unsigned int Reserved1:29; ++ unsigned int TXDMA_OWN:1; ++ ++ // TXDES1 ++ unsigned int TXBUF_Size:11; ++ unsigned int Reserved2:16; ++ unsigned int LTS:1; ++ unsigned int FTS:1; ++ unsigned int TX2FIC:1; ++ unsigned int TXIC:1; ++ unsigned int EDOTR:1; ++ ++ // RXDES2 ++ unsigned int TXBUF_BADR; ++ unsigned int VIR_TXBUF_BADR; ++} TX_DESC; ++#endif ++ ++// waiting to do: ++#define TXPOLL_CNT 8 ++#define RXPOLL_CNT 0 ++ ++#define OWNBY_SOFTWARE 0 ++#define OWNBY_FTMAC100 1 ++ ++// -------------------------------------------------------------------- ++// driver related definition ++// -------------------------------------------------------------------- ++#define RXDES_NUM 256 // must be 2's power ++#define RX_BUF_SIZE 1536 ++#define TXDES_NUM 64 // must be 2's power ++#define TX_BUF_SIZE 1536 // Luke Lee : Just bigger than 1518 ++ ++ ++struct ftmac100_local ++{ ++ // these are things that the kernel wants me to keep, so users ++ // can find out semi-useless statistics of how well the card is ++ // performing ++ struct net_device_stats stats; ++ ++ // Set to true during the auto-negotiation sequence ++ int autoneg_active; ++ ++ // Address of our PHY port ++ unsigned int phyaddr; ++ ++ // Type of PHY ++ unsigned int phytype; ++ ++ // Last contents of PHY Register 18 ++ unsigned int lastPhy18; ++ ++ spinlock_t lock; ++ ++ volatile RX_DESC *rx_descs; // receive ring base address ++ unsigned int rx_descs_dma; // receive ring physical base address ++ char *rx_buf; // receive buffer cpu address ++ int rx_buf_dma; // receive buffer physical address ++ int rx_idx; // receive descriptor ++ //struct sk_buff *rx_skbuff[RXDES_NUM]; ++ ++ volatile TX_DESC *tx_descs; ++ unsigned int tx_descs_dma; ++ char *tx_buf; ++ int tx_buf_dma; ++ int tx_idx; ++ int old_tx; ++ struct sk_buff *tx_skbuff[RXDES_NUM]; ++ ++ int maccr_val; ++}; + +-/* +- * MAC control register +- */ +-#define FTMAC100_MACCR_XDMA_EN (1 << 0) +-#define FTMAC100_MACCR_RDMA_EN (1 << 1) +-#define FTMAC100_MACCR_SW_RST (1 << 2) +-#define FTMAC100_MACCR_LOOP_EN (1 << 3) +-#define FTMAC100_MACCR_CRC_DIS (1 << 4) +-#define FTMAC100_MACCR_XMT_EN (1 << 5) +-#define FTMAC100_MACCR_ENRX_IN_HALFTX (1 << 6) +-#define FTMAC100_MACCR_RCV_EN (1 << 8) +-#define FTMAC100_MACCR_HT_MULTI_EN (1 << 9) +-#define FTMAC100_MACCR_RX_RUNT (1 << 10) +-#define FTMAC100_MACCR_RX_FTL (1 << 11) +-#define FTMAC100_MACCR_RCV_ALL (1 << 12) +-#define FTMAC100_MACCR_CRC_APD (1 << 14) +-#define FTMAC100_MACCR_FULLDUP (1 << 15) +-#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16) +-#define FTMAC100_MACCR_RX_BROADPKT (1 << 17) +- +-/* +- * PHY control register +- */ +-#define FTMAC100_PHYCR_MIIRDATA 0xffff +-#define FTMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16) +-#define FTMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21) +-#define FTMAC100_PHYCR_MIIRD (1 << 26) +-#define FTMAC100_PHYCR_MIIWR (1 << 27) +- +-/* +- * PHY write data register +- */ +-#define FTMAC100_PHYWDATA_MIIWDATA(x) ((x) & 0xffff) +- +-/* +- * Transmit descriptor, aligned to 16 bytes +- */ +-struct ftmac100_txdes { +- unsigned int txdes0; +- unsigned int txdes1; +- unsigned int txdes2; /* TXBUF_BADR */ +- unsigned int txdes3; /* not used by HW */ +-} __attribute__ ((aligned(16))); +- +-#define FTMAC100_TXDES0_TXPKT_LATECOL (1 << 0) +-#define FTMAC100_TXDES0_TXPKT_EXSCOL (1 << 1) +-#define FTMAC100_TXDES0_TXDMA_OWN (1 << 31) +- +-#define FTMAC100_TXDES1_TXBUF_SIZE(x) ((x) & 0x7ff) +-#define FTMAC100_TXDES1_LTS (1 << 27) +-#define FTMAC100_TXDES1_FTS (1 << 28) +-#define FTMAC100_TXDES1_TX2FIC (1 << 29) +-#define FTMAC100_TXDES1_TXIC (1 << 30) +-#define FTMAC100_TXDES1_EDOTR (1 << 31) +- +-/* +- * Receive descriptor, aligned to 16 bytes +- */ +-struct ftmac100_rxdes { +- unsigned int rxdes0; +- unsigned int rxdes1; +- unsigned int rxdes2; /* RXBUF_BADR */ +- unsigned int rxdes3; /* not used by HW */ +-} __attribute__ ((aligned(16))); +- +-#define FTMAC100_RXDES0_RFL 0x7ff +-#define FTMAC100_RXDES0_MULTICAST (1 << 16) +-#define FTMAC100_RXDES0_BROADCAST (1 << 17) +-#define FTMAC100_RXDES0_RX_ERR (1 << 18) +-#define FTMAC100_RXDES0_CRC_ERR (1 << 19) +-#define FTMAC100_RXDES0_FTL (1 << 20) +-#define FTMAC100_RXDES0_RUNT (1 << 21) +-#define FTMAC100_RXDES0_RX_ODD_NB (1 << 22) +-#define FTMAC100_RXDES0_LRS (1 << 28) +-#define FTMAC100_RXDES0_FRS (1 << 29) +-#define FTMAC100_RXDES0_RXDMA_OWN (1 << 31) ++#endif + +-#define FTMAC100_RXDES1_RXBUF_SIZE(x) ((x) & 0x7ff) +-#define FTMAC100_RXDES1_EDORR (1 << 31) + +-#endif /* __FTMAC100_H */ +diff -Nur linux-3.4.110.orig/drivers/net/ethernet/faraday/Kconfig linux-3.4.110/drivers/net/ethernet/faraday/Kconfig +--- linux-3.4.110.orig/drivers/net/ethernet/faraday/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/net/ethernet/faraday/Kconfig 2016-04-07 10:20:51.054085357 +0200 +@@ -5,7 +5,7 @@ + config NET_VENDOR_FARADAY + bool "Faraday devices" + default y +- depends on ARM ++ depends on ARM || NDS32 + ---help--- + If you have a network (Ethernet) card belonging to this class, say Y + and read the Ethernet-HOWTO, available from +@@ -20,7 +20,7 @@ + + config FTMAC100 + tristate "Faraday FTMAC100 10/100 Ethernet support" +- depends on ARM ++ depends on ARM || NDS32 + select NET_CORE + select MII + ---help--- +diff -Nur linux-3.4.110.orig/drivers/pci/Makefile linux-3.4.110/drivers/pci/Makefile +--- linux-3.4.110.orig/drivers/pci/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/pci/Makefile 2016-04-07 10:20:51.054085357 +0200 +@@ -49,6 +49,7 @@ + obj-$(CONFIG_MICROBLAZE) += setup-bus.o + obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o + obj-$(CONFIG_SPARC_LEON) += setup-bus.o setup-irq.o ++obj-$(CONFIG_NDS32) += setup-bus.o setup-irq.o + + # + # ACPI Related PCI FW Functions +diff -Nur linux-3.4.110.orig/drivers/rtc/Kconfig linux-3.4.110/drivers/rtc/Kconfig +--- linux-3.4.110.orig/drivers/rtc/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/rtc/Kconfig 2016-04-07 10:20:51.054085357 +0200 +@@ -779,6 +779,16 @@ + This driver can also be built as a module. If so, the module + will be called rtc-ep93xx. + ++config RTC_DRV_FTRTC010 ++ tristate "Faraday Real Time Clock" ++ depends on NDS32 ++ help ++ If you say Y here you will get access to the real time clock ++ built into your AG101 CPU. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called rtc-ftrtc010. ++ + config RTC_DRV_SA1100 + tristate "SA11x0/PXA2xx/PXA910" + depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP +diff -Nur linux-3.4.110.orig/drivers/rtc/Makefile linux-3.4.110/drivers/rtc/Makefile +--- linux-3.4.110.orig/drivers/rtc/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/rtc/Makefile 2016-04-07 10:20:51.054085357 +0200 +@@ -50,6 +50,7 @@ + obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o + obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o + obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o ++obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o + obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o + obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o + obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o +diff -Nur linux-3.4.110.orig/drivers/rtc/rtc-ftrtc010.c linux-3.4.110/drivers/rtc/rtc-ftrtc010.c +--- linux-3.4.110.orig/drivers/rtc/rtc-ftrtc010.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/rtc/rtc-ftrtc010.c 2016-04-07 10:20:51.054085357 +0200 +@@ -0,0 +1,371 @@ ++/* ++ * Faraday RTC Support ++ * ++ * Copyright (C) 2006, 2007, 2008 Paul Mundt ++ * Copyright (C) 2006 Jamie Lenehan ++ * Copyright (C) 2008 Angelo Castello ++ * Copyright (C) 2008 Roy Lee ++ * ++ * Based on the old arch/sh/kernel/cpu/rtc.c by: ++ * ++ * Copyright (C) 2000 Philipp Rumpf ++ * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PCLK ( AHB_CLK_IN / 2) ++ ++#define DRV_NAME "faraday-rtc" ++ ++#define RTC_REG( off) ( *( volatile unsigned long *)( rtc->regbase + ( off))) ++ ++#define RTC_CR RTC_REG( 0x20) /* Control */ ++#define RTC_CR_IE ( 0x1UL << 0) ++#define RTC_CR_IES ( 0x1UL << 1) ++#define RTC_CR_IEM ( 0x1UL << 2) ++#define RTC_CR_IEH ( 0x1UL << 3) ++#define RTC_CR_IED ( 0x1UL << 4) ++#define RTC_CR_ALRM ( 0x1UL << 5) ++#define RTC_CR_LOAD ( 0x1UL << 6) ++ ++#define RTC_RR RTC_REG( 0x1C) /* RTC Record Register */ ++#define RTC_DIV RTC_REG( 0x38) /* RTC Divede Register */ ++#define RTC_REV RTC_REG( 0x3C) /* RTC Divede Register */ ++ ++#define RTC_IR RTC_REG( 0x34) /* RTC interrupt state */ ++#define RTC_IR_IES ( 0x1UL << 0) /* RTC interrupt state */ ++#define RTC_IR_IEM ( 0x1UL << 1) /* RTC interrupt state */ ++#define RTC_IR_IEH ( 0x1UL << 2) /* RTC interrupt state */ ++#define RTC_IR_IED ( 0x1UL << 3) /* RTC interrupt state */ ++#define RTC_IR_ALRM ( 0x1UL << 4) /* RTC interrupt state */ ++ ++#define RTC_SECOND RTC_REG( 0x00) /* RTC sec */ ++#define RTC_MINUTE RTC_REG( 0x04) /* RTC min */ ++#define RTC_HOUR RTC_REG( 0x08) /* RTC hour */ ++#define RTC_DAYS RTC_REG( 0x0C) /* RTC day */ ++ ++#define RTC_ALRM_SECOND RTC_REG( 0x10) /* RTC alarm sec */ ++#define RTC_ALRM_MINUTE RTC_REG( 0x14) /* RTC alarm min */ ++#define RTC_ALRM_HOUR RTC_REG( 0x18) /* RTC alarm hour */ ++ ++#define RTC_WRITE_SECOND RTC_REG( 0x24) /* RTC write port for sec */ ++#define RTC_WRITE_MINUTE RTC_REG( 0x28) /* RTC write port for min */ ++#define RTC_WRITE_HOUR RTC_REG( 0x2C) /* RTC write port for hour */ ++#define RTC_WRITE_DAYS RTC_REG( 0x30) /* RTC write port for day */ ++ ++struct ft_rtc{ ++ ++ void __iomem *regbase; ++ struct resource *res; ++ unsigned int alarm_irq; ++ unsigned int interrupt_irq; ++ struct rtc_device *rtc_dev; ++ spinlock_t lock; /* Protects this structure */ ++}; ++ ++struct ft_rtc rtc_platform_data; ++ ++static irqreturn_t ft_rtc_interrupt( int irq, void *dev_id){ ++ ++ struct ft_rtc *rtc = dev_id; ++ if( RTC_IR & RTC_IR_IES){ ++ ++ RTC_IR &= ~RTC_IR_IES; ++ rtc_update_irq( rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); ++ ++ return IRQ_HANDLED; ++ } ++ ++ return IRQ_NONE; ++} ++ ++static irqreturn_t ft_rtc_alarm( int irq, void *dev_id){ ++ ++ struct ft_rtc *rtc = dev_id; ++ if( RTC_IR & RTC_IR_ALRM){ ++ ++ RTC_CR &= ~RTC_CR_ALRM; ++ RTC_IR &= ~RTC_IR_ALRM; ++ rtc_update_irq( rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); ++ ++ return IRQ_HANDLED; ++ } ++ ++ return IRQ_NONE; ++} ++ ++static void ft_rtc_release( struct device *dev){ ++ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ ++ RTC_CR &= ~RTC_CR_IES; ++ RTC_CR &= ~RTC_CR_ALRM; ++} ++ ++/* rick add */ ++static int ft_alarm_irq_enable(struct device *dev, unsigned int enabled) ++{ ++// printk("\n\nft_alarm_irq_enable\n\n"); ++ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ spin_lock_irq(&rtc->lock); ++ if (enabled) ++ RTC_CR |= RTC_CR_ALRM; ++ else ++ RTC_CR &= ~RTC_CR_ALRM; ++ spin_unlock_irq(&rtc->lock); ++ return 0; ++} ++ ++static int ft_rtc_read_time( struct device *dev, struct rtc_time *tm){ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ unsigned long time = RTC_DAYS * 86400 + RTC_HOUR * 3600 + RTC_MINUTE * 60 + RTC_SECOND; ++ rtc_time_to_tm( time, tm); ++ if( rtc_valid_tm( tm) < 0) { ++ dev_err( dev, "invalid date\n"); ++ rtc_time_to_tm( 0, tm); ++ } ++ return 0; ++} ++ ++static int ft_rtc_set_time( struct device *dev, struct rtc_time *tm){ ++ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ unsigned long time = 0; ++ ++ rtc_tm_to_time( tm, &time); ++ ++ RTC_WRITE_DAYS = time / 86400; ++ time %= 86400; ++ ++ RTC_WRITE_HOUR = time / 3600; ++ time %= 3600; ++ ++ RTC_WRITE_MINUTE = time / 60; ++ time %= 60; ++ ++ RTC_WRITE_SECOND = time; ++ ++ RTC_CR |= RTC_CR_LOAD; ++ ++ return 0; ++} ++ ++static int ft_rtc_read_alarm( struct device *dev, struct rtc_wkalrm *wkalrm){ ++ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ struct rtc_time *tm = &wkalrm->time; ++ ++ tm->tm_sec = RTC_ALRM_SECOND; ++ tm->tm_min = RTC_ALRM_MINUTE; ++ tm->tm_hour = RTC_ALRM_HOUR; ++ ++ wkalrm->enabled = ( RTC_CR & RTC_CR_ALRM) ? 1 : 0; ++ ++ return 0; ++} ++ ++static int ft_rtc_set_alarm( struct device *dev, struct rtc_wkalrm *wkalrm){ ++ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ struct rtc_time *tm = &wkalrm->time; ++ int err = rtc_valid_tm( tm); ++ if( err < 0){ ++ ++ dev_err( dev, "invalid alarm value\n"); ++ return err; ++ } ++ ++ /* disable alarm interrupt and clear the alarm flag */ ++ RTC_CR &= ~RTC_CR_ALRM; ++ ++ /* set alarm time */ ++ RTC_ALRM_SECOND = tm->tm_sec; ++ RTC_ALRM_MINUTE = tm->tm_min; ++ RTC_ALRM_HOUR = tm->tm_hour; ++ ++ if( wkalrm->enabled) ++ RTC_CR |= RTC_CR_ALRM; ++ ++ return 0; ++} ++ ++/* ++static int ft_rtc_irq_set_state( struct device *dev, int enabled){ ++ struct ft_rtc *rtc = dev_get_drvdata( dev); ++ if( enabled) ++ RTC_CR |= RTC_CR_IES; ++ else ++ RTC_CR &= ~RTC_CR_IES; ++ ++ return 0; ++} ++ ++*/ ++ ++static struct rtc_class_ops ft_rtc_ops = { ++ ++ .release = ft_rtc_release, ++ .alarm_irq_enable = ft_alarm_irq_enable, ++ ++ .read_time = ft_rtc_read_time, ++ .set_time = ft_rtc_set_time, ++ .read_alarm = ft_rtc_read_alarm, ++ .set_alarm = ft_rtc_set_alarm, ++}; ++ ++static int __devinit ft_rtc_probe( struct platform_device *pdev){ ++ ++ struct ft_rtc *rtc = &rtc_platform_data; ++ int ret = -ENOENT; ++ spin_lock_init(&rtc->lock); ++ ++ if( ( rtc->alarm_irq = platform_get_irq( pdev, 0)) < 0) ++ goto err_exit; ++ ++ if( ( rtc->interrupt_irq = platform_get_irq( pdev, 1)) < 0) ++ goto err_exit; ++ ++ if( !( rtc->res = platform_get_resource( pdev, IORESOURCE_MEM, 0))) ++ goto err_exit; ++ ++ if( ( ret = request_irq( rtc->alarm_irq , ft_rtc_alarm, 0, "RTC Alarm : ftrtc010", rtc))) ++ goto err_exit; ++ ++ if( ( ret = request_irq( rtc->interrupt_irq , ft_rtc_interrupt, 0, "RTC Interrupt : ftrtc010", rtc))) ++ goto err_interrupt_irq; ++ ++ ret = -EBUSY; ++ ++ if( !( rtc->res = request_mem_region( rtc->res->start, rtc->res->end - rtc->res->start + 1, pdev->name))) ++ goto err_request_region; ++ ++ ret = -EINVAL; ++ ++ if( !( rtc->regbase = ioremap_nocache( rtc->res->start, rtc->res->end - rtc->res->start + 1))) ++ goto err_ioremap1; ++ ++ ++ //RTC_DIV = ( 0x1UL << 31) | 2; /* AG101 */ ++ RTC_CR |= RTC_CR_IE; ++ platform_set_drvdata( pdev, rtc); ++ device_init_wakeup(&pdev->dev, true); ++ ++ rtc->rtc_dev = rtc_device_register( DRV_NAME, &pdev->dev, &ft_rtc_ops, THIS_MODULE); ++ ++ if( IS_ERR( rtc->rtc_dev)) { ++ ++ ret = PTR_ERR( rtc->rtc_dev); ++ goto err_unmap; ++ } ++ ++ rtc->rtc_dev->max_user_freq = 256; ++ rtc->rtc_dev->irq_freq = 1; ++ return 0; ++ ++err_unmap: ++ iounmap( rtc->regbase); ++err_ioremap1: ++ release_resource( rtc->res); ++err_request_region: ++ free_irq( rtc->interrupt_irq, rtc); ++err_interrupt_irq: ++ free_irq( rtc->alarm_irq, rtc); ++err_exit: ++ return ret; ++} ++ ++static int __devexit ft_rtc_remove( struct platform_device *pdev){ ++ ++ struct ft_rtc *rtc = platform_get_drvdata( pdev); ++ ++ rtc_device_unregister( rtc->rtc_dev); ++ ++ RTC_CR &= ~RTC_CR_ALRM; ++ ++ free_irq( rtc->alarm_irq, rtc); ++ free_irq( rtc->interrupt_irq, rtc); ++ ++ iounmap( rtc->regbase); ++ ++ platform_set_drvdata( pdev, NULL); ++ ++ return 0; ++} ++ ++static void platform_device_release(struct device *dev){ ++} ++ ++static struct resource rtc_resources[] = { ++ { ++ .start = RTC_FTRTC010_PA_BASE, ++ .end = RTC_FTRTC010_PA_LIMIT, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = RTC_FTRTC010_IRQ0, ++ .end = RTC_FTRTC010_IRQ0, ++ .flags = IORESOURCE_IRQ, ++ }, ++ { ++ .start = RTC_FTRTC010_IRQ1, ++ .end = RTC_FTRTC010_IRQ1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct platform_driver ft_rtc_platform_driver = { ++ ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE, ++ }, ++ .probe = ft_rtc_probe, ++ .remove = __devexit_p( ft_rtc_remove), ++}; ++ ++static struct platform_device rtc_device = { ++ ++ .name = DRV_NAME, ++ .id = 0, ++ .resource = rtc_resources, ++ .num_resources = ARRAY_SIZE( rtc_resources), ++ .dev = { ++ .platform_data = &rtc_platform_data, ++ .release = platform_device_release, ++ }, ++}; ++ ++static int __init ft_rtc_init( void){ ++ platform_device_register( &rtc_device); ++ return platform_driver_register( &ft_rtc_platform_driver); ++} ++ ++static void __exit ft_rtc_exit( void){ ++ ++ platform_driver_unregister( &ft_rtc_platform_driver); ++ platform_device_unregister( &rtc_device); ++} ++ ++module_init( ft_rtc_init); ++module_exit( ft_rtc_exit); ++ ++MODULE_DESCRIPTION( "SuperH on-chip RTC driver"); ++MODULE_AUTHOR( "Paul Mundt , " ++ "Jamie Lenehan , " ++ "Angelo Castello , " ++ "Roy Lee "); ++MODULE_LICENSE( "GPL"); ++MODULE_ALIAS( "platform:" DRV_NAME); +diff -Nur linux-3.4.110.orig/drivers/tty/serial/8250/8250.c linux-3.4.110/drivers/tty/serial/8250/8250.c +--- linux-3.4.110.orig/drivers/tty/serial/8250/8250.c 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/tty/serial/8250/8250.c 2016-04-07 10:20:51.054085357 +0200 +@@ -570,6 +570,7 @@ + serial_out(up, UART_ICR, value); + } + ++#ifndef CONFIG_NDS32 + static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) + { + unsigned int value; +@@ -581,6 +582,7 @@ + + return value; + } ++#endif + + /* + * FIFO support. +@@ -722,6 +724,7 @@ + return count; + } + ++#ifndef CONFIG_NDS32 + /* + * Read UART ID using the divisor method - set DLL and DLM to zero + * and the revision will be in DLL and device type in DLM. We +@@ -749,7 +752,9 @@ + + return id; + } ++#endif + ++#ifndef CONFIG_NDS32 + /* + * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. + * When this function is called we know it is at least a StarTech +@@ -842,6 +847,7 @@ + else + up->port.type = PORT_16650V2; + } ++#endif + + /* + * We detected a chip without a FIFO. Only two fall into +@@ -865,6 +871,7 @@ + up->port.type = PORT_16450; + } + ++#ifndef CONFIG_NDS32 + static int broken_efr(struct uart_8250_port *up) + { + /* +@@ -877,6 +884,7 @@ + + return 0; + } ++#endif + + static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) + { +@@ -908,7 +916,7 @@ + + up->port.type = PORT_16550A; + up->capabilities |= UART_CAP_FIFO; +- ++#ifndef CONFIG_NDS32 + /* + * Check for presence of the EFR when DLAB is set. + * Only ST16C650V1 UARTs pass this test. +@@ -937,6 +945,7 @@ + autoconfig_has_efr(up); + return; + } ++#endif + + /* + * Check for a National Semiconductor SuperIO chip. +@@ -1156,10 +1165,11 @@ + * We also initialise the EFR (if any) to zero for later. The + * EFR occupies the same register location as the FCR and IIR. + */ ++#ifndef CONFIG_NDS32 + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_EFR, 0); + serial_out(up, UART_LCR, 0); +- ++#endif + serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); + scratch = serial_in(up, UART_IIR) >> 6; + +diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb.h linux-3.4.110/drivers/video/FTLCDC100/faradayfb.h +--- linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/video/FTLCDC100/faradayfb.h 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1,215 @@ ++#ifndef __FARADAYFB_H ++#define __FARADAYFB_H ++ ++#define FARADAYFB_MODULE_NAME "faradayfb" ++#define DEBUG(enabled, tagged, ...) \ ++ do { \ ++ if (enabled) { \ ++ if (tagged) \ ++ printk("[ %30s() ] ", __func__); \ ++ printk(__VA_ARGS__); \ ++ } \ ++ } while (0) ++ ++#if defined(CONFIG_FFB_MODE_RGB) ++# define DEFAULT_COLOR FFB_MODE_RGB ++#elif defined(CONFIG_FFB_MODE_YUV422) ++# define DEFAULT_COLOR FFB_MODE_YUV422 ++#elif defined(CONFIG_FFB_MODE_YUV420) ++# define DEFAULT_COLOR FFB_MODE_YUV420 ++#endif ++ ++#if defined(CONFIG_FFB_MODE_8BPP) ++# define DEFAULT_BPP FFB_MODE_8BPP ++#elif defined(CONFIG_FFB_MODE_16BPP) ++# define DEFAULT_BPP FFB_MODE_16BPP ++#elif defined(CONFIG_FFB_MODE_24BPP) ++# define DEFAULT_BPP FFB_MODE_24BPP ++#endif ++ ++#define FFB_DEFAULT_MODE (DEFAULT_COLOR | DEFAULT_BPP) ++ ++struct lcd_param { ++ ++ unsigned long value; ++ unsigned long flags; ++}; ++ ++inline struct lcd_param* get_lcd_time(struct lcd_param* array, unsigned long num_array, unsigned long type) ++{ ++ int i; ++ ++ for (i = 0; i < num_array; i++) { ++ ++ struct lcd_param *r = &array[i]; ++ ++ if (r->flags & type & 0xff) ++ return r; ++ } ++ ++ return NULL; ++} ++ ++inline struct lcd_param* get_lcd_ctrl(struct lcd_param* array, unsigned long num_array, unsigned long type) ++{ ++ int i; ++ ++ for (i = 0; i < num_array; i++) { ++ ++ struct lcd_param *r = &array[i]; ++ ++ if ((r->flags & type & 0xff) && (r->flags & type & 0xff00)) ++ return r; ++ } ++ ++ return NULL; ++} ++ ++enum { RGB_8, RGB_16, RGB_24, NR_RGB}; ++ ++struct faradayfb_rgb { ++ ++ struct fb_bitfield red; ++ struct fb_bitfield green; ++ struct fb_bitfield blue; ++ struct fb_bitfield transp; ++}; ++ ++/* This structure describes the machine which we are running on. */ ++struct faradayfb_mach_info { ++ ++ unsigned long num_time0; ++ struct lcd_param * time0; ++ ++ unsigned long num_time1; ++ struct lcd_param * time1; ++ ++ unsigned long num_time2; ++ struct lcd_param * time2; ++ ++ unsigned long num_control; ++ struct lcd_param * control; ++ ++ unsigned long pixclock; ++ ++ unsigned long xres; ++ unsigned long yres; ++ ++ unsigned int max_bpp; ++ unsigned int sync; ++ ++ unsigned int cmap_greyscale:1, ++ cmap_inverse:1, ++ cmap_static:1, ++ unused:29; ++}; ++ ++struct faradayfb_info { ++ ++ struct fb_info *info; ++ struct faradayfb_rgb *rgb[NR_RGB]; ++ ++ unsigned int xres; ++ unsigned int yres; ++ unsigned int max_bpp; ++ ++ /* ++ * These are the addresses we mapped ++ * the framebuffer memory region to. ++ */ ++ dma_addr_t map_dma; ++ unsigned char * map_cpu; ++ unsigned int map_size; ++ ++ unsigned char * screen_cpu; ++ dma_addr_t screen_dma; ++ u32 * palette_cpu; ++ dma_addr_t palette_dma; ++ unsigned int palette_size; ++ ++ unsigned int cmap_inverse:1, ++ cmap_static:1, ++ unused:30; ++ ++ unsigned long time0; ++ unsigned long time1; ++ unsigned long time2; ++ unsigned long control; ++ unsigned long int_mask; ++ unsigned long io_base; ++ ++ unsigned int state; ++ unsigned int task_state; ++ struct semaphore ctrlr_sem; ++ wait_queue_head_t ctrlr_wait; ++ struct work_struct task; ++ ++ unsigned long smode; ++ unsigned long frame420_size; ++}; ++ ++/* ++ * These are the actions for set_ctrlr_state ++ */ ++#define C_DISABLE 0 ++#define C_ENABLE 1 ++#define C_DISABLE_CLKCHANGE 2 ++#define C_ENABLE_CLKCHANGE 3 ++#define C_REENABLE 4 ++#define C_DISABLE_PM 5 ++#define C_ENABLE_PM 6 ++#define C_STARTUP 7 ++ ++#define FARADAY_LCDTIME0_GET_HBP(x) ((((x) >> 24) & 0xFF) + 1) ++#define FARADAY_LCDTIME0_GET_HFP(x) ((((x) >> 16) & 0xFF) + 1) ++#define FARADAY_LCDTIME0_GET_HW(x) ((((x) >> 8) & 0xFF) + 1) ++#define FARADAY_LCDTIME1_GET_VBP(x) ((((x) >> 24) & 0xFF) ) ++#define FARADAY_LCDTIME1_GET_VFP(x) ((((x) >> 16) & 0xFF) ) ++#define FARADAY_LCDTIME1_GET_VW(x) ((((x) >> 8) & 0xFF) + 1) ++ ++#define FARADAY_LCDTIME0_HBP(x) ((((x) - 1) & 0xFF) << 24) ++#define FARADAY_LCDTIME0_HFP(x) ((((x) - 1) & 0xFF) << 16) ++#define FARADAY_LCDTIME0_HW(x) ((((x) - 1) & 0xFF) << 8) ++#define FARADAY_LCDTIME0_PL(x) (((((x) >> 4) - 1) & 0x3F) << 2) ++#define FARADAY_LCDTIME1_VBP(x) ((((x) ) & 0xFF) << 24) ++#define FARADAY_LCDTIME1_VFP(x) ((((x) ) & 0xFF) << 16) ++#define FARADAY_LCDTIME1_VW(x) ((((x) - 1) & 0xFF) << 8) ++#define FARADAY_LCDTIME1_LF(x) ((((x) - 1) & 0x3FF) ) ++ ++#define FFB_MODE_RGB 0x00000001 ++#define FFB_MODE_YUV420 0x00000002 ++#define FFB_MODE_YUV422 0x00000004 ++ ++#define FFB_MODE_8BPP 0x00000100 ++#define FFB_MODE_16BPP 0x00000200 ++#define FFB_MODE_24BPP 0x00000400 ++ ++/* Minimum X and Y resolutions */ ++#define MIN_XRES 64 ++#define MIN_YRES 64 ++ ++typedef struct LCDTag { ++ ++ u32 Timing0; /* 0x00 */ ++ u32 Timing1; /* 0x04 */ ++ u32 Timing2; /* 0x08 */ ++ u32 Timing3; /* 0x0C */ ++ u32 UPBase; /* 0x10 */ ++ u32 LPBase; /* 0x14 */ ++ u32 INTREnable; /* 0x18 */ ++ u32 Control; /* 0x1C */ ++ u32 Status; /* 0x20 */ ++ u32 Interrupt; /* 0x24 */ ++ u32 UPCurr; /* 0x28 */ ++ u32 LPCurr; /* 0x2C */ ++ u32 Reserved1[5]; /* 0x30~0x40 */ ++ u32 GPIO; /* 0x44 */ ++ u32 Reserved2[0x74 - 6]; /* 0x48~0x1FC */ ++ ++ u32 Palette[0x80]; /* 0x200~0x3FC */ ++ u32 TestReg[0x100]; /* 0x400~0x7FC */ ++ ++} LCD_Register; ++ ++#endif /* __FARADAYFB_H */ ++ +diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb-main.c linux-3.4.110/drivers/video/FTLCDC100/faradayfb-main.c +--- linux-3.4.110.orig/drivers/video/FTLCDC100/faradayfb-main.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/video/FTLCDC100/faradayfb-main.c 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1,911 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "faradayfb.h" ++#include "lcd-info.c" ++#include "pingpong-module.c" ++ ++static u32 faradayfb_pseudo_palette[32]; ++static inline void faradayfb_lcd_power(struct fb_info *info, int on) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ ++ if (on) ++ fbi->control |= (1UL << 11); ++ else ++ fbi->control &= ~(1UL << 11); ++ ++ plcd->Control = fbi->control; ++} ++ ++static void faradayfb_setup_gpio(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ ++ plcd->GPIO = 0x010000; ++} ++ ++static inline void faradayfb_pmu_on(void) ++{ ++ REG32(PMU_FTPMU010_VA_BASE + 0x44) |= 0x00700000; ++} ++ ++static inline void faradayfb_pmu_off(void) ++{ ++ REG32(PMU_FTPMU010_VA_BASE + 0x44) &= ~0x00700000; ++} ++ ++static void faradayfb_enable_controller(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ ++ plcd->Timing0 = fbi->time0; ++ plcd->Timing1 = fbi->time1; ++ plcd->Timing2 = fbi->time2; ++ plcd->Control = fbi->control & ~0x01; ++ ++ plcd->UPBase = fbi->screen_dma | fbi->frame420_size; ++ ++ faradayfb_pmu_on(); ++ plcd->Control |= 0x01; ++ ++ DEBUG(0, 1, "Time0 = 0x%08x\n", plcd->Timing0); ++ DEBUG(0, 1, "Time1 = 0x%08x\n", plcd->Timing1); ++ DEBUG(0, 1, "Time2 = 0x%08x\n", plcd->Timing2); ++ DEBUG(0, 1, "Control = 0x%08x\n", plcd->Control); ++ DEBUG(0, 1, "UPBase = 0x%08x\n", plcd->UPBase); ++} ++ ++static void faradayfb_disable_controller(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ DECLARE_WAITQUEUE(wait, current); ++ ++ set_current_state(TASK_UNINTERRUPTIBLE); ++ add_wait_queue(&fbi->ctrlr_wait, &wait); ++ ++ fbi->control &= ~0x0001; ++ plcd->Control = fbi->control; ++ faradayfb_pmu_off(); ++ ++ schedule_timeout(20 * HZ / 1000); ++ remove_wait_queue(&fbi->ctrlr_wait, &wait); ++} ++ ++static void faradayfb_enable_int(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ ++ plcd->INTREnable = fbi->int_mask; ++} ++ ++static void faradayfb_disable_int(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ ++ fbi->int_mask = plcd->INTREnable; ++ plcd->INTREnable = 0; ++ plcd->Status = 0x1e; ++} ++ ++static struct faradayfb_rgb def_rgb_8 = { ++ ++ .red = { .offset = 0, .length = 4 }, ++ .green = { .offset = 0, .length = 4 }, ++ .blue = { .offset = 0, .length = 4 }, ++ .transp = { .offset = 0, .length = 0 }, ++}; ++ ++static struct faradayfb_rgb def_rgb_16 = { ++ ++ .red = { .offset = 11, .length = 5, .msb_right = 0 }, ++ .green = { .offset = 5, .length = 6, .msb_right = 0 }, ++ .blue = { .offset = 0, .length = 5, .msb_right = 0 }, ++ .transp = { .offset = 15, .length = 0, .msb_right = 0 }, ++}; ++ ++static struct faradayfb_rgb def_rgb_24 = { ++ ++ .red = { .offset = 16, .length = 8, .msb_right = 0 }, ++ .green = { .offset = 8, .length = 8, .msb_right = 0 }, ++ .blue = { .offset = 0, .length = 8, .msb_right = 0 }, ++ .transp = { .offset = 0, .length = 0, .msb_right = 0 }, ++}; ++ ++static inline void faradayfb_schedule_work(struct fb_info *info, unsigned int state) ++{ ++ struct faradayfb_info *fbi = info->par; ++ unsigned long flags; ++ ++ local_irq_save(flags); ++ ++ /* ++ * We need to handle two requests being made at the same time. ++ * There are two important cases: ++ * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) ++ * We must perform the unblanking, which will do our REENABLE for us. ++ * 2. When we are blanking, but immediately unblank before we have ++ * blanked. We do the "REENABLE" thing here as well, just to be sure. ++ */ ++ if (fbi->task_state == C_ENABLE && state == C_REENABLE) ++ state = (unsigned int) - 1; ++ ++ if (fbi->task_state == C_DISABLE && state == C_ENABLE) ++ state = C_REENABLE; ++ ++ if (state != (unsigned int) - 1) { ++ ++ fbi->task_state = state; ++ schedule_work(&fbi->task); ++ } ++ ++ local_irq_restore(flags); ++} ++ ++static int faradayfb_setpalettereg(unsigned int regno, unsigned int red, ++ unsigned int green, unsigned int blue, unsigned int trans, ++ struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ ++ if (regno < fbi->palette_size) { ++ ++ fbi->palette_cpu[regno] = ((red >> 0) & (0x1fUL << 11)) | ++ ((green >> 5) & (0x3F << 5)) | ++ ((blue >> 11) & (0x1f << 0)); ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int faradayfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, ++ unsigned int blue, unsigned int trans, struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ int ret = 1; ++ /* ++ * If inverse mode was selected, invert all the colours ++ * rather than the register number. The register number ++ * is what you poke into the framebuffer to produce the ++ * colour you requested. ++ */ ++ if (fbi->cmap_inverse) { ++ ++ red = 0xffff - red; ++ green = 0xffff - green; ++ blue = 0xffff - blue; ++ } ++ ++ /* ++ * If greyscale is true, then we convert the RGB value ++ * to greyscale no mater what visual we are using. ++ */ ++ if (info->var.grayscale) ++ red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16; ++ ++ switch(info->fix.visual) { ++ ++ case FB_VISUAL_TRUECOLOR: ++ /* ++ * 12 or 16-bit True Colour. We encode the RGB value ++ * according to the RGB bitfield information. ++ */ ++ if (regno < 16) { ++ ++ u32 col; ++ red >>= (16 - info->var.red.length); ++ green >>= (16 - info->var.green.length); ++ blue >>= (16 - info->var.blue.length); ++ col = (red << info->var.red.offset) | ++ (green << info->var.green.offset) | ++ (blue << info->var.blue.offset) ; ++ ++ switch(info->var.bits_per_pixel) { ++ ++ /* is the following code correct?? */ ++ case 16: ++ case 32: ++ ((u32 *)(info->pseudo_palette))[regno] = col; ++ ret=0; ++ break; ++ } ++ } ++ break; ++ ++ case FB_VISUAL_STATIC_PSEUDOCOLOR: ++ case FB_VISUAL_PSEUDOCOLOR: ++ if (fbi->smode == FFB_MODE_RGB) ++ ret = faradayfb_setpalettereg(regno, red, green, blue, trans, info); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* ++ * Round up in the following order: bits_per_pixel, xres, ++ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, ++ * bitfields, horizontal timing, vertical timing. ++ */ ++static int faradayfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ int rgbidx; ++ ++ var->xres = min(var->xres, (unsigned int)MIN_XRES); ++ var->yres = min(var->yres, (unsigned int)MIN_YRES); ++ var->xres = max(var->xres, fbi->xres); ++ var->yres = max(var->yres, fbi->yres); ++ var->xres_virtual = max(var->xres_virtual, var->xres); ++ var->yres_virtual = max(var->yres_virtual, var->yres); ++ ++ DEBUG(0, 1, "var->bits_per_pixel = %d\n", var->bits_per_pixel); ++ ++ switch (var->bits_per_pixel) { ++ ++ case 1: case 2: case 4: case 8: ++ rgbidx = RGB_8; ++ break; ++ ++ case 16: ++ rgbidx = RGB_16; ++ break; ++ ++ case 32: ++ rgbidx = RGB_24; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ /* ++ * Copy the RGB parameters for this display ++ * from the machine specific parameters. ++ */ ++ var->red = fbi->rgb[ rgbidx]->red; ++ var->green = fbi->rgb[ rgbidx]->green; ++ var->blue = fbi->rgb[ rgbidx]->blue; ++ var->transp = fbi->rgb[ rgbidx]->transp; ++ ++ DEBUG(0, 1, "RGBT length = %d:%d:%d:%d\n", ++ var->red.length, var->green.length, var->blue.length, var->transp.length); ++ ++ DEBUG(0, 1, "RGBT offset = %d:%d:%d:%d\n", ++ var->red.offset, var->green.offset, var->blue.offset, var->transp.offset); ++ ++ DEBUG(0, 1, "Leave\n"); ++ ++ return 0; ++} ++ ++/* ++ * Configures LCD Controller based on entries in var parameter. Settings are ++ * only written to the controller if changes were made. ++ */ ++static int faradayfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ ++ DEBUG(0, 1, "var: xres=%d hslen=%d lm=%d rm=%d\n", var->xres, var->hsync_len, var->left_margin, var->right_margin); ++ DEBUG(0, 1, "var: yres=%d vslen=%d um=%d bm=%d\n", var->yres, var->vsync_len, var->upper_margin, var->lower_margin); ++ ++ fbi->time0 = FARADAY_LCDTIME0_HFP(var->left_margin) ++ | FARADAY_LCDTIME0_HBP(var->right_margin) ++ | FARADAY_LCDTIME0_HW(var->hsync_len) ++ | FARADAY_LCDTIME0_PL(var->xres); ++ ++ fbi->time1 = FARADAY_LCDTIME1_VBP(var->upper_margin) ++ | FARADAY_LCDTIME1_VFP(var->lower_margin) ++ | FARADAY_LCDTIME1_VW(var->vsync_len) ++ | FARADAY_LCDTIME1_LF(var->yres); ++ ++ if ((plcd->Timing0 != fbi->time0) ++ || (plcd->Timing1 != fbi->time1) ++ || (plcd->Timing2 != fbi->time2) ++ || (plcd->Control != fbi->control)) { ++ ++ faradayfb_schedule_work(info, C_REENABLE); ++ } ++ ++ return 0; ++} ++ ++/* Set the user defined part of the display for the specified console */ ++static int faradayfb_set_par(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ struct fb_var_screeninfo *var = &info->var; ++ unsigned long palette_mem_size; ++ ++ if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32) ++ info->fix.visual = FB_VISUAL_TRUECOLOR; ++ else if (!fbi->cmap_static) ++ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; ++ else { ++ /* ++ * Some people have weird ideas about wanting static ++ * pseudocolor maps. I suspect their user space ++ * applications are broken. ++ */ ++ info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; ++ } ++ ++ info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; ++ ++ fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; ++ ++ palette_mem_size = fbi->palette_size * sizeof(u32); ++ ++ DEBUG(0, 1, "info->fix.line_length = %d\n", info->fix.line_length); ++ DEBUG(0, 1, "palette_mem_size = 0x%08lx\n", (unsigned long) palette_mem_size); ++ ++ fbi->palette_cpu = (u32 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); ++ ++ fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; ++ ++ /* Set (any) board control register to handle new color depth */ ++ faradayfb_activate_var(var, info); ++ ++ DEBUG(0, 1, "Leave\n"); ++ ++ return 0; ++} ++ ++static irqreturn_t faradayfb_handle_irq(int irq, void *dev_id) ++{ ++#if 0 ++ struct fb_info *info = (struct fb_info*)dev_id; ++ struct faradayfb_info *fbi = info->par; ++ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; ++ u32 status = plcd->Interrupt; ++#endif ++ return IRQ_HANDLED; ++} ++ ++/* ++ * This function must be called from task context only, since it will ++ * sleep when disabling the LCD controller, or if we get two contending ++ * processes trying to alter state. ++ */ ++static void set_ctrlr_state(struct fb_info *info, unsigned int state) ++{ ++ struct faradayfb_info *fbi = info->par; ++ unsigned int old_state; ++ ++ down(&fbi->ctrlr_sem); ++ ++ old_state = fbi->state; ++ ++ /* Hack around fbcon initialisation. */ ++ if (old_state == C_STARTUP && state == C_REENABLE) ++ state = C_ENABLE; ++ ++ switch (state) { ++ case C_DISABLE_PM: ++ case C_DISABLE: ++ ++ /* Disable controller */ ++ if (old_state != C_DISABLE) { ++ ++ fbi->state = state; ++ faradayfb_disable_int(info); ++ faradayfb_lcd_power(info, 0); ++ // faradayfb_disable_controller(info); ++ } ++ break; ++ ++ case C_REENABLE: ++ /* ++ * Re-enable the controller only if it was already ++ * enabled. This is so we reprogram the control ++ * registers. ++ */ ++ if (old_state == C_ENABLE) { ++ ++ faradayfb_disable_int(info); ++ faradayfb_lcd_power(info, 0); ++ faradayfb_disable_controller(info); ++ ++ faradayfb_setup_gpio(info); ++ faradayfb_lcd_power(info, 1); ++ faradayfb_enable_controller(info); ++ faradayfb_enable_int(info); ++ } ++ break; ++ ++ case C_ENABLE_PM: ++ /* ++ * Re-enable the controller after PM. This is not ++ * perfect - think about the case where we were doing ++ * a clock change, and we suspended half-way through. ++ */ ++ if (old_state != C_DISABLE_PM) ++ break; ++ /* fall through */ ++ ++ case C_ENABLE: ++ /* ++ * Power up the LCD screen, enable controller, and ++ * turn on the backlight. ++ */ ++ if (old_state != C_ENABLE) { ++ ++ fbi->state = C_ENABLE; ++ faradayfb_setup_gpio(info); ++ faradayfb_lcd_power(info, 1); ++ faradayfb_enable_controller(info); ++ faradayfb_enable_int(info); ++ } ++ break; ++ } ++ up(&fbi->ctrlr_sem); ++} ++ ++/* ++ * Blank the display by setting all palette values to zero. Note, the ++ * 12 and 16 bpp modes don't really use the palette, so this will not ++ * blank the display in all modes. ++ */ ++static int faradayfb_blank(int blank, struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ int i; ++ ++ switch (blank) { ++ case FB_BLANK_POWERDOWN: ++ case FB_BLANK_VSYNC_SUSPEND: ++ case FB_BLANK_HSYNC_SUSPEND: ++ case FB_BLANK_NORMAL: ++ ++ if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR || ++ info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { ++ ++ for (i = 0; i < fbi->palette_size; i++) ++ faradayfb_setpalettereg(i, 0, 0, 0, 0, info); ++ } ++ ++ faradayfb_schedule_work(info, C_DISABLE); ++ ++ break; ++ ++ case FB_BLANK_UNBLANK: ++ ++ if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR || ++ info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) ++ fb_set_cmap(&info->cmap, info); ++ ++ faradayfb_schedule_work(info, C_ENABLE); ++ ++ break; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Our LCD controller task (which is called when we blank or unblank) ++ * via keventd. ++ */ ++static void faradayfb_task(struct work_struct *dummy) ++{ ++ struct faradayfb_info *fbi = container_of(dummy, struct faradayfb_info, task); ++ struct fb_info *info = fbi->info; ++ unsigned int state; ++ ++ state = xchg(&fbi->task_state, -1); ++ set_ctrlr_state(info, state); ++} ++ ++/* Fake monspecs to fill in fbinfo structure */ ++static struct fb_monspecs monspecs = { ++ ++ .hfmin = 30000, ++ .hfmax = 70000, ++ .vfmin = 50, ++ .vfmax = 65, ++}; ++ ++static int ffb_get_mach_param(struct faradayfb_mach_info *inf, struct fb_info *info, unsigned long smode) ++{ ++ struct faradayfb_info *fbi = info->par; ++ struct lcd_param *tparam; ++ unsigned long bpp_mode; ++ ++ if (!(tparam = get_lcd_time(inf->time0, inf->num_time0, smode))) ++ return -1; ++ ++ fbi->time0 = tparam->value; ++ ++ if (!(tparam = get_lcd_time(inf->time1, inf->num_time1, smode))) ++ return -1; ++ ++ fbi->time1 = tparam->value; ++ ++ if (!(tparam = get_lcd_time(inf->time2, inf->num_time2, smode))) ++ return -1; ++ ++ fbi->time2 = tparam->value; ++ ++ switch(info->var.bits_per_pixel) { ++ ++ case 1: case 2: case 4: case 8: ++ bpp_mode = FFB_MODE_8BPP; ++ break; ++ ++ case 16: ++ bpp_mode = FFB_MODE_16BPP; ++ break; ++ ++ case 32: ++ bpp_mode = FFB_MODE_24BPP; ++ break; ++ ++ default: ++ DEBUG(1, 1, "Unsupported BPP, set default BPP to 16\n"); ++ bpp_mode = FFB_MODE_16BPP; ++ break; ++ } ++ ++ if (!(tparam = get_lcd_ctrl(inf->control, inf->num_control, smode | bpp_mode))) ++ return -1; ++ ++ fbi->control = tparam->value; ++ ++ fbi->xres = inf->xres; ++ fbi->yres = inf->yres; ++ ++ return 0; ++} ++ ++static int faradayfb_set_var(struct fb_info *info, struct faradayfb_mach_info *inf, unsigned long type) ++{ ++ struct faradayfb_info *fbi = info->par; ++ unsigned long t_smode = 0; ++ ++ if (!type) ++ t_smode = fbi->smode; ++ else ++ t_smode = type; ++ ++ if (ffb_get_mach_param(inf, info, t_smode)) { ++ ++ DEBUG(1, 1, "Not support mode(%lx)\n", t_smode); ++ return -1; ++ } ++ ++ info->var.xres = fbi->xres; ++ info->var.xres_virtual = fbi->xres; ++ info->var.yres = fbi->yres; ++ info->var.yres_virtual = fbi->yres; ++ ++ info->var.upper_margin = FARADAY_LCDTIME1_GET_VBP(fbi->time1); ++ info->var.lower_margin = FARADAY_LCDTIME1_GET_VFP(fbi->time1); ++ info->var.vsync_len = FARADAY_LCDTIME1_GET_VW(fbi->time1); ++ info->var.left_margin = FARADAY_LCDTIME0_GET_HFP(fbi->time0); ++ info->var.right_margin = FARADAY_LCDTIME0_GET_HBP(fbi->time0); ++ info->var.hsync_len = FARADAY_LCDTIME0_GET_HW(fbi->time0); ++ ++ fbi->int_mask = 0; ++ ++ if (t_smode & FFB_MODE_YUV420) ++ fbi->frame420_size = (((info->var.xres * info->var.yres + 0xffff) & 0xffff0000) >> 16) << 2; ++ else ++ fbi->frame420_size = 0; ++ ++ return 0; ++} ++ ++static struct fb_ops faradayfb_ops = { ++ ++ .owner = THIS_MODULE, ++ .fb_check_var = faradayfb_check_var, ++ .fb_set_par = faradayfb_set_par, ++ .fb_setcolreg = faradayfb_setcolreg, ++ .fb_fillrect = cfb_fillrect, ++ .fb_copyarea = cfb_copyarea, ++ .fb_imageblit = cfb_imageblit, ++ .fb_blank = faradayfb_blank, ++ .fb_mmap = faradayfb_mmap, ++ .fb_ioctl = faradayfb_ioctl, ++}; ++ ++static struct fb_info * __init faradayfb_init_fbinfo(struct device *dev) ++{ ++ struct faradayfb_mach_info *inf; ++ struct fb_info *info; ++ struct faradayfb_info *fbi; ++ ++ if (!(info = framebuffer_alloc(sizeof(struct faradayfb_info), dev))) ++ return NULL; ++ ++ fbi = info->par; ++ fbi->info = info; ++ ++ fbi->io_base = LCD_FTLCDC100_0_VA_BASE; ++ strcpy(info->fix.id, FARADAYFB_MODULE_NAME); ++ ++ info->fix.type = FB_TYPE_PACKED_PIXELS; ++ info->fix.type_aux = 0; ++ info->fix.xpanstep = 0; ++ info->fix.ypanstep = 0; ++ info->fix.ywrapstep = 0; ++ info->fix.accel = FB_ACCEL_NONE; ++ ++ info->var.nonstd = 0; ++ info->var.activate = FB_ACTIVATE_NOW; ++ info->var.height = -1; ++ info->var.width = -1; ++ info->var.accel_flags = 0; ++ info->var.vmode = FB_VMODE_NONINTERLACED; ++ ++ info->fbops = &faradayfb_ops; ++ info->flags = FBINFO_DEFAULT; ++ info->monspecs = monspecs; ++ info->pseudo_palette = &faradayfb_pseudo_palette; ++ ++ fbi->rgb[RGB_8] = &def_rgb_8; ++ fbi->rgb[RGB_16] = &def_rgb_16; ++ fbi->rgb[RGB_24] = &def_rgb_24; ++ ++ inf = (struct faradayfb_mach_info*)dev->platform_data; ++ ++ /* ++ * People just don't seem to get this. We don't support ++ * anything but correct entries now, so panic if someone ++ * does something stupid. ++ */ ++ ++ fbi->xres = inf->xres; ++ fbi->yres = inf->yres; ++ fbi->max_bpp = 32; ++#if defined(CONFIG_FFB_MODE_8BPP) ++ info->var.bits_per_pixel = min((u32)8, inf->max_bpp); ++#elif defined(CONFIG_FFB_MODE_16BPP) ++ info->var.bits_per_pixel = min((u32)16, inf->max_bpp); ++#elif defined(CONFIG_FFB_MODE_24BPP) ++ info->var.bits_per_pixel = min((u32)32, inf->max_bpp); ++ info->var.bits_per_pixel = 32; ++#endif ++ ++ info->var.pixclock = inf->pixclock; ++ info->var.sync = inf->sync; ++ info->var.grayscale = inf->cmap_greyscale; ++ fbi->cmap_inverse = inf->cmap_inverse; ++ fbi->cmap_static = inf->cmap_static; ++ ++ fbi->smode = FFB_DEFAULT_MODE; ++ ++ if (faradayfb_set_var(info, inf, 0)) ++ goto err; ++ ++ fbi->state = C_STARTUP; ++ fbi->task_state = (unsigned char) - 1; ++ info->fix.smem_len = faradayfb_cal_frame_buf_size(fbi); ++ ++ init_waitqueue_head(&fbi->ctrlr_wait); ++ INIT_WORK(&fbi->task, faradayfb_task); ++ init_MUTEX(&fbi->ctrlr_sem); ++ ++ return info; ++err: ++ kfree(fbi); ++ kfree(info); ++ ++ return NULL; ++} ++ ++static int faradayfb_probe(struct platform_device *pdev) ++{ ++ struct fb_info *info; ++ struct faradayfb_info *fbi; ++ int irq; ++ int ret = 0; ++ ++ ret = -ENOMEM; ++ ++ if (!(info = faradayfb_init_fbinfo(&pdev->dev))) { ++ ++ DEBUG(1, 1, "unable to allocate memory for device info\n"); ++ goto err_exit; ++ } ++ ++ fbi = info->par; ++ ++ /* Initialize video memory */ ++ if ((ret = faradayfb_map_video_memory(info)) < 0) ++ goto err_free_mem; ++ ++ ret = -EINVAL; ++ ++ if ((irq = platform_get_irq(pdev, 0)) <= 0) ++ goto err_free_map; ++ ++ if (request_irq(irq, faradayfb_handle_irq, IRQF_DISABLED, "LCD", info)) { ++ ++ DEBUG(1, 1, "request_irq failed: %d\n", ret); ++ goto err_free_map; ++ } ++ ++ /* ++ * This makes sure that our colour bitfield ++ * descriptors are correctly initialised. ++ */ ++ faradayfb_check_var(&info->var, info); ++ faradayfb_set_par(info); ++ ++ dev_set_drvdata(&pdev->dev, info); ++ ++// <============================================ ++ if ((ret = register_framebuffer(info)) < 0) { ++ ++ DEBUG(1, 1, "register_framebuffer failed\n"); ++ goto err_free_irq; ++ } ++// <============================================ ++ ++ faradayfb_clean_screen(info); ++ ++ return 0; ++ ++err_free_irq: ++ dev_set_drvdata(&pdev->dev, NULL); ++ free_irq(irq, info); ++err_free_map: ++ faradayfb_unmap_video_memory(info); ++err_free_mem: ++ kfree(info->par); ++ kfree(info); ++err_exit: ++ return ret; ++} ++ ++/* Called when the device is being detached from the driver */ ++static int faradayfb_remove(struct platform_device *pdev) ++{ ++ struct fb_info *info = platform_get_drvdata(pdev); ++ int irq; ++ ++ set_ctrlr_state(info, C_DISABLE); ++ ++ irq = platform_get_irq(pdev, 0); ++ free_irq(irq, info); ++ ++ unregister_framebuffer(info); ++ faradayfb_unmap_video_memory(info); ++ dev_set_drvdata(&pdev->dev, NULL); ++ kfree(info->par); ++ kfree(info); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++/* suspend and resume support for the lcd controller */ ++static int faradayfb_suspend(struct platform_device *pdev, pm_message_t mesg) ++{ ++ struct fb_info *info = platform_get_drvdata(pdev); ++ ++ // if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) ++ if (mesg.event == PM_EVENT_PRETHAW || mesg.event & PM_EVENT_SLEEP) ++ set_ctrlr_state(info, C_DISABLE_PM); ++ ++ return 0; ++} ++ ++static int faradayfb_resume(struct platform_device *pdev) ++{ ++ struct fb_info *info = platform_get_drvdata(pdev); ++ ++ // need modify ++ // if (level == RESUME_ENABLE) ++ set_ctrlr_state(info, C_ENABLE_PM); ++ ++ return 0; ++} ++ ++#else ++#define faradayfb_suspend NULL ++#define faradayfb_resume NULL ++#endif ++ ++static struct resource faradayfb_resource[] = { ++ ++ { ++ .start = LCD_FTLCDC100_0_PA_BASE, ++ .end = LCD_FTLCDC100_0_PA_LIMIT, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = LCD_FTLCDC100_0_IRQ, ++ .end = LCD_FTLCDC100_0_IRQ, ++ .flags = IORESOURCE_IRQ, ++ } ++}; ++ ++static u64 faradayfb_dmamask = ~(u32)0; ++ ++static struct platform_device faradayfb_device = { ++ ++ .name = "faraday-lcd", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(faradayfb_resource), ++ .resource = faradayfb_resource, ++ .dev = { ++ ++ .platform_data = &ffb_mach_info, ++ .dma_mask = &faradayfb_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ } ++}; ++ ++static struct platform_driver faradayfb_driver = { ++ .probe = faradayfb_probe, ++ .remove = faradayfb_remove, ++ .suspend = faradayfb_suspend, ++ .resume = faradayfb_resume, ++ .driver = { ++ .name = "faraday-lcd", ++ }, ++}; ++ ++/* ++rick note faraday driver ++*/ ++ ++/* Register both the driver and the device */ ++int __init faradayfb_init(void) ++{ ++ int ret = 0; ++ /* Register the device with LDM */ ++ ++#if 1 ++ if (platform_device_register(&faradayfb_device)) { ++ ++ DEBUG(1, 1, "failed to register faradayfb device\n"); ++ ret = -ENODEV; ++ goto exit; ++ } ++#endif ++ /* Register the driver with LDM */ ++ if (platform_driver_register(&faradayfb_driver)) { ++ ++ DEBUG(1, 1, "failed to register faradayfb driver\n"); ++ platform_device_unregister(&faradayfb_device); ++ ret = -ENODEV; ++ goto exit; ++ } ++exit: ++ return ret; ++} ++ ++static void __exit faradayfb_cleanup(void) ++{ ++ platform_driver_unregister(&faradayfb_driver); ++ platform_device_unregister(&faradayfb_device); ++} ++ ++module_init(faradayfb_init); ++module_exit(faradayfb_cleanup); ++MODULE_DESCRIPTION("Faraday LCD driver"); ++MODULE_AUTHOR("Francis Huang "); ++MODULE_LICENSE("GPL"); +diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/Kconfig linux-3.4.110/drivers/video/FTLCDC100/Kconfig +--- linux-3.4.110.orig/drivers/video/FTLCDC100/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/video/FTLCDC100/Kconfig 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1,74 @@ ++config FB_FTLCDC100 ++ tristate "Faraday FTLCDC100 driver" ++ depends on FB && NDS32 ++ select FB_CFB_FILLRECT ++ select FB_CFB_COPYAREA ++ select FB_CFB_IMAGEBLIT ++ ++ choice ++ prompt "Default LCD Panel" ++ depends on FB_FTLCDC100 ++ default PANEL_AUA036QN01 ++ help ++ This option select a default panel setting for the LCD controller ++ ++ config PANEL_AUA036QN01 ++ bool "AU 3.5 inch LCD Panel" ++ ++ config PANEL_CH7013A ++ bool "Chrontel Digital PC to TV Encoder" ++ select I2C ++ select I2C_FARADAY ++ select CH7013A ++ ++ config PANEL_AUA070VW04 ++ bool "AU 7.0 inch LCD Panel" ++ ++ config PANEL_LW500AC9601 ++ bool "CHIMEI 5.0 inch LCD panel" ++ ++ endchoice ++ ++ # config FTLCD_OSD ++ # bool "Enable OSD (On Screen Display)" ++ # depends on FB_FTLCDC100 ++ # default n ++ # ---help--- ++ # This enables access to the OSD (On Screen Display) for Faraday ++ # FTLCDC100 LCD control. Disabling OSD will reduce the size of ++ # the kernel by approximately 6kb. ++ # ++ ++ choice ++ prompt "Default Color Mode" ++ depends on FB_FTLCDC100 ++ default FFB_MODE_RGB ++ help ++ This option select default color mode ++ ++ config FFB_MODE_RGB ++ bool "RGB Mode" ++ config FFB_MODE_YUV422 ++ bool "YUV422 Mode" ++ config FFB_MODE_YUV420 ++ bool "YUV420 Mode" ++ endchoice ++ ++ choice ++ prompt "Default BPP" ++ depends on FB_FTLCDC100 ++ default FFB_MODE_16BPP ++ help ++ This option select default BPP (bits-per-pixel) ++ ++ config FFB_MODE_8BPP ++ depends on FFB_MODE_RGB || FFB_MODE_YUV420 ++ bool "8 bits-per-pixel" ++ config FFB_MODE_16BPP ++ depends on FFB_MODE_RGB || FFB_MODE_YUV422 ++ bool "16 bits-per-pixel" ++ config FFB_MODE_24BPP ++ depends on FFB_MODE_RGB ++ bool "24 bits-per-pixel" ++ endchoice ++ +diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/lcd-info.c linux-3.4.110/drivers/video/FTLCDC100/lcd-info.c +--- linux-3.4.110.orig/drivers/video/FTLCDC100/lcd-info.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/video/FTLCDC100/lcd-info.c 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1,264 @@ ++/* ++ * HBP : Horizontal Back Porch ++ * HFP : Horizontal Front Porch ++ * HSPW: Horizontal Sync. Pulse Width ++ * PPL : Pixels-per-line = 16(PPL+1) ++ */ ++#define ENC_PARAM_TIME0(HBP, HFP, HSPW, PPL) \ ++ ((((HBP) - 1) << 24) | \ ++ (((HFP) - 1) << 16) | \ ++ (((HSPW) - 1) << 8 ) | \ ++ ((((PPL) >> 4) - 1) << 2 )) ++ ++/* ++ * HBP : Vertical Back Porch ++ * HFP : Vertical Front Porch ++ * HSPW: Vertical Sync. Pulse Width ++ * LPP : Lines-per-panel = LPP + 1 ++ */ ++#define ENC_PARAM_TIME1(VBP, VFP, VSPW, LPP) \ ++ ((((VBP) ) << 24) | \ ++ (((VFP) ) << 16) | \ ++ (((VSPW) - 1) << 10) | \ ++ (((LPP) - 1) )) ++ ++/* ++ * PRA : Pixel Rate Adaptive ++ * IOE : Invert Panel Output Enable ++ * IPC : Invert Panel Clock (Test Chip Testing) ++ * IHS : Invert Horisontal Sync. ++ * IVS : Invert Versical Sync. ++ * PCD : Panel Clock Divisor ++ */ ++#define ENC_PARAM_TIME2(PRA, IOE, IPC, IHS, IVS, PCD) \ ++ (((PRA) << 15) | \ ++ ((IOE) << 14) | \ ++ ((IPC) << 13) | \ ++ ((IHS) << 12) | \ ++ ((IVS) << 11) | \ ++ (((PCD) - 1) )) ++ ++/* ++ * Enable YCbCr ++ * Enable YCbCr420 ++ * FIFO threadhold ++ * Panel type, 0-6bit, 1-8bit ++ * LcdVComp, when to generate interrupt, 1: start of back_porch ++ * Power Enable ++ * Big Endian Pixel/Byte Ordering ++ * BGR ++ * TFT ++ * LCD bits per pixel ++ * Controller Enable ++ */ ++ ++#define ENC_PARAM_CTRL(ENYUV, ENYUV420, FIFOTH, PTYPE, VCOMP, LCD_ON, ENDIAN, BGR, TFT, BPP, LCD_EN) \ ++ ((ENYUV << 18) | \ ++ (ENYUV420 << 17) | \ ++ (FIFOTH << 16) | \ ++ (PTYPE << 15) | \ ++ (VCOMP << 12) | \ ++ (LCD_ON << 11) | \ ++ (ENDIAN << 9) | \ ++ (BGR << 8) | \ ++ (TFT << 5) | \ ++ (BPP << 1) | \ ++ (LCD_EN)) ++ ++static struct lcd_param control[] = { ++ ++ { ++ .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x3, 1), ++ .flags = FFB_MODE_RGB | FFB_MODE_8BPP, ++ }, ++ { ++ .value = ENC_PARAM_CTRL(1, 1, 1, 1, 0x3, 1, 0x0, 0, 1, 0x3, 1), ++ .flags = FFB_MODE_YUV420 | FFB_MODE_8BPP, ++ }, ++ { ++ .value = ENC_PARAM_CTRL(1, 0, 1, 1, 0x3, 1, 0x0, 0, 1, 0x4, 1), ++ .flags = FFB_MODE_YUV422 | FFB_MODE_16BPP, ++ }, ++ { ++ .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x4, 1), ++ .flags = FFB_MODE_RGB | FFB_MODE_16BPP, ++ }, ++ { ++ .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x5, 1), ++ .flags = FFB_MODE_RGB | FFB_MODE_24BPP, ++ }, ++}; ++ ++#ifdef CONFIG_PANEL_AUA036QN01 ++ ++static struct lcd_param time0[] = { ++ ++ { ++ .value = ENC_PARAM_TIME0(7, 6, 1, 320), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct lcd_param time1[] = { ++ ++ { ++ .value = ENC_PARAM_TIME1(1, 1, 1, 240), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct lcd_param time2[] = { ++ ++ { ++ .value = ENC_PARAM_TIME2(0, 0, 1, 1, 1, 0x7), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct faradayfb_mach_info ffb_mach_info = { ++ ++ .pixclock = 171521, ++ .xres = 320, ++ .yres = 240, ++ .max_bpp = 24, ++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .num_time0 = ARRAY_SIZE(time0), ++ .time0 = time0, ++ .num_time1 = ARRAY_SIZE(time1), ++ .time1 = time1, ++ .num_time2 = ARRAY_SIZE(time2), ++ .time2 = time2, ++ .num_control = ARRAY_SIZE(control), ++ .control = control, ++}; ++#endif ++ ++#ifdef CONFIG_PANEL_AUA070VW04 ++static struct lcd_param time0[] = { ++ ++ { ++ .value = ENC_PARAM_TIME0(88, 40, 128, 800), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct lcd_param time1[] = { ++ ++ { ++ .value = ENC_PARAM_TIME1(21, 1, 3, 480), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct lcd_param time2[] = { ++ ++ { ++ .value = ENC_PARAM_TIME2(0, 1, 1, 1, 1, 0x5), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct faradayfb_mach_info ffb_mach_info = { ++ ++ .pixclock = 171521, ++ .xres = 800, ++ .yres = 480, ++ .max_bpp = 24, ++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .num_time0 = ARRAY_SIZE(time0), ++ .time0 = time0, ++ .num_time1 = ARRAY_SIZE(time1), ++ .time1 = time1, ++ .num_time2 = ARRAY_SIZE(time2), ++ .time2 = time2, ++ .num_control = ARRAY_SIZE(control), ++ .control = control, ++}; ++ ++#endif ++ ++#ifdef CONFIG_PANEL_LW500AC9601 ++static struct lcd_param time0[] = { ++ ++ { ++ .value = ENC_PARAM_TIME0(88, 40, 128, 800), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct lcd_param time1[] = { ++ ++ { ++ .value = ENC_PARAM_TIME1(21, 1, 3, 480), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct lcd_param time2[] = { ++ ++ { ++ .value = ENC_PARAM_TIME2( 0, 0, 1, 1, 1, 0x3), ++ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, ++ }, ++}; ++ ++static struct faradayfb_mach_info ffb_mach_info = { ++ ++ .pixclock = 171521, ++ .xres = 800, ++ .yres = 480, ++ .max_bpp = 24, ++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .num_time0 = ARRAY_SIZE(time0), ++ .time0 = time0, ++ .num_time1 = ARRAY_SIZE(time1), ++ .time1 = time1, ++ .num_time2 = ARRAY_SIZE(time2), ++ .time2 = time2, ++ .num_control = ARRAY_SIZE(control), ++ .control = control, ++}; ++#endif ++ ++#ifdef CONFIG_CH7013A ++static struct lcd_param time0[] = { ++ ++ { ++ .value = ENC_PARAM_TIME0(42, 10, 96, 640), ++ .flags = FFB_MODE_RGB, ++ }, ++}; ++ ++static struct lcd_param time1[] = { ++ ++ { ++ .value = ENC_PARAM_TIME1(28, 5, 2, 480), ++ .flags = FFB_MODE_RGB, ++ }, ++}; ++static struct lcd_param time2[] = { ++ ++ { ++ .value = ENC_PARAM_TIME2(0, 1, 1, 0, 0, 0x3), ++ .flags = FFB_MODE_RGB, ++ }, ++}; ++ ++static struct faradayfb_mach_info ffb_mach_info = { ++ ++ .pixclock = 37910, ++ .xres = 640, ++ .yres = 480, ++ .max_bpp = 24, ++ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .num_time0 = ARRAY_SIZE(time0), ++ .time0 = time0, ++ .num_time1 = ARRAY_SIZE(time1), ++ .time1 = time1, ++ .num_time2 = ARRAY_SIZE(time2), ++ .time2 = time2, ++ .num_control = ARRAY_SIZE(control), ++ .control = control, ++}; ++ ++#endif /* CONFIG_CH7013A */ +diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/Makefile linux-3.4.110/drivers/video/FTLCDC100/Makefile +--- linux-3.4.110.orig/drivers/video/FTLCDC100/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/video/FTLCDC100/Makefile 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1 @@ ++obj-$(CONFIG_FB_FTLCDC100) += faradayfb-main.o +diff -Nur linux-3.4.110.orig/drivers/video/FTLCDC100/pingpong-module.c linux-3.4.110/drivers/video/FTLCDC100/pingpong-module.c +--- linux-3.4.110.orig/drivers/video/FTLCDC100/pingpong-module.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/video/FTLCDC100/pingpong-module.c 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1,592 @@ ++void *fmem_alloc(size_t size, dma_addr_t *dma_handle, unsigned long flags) ++{ ++ struct page *page; ++ void *cpu_addr = NULL; ++ ++ size = PAGE_ALIGN(size); ++ ++ if (!(page = alloc_pages(GFP_DMA, get_order(size)))) { ++ ++ DEBUG(1, 1, "alloc_pages fail! (requested %#x)", size); ++ goto no_page; ++ } ++ ++ *dma_handle = page_to_phys(page); ++ ++ if ((cpu_addr = __ioremap(*dma_handle, size, flags, 1))) { ++ ++ do { ++ SetPageReserved(page); ++ page++; ++ } while (size -= PAGE_SIZE); ++ } ++ else { ++ __free_pages(page, get_order(size)); ++ DEBUG(1, 1, "__ioremap fail! (phy %#x)", *dma_handle); ++ } ++no_page: ++ return cpu_addr; ++} ++ ++void fmem_free(size_t size, void *cpu_addr, dma_addr_t handle) ++{ ++ struct page *page = pfn_to_page(handle >> PAGE_SHIFT); ++ ++ __iounmap(cpu_addr); ++ size = PAGE_ALIGN(size); ++ ++ do { ++ ClearPageReserved(page); ++ __free_page(page); ++ page++; ++ ++ } while (size -= PAGE_SIZE); ++} ++ ++static int faradayfb_mmap(struct fb_info *info, struct vm_area_struct *vma) ++{ ++ struct faradayfb_info *fbi = info->par; ++ unsigned long off = vma->vm_pgoff << PAGE_SHIFT; ++ int ret = -EINVAL; ++ ++ DEBUG(0, 1, "Enter\n"); ++ ++ if (off < info->fix.smem_len) { ++ ++ off += fbi->screen_dma & PAGE_MASK; ++ vma->vm_pgoff = off >> PAGE_SHIFT; ++ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); ++ vma->vm_flags |= VM_RESERVED; ++ ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, ++ vma->vm_end - vma->vm_start, vma->vm_page_prot); ++ } ++ else { ++ DEBUG(1, 1, "buffer mapping error !!\n"); ++ } ++ ++ DEBUG(0, 1, "Leave\n"); ++ ++ return ret; ++} ++ ++/* ++ * Allocates the DRAM memory for the frame buffer. This buffer is ++ * remapped into a non-cached, non-buffered, memory region to ++ * allow palette and pixel writes to occur without flushing the ++ * cache. Once this area is remapped, all virtual memory ++ * access to the video memory should occur at the new region. ++ */ ++static int __init faradayfb_map_video_memory(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ ++ /* ++ * We reserve one page for the palette, plus the size ++ * of the framebuffer. ++ */ ++ fbi->map_size = PAGE_ALIGN(info->fix.smem_len + PAGE_SIZE); ++ ++ fbi->map_cpu = fmem_alloc(fbi->map_size, &fbi->map_dma, pgprot_writecombine(PAGE_KERNEL)); ++ // fbi->map_cpu = dma_alloc_writecombine(fbi->info->dev, fbi->map_size, &fbi->map_dma, GFP_KERNEL); ++ ++ if (fbi->map_cpu) { ++ ++ memset(fbi->map_cpu, 0x1d, fbi->map_size); ++ info->screen_base = fbi->map_cpu + PAGE_SIZE; ++ fbi->screen_dma = fbi->map_dma + PAGE_SIZE; ++ info->fix.smem_start = fbi->screen_dma; ++ } ++ ++ return fbi->map_cpu ? 0 : -ENOMEM; ++} ++ ++static inline void faradayfb_clean_screen(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ int size = info->var.xres * info->var.yres; ++ ++ if (fbi->smode & FFB_MODE_YUV422) { ++ ++ memset(fbi->map_cpu, 16, size * info->var.bits_per_pixel / 8); ++ } ++ else if (fbi->smode & FFB_MODE_YUV420) { ++ ++ memset(fbi->map_cpu, 16, size); ++ memset(fbi->map_cpu + PAGE_SIZE + ((size + 0xffff) & 0xffff0000), 128, size / 4); ++ memset(fbi->map_cpu + PAGE_SIZE + ((size + 0xffff) & 0xffff0000) * 5 / 4, 128, size / 4); ++ } ++} ++ ++static inline void faradayfb_unmap_video_memory(struct fb_info *info) ++{ ++ struct faradayfb_info *fbi = info->par; ++ fmem_free(fbi->map_size, fbi->map_cpu, fbi->map_dma); ++} ++ ++#define FRAME_SIZE_RGB(xres, yres, mbpp) ((xres) * (yres) * (mbpp) / 8) ++#define FRAME_SIZE_YUV422(xres, yres, mbpp) (((xres) * (yres) * (mbpp) / 8) * 2) ++#define FRAME_SIZE_YUV420(xres, yres, mbpp) (((((xres) * (yres) * (mbpp) / 8) + 0xffff) & 0xffff0000) * 3 / 2) ++ ++static inline u32 faradayfb_cal_frame_buf_size(struct faradayfb_info *fbi) ++{ ++ u32 size_rgb = FRAME_SIZE_RGB(fbi->xres, fbi->yres, fbi->max_bpp); ++ u32 size_yuv422 = FRAME_SIZE_YUV422(fbi->xres, fbi->yres, 8); ++ u32 size_yuv420 = FRAME_SIZE_YUV420(fbi->xres, fbi->yres, 8); ++ ++ return max(size_rgb, max(size_yuv422, size_yuv420)); ++} ++ ++#ifdef CONFIG_FTLCD_OSD ++/************************************ ++ * OSD ++ ***********************************/ ++#define FOSD_SETPOS 0x46e1 ++#define FOSD_SETDIM 0x46e2 ++#define FOSD_SETSCAL 0x46e3 ++#define FLCD_SET_TRANSPARENT 0x46e4 ++#define FLCD_SET_STRING 0x46e5 ++#define FOSD_ON 0x46e6 ++#define FOSD_OFF 0x46e7 ++#define FRREG 0x46e8 ++#define FWREG 0x46e9 ++ ++#define dig_alpha (16 * 10) + (16 * 26) + (16 * 3) ++ ++struct fosd_string { ++ ++ unsigned int Str_row; ++ unsigned int display_mode; ++ unsigned int fg_color; ++ unsigned int bg_color; ++ unsigned char Str_OSD[30]; ++}; ++ ++struct fosd_data { ++ ++ unsigned int HPos; ++ unsigned int VPos; ++ unsigned int HDim; ++ unsigned int VDim; ++ unsigned int transparent_level; ++ unsigned int HScal; ++ unsigned int VScal; ++ struct fosd_string Str_Data[10]; ++}; ++ ++unsigned int OSD_Font[] = { ++ ++ /* 0 */ ++ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x67, 0x6f, 0x7b, ++ 0x73, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 1 */ ++ 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x0c, 0x0c, ++ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 2 */ ++ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x03, 0x06, 0x0c, ++ 0x18, 0x30, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 3 */ ++ 0x00, 0x00, 0x00, 0x3E, 0x63, 0x03, 0x03, 0x1e, ++ 0x03, 0x03, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 4 */ ++ 0x00, 0x00, 0x00, 0x06, 0x0e, 0x1e, 0x36, 0x66, ++ 0x7f, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 5 */ ++ 0x00, 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x7e, ++ 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 6 */ ++ 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7e, ++ 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 7 */ ++ 0x00, 0x00, 0x00, 0x7f, 0x63, 0x03, 0x06, 0x0c, ++ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 8 */ ++ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3e, ++ 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* 9 */ ++ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3f, ++ 0x03, 0x03, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00, ++ ++ /* A */ ++ 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, ++ 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, ++ ++ /* B */ ++ 0x00, 0x00, 0x00, 0x7E, 0x33, 0x33, 0x33, 0x3E, ++ 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00, ++ ++ /* C */ ++ 0x00, 0x00, 0x00, 0x1E, 0x33, 0x61, 0x60, 0x60, ++ 0x60, 0x61, 0x33, 0x1E, 0x00, 0x00, 0x00, 0x00, ++ ++ /* D */ ++ 0x00, 0x00, 0x00, 0x7c, 0x36, 0x33, 0x33, 0x33, ++ 0x33, 0x33, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00, ++ ++ /* E */ ++ 0x00, 0x00, 0x00, 0x7f, 0x33, 0x31, 0x34, 0x3c, ++ 0x34, 0x31, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00, ++ ++ /* F */ ++ 0x00, 0x00, 0x00, 0x7f, 0x33, 0x31, 0x34, 0x3c, ++ 0x34, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, ++ ++ /* G */ ++ 0x00, 0x00, 0x00, 0x1E, 0x33, 0x61, 0x60, 0x60, ++ 0x6F, 0x63, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00, ++ ++ /* H */ ++ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x64, 0x7f, ++ 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, ++ ++ /* I */ ++ 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, ++ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, ++ ++ /* J */ ++ 0x00, 0x00, 0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, ++ 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, ++ ++ /* K */ ++ 0x00, 0x00, 0x00, 0x73, 0x33, 0x36, 0x36, 0x3c, ++ 0x36, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00, ++ ++ /* L */ ++ 0x00, 0x00, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, ++ 0x30, 0x31, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00, ++ ++ /* M */ ++ 0x00, 0x00, 0x00, 0x63, 0x77, 0x7f, 0x6b, 0x63, ++ 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, ++ ++ /* N */ ++ 0x00, 0x00, 0x00, 0x63, 0x73, 0x7b, 0x7f, 0x6f, ++ 0x67, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, ++ ++ /* O */ ++ 0x00, 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, ++ 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, ++ ++ /* P */ ++ 0x00, 0x00, 0x00, 0x7e, 0x33, 0x33, 0x33, 0x3e, ++ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, ++ ++ /* Q */ ++ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, ++ 0x6b, 0x6f, 0x3e, 0x06, 0x07, 0x00, 0x00, 0x00, ++ ++ /* R */ ++ 0x00, 0x00, 0x00, 0x7e, 0x33, 0x33, 0x33, 0x3e, ++ 0x36, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00, ++ ++ /* S */ ++ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x1c, ++ 0x06, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* T */ ++ 0x00, 0x00, 0x00, 0xFF, 0x99, 0x18, 0x18, 0x18, ++ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, ++ ++ /* U */ ++ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, ++ 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* V */ ++ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, ++ 0x63, 0x36, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, ++ ++ /* W */ ++ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, ++ 0x6b, 0x7f, 0x77, 0x63, 0x00, 0x00, 0x00, 0x00, ++ ++ /* X */ ++ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1c, ++ 0x36, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, ++ ++ /* Y */ ++ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1c, ++ 0x1c, 0x1c, 0x1c, 0x3e, 0x00, 0x00, 0x00, 0x00, ++ ++ /* Z */ ++ 0x00, 0x00, 0x00, 0x7f, 0x63, 0x46, 0x0c, 0x18, ++ 0x30, 0x61, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, ++ ++ /* space */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* = */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, ++ 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ ++ /* , */ ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, ++}; ++ ++void OSD_On(struct faradayfb_info *fbi) ++{ ++ REG32(fbi->io_base + 0x34) &= 0xfffffffe; ++ REG32(fbi->io_base + 0x34) |= 1; ++} ++ ++void OSD_Off(struct faradayfb_info *fbi) ++{ ++ REG32(fbi->io_base + 0x34) &= 0xfffffffe; ++} ++ ++void OSD_Pos(struct faradayfb_info *fbi, int HPos, int VPos) ++{ ++ REG32(fbi->io_base + 0x38) = (HPos << 10) | VPos; ++} ++ ++void OSD_Dim(struct faradayfb_info *fbi, int HDim, int VDim) ++{ ++ REG32(fbi->io_base + 0x34) &= 0x0000001f; ++ REG32(fbi->io_base + 0x34) |= ((HDim << 10) | (VDim << 5)); ++} ++ ++void OSD_transparent(struct faradayfb_info *fbi, int level) ++{ ++ REG32(fbi->io_base + 0x40) &= 0xffffff00; ++ REG32(fbi->io_base + 0x40) |= (level << 6); ++} ++ ++void OSD_fg_color(struct faradayfb_info *fbi, int pal0, int pal1, int pal2, int pal3) ++{ ++ REG32(fbi->io_base + 0x3c) = (pal0) | (pal1 << 8) | (pal2 << 16) | (pal3<< 24); ++} ++ ++void OSD_bg_color(struct faradayfb_info *fbi, int pal1, int pal2, int pal3) ++{ ++ REG32(fbi->io_base + 0x40) &= 0x000000ff; ++ REG32(fbi->io_base + 0x40) |= (pal1 << 8) | (pal2 << 16) | (pal3 << 24); ++} ++ ++void OSD_Scal(struct faradayfb_info *fbi, int HScal, int VScal) ++{ ++ REG32(fbi->io_base + 0x34) &= 0xffffffe1; ++ REG32(fbi->io_base + 0x34) |= (HScal << 3) | (VScal << 1); ++} ++ ++void OSD_putc(struct faradayfb_info *fbi, char c, int position, unsigned int value) ++{ ++ if (c >= '0' && c <= '9') ++ REG32(fbi->io_base + 0xc000 + position * 4) = ((c -'0') << 4) | value; ++ ++ else if (c>= 'A' && c <= 'Z') ++ REG32(fbi->io_base + 0xc000 + position * 4) = ((c - 'A' + 10) << 4) | value; ++ ++ if (c == ' ') ++ REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 1) << 4) | value; ++ ++ if (c == '=') ++ REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 2) << 4) | value; ++ ++ if (c == ',') ++ REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 3) << 4) | value; ++} ++ ++void OSD_puts(struct faradayfb_info *fbi, char *str, int position, unsigned int value) ++{ ++ int i; ++ ++ for (i = 0; i < strlen(str); i++) ++ OSD_putc(fbi, *(str + i), position + i, value); ++} ++ ++void OSD_String(struct faradayfb_info *fbi, int row, int mode, char *str, int fg_color, int bg_color) ++{ ++ int i, j, x, y; ++ unsigned int value = fg_color | bg_color; ++ ++ /* 10 digit & 26 alphabet & ' ' & '=' & ',' */ ++ for (i = 0; i < dig_alpha; i++) { ++ ++ x = 0; ++ y = OSD_Font[i]; ++ ++ for (j = 0; j < 12; j ++) { /* reorder */ ++ if (y & 1) ++ x |= 1; ++ y >>= 1; ++ x <<= 1; ++ } ++ ++ x >>= 1; ++ REG32(fbi->io_base + 0x8000 + i * 4) = x; ++ } ++ ++ OSD_puts(fbi, str, row, value); ++ ++ if (mode == 2) { /* YCbCr */ ++ ++ OSD_fg_color(fbi, 0x57, 0x88, 0x3B, 0xFF); ++ OSD_bg_color(fbi, 0x57, 0x88, 0x3B); ++ } ++ else { ++ OSD_fg_color(fbi, 0x07, 0x38, 0xC0, 0xFF); ++ OSD_bg_color(fbi, 0x07, 0x38, 0xc0); ++ } ++} ++#endif /* CONFIG_FTLCD_OSD */ ++ ++struct andesIO { ++ ++ unsigned long Regaddr; ++ unsigned long Regoffset; ++ unsigned long Regvalue; ++}; ++ ++static int faradayfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) ++{ ++ int ret = 0; ++#ifdef CONFIG_FTLCD_OSD ++ struct faradayfb_info *fbi = info->par; ++ int i; ++ struct fosd_data fosd; ++ ++ struct andesIO IOAccess; ++ unsigned long *Regaccess; ++#endif ++ ++ DEBUG(0, 1, "Enter\n"); ++ ++ switch (cmd) { ++#ifdef CONFIG_FTLCD_OSD ++ case FRREG: ++ ++ if (copy_from_user(&IOAccess, (struct andesIO *)arg, sizeof(struct andesIO))) { ++ ++ ret = -EFAULT; ++ break; ++ } ++ ++ Regaccess = (unsigned long *)(((IOAccess.Regaddr >> 4) | (unsigned long)0xF0000000) + IOAccess.Regoffset); ++ ++ IOAccess.Regvalue = *(Regaccess); ++ ++ if (copy_to_user((struct andesIO *)arg, &IOAccess, sizeof(struct andesIO))) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ break; ++ ++ case FWREG: ++ ++ if (copy_from_user(&IOAccess, (struct andesIO *)arg, sizeof(struct andesIO))) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ Regaccess = (unsigned long *)(((IOAccess.Regaddr >> 4) | (unsigned long)0xF0000000) + IOAccess.Regoffset); ++ *(Regaccess) = IOAccess.Regvalue; ++ ++ break; ++ ++ case FOSD_ON: ++ ++ DEBUG(1, 1, "FOSD_ON:\n"); ++ OSD_On(fbi); ++ break; ++ ++ case FOSD_OFF: ++ ++ DEBUG(1, 1, "FOSD_OFF:\n"); ++ OSD_Off(fbi); ++ break; ++ ++ case FOSD_SETPOS: ++ ++ DEBUG(1, 1, "FOSD_SETPOS:\n"); ++ ++ if (copy_from_user(&fosd, (unsigned int *)arg, 2 * sizeof(unsigned int))) { ++ ++ ret = -EFAULT; ++ break; ++ } ++ ++ OSD_Pos(fbi, fosd.HPos, fosd.VPos); ++ DEBUG(1, 1, "OSD_Pos = %d %d\n", fosd.HPos, fosd.VPos); ++ break; ++ ++ case FOSD_SETDIM: ++ ++ DEBUG(1, 1, "FOSD_SETDIM:\n"); ++ ++ if (copy_from_user(&fosd, (unsigned int *)arg, 4 * sizeof(unsigned int))) { ++ ++ ret = -EFAULT; ++ break; ++ } ++ ++ OSD_Dim(fbi, fosd.HDim, fosd.VDim); ++ DEBUG(1, 1, "OSD_Dim = %d %d\n", fosd.HDim, fosd.VDim); ++ break; ++ ++ case FOSD_SETSCAL: ++ ++ DEBUG(1, 1, "FOSD_SETSCAL:\n"); ++ ++ if (copy_from_user(&fosd, (unsigned int *)arg, 7 * sizeof(unsigned int))) { ++ ret = -EFAULT; ++ break; ++ } ++ ++ OSD_Scal(fbi, fosd.HScal, fosd.VScal); ++ break; ++ ++ case FLCD_SET_TRANSPARENT: ++ ++ DEBUG(1, 1, "FLCD_SET_TRANSPARENT:\n"); ++ ++ if (copy_from_user(&fosd, (unsigned int *)arg, 5 * sizeof(unsigned int))) { ++ ++ ret = -EFAULT; ++ break; ++ } ++ ++ OSD_transparent(fbi, fosd.transparent_level); ++ DEBUG(1, 1, "OSD_transparent = %d\n", fosd.transparent_level); ++ break; ++ ++ case FLCD_SET_STRING: ++ ++ DEBUG(1, 1, "FLCD_SET_STRING:\n"); ++ ++ if (copy_from_user(&fosd, (unsigned int *)arg, sizeof(struct fosd_data))) { ++ ++ ret = -EFAULT; ++ break; ++ } ++ ++ for (i = 0; i < fosd.VDim; i++) ++ ++ OSD_String(fbi, fosd.Str_Data[i].Str_row, ++ fosd.Str_Data[i].display_mode, ++ fosd.Str_Data[i].Str_OSD, ++ fosd.Str_Data[i].fg_color, ++ fosd.Str_Data[i].bg_color); ++ break; ++#endif /* CONFIG_FTLCD_OSD */ ++ ++ default: ++ ++ DEBUG(1, 1, "IOCTL CMD(0x%08u) no define!\n", cmd); ++ ret = -EFAULT; ++ break; ++ } ++ ++ DEBUG(0, 1, "Leave\n"); ++ return ret; ++} ++ +diff -Nur linux-3.4.110.orig/drivers/video/Kconfig linux-3.4.110/drivers/video/Kconfig +--- linux-3.4.110.orig/drivers/video/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/video/Kconfig 2016-04-07 10:20:51.058085512 +0200 +@@ -2166,6 +2166,8 @@ + ---help--- + Say Y here to enable support for PNX4008 RGB Framebuffer + ++source "drivers/video/FTLCDC100/Kconfig" ++ + config FB_IBM_GXT4500 + tristate "Framebuffer support for IBM GXT4500P adaptor" + depends on FB && PPC +diff -Nur linux-3.4.110.orig/drivers/video/Makefile linux-3.4.110/drivers/video/Makefile +--- linux-3.4.110.orig/drivers/video/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/video/Makefile 2016-04-07 10:20:51.058085512 +0200 +@@ -143,6 +143,7 @@ + obj-$(CONFIG_FB_CARMINE) += carminefb.o + obj-$(CONFIG_FB_MB862XX) += mb862xx/ + obj-$(CONFIG_FB_MSM) += msm/ ++obj-$(CONFIG_FB_FTLCDC100) += FTLCDC100/ + obj-$(CONFIG_FB_NUC900) += nuc900fb.o + obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o + obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o +diff -Nur linux-3.4.110.orig/drivers/watchdog/ftwdt010_wdt.c linux-3.4.110/drivers/watchdog/ftwdt010_wdt.c +--- linux-3.4.110.orig/drivers/watchdog/ftwdt010_wdt.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/drivers/watchdog/ftwdt010_wdt.c 2016-04-07 10:20:51.058085512 +0200 +@@ -0,0 +1,127 @@ ++/* ++ * Watchdog driver for the FTWDT010 Watch Dog Driver ++ * ++ * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) ++ * Based on sa1100_wdt.c by Oleg Drokin ++ * Based on SoftDog driver by Alan Cox ++ * ++ * 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. ++ * ++ * 27/11/2004 Initial release ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DEBUG( str, ...) \ ++ do{ \ ++ if( debug) \ ++ printk( str, ##__VA_ARGS__); \ ++ } while(0) ++ ++#define wdcounter (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x00)) ++#define wdload (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x04)) ++#define wdrestart (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x08)) ++#define wdcr (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x0C)) ++#define wdstatus (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x10)) ++#define wdclear (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x14)) ++#define wdintrcter (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x18)) ++ ++#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */ ++#define RESTART_MAGIC 0x5AB9 ++#define PCLK (AHB_CLK_IN / 2) ++ ++static int debug = 0; ++static int timeout = TIMER_MARGIN; /* in seconds */ ++ ++module_param(debug, int, 0); ++module_param(timeout, int, 0); ++ ++static int ftwdt010_dog_open(struct inode *inode, struct file *file){ ++ ++#if 0 ++ /* Allow only one person to hold it open */ ++ if( test_and_set_bit( 1, &ftwdt010_wdt_users)) ++ return -EBUSY; ++ ++ ftwdt010_wdt_users = 1; ++#endif ++ DEBUG("Activating WDT..\n"); ++ ++ wdcr = 0; ++ wdload = PCLK * timeout; ++ wdrestart = RESTART_MAGIC; /* Magic number */ ++ wdcr = 0x03; /* Enable WDT */ ++ ++ return 0; ++} ++ ++static int ftwdt010_dog_release(struct inode *inode, struct file *file){ ++ ++#ifndef CONFIG_WATCHDOG_NOWAYOUT ++ /* ++ * Shut off the timer. ++ * Lock it in if it's a module and we defined ...NOWAYOUT ++ */ ++ wdcr = 0; ++ DEBUG( "Deactivating WDT..\n"); ++#endif ++ return 0; ++} ++ ++static ssize_t ftwdt010_dog_write(struct file *file, const char *data, size_t len, loff_t *ppos){ ++ ++ if(len){ ++ ++ wdrestart = RESTART_MAGIC; ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static struct file_operations ftwdt010_dog_fops = { ++ ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = ftwdt010_dog_write, ++ .open = ftwdt010_dog_open, ++ .release = ftwdt010_dog_release, ++}; ++ ++static struct miscdevice ftwdt010_dog_miscdev = { ++ ++ WATCHDOG_MINOR, ++ "FTWDT010 watchdog", ++ &ftwdt010_dog_fops ++}; ++ ++static int __init ftwdt010_dog_init( void){ ++ ++ int ret; ++ ++ ret = misc_register(&ftwdt010_dog_miscdev); ++ ++ if( ret) ++ return ret; ++ ++ DEBUG("FTWDT010 watchdog timer: timer timeout %d sec\n", timeout); ++ ++ return 0; ++} ++ ++static void __exit ftwdt010_dog_exit( void){ ++ ++ misc_deregister(&ftwdt010_dog_miscdev); ++} ++ ++module_init(ftwdt010_dog_init); ++module_exit(ftwdt010_dog_exit); ++MODULE_AUTHOR("Faraday Corp."); ++MODULE_LICENSE("GPL"); +diff -Nur linux-3.4.110.orig/drivers/watchdog/Kconfig linux-3.4.110/drivers/watchdog/Kconfig +--- linux-3.4.110.orig/drivers/watchdog/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/watchdog/Kconfig 2016-04-07 10:20:51.058085512 +0200 +@@ -64,6 +64,12 @@ + To compile this driver as a module, choose M here: the + module will be called softdog. + ++config FTWDT010_WATCHDOG ++ tristate "FTWDT010_WATCHDOG" ++ help ++ Support for Faraday ftwdt010 watchdog. When the watchdog triigers the ++ system will be reset. ++ + config WM831X_WATCHDOG + tristate "WM831x watchdog" + depends on MFD_WM831X +diff -Nur linux-3.4.110.orig/drivers/watchdog/Makefile linux-3.4.110/drivers/watchdog/Makefile +--- linux-3.4.110.orig/drivers/watchdog/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/drivers/watchdog/Makefile 2016-04-07 10:20:51.058085512 +0200 +@@ -163,6 +163,7 @@ + obj-$(CONFIG_XEN_WDT) += xen_wdt.o + + # Architecture Independent ++obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o + obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o + obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o + obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o +diff -Nur linux-3.4.110.orig/include/linux/mm.h linux-3.4.110/include/linux/mm.h +--- linux-3.4.110.orig/include/linux/mm.h 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/include/linux/mm.h 2016-04-07 10:20:51.058085512 +0200 +@@ -157,6 +157,7 @@ + #define FAULT_FLAG_ALLOW_RETRY 0x08 /* Retry fault if blocking */ + #define FAULT_FLAG_RETRY_NOWAIT 0x10 /* Don't drop mmap_sem and wait when retrying */ + #define FAULT_FLAG_KILLABLE 0x20 /* The fault task is in SIGKILL killable region */ ++#define FAULT_FLAG_TRIED 0x40 /* second try */ + + /* + * This interface is used by x86 PAT code to identify a pfn mapping that is +diff -Nur linux-3.4.110.orig/include/linux/semaphore.h linux-3.4.110/include/linux/semaphore.h +--- linux-3.4.110.orig/include/linux/semaphore.h 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/include/linux/semaphore.h 2016-04-07 10:20:51.062085666 +0200 +@@ -36,6 +36,9 @@ + lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); + } + ++#define init_MUTEX(sem) sema_init(sem, 1) ++#define init_MUTEX_LOCKED(sem) sema_init(sem, 0) ++ + extern void down(struct semaphore *sem); + extern int __must_check down_interruptible(struct semaphore *sem); + extern int __must_check down_killable(struct semaphore *sem); +diff -Nur linux-3.4.110.orig/init/Kconfig linux-3.4.110/init/Kconfig +--- linux-3.4.110.orig/init/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/init/Kconfig 2016-04-07 10:20:51.062085666 +0200 +@@ -966,7 +966,7 @@ + + config UID16 + bool "Enable 16-bit UID system calls" if EXPERT +- depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) ++ depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || NDS32 || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) + default y + help + This enables the legacy 16-bit UID syscall wrappers. +diff -Nur linux-3.4.110.orig/kernel/Makefile linux-3.4.110/kernel/Makefile +--- linux-3.4.110.orig/kernel/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/kernel/Makefile 2016-04-07 10:20:51.062085666 +0200 +@@ -20,6 +20,7 @@ + CFLAGS_REMOVE_rtmutex-debug.o = -pg + CFLAGS_REMOVE_cgroup-debug.o = -pg + CFLAGS_REMOVE_irq_work.o = -pg ++CFLAGS_REMOVE_kallsyms.o = -pg + endif + + obj-y += sched/ +diff -Nur linux-3.4.110.orig/kernel/trace/Kconfig linux-3.4.110/kernel/trace/Kconfig +--- linux-3.4.110.orig/kernel/trace/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/kernel/trace/Kconfig 2016-04-07 10:20:51.062085666 +0200 +@@ -141,7 +141,7 @@ + config FUNCTION_TRACER + bool "Kernel Function Tracer" + depends on HAVE_FUNCTION_TRACER +- select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE ++ select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE && !NDS32 + select KALLSYMS + select GENERIC_TRACER + select CONTEXT_SWITCH_TRACER +diff -Nur linux-3.4.110.orig/lib/Kconfig.debug linux-3.4.110/lib/Kconfig.debug +--- linux-3.4.110.orig/lib/Kconfig.debug 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/lib/Kconfig.debug 2016-04-07 10:20:51.062085666 +0200 +@@ -615,7 +615,7 @@ + bool + depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT + select STACKTRACE +- select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE ++ select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !NDS32 + select KALLSYMS + select KALLSYMS_ALL + +@@ -1122,7 +1122,7 @@ + depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT + depends on !X86_64 + select STACKTRACE +- select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND ++ select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !NDS32 + help + Provide stacktrace filter for fault-injection capabilities + +@@ -1132,7 +1132,7 @@ + depends on DEBUG_KERNEL + depends on STACKTRACE_SUPPORT + depends on PROC_FS +- select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND ++ select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !NDS32 + select KALLSYMS + select KALLSYMS_ALL + select STACKTRACE +diff -Nur linux-3.4.110.orig/sound/Kconfig linux-3.4.110/sound/Kconfig +--- linux-3.4.110.orig/sound/Kconfig 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/sound/Kconfig 2016-04-07 10:20:51.062085666 +0200 +@@ -93,6 +93,8 @@ + + source "sound/sh/Kconfig" + ++source "sound/nds32/Kconfig" ++ + # the following will depend on the order of config. + # here assuming USB is defined before ALSA + source "sound/usb/Kconfig" +diff -Nur linux-3.4.110.orig/sound/Makefile linux-3.4.110/sound/Makefile +--- linux-3.4.110.orig/sound/Makefile 2015-10-22 03:20:09.000000000 +0200 ++++ linux-3.4.110/sound/Makefile 2016-04-07 10:20:51.062085666 +0200 +@@ -6,7 +6,7 @@ + obj-$(CONFIG_SOUND_PRIME) += oss/ + obj-$(CONFIG_DMASOUND) += oss/ + obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ +- firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ ++ firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ nds32/ + obj-$(CONFIG_SND_AOA) += aoa/ + + # This one must be compilable even if sound is configured out +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_ALSA.c linux-3.4.110/sound/nds32/FTSSP010_ALSA.c +--- linux-3.4.110.orig/sound/nds32/FTSSP010_ALSA.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_ALSA.c 2016-04-07 10:20:51.062085666 +0200 +@@ -0,0 +1,2020 @@ ++/* FTSSP010 - UDA1345TS module: ++ * ++ * $log$ ++ * ++ * 2006/02/23: I-Jui Sung: OSS emulation half-duplex ++ * playback/capture at 48K, 44.1K, 8K ++ * with mono/stereo 16bit/8bit ++ * ++ * 2006/02/22: I-Jui Sung: OSS emulation playback at 44.1KHz ++ * 16-bit mono completed. Relying ALSA to ++ * resample ++ * 2009/02/24: dma upgrade checking list: ++ * - ac97 mode playback ................. ok ++ * - ac97 mode capture .................. ok ++ * - i2s mode playback .................. ok ++ * - i2s mode capture ................... ok ++ * - mixer support (snd_ctl_add, ...) ... todo ++ * - debug /proc entry .................. ok ++ */ ++ ++ ++#include ++#include ++#include ++#include ++//#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "FTSSP010_UDA1345TS.h" ++ ++//ADD by river 2011.06.02 ++struct alc5630_data; ++//End ADD by river 2011.06.02 ++ ++void init_hw(unsigned int cardno,unsigned int ac97, struct i2c_client *client); ++ ++#if (!defined(CONFIG_PLATFORM_AHBDMA) && !defined(CONFIG_PLATFORM_APBDMA)) ++#warning needs ahb/apb dma to wrok ++#endif ++ ++/* --------------------------------------------------------------------------- ++ * Define the debug level of FTSSP_DEBUG ++ */ ++#define FTSSP_DEBUG 0 ++#define FTSSP_DEBUG_VERBOSE 0 ++#define FTSSP_PROC_FS 0 ++ ++#undef VVDBG ++#if (FTSSP_DEBUG_VERBOSE) ++#define VVDBG(vvar...) (void)0 ++//#define VVDBG(vvar...) printk(KERN_INFO vvar) ++#else ++#define VVDBG(vvar...) (void)0 ++#endif ++ ++#undef ERR ++#define ERR(vvar...) printk(KERN_ERR vvar) ++ ++#undef INFO ++#define INFO(vvar...) printk(KERN_INFO vvar) ++ ++#if (FTSSP_DEBUG) ++#undef DBG ++#define DBG(vvar...) printk(KERN_INFO vvar) ++#else ++#define DBG(vvar...) (void)0 ++#endif ++ ++#if (FTSSP_DEBUG_VERBOSE) ++#undef VDBG ++#define VDBG(vvar...) printk(KERN_INFO vvar) ++#else ++#define VDBG(vvar...) (void)0 ++#endif ++ ++#ifdef CONFIG_SND_FTSSP010_I2S ++//ADD by river 2011.02.11 ++static struct i2c_client *g_i2c_client; ++ ++////////// ADD by river 2011.01.26 ++// Each client has this additional data ++struct alc5630_data { ++ struct i2c_client *client; ++ struct delayed_work work; ++ unsigned long gpio2_value; ++ struct mutex mtx; ++}; ++ ++static int alc5630_i2c_attach(struct i2c_adapter *adapter); ++static int alc5630_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); ++static int alc5630_i2c_suspend(struct i2c_client *i2c_client, pm_message_t mesg); ++static int alc5630_i2c_resume(struct i2c_client *i2c_client); ++ ++static int alc5630_i2c_remove(struct i2c_client *client); ++static int ftssp_alsa_init(struct i2c_client *client); ++ ++ ++static int i2s_alc5630_read(unsigned int raddr, char *data, struct i2c_client *client) ++{ ++ struct i2c_adapter *adap = client->adapter; ++ struct i2c_msg msg; ++ int ret, i2c_value; ++ ++ //Reading ALC5630 register ++ msg.addr = raddr; ++ msg.flags = (client->flags & I2C_M_TEN) | I2C_M_RD; ++ msg.len = 1; ++ msg.buf = (char *)data; ++ ++ //ret = i2c_transfer(adap, &msg, 1); ++ #ifndef CONFIG_SND_FTSSP010_AC97 ++ ret = i2c_transfer(adap, &msg, 1); ++ #endif ++ ++ if (ret != 0) { ++ printk("i2c read failed\n"); ++ return -1; ++ } ++ else ++ { ++ i2c_value = (data[0]&0xff) << 8 | (data[1]&0xff); ++ return i2c_value; ++ } ++ ++} ++ ++static void i2s_alc5630_write(unsigned int addr, unsigned int data, struct i2c_client *client) ++{ ++ ++ struct i2c_adapter *adap = client->adapter; ++ struct i2c_msg msg; ++ int ret, i2c_value; ++ char buf[3]; ++ ++ //Writing ALC5630 register ++ i2c_value = 0x0; ++ msg.addr = addr; ++ msg.flags = (client->flags & I2C_M_TEN) | ~I2C_M_RD; ++ msg.len = 1; ++ ++ buf[0] = (data >> 8) & 0xff; ++ buf[1] = data & 0xff; ++ msg.buf = (char *)buf; ++ ++ //ret = i2c_transfer(adap, &msg, 1); ++ #ifndef CONFIG_SND_FTSSP010_AC97 ++ ret = i2c_transfer(adap, &msg, 1); ++ #endif ++ ++ if (ret != 0) { ++ printk("i2c write failed\n"); ++ } ++ ++} ++ ++static void i2s_alc5630_read_test(struct i2c_client *client) ++{ ++ char data[3]; ++ //printk(">>>>> : i2s_alc5630_read_test().....\n"); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0, i2s_alc5630_read(0x0, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x02, i2s_alc5630_read(0x02, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x04, i2s_alc5630_read(0x04, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x06, i2s_alc5630_read(0x06, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x08, i2s_alc5630_read(0x08, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0a, i2s_alc5630_read(0x0a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0c, i2s_alc5630_read(0x0c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0e, i2s_alc5630_read(0x0e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x10, i2s_alc5630_read(0x10, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x12, i2s_alc5630_read(0x12, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x14, i2s_alc5630_read(0x14, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x16, i2s_alc5630_read(0x16, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x18, i2s_alc5630_read(0x18, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x1a, i2s_alc5630_read(0x1a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x1c, i2s_alc5630_read(0x1c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x1e, i2s_alc5630_read(0x1e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x20, i2s_alc5630_read(0x20, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x22, i2s_alc5630_read(0x22, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x24, i2s_alc5630_read(0x24, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x26, i2s_alc5630_read(0x26, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x28, i2s_alc5630_read(0x28, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x2a, i2s_alc5630_read(0x2a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x2c, i2s_alc5630_read(0x2c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x2e, i2s_alc5630_read(0x2e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x30, i2s_alc5630_read(0x30, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x32, i2s_alc5630_read(0x32, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x34, i2s_alc5630_read(0x34, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x36, i2s_alc5630_read(0x36, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x38, i2s_alc5630_read(0x38, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x3a, i2s_alc5630_read(0x3a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x3c, i2s_alc5630_read(0x3c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x3e, i2s_alc5630_read(0x3e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x40, i2s_alc5630_read(0x40, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x42, i2s_alc5630_read(0x42, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x44, i2s_alc5630_read(0x44, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x46, i2s_alc5630_read(0x46, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x48, i2s_alc5630_read(0x48, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x4a, i2s_alc5630_read(0x4a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x4c, i2s_alc5630_read(0x4c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x4e, i2s_alc5630_read(0x4e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x50, i2s_alc5630_read(0x50, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x52, i2s_alc5630_read(0x52, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x54, i2s_alc5630_read(0x54, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x56, i2s_alc5630_read(0x56, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x58, i2s_alc5630_read(0x58, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x5a, i2s_alc5630_read(0x5a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x5c, i2s_alc5630_read(0x5c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x5e, i2s_alc5630_read(0x5e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x60, i2s_alc5630_read(0x60, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x62, i2s_alc5630_read(0x62, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x64, i2s_alc5630_read(0x64, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x66, i2s_alc5630_read(0x66, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x68, i2s_alc5630_read(0x68, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x6a, i2s_alc5630_read(0x6a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x6c, i2s_alc5630_read(0x6c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x6e, i2s_alc5630_read(0x6e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x70, i2s_alc5630_read(0x70, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x72, i2s_alc5630_read(0x72, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x74, i2s_alc5630_read(0x74, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x76, i2s_alc5630_read(0x76, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x78, i2s_alc5630_read(0x78, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x7a, i2s_alc5630_read(0x7a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x7c, i2s_alc5630_read(0x7c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x7e, i2s_alc5630_read(0x7e, data,client)); ++ ++} ++ ++static int alc5630_i2c_attach(struct i2c_adapter *adapter){ ++ ++ struct i2c_board_info info; ++ struct i2c_client *client; ++ ++ int ret=0; ++ ++ //i2c_dbg( 1, "alc5630_i2c_attach() is called.\n"); ++ //printk(">>>>>>>>>> (2) alc5630_i2c_attach() is called.\n"); ++ ++ //ret = i2c_probe(adapter, &addr_data, alc5630_detect); ++ memset(&info, 0, sizeof(struct i2c_board_info)); ++ strlcpy(info.type, "alc5630_codec", I2C_NAME_SIZE); ++ //info.addr = 0x3e; ++ info.addr = 0x66; ++ //info.platform_data = node; ++ ++ //client = i2c_new_device(adapter, &info); ++ #ifndef CONFIG_SND_FTSSP010_AC97 ++ client = i2c_new_device(adapter, &info); ++ #endif ++ if (!client) { ++ printk("$$$$$????? : i2c_new_device() failed.....\n"); ++ return -ENODEV; ++ } ++ /* ++ * We know the driver is already loaded, so the device should be ++ * already bound. If not it means binding failed, and then there ++ * is no point in keeping the device instantiated. ++ */ ++ if (!client->driver) { ++ //i2c_unregister_device(client); ++ #ifndef CONFIG_SND_FTSSP010_AC97 ++ i2c_unregister_device(client); ++ #endif ++ return -ENODEV; ++ } ++ ++ /* ++ * Let i2c-core delete that device on driver removal. ++ * This is safe because i2c-core holds the core_lock mutex for us. ++ */ ++ list_add_tail(&client->detected, &client->driver->clients); ++ ++ return ret; ++} ++ ++static irqreturn_t gpio2_irq(int irq, void *dev_id) ++{ ++ ++ struct i2c_client *client = (struct i2c_client *)dev_id; ++ struct alc5630_data *alc5630 = i2c_get_clientdata(client); ++ ++ unsigned long org_mask, org_dir; ++ //printk("@@@@@#####$$$$$!!!!! : gpio2_irq is detected ???....\n"); ++ ++ //Mask GPIO interrupt ++ //REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) & ~(1 << 13); //GPIO interrupt disable ++ ++ //Dump AMIC contents and ir~ ++ unsigned long ir0,ir1,ir2, ir3, ir4, ir5; ++ unsigned long ir6, ir7, ir8, ir9, ir10; ++ unsigned long ir11, ir12, ir13, ir14, ir15; ++ unsigned long gpio2_value, value; ++ char data[3]; ++ ++ ++ //__asm__ volatile ("setgie.d\n\t"); ++ //REG32(AMIC_VA_BASE + 0x80) = 0; ++ ++ ++ //Get original gpio direction ++ org_dir = REG32(GPIO_VA_BASE + 0x08); ++ ++ //Get original gpio interrupt mask ++ org_mask = REG32(GPIO_VA_BASE + 0x2c); ++ ++ //Mask all gpio interrupt ++ REG32(GPIO_VA_BASE + 0x2c) = 0x0000FFFF; ++ //Clear all gpio interrupt ++ REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; ++ ++ //Get gpio pin value ++ REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 2); //Set gpio2 direction => input ++ gpio2_value = (REG32(GPIO_VA_BASE + 0x04) >> 2 & 1); ++ //printk("The gpio2 value is 0x%08x\n",gpio2_value); ++ ++ ++ alc5630->gpio2_value = gpio2_value; ++ schedule_delayed_work(&alc5630->work, 1); ++ ++ /*if (gpio3_value==0x1) { ++ i2s_alc5630_write(0x02, 0x0000, g_i2c_client); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0040 , g_i2c_client); ++ printk("External speaker is plugged in... and Try to mute internal speaker......\n"); ++ } ++ else { ++ i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0440 , g_i2c_client); ++ printk("External speaker is pulled ... and Try to unmute internal speaker......\n"); ++ }*/ ++ ++ ++ //Set gpio3 pin value to 0 ++ //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) | (0x1UL << 3); //Set gpio3 direction => output ++ //value = REG32(GPIO_VA_BASE + 0x00) & ~(0x1UL << 3); ++ //REG32(GPIO_VA_BASE + 0x00) = value; ++ ++ //Get gpio pin value again ++ //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 3); //Set gpio3 direction => input ++ //gpio3_value = (REG32(GPIO_VA_BASE + 0x04) >> 3 & 1); ++ //printk("The gpio3 value is 0x%08x\n",gpio3_value); ++ ++ //restore original gpio interrupt mask ++ REG32(GPIO_VA_BASE + 0x2c) = org_mask; ++ ++ //restore original gpio direction ++ REG32(GPIO_VA_BASE + 0x08) = org_dir; ++ ++ //unmask GPIO interrupt ++ //REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) | (1 << 13); //GPIO interrupt enable ++ REG32(AMIC_VA_BASE + 0x84) = REG32(AMIC_VA_BASE + 0x84) | (1 << 13); //Clear GPIO interrupt ++ REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; //Clear all gpio interrupt ++ ++ //printk("@@@@@#####$$$$$!!!!! : gpio2_irq() is exited....\n"); ++ ++ return IRQ_HANDLED; ++} ++ ++static void iic_work(struct work_struct *work) ++{ ++ char data[3]; ++ struct alc5630_data *alc5630 = ++ container_of(to_delayed_work(work), struct alc5630_data, work); ++ ++ ++ if (alc5630->gpio2_value==0x0) { ++ //i2s_alc5630_write(0x02, 0x0000, alc5630->client); ++ i2s_alc5630_write(0x02, 0x5F5F, alc5630->client); ++ i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,alc5630->client) & 0xFBFF) | 0x0040 , alc5630->client); ++ //printk("External speaker is plugged in... and Try to mute internal speaker......\n"); ++ //i2s_alc5630_read_test(alc5630->client); ++ } ++ else { ++ //i2s_alc5630_write(0x02, 0x5F5F, alc5630->client); ++ i2s_alc5630_write(0x02, 0x0000, alc5630->client); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,alc5630->client)|0x0440 , alc5630->client); ++ //printk("External speaker is pulled ... and Try to unmute internal speaker......\n"); ++ //i2s_alc5630_read_test(alc5630->client); ++ } ++ //ftsdc_enable_irq(host, false); ++ ++ ++ //ftsdc_enable_irq(host, true); ++} ++ ++static int alc5630_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) ++{ ++ ++ struct alc5630_data *alc5630; ++ struct i2c_adapter *adap = client->adapter; ++ //unsigned char ret1, ret2; ++ struct i2c_msg msg; ++ char rbuf[3], wbuf[3]; ++ int ret, i2c_rvalue, i2c_wvalue; ++ unsigned int gpio2_value; ++ char data[3]; ++ ++ //i2c_dbg( 1, "alc5630_i2c_probe() is called.\n"); ++ //printk(">>>>>>>>>> (3) alc5630_i2c_probe() is called.\n"); ++ ++ alc5630 = kzalloc(sizeof(struct alc5630_data), GFP_KERNEL); ++ ++ if (!alc5630) ++ return -ENOMEM; ++ ++ mutex_init(&alc5630->mtx); ++ client-> flags = 0; ++ alc5630->client = client; ++ i2c_set_clientdata(client, alc5630); ++ ++ //ADD by river 2011.05.18 for GPIO2 interrupt => edge trigger and rising edge ++ REG32(GPIO_VA_BASE + 0x20) = 0x00000000; ++ REG32(GPIO_VA_BASE + 0x2c) = 0x00000000; ++ REG32(GPIO_VA_BASE + 0x2c) = 0x00000000; ++ REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; ++ REG32(GPIO_VA_BASE + 0x38) = 0x0000FFFF; ++ REG32(GPIO_VA_BASE + 0x40) = 0x0000FFFF; ++ ++ ++ REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(1 << 2); //GPIO2 as input ++ REG32(GPIO_VA_BASE + 0x34) = REG32(GPIO_VA_BASE + 0x34) & ~(1 << 2); //GPIO2 edge trigger ++ //REG32(GPIO_VA_BASE + 0x38) = REG32(GPIO_VA_BASE + 0x38) & ~(1 << 2); //GPIO2 single edge ++ REG32(GPIO_VA_BASE + 0x38) = REG32(GPIO_VA_BASE + 0x38) | (1 << 2); //GPIO2 both edge ++ REG32(GPIO_VA_BASE + 0x3c) = REG32(GPIO_VA_BASE + 0x3c) & ~(1 << 2); //GPIO2 rising edge ++ REG32(GPIO_VA_BASE + 0x20) = REG32(GPIO_VA_BASE + 0x20) | (1 << 2); //GPIO2 pin interrupt enable ++ ++ REG32(AMIC_VA_BASE + 0x20) = REG32(AMIC_VA_BASE + 0x20) | (1 << 13); //Interrupt Trigger Mode (edge trigger) ++ REG32(AMIC_VA_BASE + 0x24) = REG32(AMIC_VA_BASE + 0x24) & ~(1 << 13); //Interrupt Trigger edge(rising edge) ++ REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) | (1 << 13); //GPIO interrupt enabled ++ //REG32(AMIC_VA_BASE + 0x80) = 0; //GPIO interrupt enabled ++ ++ if (request_irq(GPIO_FTGPIO010_IRQ, gpio2_irq, IRQF_SHARED, "gpio2", client)) { ++ printk("Failed to request GPIO2 interrupt.\n"); ++ goto fail; ++ } ++ ++ //ADD by river 2011.07.11 ++ //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 3); //Set gpio3 direction => input ++ gpio2_value = (REG32(GPIO_VA_BASE + 0x04) >> 2 & 1); ++ //printk("The gpio2 value is 0x%08x\n",gpio2_value); ++ alc5630->gpio2_value = gpio2_value; ++ ++ if (gpio2_value==0x0) { ++ i2s_alc5630_write(0x02, 0x5F5F, alc5630->client); ++ i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,alc5630->client) & 0xFBFF) | 0x0040 , alc5630->client); ++ //printk("@@@@@ alc5630_i2c_probe : External speaker is plugged in... and Try to mute internal speaker......\n"); ++ //i2s_alc5630_read_test(alc5630->client); ++ } ++ else { ++ i2s_alc5630_write(0x02, 0x0000, alc5630->client); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,alc5630->client)|0x0440 , alc5630->client); ++ //printk("@@@@@ alc5630_i2c_probe : External speaker is pulled ... and Try to unmute internal speaker......\n"); ++ //i2s_alc5630_read_test(alc5630->client); ++ } ++ ++ //End ADD by river 2011.07.11 ++ ++ //ADD by river 2011.06.02 ++ INIT_DELAYED_WORK(&alc5630->work, iic_work); ++ //End ADD by river 2011.06.02 ++ //End ADD by river 2011.05.18 ++ ++ ftssp_alsa_init(client); ++ ++ return 0; ++ fail: ++ mutex_destroy(&alc5630->mtx); ++ kfree(alc5630); ++ return -EINVAL; ++ ++} ++ ++////////End ADD by river 2011.01.26 ++#endif ++ ++/* --------------------------------------------------------------------------- ++ * Preserved size of memory space for audio DMA ring ++ */ ++#define FTSSP_HW_DMA_SIZE (512 * 1024) ++ ++/* Buffer sizes reported to ALSA layer - AC97 mode */ ++ ++/* ring size, exported to application */ ++#define AC97_HW_BUFFER_BYTES_MAX (42 * 1024) ++/* should not exceed AC97_HW_PERIOD_BYTES_MAX */ ++#define AC97_HW_PERIOD_BYTES_MIN (2 * 1024) ++/* AC97_HW_PERIOD_BYTES_MAX * AC97_HW_PERIODS_MAX <= AC97_HW_BUFFER_SIZE */ ++#define AC97_HW_PERIOD_BYTES_MAX (8 * 1024) ++/* 3 <= AC97_HW_PERIODS_MIN <= AC97_HW_PERIODS_MAX */ ++#define AC97_HW_PERIODS_MIN 3 ++/* AC97_HW_PERIOD_BYTES_MAX * AC97_HW_PERIODS_MAX <= AC97_HW_BUFFER_SIZE */ ++#define AC97_HW_PERIODS_MAX 5 ++ ++/* Driver internal dma buffer size, x2 for S16_LE(16-bits) to AC97 (20-bits), ++ * x6 for sampling rate converion from minimum 8k to AC97 48k. ++ * ++ * Note that AC97 mode cannot do playback and recording simultaneouly. So we ++ * use up all FTSSP_HW_DMA_SIZE of memory. ++ */ ++#define AC97_HW_DMA_SIZE (AC97_HW_BUFFER_BYTES_MAX * 2 * 6) ++ ++/* Buffer sizes reported to ALSA layer - I2S mode */ ++ ++/* ring size, exported to application */ ++#define I2S_HW_BUFFER_BYTES_MAX (256 * 1024) ++/* should not exceed I2S_HW_PERIOD_BYTES_MAX */ ++#define I2S_HW_PERIOD_BYTES_MIN (2 * 1024) ++/* I2S_HW_PERIOD_BYTES_MAX * I2S_HW_PERIODS_MAX <= I2S_HW_BUFFER_SIZE */ ++#define I2S_HW_PERIOD_BYTES_MAX (32 * 1024) ++/* 3 <= I2S_HW_PERIODS_MIN <= I2S_HW_PERIODS_MAX */ ++#define I2S_HW_PERIODS_MIN 3 ++/* I2S_HW_PERIOD_BYTES_MAX * I2S_HW_PERIODS_MAX <= I2S_HW_BUFFER_SIZE */ ++#define I2S_HW_PERIODS_MAX 8 ++ ++/* Page-in size for playback and capture each. Note that I2S mode can do ++ * playback and recording simultaneouly, so this size should be less than or ++ * equal to FTSSP_HW_DMA_SIZE/2 ++ */ ++#define I2S_HW_DMA_SIZE (I2S_HW_BUFFER_BYTES_MAX) ++ ++/* --------------------------------------------------------------------------- ++ * Audio formats ++ */ ++#define AC97_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) ++#define AC97_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_48000 | \ ++ SNDRV_PCM_RATE_16000 | \ ++ SNDRV_PCM_RATE_8000) ++#define AC97_CODEC_SAMPLE_RATE_MIN (8000) ++#define AC97_CODEC_SAMPLE_RATE_MAX (48000) ++ ++#define I2S_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) ++#define I2S_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_48000 | \ ++ SNDRV_PCM_RATE_44100 | \ ++ SNDRV_PCM_RATE_32000 | \ ++ SNDRV_PCM_RATE_22050 | \ ++ SNDRV_PCM_RATE_16000 | \ ++ SNDRV_PCM_RATE_11025 | \ ++ SNDRV_PCM_RATE_8000) ++#define I2S_CODEC_SAMPLE_RATE_MIN (8000) ++#define I2S_CODEC_SAMPLE_RATE_MAX (48000) ++ ++ ++/* --------------------------------------------------------------------------- ++ * Configuration ++ */ ++#if (CONFIG_PROC_FS == 0) ++#undef FTSSP_PROC_FS ++#define FTSSP_PROC_FS 0 ++#else ++#if (FTSSP_PROC_FS) ++#include ++#endif /* FTSSP_PROC_FS */ ++#endif /* CONFIG_PROC_FS */ ++ ++#define FTSSP_CARD_ID "ftssp010" ++#define FTSSP_DRIVER_NAME "ftssp" ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Faraday Technology Corp."); ++MODULE_DESCRIPTION("FTSSP010 Linux 2.6 Driver"); ++ ++static int cardno = 0; ++//static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = ++// { SSP_FTSSP010_PA_BASE }; ++ ++/* Driver mode */ ++#ifdef CONFIG_SND_FTSSP010_AC97 ++static int ac97 = 1; ++#else ++static int ac97 = 0; ++#endif ++ ++// ---------------------------------------------- ++module_param(cardno, int, 0); ++MODULE_PARM_DESC(cardno, "FTSSP No."); ++ ++module_param(ac97, int, 0); ++MODULE_PARM_DESC(ac97, "AC97 mode"); ++// ---------------------------------------------- ++ ++/* --------------------------------------------------------------------------- ++ * Structures ++ */ ++ ++/* private data for card */ ++typedef struct { ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ struct snd_pcm_substream *substream_tx; ++ struct snd_pcm_substream *substream_rx; ++#if (FTSSP_PROC_FS) ++ struct snd_info_entry *info_buf_max; ++ struct snd_info_entry *info_period_min; ++ struct snd_info_entry *info_period_max; ++ struct snd_info_entry *info_periods_min; ++ struct snd_info_entry *info_periods_max; ++#endif ++} ftssp_chip; ++ ++/* dma request descriptors */ ++dmad_chreq dma_chreq_tx = { ++ .channel = -1, ++ .drq = NULL, ++}; ++ ++dmad_chreq dma_chreq_rx = { ++ .channel = -1, ++ .drq = NULL, ++}; ++ ++/* Holds ALSA card instance pointers */ ++struct snd_card *ftssp_cards[SSP_FTSSP010_COUNT]; ++ ++/* snd_pcm_hardware */ ++static struct snd_pcm_hardware snd_ftssp_pcm_hw = ++{ ++ .info = SNDRV_PCM_INFO_INTERLEAVED, ++ .formats = I2S_CODEC_FORMATS, ++ .rates = I2S_CODEC_SAMPLE_RATES, ++ .rate_min = I2S_CODEC_SAMPLE_RATE_MIN, ++ .rate_max = I2S_CODEC_SAMPLE_RATE_MAX, ++ .channels_min = 1, ++ .channels_max = 2, ++ .buffer_bytes_max = I2S_HW_BUFFER_BYTES_MAX, ++ .period_bytes_min = I2S_HW_PERIOD_BYTES_MIN, ++ .period_bytes_max = I2S_HW_PERIOD_BYTES_MAX, ++ .periods_min = I2S_HW_PERIODS_MIN, ++ .periods_max = I2S_HW_PERIODS_MAX, ++}; ++ ++/* private data for a substream (playback or capture) */ ++/* function pointer for set up AHBDMA for this substream */ ++typedef void (*start_t)(int cardno, unsigned use_dma); ++typedef void (*pmu_set_clocking_t)(unsigned int); ++typedef void (*ftssp010_config_t)(int cardno, unsigned is_stereo, ++ unsigned speed, int use8bit); ++ ++typedef struct { ++ u32 busy; ++ spinlock_t dma_lock; ++ unsigned dma_area_va; ++ int dma_width; ++ unsigned int tx_period; ++ unsigned int rx_period; ++ ++ start_t start; ++ pmu_set_clocking_t pmu_set_clocking; ++ ftssp010_config_t hw_config; ++} ftssp_substream; ++ ++static ftssp_substream ftssp010_substreams[2] = { ++ /* Playback substream */ ++ { ++ busy : 0, ++ start : ftssp010_start_tx, ++ pmu_set_clocking : pmu_set_i2s_clocking, ++ hw_config : ftssp010_config_tx, ++ }, ++ /* Capture substream */ ++ { ++ busy : 0, ++ start : ftssp010_start_rx, ++ pmu_set_clocking : pmu_set_i2s_clocking, ++ hw_config : ftssp010_config_rx, ++ } ++}; ++ ++/* (AC97 only) Convert 16 bits PCM data in user buffer to/from 20 bits PCM data ++ * (32 bits actaully in dma buffer) for AC97 codec. ++ */ ++static int snd_ftssp_playback_copy(struct snd_pcm_substream *substream, ++ int channel, snd_pcm_uframes_t pos, void *usr_buf, ++ snd_pcm_uframes_t count) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *) runtime->private_data; ++ ++ ++ //printk("~~~~~ : snd_ftssp_playback_copy() is invoked....\n"); ++ u32 *dma_va = NULL; ++ u16 *usr_va = usr_buf; ++ int copy_words; ++ int pcm_data; ++ ++ dmad_chreq *dma_chreq; ++ ++ /* frames_to_bytes(runtime, pos + count) * 2(bytes/per pcm) / ++ * 4(bytes per dma unit) */ ++ u32 sw_ptr = (u32)frames_to_bytes(runtime, pos + count) >> 1; ++ ++ switch (runtime->rate) { ++ case 8000: ++ sw_ptr *= 6; ++ ++ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + ++ frames_to_bytes(runtime, pos * 6) * 2); ++ ++ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", ++ __func__, (u32)pos, (u32)count, (u32)(pos + count)); ++ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", ++ __func__, (u32)ftssp010_substream->dma_area_va, ++ (u32)dma_va, ++ (u32)dma_va + ++ (u32)2 * frames_to_bytes(runtime, count * 6)); ++ ++ if (runtime->channels == 1) { ++ while (count--) { ++ dma_va[0] = (u32)(*usr_va++) << 4; ++ dma_va[1] = dma_va[2] = dma_va[3] = ++ dma_va[4] = dma_va[5] = dma_va[0]; ++ //memcpy(&dma_va[1], &dma_va[0], 5 * 4 * 1); ++ dma_va += 6; ++ } ++ } else { // assume 2 channels ++ while (count--) { ++ dma_va[0] = (u32)(*usr_va++) << 4; ++ dma_va[1] = (u32)(*usr_va++) << 4; ++ dma_va[2] = dma_va[4] = dma_va[6] = ++ dma_va[8] = dma_va[10] = dma_va[0]; ++ dma_va[3] = dma_va[5] = dma_va[7] = ++ dma_va[9] = dma_va[11] = dma_va[0]; ++ //memcpy(&dma_va[2], &dma_va[0], 5 * 4 * 2); ++ dma_va += 12; ++ } ++ } ++ break; ++ case 16000: ++ sw_ptr *= 3; ++ ++ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + ++ frames_to_bytes(runtime, pos * 3) * 2); ++ ++ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", ++ __func__, (u32)pos, (u32)count, (u32)(pos + count)); ++ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", ++ __func__, (u32)ftssp010_substream->dma_area_va, ++ (u32)dma_va, ++ (u32)dma_va + ++ (u32)2 * frames_to_bytes(runtime, count * 3)); ++ ++ if (runtime->channels == 1) { ++ while (count--) { ++ dma_va[0] = (u32)(*usr_va++) << 4; ++ dma_va[1] = dma_va[2] = dma_va[0]; ++ //memcpy(&dma_va[1], &dma_va[0], 2 * 4 * 1); ++ dma_va += 3; ++ } ++ } else { // assume 2 channels ++ while (count--) { ++ dma_va[0] = (u32)(*usr_va++) << 4; ++ dma_va[1] = (u32)(*usr_va++) << 4; ++ dma_va[2] = dma_va[4] = dma_va[0]; ++ dma_va[3] = dma_va[5] = dma_va[1]; ++ //memcpy(&dma_va[2], &dma_va[0], 2 * 4 * 2); ++ dma_va += 6; ++ } ++ } ++ break; ++ case 48000: ++ default: ++ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + ++ frames_to_bytes(runtime, pos) * 2); ++ copy_words = 2 * frames_to_bytes(runtime, count) / sizeof(u32); ++ ++ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", ++ __func__, (u32)pos, (u32)count, (u32)(pos + count)); ++ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", ++ __func__, (u32)ftssp010_substream->dma_area_va, ++ (u32)dma_va, ++ (u32)dma_va + (u32)copy_words*4); ++ ++ while (copy_words--) { ++ pcm_data = (*usr_va++); ++ *dma_va++= pcm_data << 4; ++ } ++ break; ++ } ++ ++ dma_chreq = &dma_chreq_tx; ++ ++ if (dmad_update_ring_sw_ptr(dma_chreq, sw_ptr, ++ (runtime->status->state == SNDRV_PCM_STATE_RUNNING) ? 1:0) != 0) ++ { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++static int snd_ftssp_capture_copy(struct snd_pcm_substream *substream, ++ int channel, snd_pcm_uframes_t pos, void *usr_buf, ++ snd_pcm_uframes_t count) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *) runtime->private_data; ++ ++ //printk("~~~~~ : snd_ftssp_capture_copy() is invoked....\n"); ++ //printk(">>>>>>>>>> : snd_ftssp_capture_copy() for recording....\n"); ++ u32 *dma_va = NULL; ++ u16 *usr_va = usr_buf; ++ ++ switch (runtime->rate) { ++ case 8000: ++ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + ++ frames_to_bytes(runtime, pos * 6) * 2); ++ ++ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", ++ __func__, (u32)pos, (u32)count, (u32)(pos + count)); ++ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", ++ __func__, (u32)ftssp010_substream->dma_area_va, ++ (u32)dma_va, ++ (u32)dma_va + ++ (u32)2 * frames_to_bytes(runtime, count * 6)); ++ ++ if (runtime->channels == 1) { ++ while (count--) { ++ *usr_va++ = (u16)(dma_va[0] >> 4); ++ dma_va += 6; ++ } ++ } else { ++ while (count--) { ++ usr_va[0] = (u16)(dma_va[0] >> 4); ++ ++ /* [hw-limit] only slot-3 has valid data in ++ * recording mode -- check TAG_DATA_MONO ++ * defined in "FTSSP010_lib.c". Mask out ++ * one channel to avoid hi-freq noise. ++ */ ++ usr_va[1] = usr_va[0]; ++ usr_va += 2; ++ dma_va += 12; ++ } ++ } ++ break; ++ case 16000: ++ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + ++ frames_to_bytes(runtime, pos * 3) * 2); ++ ++ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", ++ __func__, (u32)pos, (u32)count, (u32)(pos + count)); ++ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", ++ __func__, (u32)ftssp010_substream->dma_area_va, ++ (u32)dma_va, ++ (u32)dma_va + ++ (u32)2 * frames_to_bytes(runtime, count * 3)); ++ ++ if (runtime->channels == 1) { ++ while (count--) { ++ *usr_va++ = (u16)(dma_va[0] >> 4); ++ dma_va += 3; ++ } ++ } else { ++ while (count--) { ++ usr_va[0] = (u16)(dma_va[0] >> 4); ++ ++ /* [hw-limit] only slot-3 has valid data in ++ * recording mode -- check TAG_DATA_MONO ++ * defined in "FTSSP010_lib.c". Mask out ++ * one channel to avoid hi-freq noise. ++ */ ++ usr_va[1] = usr_va[0]; ++ usr_va += 2; ++ dma_va += 6; ++ } ++ } ++ break; ++ case 48000: ++ default: ++ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + ++ frames_to_bytes(runtime, pos) * 2); ++ ++ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", ++ __func__, (u32)pos, (u32)count, (u32)(pos + count)); ++ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", ++ __func__, (u32)ftssp010_substream->dma_area_va, ++ (u32)dma_va, ++ (u32)dma_va + ++ (u32)2 * frames_to_bytes(runtime, count)); ++ ++ if (runtime->channels == 1) { ++ while (count--) { ++ *usr_va++ = (u16)(*dma_va++ >> 4); ++ } ++ } else { ++ while (count--) { ++ usr_va[0] = (u16)(dma_va[0] >> 4); ++ ++ /* [hw-limit] only slot-3 has valid data in ++ * recording mode -- check TAG_DATA_MONO ++ * defined in "FTSSP010_lib.c". Mask out ++ * one channel to avoid hi-freq noise. ++ */ ++ usr_va[1] = usr_va[0]; ++ usr_va += 2; ++ dma_va += 2; ++ } ++ } ++ break; ++ } ++ ++ return 0; ++} ++ ++/** ++ * These dma callbacks are called in interrupt context. ++ * @data: pointer to the chip-wide structure. ++ * TODO: use stream-specifc data ++ */ ++__attribute__((__unused__)) ++static void ftssp_dma_callback_tx(int ch, u16 int_status, void *data) ++{ ++ ftssp_chip *chip = (ftssp_chip *)data; ++ ++ //printk("~~~~~ : ftssp_dma_callback_tx() is invoked....\n"); ++ if (!ac97) { ++ /* in i2s mode, no indication to driver for user data length. ++ * For simplicity, just go ahead by one period */ ++ ++ struct snd_pcm_runtime *runtime = chip->substream_tx->runtime; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)runtime->private_data; ++ u32 sw_ptr; ++ u32 tx_period = ftssp010_substream->tx_period + 1; ++ ++ if (tx_period == runtime->periods) ++ sw_ptr = runtime->buffer_size; ++ else ++ sw_ptr = tx_period * runtime->period_size; ++ ++ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; ++ ++ if (dmad_update_ring_sw_ptr(&dma_chreq_tx, (u32)sw_ptr, 0)) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ } ++ ++ ftssp010_substream->tx_period = tx_period % runtime->periods; ++ } ++ ++ snd_pcm_period_elapsed(chip->substream_tx); ++} ++ ++__attribute__((__unused__)) ++static void ftssp_dma_callback_rx(int ch, u16 int_status, void *data) ++{ ++ ftssp_chip *chip = (ftssp_chip *)data; ++ struct snd_pcm_runtime *runtime = chip->substream_rx->runtime; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)runtime->private_data; ++ ++ //printk("~~~~~ : ftssp_dma_callback_rx() is invoked....\n"); ++ //printk(">>>>>>>>>> : ftssp_dma_callback_rx() for recording....\n"); ++ ++ u32 sw_ptr; ++ u32 rx_period = ftssp010_substream->rx_period + 1; ++ ++ if (rx_period == runtime->periods) ++ sw_ptr = runtime->buffer_size; ++ else ++ sw_ptr = rx_period * runtime->period_size; ++ ++ if (ac97) { ++ switch (runtime->rate) { ++ case 8000: ++ sw_ptr = sw_ptr * 6; ++ break; ++ case 16000: ++ sw_ptr = sw_ptr * 3; ++ break; ++ case 48000: ++ default: ++ break; ++ } ++ } ++ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; ++ ++ if (dmad_update_ring_sw_ptr(&dma_chreq_rx, (u32)sw_ptr, 0) != 0) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ } ++ ++ ftssp010_substream->rx_period = rx_period % runtime->periods; ++ ++ snd_pcm_period_elapsed(chip->substream_rx); ++} ++ ++static inline int snd_ftssp_dma_ch_alloc(struct snd_pcm_substream *substream) ++{ ++ dmad_chreq *ch_req __attribute__((__unused__)) = 0; ++ ++ //printk("~~~~~ WATCH : snd_ftssp_dma_ch_alloc() is invoked....\n"); ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ ch_req = &dma_chreq_tx; ++ ch_req->completion_cb = ftssp_dma_callback_tx; ++ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; ++ /*for amerald ac97 ssp2 */ ++ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) ++ { ++ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX_AMERALD; ++ } ++ else ++ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX; ++ } else { ++ ch_req = &dma_chreq_rx; ++ ch_req->completion_cb = ftssp_dma_callback_rx; ++ ch_req->apb_req.tx_dir = DMAD_DIR_A1_TO_A0; ++ /*for amerald ac97 ssp2 */ ++ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) ++ { ++ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX_AMERALD; ++ } ++ else ++ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX; ++ } ++ ++ ch_req->controller = DMAD_DMAC_APB_CORE; ++ ch_req->flags = DMAD_FLAGS_RING_MODE; ++ ch_req->ring_base = 0; ++ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); ++ ch_req->periods = 0; ++ ch_req->period_size = 0; ++ ++ if (ac97) { ++ ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I4X; ++ ch_req->apb_req.ring_reqn = APBBR_REQN_NONE; ++ ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED; ++ ch_req->apb_req.burst_mode = 0; ++ ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; ++ } else { ++ ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I2X; ++ ch_req->apb_req.ring_reqn = APBBR_REQN_NONE; ++ ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED; ++ ch_req->apb_req.burst_mode = 0; ++ ch_req->apb_req.data_width = APBBR_DATAWIDTH_2; ++ } ++ ++ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ ERR("%s: APBDMA channel allocation failed\n",__func__); ++ goto _try_ahb; ++ } ++ ++ DBG("%s: APBDMA channel allocated (ch: %d) ring_mode\n", ++ __func__, ch_req->channel); ++ ++ return 0; ++ ++_try_ahb: ++ ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ ch_req = &dma_chreq_tx; ++ ch_req->completion_cb = ftssp_dma_callback_tx; ++ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; ++ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) ++ { ++ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX_AMERALD; ++ } ++ else ++ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX; ++ } else { ++ ch_req = &dma_chreq_rx; ++ ch_req->completion_cb = ftssp_dma_callback_rx; ++ ch_req->ahb_req.tx_dir = DMAD_DIR_A1_TO_A0; ++ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) ++ { ++ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX_AMERALD; ++ } ++ else ++ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX; ++ } ++ ++ ch_req->controller = DMAD_DMAC_AHB_CORE; ++ ch_req->flags = DMAD_FLAGS_RING_MODE; ++ ch_req->ring_base = 0; ++ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); ++ ch_req->periods = 0; ++ ch_req->period_size = 0; ++ ++ ch_req->ahb_req.sync = 1; ++ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_2; ++ ch_req->ahb_req.hw_handshake = 1; ++ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_1; ++ ++ if (ac97) { ++ ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_32; ++ ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC; ++ ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE; ++ ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_32; ++ ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX; ++ } else { ++ ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_16; ++ ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC; ++ ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE; ++ ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_16; ++ ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX; ++ } ++ ++ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ ERR("%s: AHBDMA channel allocation failed\n", __func__); ++ goto _err_exit; ++ } ++ ++ DBG("%s: AHBDMA channel allocated (ch: %d) ring_mode\n", ++ __func__, ch_req->channel); ++ ++ return 0; ++ ++_err_exit: ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++ return -ENODEV; ++} ++ ++static inline ftssp_substream *ftssp010_substream_new(int stream_id) ++{ ++ ftssp_substream *s = NULL; ++ ++ //printk("~~~~~ : ftssp010_substream_new() is invoked....\n"); ++ ++ switch (stream_id) { ++ case SNDRV_PCM_STREAM_PLAYBACK: ++ s = &ftssp010_substreams[0]; ++ break; ++ case SNDRV_PCM_STREAM_CAPTURE: ++ s = &ftssp010_substreams[1]; ++ break; ++ default: ++ ERR("%s: wrong stream type (%d)\n", __func__, stream_id); ++ return NULL; ++ } ++ ++ if (s->busy) { ++ ERR("%s: device busy!\n", __func__); ++ return NULL; ++ } ++ s->busy = 1; ++ ++ spin_lock_init(&s->dma_lock); ++ ++ return s; ++} ++ ++static int snd_ftssp_pcm_open(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ int stream_id = substream->pstr->stream; ++ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ //printk("~~~~~ : snd_ftssp_pcm_open() is invoked....\n"); ++ ++ /* Both playback and capture share a hardware description */ ++ runtime->hw = snd_ftssp_pcm_hw; ++ ++ /* Allocate & Initialize stream-specific data */ ++ runtime->private_data = ftssp010_substream_new(stream_id); ++ ++ if (runtime->private_data) { ++ //printk("~~~~~ YAYAYA @@@@@ : Calling snd_ftssp_dma_ch_alloc().\n"); ++ return snd_ftssp_dma_ch_alloc(substream); ++ } ++ else ++ return -EBUSY; ++} ++ ++static int snd_ftssp_pcm_close(struct snd_pcm_substream *substream) ++{ ++ int stream_id = substream->pstr->stream; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)substream->runtime->private_data; ++ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ //printk("~~~~~ : snd_ftssp_pcm_close() is invoked....\n"); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ++ dmad_channel_free(&dma_chreq_tx); ++ else ++ dmad_channel_free(&dma_chreq_rx); ++ ++ ftssp010_substream->busy = 0; ++ return 0; ++} ++ ++static int snd_ftssp_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *hw_params) ++{ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ //printk("~~~~~ : snd_ftssp_pcm_hw_params() is invoked....\n"); ++ ++ if (ac97) ++ return snd_pcm_lib_malloc_pages(substream, AC97_HW_DMA_SIZE); ++ else ++ return snd_pcm_lib_malloc_pages(substream, I2S_HW_DMA_SIZE); ++} ++ ++static int snd_ftssp_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ //printk("~~~~~ : snd_ftssp_pcm_hw_free() is invoked....\n"); ++ ++ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ dmad_drain_requests(&dma_chreq_tx, 1); ++ else ++ dmad_drain_requests(&dma_chreq_rx, 1); ++ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++/* Prepare FTSSP010 AHBDMA for playback & capture */ ++static int snd_ftssp_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ ftssp_chip *chip = snd_pcm_substream_chip(substream); ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ ++ //printk("~~~~~ : snd_ftssp_pcm_prepare() is invoked....\n"); ++ //printk("@@@@@ >>>>> : snd_ftssp_pcm_prepare() is called.\n"); ++ ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)runtime->private_data; ++ ++ int stream_id = substream->pstr->stream; ++ dmad_chreq *dma_chreq; ++ unsigned period_size, buffer_size; ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ++ dma_chreq = &dma_chreq_tx; ++ else ++ dma_chreq = &dma_chreq_rx; ++ ++ period_size = frames_to_bytes(runtime, runtime->period_size); ++ buffer_size = frames_to_bytes(runtime, runtime->buffer_size); ++ ++ if (runtime->format != SNDRV_PCM_FORMAT_S16_LE) ++ return -ENODEV; ++ ++ if (ac97) { ++ switch (runtime->rate) { ++ case 8000: ++ period_size *= 12; ++ buffer_size *= 12; ++ break; ++ case 16000: ++ period_size *= 6; ++ buffer_size *= 6; ++ break; ++ case 48000: ++ default: ++ period_size *= 2; ++ buffer_size *= 2; ++ break; ++ } ++ ++ ftssp010_substream->dma_width = 4; ++ } else { ++ ftssp010_substream->dma_width = 2; ++ } ++ ++ dmad_drain_requests(dma_chreq, 1); ++ ++ dma_chreq->ring_base = (dma_addr_t)runtime->dma_addr; ++ dma_chreq->periods = (dma_addr_t)runtime->periods; ++ if (ac97) { ++ dma_chreq->period_size = (dma_addr_t)(period_size >> 2); ++ dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 2); ++ } else { ++ dma_chreq->period_size = (dma_addr_t)(period_size >> 1); ++ dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 1); ++ } ++ dmad_update_ring(dma_chreq); ++ ++ /* Set PMU, FTSSP010, and DMA */ ++ spin_lock(&ftssp010_substream->dma_lock); ++ ++ /* keep DMA buffer VA for copy() callback */ ++ // todo: support playback/capture simultaneously ++ ftssp010_substream->dma_area_va = (u32)runtime->dma_area; ++ ++ if (ac97) { ++ ftssp010_substream->pmu_set_clocking(48000); ++ ftssp010_substream->hw_config(cardno, ++ runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */ ++ 48000, ftssp010_substream->dma_width); ++ } else { ++ ++ ftssp010_substream->pmu_set_clocking(runtime->rate); ++ ftssp010_substream->hw_config(cardno, ++ runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */ ++ runtime->rate, ftssp010_substream->dma_width); ++ } ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ ftssp010_substream->tx_period = 0; ++ chip->substream_tx = substream; ++ } else { ++ ftssp010_substream->rx_period = 0; ++ chip->substream_rx = substream; ++ } ++ ++ spin_unlock(&ftssp010_substream->dma_lock); ++ ++ VVDBG("%s <<\n", __func__); ++ ++ return 0; ++} ++ ++static inline int snd_ftssp_start_play(ftssp_substream *ftssp010_substream, ++ struct snd_pcm_runtime *runtime) ++{ ++ int err = 0; ++ ++ //printk("~~~~~ : snd_ftssp_start_play() is invoked....\n"); ++ ++ if (ac97) { ++ /* in ac97 mode, user data was fed to dma buffer through ++ * driver-provided copy callback */ ++ err = dmad_kickoff_requests(&dma_chreq_tx); ++ if (err != 0) { ++ ERR("%s: failed to kickoff dma!\n", __func__); ++ return err; ++ } ++ } else { ++ /* in i2s mode, no indication to driver for user data length ++ * (except start threshold). For simplicity at start, just go ++ * ahead by one cycle */ ++ ++ u32 sw_ptr = ++ (u32)frames_to_bytes(runtime, runtime->buffer_size) >>1; ++ ++ err = dmad_update_ring_sw_ptr(&dma_chreq_tx, sw_ptr, 0); ++ if (err != 0) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ return err; ++ } ++ ++ err = dmad_kickoff_requests(&dma_chreq_tx); ++ if (err != 0) { ++ ERR("%s: failed to kickoff dma!\n", __func__); ++ return err; ++ } ++ } ++ ++ ftssp010_substream->start(cardno, 1); ++ ++ //ADD by river 2011.03.08 ++ //i2s_alc5630_write(0x02, 0x0000, g_i2c_client); ++ //i2s_alc5630_write(0x04, 0x0000, g_i2c_client); ++ //i2s_alc5630_write(0x0c, 0x1010, g_i2c_client); ++ //i2s_alc5630_write(0x10, 0xff03, g_i2c_client); ++ //End ADD by river 2011.03.08 ++ ++ return 0; ++} ++ ++static inline int snd_ftssp_start_record(ftssp_substream *ftssp010_substream, ++ struct snd_pcm_runtime *runtime) ++{ ++ int err = 0; ++ ++ //printk("~~~~~ : snd_ftssp_start_record() is invoked....\n"); ++ ++ u32 sw_ptr = (u32)frames_to_bytes(runtime, runtime->buffer_size); ++ ++ if (ac97) { ++ switch (runtime->rate) { ++ case 8000: ++ sw_ptr = (sw_ptr * 3); ++ break; ++ case 16000: ++ sw_ptr = (sw_ptr * 3) >> 1; ++ break; ++ case 48000: ++ default: ++ sw_ptr = sw_ptr >> 1; ++ break; ++ } ++ } else { ++ ++ //printk(">>>>>>>>>> : snd_ftssp_start_record() for recording....\n"); ++ sw_ptr = sw_ptr >> 1; ++ } ++ ++ err = dmad_update_ring_sw_ptr(&dma_chreq_rx, sw_ptr, 0); ++ if (err != 0) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ return err; ++ } ++ ++ err = dmad_kickoff_requests(&dma_chreq_rx); ++ if (err != 0) { ++ ERR("%s: failed to kickoff dma!\n", __func__); ++ return err; ++ } ++ ++ ftssp010_substream->start(cardno, 1); ++ ++ return 0; ++} ++ ++/* Triggers AHBDMA for playback & capture */ ++static int snd_ftssp_pcm_trigger(struct snd_pcm_substream * substream, int cmd) ++{ ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)substream->runtime->private_data; ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ int err = 0; ++ int stream_id = substream->pstr->stream; ++ ++ //printk("~~~~~ : snd_ftssp_pcm_trigger() is invoked....\n"); ++ ++ /* note local interrupts are already disabled in the midlevel code */ ++ spin_lock(&ftssp010_substream->dma_lock); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ ++ VDBG("%s: SNDRV_PCM_TRIGGER_START state(0x%08x)\n", ++ __func__, (u32)runtime->status->state); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ err = snd_ftssp_start_play(ftssp010_substream, runtime); ++ } else { ++ err = snd_ftssp_start_record(ftssp010_substream, ++ runtime); ++ } ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ ++ VDBG("%s: SNDRV_PCM_TRIGGER_STOP state(0x%08x)\n", ++ __func__, (u32)substream->runtime->status->state); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ ftssp010_stop_tx(cardno); ++ dmad_drain_requests(&dma_chreq_tx, 1); ++ } else { ++ ftssp010_stop_rx(cardno); ++ dmad_drain_requests(&dma_chreq_rx, 1); ++ } ++ break; ++ default: ++ err = -EINVAL; ++ break; ++ } ++ ++ spin_unlock(&ftssp010_substream->dma_lock); ++ return err; ++} ++ ++// pcm middle-layer call this function within irq (snd_pcm_period_elapsed) or ++// with local irq disabled (snd_pcm_lib_write1) ++static snd_pcm_uframes_t snd_ftssp_pcm_pointer( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ u32 hw_ptr; ++ snd_pcm_uframes_t ret; ++ int stream_id = substream->pstr->stream; ++ ++ //printk("~~~~~ : snd_ftssp_pcm_pointer() is invoked....\n"); ++ ++ ++ /* Fetch DMA pointer, with spin lock */ ++ //spin_lock_irqsave(&ftssp010_substream->dma_lock, flags); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_tx); ++ } else { ++ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_rx); ++ } ++ ++ //spin_unlock_irqrestore(&ftssp010_substream->dma_lock, flags); ++ ++ if (ac97) { ++ ret = bytes_to_frames(runtime, hw_ptr << 1); ++ ++ switch (runtime->rate) { ++ case 8000: ++ ret = ret / 6; ++ break; ++ case 16000: ++ ret = ret / 3; ++ break; ++ case 48000: ++ default: ++ break; ++ } ++ } else { ++ ret = bytes_to_frames(runtime, hw_ptr << 1); ++ } ++ ++ ++ VVDBG("%s: hw_ptr(0x%08x) ret(0x%08x)\n", ++ (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? "p" : "c", ++ (u32)hw_ptr, (u32)ret); ++ ++ /* ALSA requires return value 0 <= ret < buffer_size */ ++ if (ret >= runtime->buffer_size) ++ return 0; ++ return ret; ++} ++ ++/* For FTSSP010 driver, operations are shared among playback & capture */ ++static struct snd_pcm_ops snd_ftssp_playback_ops = { ++ .open = snd_ftssp_pcm_open, ++ .close = snd_ftssp_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = snd_ftssp_pcm_hw_params, ++ .hw_free = snd_ftssp_pcm_hw_free, ++ .prepare = snd_ftssp_pcm_prepare, ++ .trigger = snd_ftssp_pcm_trigger, ++ .pointer = snd_ftssp_pcm_pointer, ++ .copy = NULL, ++}; ++ ++static struct snd_pcm_ops snd_ftssp_capture_ops = { ++ .open = snd_ftssp_pcm_open, ++ .close = snd_ftssp_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = snd_ftssp_pcm_hw_params, ++ .hw_free = snd_ftssp_pcm_hw_free, ++ .prepare = snd_ftssp_pcm_prepare, ++ .trigger = snd_ftssp_pcm_trigger, ++ .pointer = snd_ftssp_pcm_pointer, ++ .copy = NULL, ++}; ++ ++/* ALSA PCM constructor */ ++static int snd_ftssp_new_pcm(ftssp_chip *chip) ++{ ++ struct snd_pcm *pcm; ++ int err; ++ ++ //printk("~~~~~ : snd_ftssp_new_pcm() is invoked....\n"); ++ ++ /* PCM device #0 with 1 playback and 1 capture */ ++ if ((err = snd_pcm_new(chip->card, "ftssp_pcm", 0, 1, 1, &pcm)) < 0) ++ return err; ++ ++ pcm->private_data = chip; ++ strcpy(pcm->name, "ftssp_pcm device"); ++ chip->pcm = pcm; ++ ++ /* set operators for playback and capture*/ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ &snd_ftssp_playback_ops); ++ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ++ &snd_ftssp_capture_ops); ++ ++ /* Pre-allocate buffer, as suggested by ALSA driver document */ ++ // todo: support playback/capture simultaneously ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, ++ NULL, FTSSP_HW_DMA_SIZE, FTSSP_HW_DMA_SIZE); ++ ++ /* Force half-duplex (on A320D, or AC97 mode) */ ++ if (ac97) ++ pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; ++ ++ return 0; ++} ++ ++#if (FTSSP_PROC_FS) ++static void snd_ftssp_buf_max_read(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.buffer_bytes_max); ++} ++ ++static void snd_ftssp_buf_max_write(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ char tmp[128]; ++ char *ptr_e; ++ u32 val; ++ ++ if (buffer->size == 0) ++ return; ++ ++ memset(tmp, 0, 128); ++ snd_info_get_str(tmp, buffer->buffer, 127); ++ ++ val = simple_strtoul(tmp, &ptr_e, 10); ++ if (*ptr_e == 'k') ++ val *= 1024; ++ else if (*ptr_e == 'm') ++ val *= 1024 * 1024; ++ ++ if (ac97) { ++ if (val > AC97_HW_BUFFER_BYTES_MAX) ++ val = AC97_HW_BUFFER_BYTES_MAX; ++ } else { ++ if (val > I2S_HW_BUFFER_BYTES_MAX) ++ val = I2S_HW_BUFFER_BYTES_MAX; ++ } ++ ++ snd_ftssp_pcm_hw.buffer_bytes_max = (size_t)val; ++} ++ ++static void snd_ftssp_period_min_read(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.period_bytes_min); ++} ++ ++static void snd_ftssp_period_min_write(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ char tmp[128]; ++ char *ptr_e; ++ u32 val; ++ ++ if (buffer->size == 0) ++ return; ++ ++ memset(tmp, 0, 128); ++ snd_info_get_str(tmp, buffer->buffer, 127); ++ ++ val = simple_strtoul(tmp, &ptr_e, 10); ++ if (*ptr_e == 'k') ++ val *= 1024; ++ else if (*ptr_e == 'm') ++ val *= 1024 * 1024; ++ ++ snd_ftssp_pcm_hw.period_bytes_min = (size_t)val; ++ ++ if ((val * snd_ftssp_pcm_hw.periods_max) > ++ snd_ftssp_pcm_hw.buffer_bytes_max) { ++ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " ++ "hw_buffer_size(%d).\n", ++ snd_ftssp_pcm_hw.period_bytes_min, ++ snd_ftssp_pcm_hw.periods_max, ++ snd_ftssp_pcm_hw.buffer_bytes_max); ++ INFO(" Unexpected access violation may occur!\n"); ++ } ++} ++ ++static void snd_ftssp_period_max_read(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.period_bytes_max); ++} ++ ++static void snd_ftssp_period_max_write(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ char tmp[128]; ++ char *ptr_e; ++ u32 val; ++ ++ if (buffer->size == 0) ++ return; ++ ++ memset(tmp, 0, 128); ++ snd_info_get_str(tmp, buffer->buffer, 127); ++ ++ val = simple_strtoul(tmp, &ptr_e, 10); ++ if (*ptr_e == 'k') ++ val *= 1024; ++ else if (*ptr_e == 'm') ++ val *= 1024 * 1024; ++ ++ snd_ftssp_pcm_hw.period_bytes_max = (size_t)val; ++ ++ if ((val * snd_ftssp_pcm_hw.periods_max) > ++ snd_ftssp_pcm_hw.buffer_bytes_max) { ++ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " ++ "hw_buffer_size(%d).\n", ++ snd_ftssp_pcm_hw.period_bytes_max, ++ snd_ftssp_pcm_hw.periods_max, ++ snd_ftssp_pcm_hw.buffer_bytes_max); ++ INFO(" Unexpected access violation may occur!\n"); ++ } ++} ++ ++static void snd_ftssp_periods_min_read(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.periods_min); ++} ++ ++static void snd_ftssp_periods_min_write(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ char tmp[128]; ++ char *ptr_e; ++ u32 val; ++ ++ if (buffer->size == 0) ++ return; ++ ++ memset(tmp, 0, 128); ++ snd_info_get_str(tmp, buffer->buffer, 127); ++ ++ val = simple_strtoul(tmp, &ptr_e, 10); ++ if (*ptr_e == 'k') ++ val *= 1024; ++ else if (*ptr_e == 'm') ++ val *= 1024 * 1024; ++ ++ snd_ftssp_pcm_hw.periods_min = (size_t)val; ++ ++ if ((val * snd_ftssp_pcm_hw.period_bytes_max) > ++ snd_ftssp_pcm_hw.buffer_bytes_max) { ++ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " ++ "hw_buffer_size(%d).\n", ++ snd_ftssp_pcm_hw.period_bytes_max, ++ snd_ftssp_pcm_hw.periods_min, ++ snd_ftssp_pcm_hw.buffer_bytes_max); ++ INFO(" Unexpected access violation may occur!\n"); ++ } ++} ++ ++static void snd_ftssp_periods_max_read(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.periods_max); ++} ++ ++static void snd_ftssp_periods_max_write(struct snd_info_entry *entry, ++ struct snd_info_buffer *buffer) ++{ ++ char tmp[128]; ++ char *ptr_e; ++ u32 val; ++ ++ if (buffer->size == 0) ++ return; ++ ++ memset(tmp, 0, 128); ++ snd_info_get_str(tmp, buffer->buffer, 127); ++ ++ val = simple_strtoul(tmp, &ptr_e, 10); ++ if (*ptr_e == 'k') ++ val *= 1024; ++ else if (*ptr_e == 'm') ++ val *= 1024 * 1024; ++ ++ snd_ftssp_pcm_hw.periods_max = (size_t)val; ++ ++ if ((val * snd_ftssp_pcm_hw.period_bytes_max) > ++ snd_ftssp_pcm_hw.buffer_bytes_max) { ++ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " ++ "hw_buffer_size(%d).\n", ++ snd_ftssp_pcm_hw.period_bytes_max, ++ snd_ftssp_pcm_hw.periods_max, ++ snd_ftssp_pcm_hw.buffer_bytes_max); ++ INFO(" Unexpected access violation may occur!\n"); ++ } ++} ++#endif //FTSSP_PROC_FS ++ ++static inline void ftssp_ac97_init(void) ++{ ++ //driver_name = AC97_DRIVER_NAME; ++ //codec_info = AC97_CODEC_NAME; ++ ++ /* Change codec-dependent callbacks to AC97 */ ++ ftssp010_substreams[0].pmu_set_clocking = pmu_set_ac97_clocking; ++ ftssp010_substreams[0].hw_config = ftssp010_config_ac97_play; ++ ftssp010_substreams[1].pmu_set_clocking = pmu_set_ac97_clocking; ++ ftssp010_substreams[1].hw_config = ftssp010_config_ac97_rec; ++ ++ snd_ftssp_playback_ops.copy = snd_ftssp_playback_copy; ++ snd_ftssp_capture_ops.copy = snd_ftssp_capture_copy; ++ ++ snd_ftssp_pcm_hw.rates = AC97_CODEC_SAMPLE_RATES; ++ snd_ftssp_pcm_hw.rate_min = AC97_CODEC_SAMPLE_RATE_MIN; ++ snd_ftssp_pcm_hw.rate_max = AC97_CODEC_SAMPLE_RATE_MAX; ++ snd_ftssp_pcm_hw.formats = AC97_CODEC_FORMATS; ++ snd_ftssp_pcm_hw.buffer_bytes_max = AC97_HW_BUFFER_BYTES_MAX; ++ snd_ftssp_pcm_hw.period_bytes_min = AC97_HW_PERIOD_BYTES_MIN; ++ snd_ftssp_pcm_hw.period_bytes_max = AC97_HW_PERIOD_BYTES_MAX; ++ snd_ftssp_pcm_hw.periods_min = AC97_HW_PERIODS_MIN; ++ snd_ftssp_pcm_hw.periods_max = AC97_HW_PERIODS_MAX; ++} ++ ++static int ftssp_alsa_init(struct i2c_client *client) ++{ ++ ftssp_chip *chip; ++ int err; ++ ++ //ADD by river 2011.03.08 ++ //g_i2c_client = client; ++ //End ADD by river 2011.03.08 ++ //printk(">>>>>>>>> (4) ftssp_alsa_init().\n"); ++ init_hw(cardno, ac97, client); ++ ++ if (ac97) ++ ftssp_ac97_init(); ++ ++ DBG("%s: FTSSP010 #%d (Physical Addr=0x%08X), mode: %s\n", ++ __func__, ++ cardno, SSP_FTSSP010_pa_base[cardno], ++ ac97 ? "ac97" : "i2s"); ++ ++ err = snd_card_create(cardno, FTSSP_CARD_ID, THIS_MODULE, ++ sizeof(ftssp_chip), &ftssp_cards[cardno]); ++ if (err < 0) ++ return err; ++ ++ if (ac97) { ++ sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME); ++ sprintf(ftssp_cards[cardno]->shortname, ++ FTSSP_DRIVER_NAME "_ac97"); ++ sprintf(ftssp_cards[cardno]->longname, ++ FTSSP_DRIVER_NAME "_ac97 controller"); ++ } else { ++ sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME); ++ sprintf(ftssp_cards[cardno]->shortname, ++ FTSSP_DRIVER_NAME "_i2s"); ++ sprintf(ftssp_cards[cardno]->longname, ++ FTSSP_DRIVER_NAME "_i2s controller"); ++ } ++ ++ // PCM ++ chip = (ftssp_chip *)(ftssp_cards[cardno]->private_data); ++ chip->card = ftssp_cards[cardno]; ++ ++ if ((err = snd_ftssp_new_pcm(chip))) { ++ ERR("%s, Can't new PCM devices\n",__func__); ++ return -ENODEV; ++ } ++ ++#if (FTSSP_PROC_FS) ++ // new a proc entries subordinate to card->proc_root for debugging ++ // /proc/card#/buf_max ++ snd_card_proc_new(chip->card, "buf_max", &chip->info_buf_max); ++ if (chip->info_buf_max) { ++ chip->info_buf_max->c.text.read = snd_ftssp_buf_max_read; ++ chip->info_buf_max->c.text.write = snd_ftssp_buf_max_write; ++ } ++ // /proc/card#/period_min ++ snd_card_proc_new(chip->card, "period_size_min", ++ &chip->info_period_min); ++ if (chip->info_period_min) { ++ chip->info_period_min->c.text.read = snd_ftssp_period_min_read; ++ chip->info_period_min->c.text.write = ++ snd_ftssp_period_min_write; ++ } ++ // /proc/card#/period_max ++ snd_card_proc_new(chip->card, "period_size_max", ++ &chip->info_period_max); ++ if (chip->info_period_max) { ++ chip->info_period_max->c.text.read = snd_ftssp_period_max_read; ++ chip->info_period_max->c.text.write = ++ snd_ftssp_period_max_write; ++ } ++ // /proc/card#/periods_min ++ snd_card_proc_new(chip->card, "periods_min", &chip->info_periods_min); ++ if (chip->info_periods_min) { ++ chip->info_periods_min->c.text.read = ++ snd_ftssp_periods_min_read; ++ chip->info_periods_min->c.text.write = ++ snd_ftssp_periods_min_write; ++ } ++ // /proc/card#/periods_max ++ snd_card_proc_new(chip->card, "periods_max", &chip->info_periods_max); ++ if (chip->info_periods_max) { ++ chip->info_periods_max->c.text.read = ++ snd_ftssp_periods_max_read; ++ chip->info_periods_max->c.text.write = ++ snd_ftssp_periods_max_write; ++ } ++#endif ++ ++ // Register the card to ALSA ++ if ((err = snd_card_register(chip->card)) == 0) { ++ INFO("%s card registered!\n", FTSSP_CARD_ID); ++ } ++ ++ return 0; ++} ++ ++#ifdef CONFIG_SND_FTSSP010_I2S ++//ADD by river 2011.01.26 ++static int alc5630_i2c_remove(struct i2c_client *client) ++{ ++ struct alc5630_data *alc5630 = i2c_get_clientdata(client); ++ ++ // power down codec chip ++ //tas_write_reg(tas, TAS_REG_ACR, 1, &tmp); ++ ++ mutex_destroy(&alc5630->mtx); ++ kfree(alc5630); ++ return 0; ++} ++ ++static const struct i2c_device_id alc5630_i2c_id[] = { ++ { "alc5630_codec", 0 }, ++ { } ++}; ++ ++// This is the driver that will be inserted ++static struct i2c_driver alc5630_driver = { ++ .driver = { ++ .name = "alc5630_codec", ++ .owner = THIS_MODULE, ++ }, ++ .attach_adapter = alc5630_i2c_attach, ++ .probe = alc5630_i2c_probe, ++ .remove = alc5630_i2c_remove, ++ .suspend = alc5630_i2c_suspend, ++ .resume = alc5630_i2c_resume, ++ .id_table = alc5630_i2c_id, ++}; ++ ++static int alc5630_i2c_suspend(struct i2c_client *i2c_client, pm_message_t mesg) ++{ ++ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() is invoked.\n"); ++ ++ //i2c_del_driver(&alc5630_driver); ++ //#ifndef CONFIG_SND_FTSSP010_AC97 ++ // i2c_del_driver(&alc5630_driver); ++ //#endif ++ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() -2 is invoked.\n"); ++ dmad_channel_free(&dma_chreq_tx); ++ dmad_channel_free(&dma_chreq_rx); ++ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() -3 is invoked.\n"); ++ //snd_card_free(ftssp_cards[cardno]); ++ ++ return 0; ++ ++} ++ ++static int alc5630_i2c_resume(struct i2c_client *i2c_client) ++{ ++ ++ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_resume() is invoked.\n"); ++ //#ifdef CONFIG_SND_FTSSP010_AC97 ++ // ftssp_alsa_init(NULL); ++ //#else ++ // return i2c_add_driver(&alc5630_driver); ++ //#endif ++ ++ return 0; ++ ++} ++#endif ++ ++static __init int ftssp_alsa_i2c_i2s_init(void) ++{ ++ ++ //printk(">>>>>>>>>> (1) ftssp_alsa_i2c_i2s_init().\n"); ++ //return i2c_add_driver(&alc5630_driver); ++ #ifdef CONFIG_SND_FTSSP010_AC97 ++ return ftssp_alsa_init(NULL); ++ #else ++ return i2c_add_driver(&alc5630_driver); ++ #endif ++} ++//End ADD by river 2011.01.26 ++ ++static __exit void ftssp_alsa_i2c_i2s_exit(void) ++{ ++ DBG("%s, cleaning up\n",__func__); ++ ++ //i2c_del_driver(&alc5630_driver); ++ #ifndef CONFIG_SND_FTSSP010_AC97 ++ i2c_del_driver(&alc5630_driver); ++ #endif ++ ++ dmad_channel_free(&dma_chreq_tx); ++ dmad_channel_free(&dma_chreq_rx); ++ ++ snd_card_free(ftssp_cards[cardno]); ++} ++ ++/*static __exit void ftssp_alsa_exit(void) ++{ ++ DBG("%s, cleaning up\n",__func__); ++ ++ dmad_channel_free(&dma_chreq_tx); ++ dmad_channel_free(&dma_chreq_rx); ++ ++ snd_card_free(ftssp_cards[cardno]); ++}*/ ++ ++//MOD by river 2011.01.26 ++//module_init(ftssp_alsa_init); ++//module_exit(ftssp_alsa_exit); ++module_init(ftssp_alsa_i2c_i2s_init); ++module_exit(ftssp_alsa_i2c_i2s_exit); ++//End MOD by river 2011.01.26 +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.c linux-3.4.110/sound/nds32/FTSSP010_HDA.c +--- linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_HDA.c 2016-04-07 10:20:51.062085666 +0200 +@@ -0,0 +1,745 @@ ++/* FTSSP010 - UDA1345TS module: ++ * ++ * $log$ ++ * ++ * 2006/02/23: I-Jui Sung: OSS emulation half-duplex ++ * playback/capture at 48K, 44.1K, 8K ++ * with mono/stereo 16bit/8bit ++ * ++ * 2006/02/22: I-Jui Sung: OSS emulation playback at 44.1KHz ++ * 16-bit mono completed. Relying ALSA to ++ * resample ++ * 2009/02/24: dma upgrade checking list: ++ * - ac97 mode playback ................. ok ++ * - ac97 mode capture .................. ok ++ * - i2s mode playback .................. ok ++ * - i2s mode capture ................... ok ++ * - mixer support (snd_ctl_add, ...) ... todo ++ * - debug /proc entry .................. ok ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "FTSSP010_HDA.h" ++void init_hw(unsigned int cardno); ++ ++#if (!defined(CONFIG_PLATFORM_AHBDMA) && !defined(CONFIG_PLATFORM_APBDMA)) ++#warning needs ahb/apb dma to wrok ++#endif ++ ++/* --------------------------------------------------------------------------- ++ * Define the debug level of FTSSP_DEBUG ++ */ ++#define FTSSP_DEBUG 0 ++#define FTSSP_DEBUG_VERBOSE 0 ++#define FTSSP_PROC_FS 1 ++ ++#undef VVDBG ++#if (FTSSP_DEBUG_VERBOSE) ++//#define VVDBG(vvar...) (void)0 ++#define VVDBG(vvar...) printk(KERN_INFO vvar) ++#else ++#define VVDBG(vvar...) (void)0 ++#endif ++ ++#undef ERR ++#define ERR(vvar...) printk(KERN_ERR vvar) ++ ++#undef INFO ++#define INFO(vvar...) printk(KERN_INFO vvar) ++ ++#if (FTSSP_DEBUG) ++#undef DBG ++#define DBG(vvar...) printk(KERN_INFO vvar) ++#else ++#define DBG(vvar...) (void)0 ++#endif ++ ++#if (FTSSP_DEBUG_VERBOSE) ++#undef VDBG ++#define VDBG(vvar...) printk(KERN_INFO vvar) ++#else ++#define VDBG(vvar...) (void)0 ++#endif ++ ++/* --------------------------------------------------------------------------- ++ * Preserved size of memory space for audio DMA ring ++ */ ++#define FTSSP_HW_DMA_SIZE (512 * 1024) ++ ++ ++/* HDA HW configuration*/ ++/* ring size, exported to application */ ++#define HDA_HW_BUFFER_BYTES_MAX (256 * 1024) ++#define HDA_HW_PERIOD_BYTES_MIN (2 * 1024) ++#define HDA_HW_PERIOD_BYTES_MAX (32 * 1024) ++#define HDA_HW_PERIODS_MIN 3 ++#define HDA_HW_PERIODS_MAX 8 ++ ++#define HDA_HW_DMA_SIZE (HDA_HW_BUFFER_BYTES_MAX) ++ ++ ++/* --------------------------------------------------------------------------- ++ * Audio formats ++ */ ++ ++/* HDA formats */ ++#define HDA_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) ++#define HDA_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_192000 | \ ++ SNDRV_PCM_RATE_176400| \ ++ SNDRV_PCM_RATE_96000 | \ ++ SNDRV_PCM_RATE_88200 | \ ++ SNDRV_PCM_RATE_48000 | \ ++ SNDRV_PCM_RATE_44100 | \ ++ SNDRV_PCM_RATE_32000 | \ ++ SNDRV_PCM_RATE_22050 | \ ++ SNDRV_PCM_RATE_16000 | \ ++ SNDRV_PCM_RATE_11025 | \ ++ SNDRV_PCM_RATE_8000) ++#define HDA_CODEC_SAMPLE_RATE_MIN (8000) ++#define HDA_CODEC_SAMPLE_RATE_MAX (192000) ++ ++/* --------------------------------------------------------------------------- ++ * Configuration ++ */ ++#if (CONFIG_PROC_FS == 0) ++#undef FTSSP_PROC_FS ++#define FTSSP_PROC_FS 0 ++#else ++#if (FTSSP_PROC_FS) ++#include ++#endif /* FTSSP_PROC_FS */ ++#endif /* CONFIG_PROC_FS */ ++ ++#define FTSSP_CARD_ID "ftssp010" ++#define FTSSP_DRIVER_NAME "ftssp" ++ ++MODULE_LICENSE("Faraday License"); ++MODULE_AUTHOR("Faraday Technology Corp."); ++MODULE_DESCRIPTION("FTSSP010 Linux 2.6 Driver"); ++ ++static int cardno = 0; ++static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = ++ { SSP_FTSSP010_PA_BASE }; ++ ++/* Driver mode */ ++ ++// ---------------------------------------------- ++module_param(cardno, int, 0); ++MODULE_PARM_DESC(cardno, "FTSSP No."); ++ ++// ---------------------------------------------- ++ ++/* --------------------------------------------------------------------------- ++ * Structures ++ */ ++ ++/* private data for card */ ++typedef struct { ++ struct snd_card *card; ++ struct snd_pcm *pcm; ++ struct snd_pcm_substream *substream_tx; ++ struct snd_pcm_substream *substream_rx; ++} ftssp_chip; ++ ++/* dma request descriptors */ ++dmad_chreq dma_chreq_tx = { ++ .channel = -1, ++ .drq = NULL, ++}; ++ ++dmad_chreq dma_chreq_rx = { ++ .channel = -1, ++ .drq = NULL, ++}; ++ ++/* Holds ALSA card instance pointers */ ++struct snd_card *ftssp_cards[SSP_FTSSP010_COUNT]; ++ ++/* snd_pcm_hardware */ ++static struct snd_pcm_hardware snd_ftssp_pcm_hw = ++{ ++ .info = SNDRV_PCM_INFO_INTERLEAVED, ++ .formats = HDA_CODEC_FORMATS, ++ .rates = HDA_CODEC_SAMPLE_RATES, ++ .rate_min = HDA_CODEC_SAMPLE_RATE_MIN, ++ .rate_max = HDA_CODEC_SAMPLE_RATE_MAX, ++ .channels_min = 1, ++ .channels_max = 2, ++ .buffer_bytes_max = HDA_HW_BUFFER_BYTES_MAX, ++ .period_bytes_min = HDA_HW_PERIOD_BYTES_MIN, ++ .period_bytes_max = HDA_HW_PERIOD_BYTES_MAX, ++ .periods_min = HDA_HW_PERIODS_MIN, ++ .periods_max = HDA_HW_PERIODS_MAX, ++}; ++ ++/* private data for a substream (playback or capture) */ ++/* function pointer for set up AHBDMA for this substream */ ++typedef void (*start_t)(int cardno, unsigned use_dma); ++typedef void (*ftssp010_config_t)(int cardno, unsigned is_stereo, ++ unsigned speed, int use8bit); ++ ++typedef struct { ++ u32 busy; ++ spinlock_t dma_lock; ++ unsigned dma_area_va; ++ int dma_width; ++ unsigned int tx_period; ++ unsigned int rx_period; ++ ++ start_t start; ++ ftssp010_config_t hw_config; ++} ftssp_substream; ++ ++static ftssp_substream ftssp010_substreams[2] = { ++ /* Playback substream */ ++ { ++ busy : 0, ++ hw_config : ftssp010_config_hda_play, ++ }, ++ /* Capture substream */ ++ { ++ busy : 0, ++ hw_config : ftssp010_config_hda_rec, ++ } ++}; ++ ++ ++/** ++ * These dma callbacks are called in interrupt context. ++ * @data: pointer to the chip-wide structure. ++ * TODO: use stream-specifc data ++ */ ++__attribute__((__unused__)) ++static void ftssp_dma_callback_tx(int ch, u16 int_status, void *data) ++{ ++ ftssp_chip *chip = (ftssp_chip *)data; ++ struct snd_pcm_runtime *runtime = chip->substream_tx->runtime; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)runtime->private_data; ++ u32 sw_ptr; ++ u32 tx_period = ftssp010_substream->tx_period + 1; ++ ++ if (tx_period == runtime->periods) ++ sw_ptr = runtime->buffer_size; ++ else ++ sw_ptr = tx_period * runtime->period_size; ++ ++ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; ++ ++ if (dmad_update_ring_sw_ptr(&dma_chreq_tx, (u32)sw_ptr, 0)) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ } ++ ++ ftssp010_substream->tx_period = tx_period % runtime->periods; ++ snd_pcm_period_elapsed(chip->substream_tx); ++} ++ ++__attribute__((__unused__)) ++static void ftssp_dma_callback_rx(int ch, u16 int_status, void *data) ++{ ++ ftssp_chip *chip = (ftssp_chip *)data; ++ struct snd_pcm_runtime *runtime = chip->substream_rx->runtime; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)runtime->private_data; ++ u32 sw_ptr; ++ u32 rx_period = ftssp010_substream->rx_period + 1; ++ ++ if (rx_period == runtime->periods) ++ sw_ptr = runtime->buffer_size; ++ else ++ sw_ptr = rx_period * runtime->period_size; ++ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; ++ ++ if (dmad_update_ring_sw_ptr(&dma_chreq_rx, (u32)sw_ptr, 0) != 0) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ } ++ ++ ftssp010_substream->rx_period = rx_period % runtime->periods; ++ ++ snd_pcm_period_elapsed(chip->substream_rx); ++} ++ ++static inline int snd_ftssp_dma_ch_alloc(struct snd_pcm_substream *substream) ++{ ++ dmad_chreq *ch_req __attribute__((__unused__)) = 0; ++ ++#ifdef CONFIG_PLATFORM_APBDMA ++ ++ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ ch_req = &dma_chreq_tx; ++ ch_req->completion_cb = ftssp_dma_callback_tx; ++ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; ++ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX; ++ } else { ++ ch_req = &dma_chreq_rx; ++ ch_req->completion_cb = ftssp_dma_callback_rx; ++ ch_req->apb_req.tx_dir = DMAD_DIR_A1_TO_A0; ++ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX; ++ } ++ ++ ch_req->controller = DMAD_DMAC_APB_CORE; ++ ch_req->flags = DMAD_FLAGS_RING_MODE; ++ ch_req->ring_base = 0; ++ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); ++ ch_req->periods = 0; ++ ch_req->period_size = 0; ++ ++ ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I2X; ++ ch_req->apb_req.ring_reqn = APBBR_REQN_NONE; ++ ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED; ++ ch_req->apb_req.burst_mode = 0; ++ ch_req->apb_req.data_width = APBBR_DATAWIDTH_2; ++ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); ++ ++ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ ERR("%s: APBDMA channel allocation failed\n",__func__); ++ goto _try_ahb; ++ } ++ ++ DBG("%s: APBDMA channel allocated (ch: %d) ring_mode\n", ++ __func__, ch_req->channel); ++ ++ return 0; ++ ++_try_ahb: ++ ++#endif /* CONFIG_PLATFORM_APBDMA */ ++ ++#ifdef CONFIG_PLATFORM_AHBDMA ++ ++ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ ch_req = &dma_chreq_tx; ++ ch_req->completion_cb = ftssp_dma_callback_tx; ++ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; ++ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX; ++ } else { ++ ch_req = &dma_chreq_rx; ++ ch_req->completion_cb = ftssp_dma_callback_rx; ++ ch_req->ahb_req.tx_dir = DMAD_DIR_A1_TO_A0; ++ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX; ++ } ++ ++ ch_req->controller = DMAD_DMAC_AHB_CORE; ++ ch_req->flags = DMAD_FLAGS_RING_MODE; ++ ch_req->ring_base = 0; ++ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); ++ ch_req->periods = 0; ++ ch_req->period_size = 0; ++ ++ ch_req->ahb_req.sync = 1; ++ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_2; ++ ch_req->ahb_req.hw_handshake = 1; ++ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_1; ++ ++ ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_32; ++ ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC; ++ ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE; ++ ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_32; ++ ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX; ++ ++ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); ++ ++ if (dmad_channel_alloc(ch_req) != 0) { ++ ERR("%s: AHBDMA channel allocation failed\n", __func__); ++ goto _err_exit; ++ } ++ ++ DBG("%s: AHBDMA channel allocated (ch: %d) ring_mode\n", ++ __func__, ch_req->channel); ++ ++ return 0; ++ ++_err_exit: ++ ++#endif /* CONFIG_PLATFORM_AHBDMA */ ++ ++ return -ENODEV; ++} ++ ++static inline ftssp_substream *ftssp010_substream_new(int stream_id) ++{ ++ ftssp_substream *s = NULL; ++ ++ switch (stream_id) { ++ case SNDRV_PCM_STREAM_PLAYBACK: ++ s = &ftssp010_substreams[0]; ++ break; ++ case SNDRV_PCM_STREAM_CAPTURE: ++ s = &ftssp010_substreams[1]; ++ break; ++ default: ++ ERR("%s: wrong stream type (%d)\n", __func__, stream_id); ++ return NULL; ++ } ++ ++ if (s->busy) { ++ ERR("%s: device busy!\n", __func__); ++ return NULL; ++ } ++ s->busy = 1; ++ ++ spin_lock_init(&s->dma_lock); ++ ++ return s; ++} ++ ++static int snd_ftssp_pcm_open(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ int stream_id = substream->pstr->stream; ++ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ /* Both playback and capture share a hardware description */ ++ runtime->hw = snd_ftssp_pcm_hw; ++ ++ /* Allocate & Initialize stream-specific data */ ++ runtime->private_data = ftssp010_substream_new(stream_id); ++ ++ if (runtime->private_data) ++ return snd_ftssp_dma_ch_alloc(substream); ++ else ++ return -EBUSY; ++} ++ ++static int snd_ftssp_pcm_close(struct snd_pcm_substream *substream) ++{ ++ int stream_id = substream->pstr->stream; ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)substream->runtime->private_data; ++ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ++ dmad_channel_free(&dma_chreq_tx); ++ else ++ dmad_channel_free(&dma_chreq_rx); ++ ++ ftssp010_substream->busy = 0; ++ return 0; ++} ++ ++static int snd_ftssp_pcm_hw_params(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *hw_params) ++{ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ return snd_pcm_lib_malloc_pages(substream, HDA_HW_DMA_SIZE); ++} ++ ++static int snd_ftssp_pcm_hw_free(struct snd_pcm_substream *substream) ++{ ++ VDBG("%s, %s\n", __func__, ++ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ++ "playback" : "capture"); ++ ++ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ++ dmad_drain_requests(&dma_chreq_tx, 1); ++ else ++ dmad_drain_requests(&dma_chreq_rx, 1); ++ ++ return snd_pcm_lib_free_pages(substream); ++} ++ ++/* Prepare FTSSP010 AHBDMA for playback & capture */ ++static int snd_ftssp_pcm_prepare(struct snd_pcm_substream *substream) ++{ ++ ftssp_chip *chip = snd_pcm_substream_chip(substream); ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)runtime->private_data; ++ ++ int stream_id = substream->pstr->stream; ++ dmad_chreq *dma_chreq; ++ unsigned period_size, buffer_size; ++ VVDBG("%s before spin_lock<<\n", __func__); ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ++ dma_chreq = &dma_chreq_tx; ++ else ++ dma_chreq = &dma_chreq_rx; ++ ++ period_size = frames_to_bytes(runtime, runtime->period_size); ++ buffer_size = frames_to_bytes(runtime, runtime->buffer_size); ++ ++ if (runtime->format != SNDRV_PCM_FORMAT_S16_LE) ++ return -ENODEV; ++ ++ ftssp010_substream->dma_width = 4; ++ ++ dmad_drain_requests(dma_chreq, 1); ++ ++ dma_chreq->ring_base = (dma_addr_t)runtime->dma_addr; ++ dma_chreq->periods = (dma_addr_t)runtime->periods; ++ dma_chreq->period_size = (dma_addr_t)(period_size >> 1); ++ dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 1); ++ dmad_update_ring(dma_chreq); ++ ++ /* Set PMU, FTSSP010, and DMA */ ++ spin_lock(&ftssp010_substream->dma_lock); ++ ++ /* keep DMA buffer VA for copy() callback */ ++ // todo: support playback/capture simultaneously ++ ftssp010_substream->dma_area_va = (u32)runtime->dma_area; ++ VVDBG("%s before hw_config<<\n", __func__); ++ ftssp010_substream->hw_config(cardno, ++ runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */ ++ runtime->rate, ftssp010_substream->dma_width); ++ VVDBG("%s after hw_config<<\n", __func__); ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ ftssp010_substream->tx_period = 0; ++ chip->substream_tx = substream; ++ } else { ++ ftssp010_substream->rx_period = 0; ++ chip->substream_rx = substream; ++ } ++ ++ spin_unlock(&ftssp010_substream->dma_lock); ++ VVDBG("%s after spin_unlock <<\n", __func__); ++ ++ return 0; ++} ++ ++static inline int snd_ftssp_start_play(ftssp_substream *ftssp010_substream, ++ struct snd_pcm_runtime *runtime) ++{ ++ int err = 0; ++ u32 sw_ptr = ++ (u32)frames_to_bytes(runtime, runtime->buffer_size) >> 1; ++ ++ err = dmad_update_ring_sw_ptr(&dma_chreq_tx, sw_ptr, 0); ++ if (err != 0) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ return err; ++ } ++ err = dmad_kickoff_requests(&dma_chreq_tx); ++ if (err != 0) { ++ ERR("%s: failed to kickoff dma!\n", __func__); ++ return err; ++ } ++ ++ return 0; ++} ++ ++static inline int snd_ftssp_start_record(ftssp_substream *ftssp010_substream, ++ struct snd_pcm_runtime *runtime) ++{ ++ int err = 0; ++ u32 sw_ptr = (u32)frames_to_bytes(runtime, runtime->buffer_size); ++ ++ sw_ptr = sw_ptr >> 1; ++ printk(">>>>>>>>>> : snd_ftssp_start_record() for recording....\n"); ++ err = dmad_update_ring_sw_ptr(&dma_chreq_rx, sw_ptr, 0); ++ if (err != 0) { ++ ERR("%s: failed to update sw-pointer!\n", __func__); ++ return err; ++ } ++ ++ err = dmad_kickoff_requests(&dma_chreq_rx); ++ if (err != 0) { ++ ERR("%s: failed to kickoff dma!\n", __func__); ++ return err; ++ } ++ ++ ++ return 0; ++} ++ ++/* Triggers AHBDMA for playback & capture */ ++static int snd_ftssp_pcm_trigger(struct snd_pcm_substream * substream, int cmd) ++{ ++ ftssp_substream *ftssp010_substream = ++ (ftssp_substream *)substream->runtime->private_data; ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ int err = 0; ++ int stream_id = substream->pstr->stream; ++ ++ /* note local interrupts are already disabled in the midlevel code */ ++ spin_lock(&ftssp010_substream->dma_lock); ++ ++ switch (cmd) { ++ case SNDRV_PCM_TRIGGER_START: ++ ++ VDBG("%s: SNDRV_PCM_TRIGGER_START state(0x%08x)\n", ++ __func__, (u32)runtime->status->state); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ err = snd_ftssp_start_play(ftssp010_substream, runtime); ++ } else { ++ err = snd_ftssp_start_record(ftssp010_substream, ++ runtime); ++ } ++ break; ++ ++ case SNDRV_PCM_TRIGGER_STOP: ++ ++ VDBG("%s: SNDRV_PCM_TRIGGER_STOP state(0x%08x)\n", ++ __func__, (u32)substream->runtime->status->state); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ ftssp010_stop_tx(cardno); ++ dmad_drain_requests(&dma_chreq_tx, 1); ++ } else { ++ ftssp010_stop_rx(cardno); ++ dmad_drain_requests(&dma_chreq_rx, 1); ++ } ++ break; ++ default: ++ err = -EINVAL; ++ break; ++ } ++ ++ spin_unlock(&ftssp010_substream->dma_lock); ++ return err; ++} ++ ++// pcm middle-layer call this function within irq (snd_pcm_period_elapsed) or ++// with local irq disabled (snd_pcm_lib_write1) ++static snd_pcm_uframes_t snd_ftssp_pcm_pointer( ++ struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ u32 hw_ptr; ++ snd_pcm_uframes_t ret; ++ int stream_id = substream->pstr->stream; ++ ++ /* Fetch DMA pointer, with spin lock */ ++ //spin_lock_irqsave(&ftssp010_substream->dma_lock, flags); ++ ++ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { ++ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_tx); ++ } else { ++ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_rx); ++ } ++ ret = bytes_to_frames(runtime, hw_ptr << 1); ++ //spin_unlock_irqrestore(&ftssp010_substream->dma_lock, flags); ++ VVDBG("%s: hw_ptr(0x%08x) ret(0x%08x)\n", ++ (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? "p" : "c", ++ (u32)hw_ptr, (u32)ret); ++ ++ /* ALSA requires return value 0 <= ret < buffer_size */ ++ if (ret >= runtime->buffer_size) ++ return 0; ++ return ret; ++} ++ ++/* For FTSSP010 driver, operations are shared among playback & capture */ ++static struct snd_pcm_ops snd_ftssp_playback_ops = { ++ .open = snd_ftssp_pcm_open, ++ .close = snd_ftssp_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = snd_ftssp_pcm_hw_params, ++ .hw_free = snd_ftssp_pcm_hw_free, ++ .prepare = snd_ftssp_pcm_prepare, ++ .trigger = snd_ftssp_pcm_trigger, ++ .pointer = snd_ftssp_pcm_pointer, ++ .copy = NULL, ++}; ++ ++static struct snd_pcm_ops snd_ftssp_capture_ops = { ++ .open = snd_ftssp_pcm_open, ++ .close = snd_ftssp_pcm_close, ++ .ioctl = snd_pcm_lib_ioctl, ++ .hw_params = snd_ftssp_pcm_hw_params, ++ .hw_free = snd_ftssp_pcm_hw_free, ++ .prepare = snd_ftssp_pcm_prepare, ++ .trigger = snd_ftssp_pcm_trigger, ++ .pointer = snd_ftssp_pcm_pointer, ++ .copy = NULL, ++}; ++ ++/* ALSA PCM constructor */ ++static int snd_ftssp_new_pcm(ftssp_chip *chip) ++{ ++ struct snd_pcm *pcm; ++ int err; ++ ++ /* PCM device #0 with 1 playback and 1 capture */ ++ if ((err = snd_pcm_new(chip->card, "ftssp_pcm", 0, 1, 1, &pcm)) < 0) ++ return err; ++ ++ pcm->private_data = chip; ++ strcpy(pcm->name, "ftssp_pcm device"); ++ chip->pcm = pcm; ++ ++ /* set operators for playback and capture*/ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ++ &snd_ftssp_playback_ops); ++ ++ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ++ &snd_ftssp_capture_ops); ++ ++ /* Pre-allocate buffer, as suggested by ALSA driver document */ ++ // todo: support playback/capture simultaneously ++ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, ++ NULL, FTSSP_HW_DMA_SIZE, FTSSP_HW_DMA_SIZE); ++ ++ return 0; ++} ++ ++static __init int ftssp_alsa_init(void) ++{ ++ ftssp_chip *chip; ++ int err; ++ init_hw(cardno); ++ INFO("After init_hw!\n"); ++ err = snd_card_create(cardno, FTSSP_CARD_ID, THIS_MODULE, ++ sizeof(ftssp_chip), &ftssp_cards[cardno]); ++ INFO("After snd_card_create!\n"); ++ if (err < 0) ++ return err; ++ sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME); ++ sprintf(ftssp_cards[cardno]->shortname, ++ FTSSP_DRIVER_NAME "_HDA"); ++ sprintf(ftssp_cards[cardno]->longname, ++ FTSSP_DRIVER_NAME "_HDA controller"); ++ /* PCM */ ++ chip = (ftssp_chip *)(ftssp_cards[cardno]->private_data); ++ chip->card = ftssp_cards[cardno]; ++ ++ if ((err = snd_ftssp_new_pcm(chip))) { ++ ERR("%s, Can't new PCM devices\n",__func__); ++ return -ENODEV; ++ } ++ ++ ++ /* Register the card to ALSA */ ++ if ((err = snd_card_register(chip->card)) == 0) { ++ INFO("%s card registered!\n", FTSSP_CARD_ID); ++ } ++ ++ return 0; ++} ++ ++static __exit void ftssp_alsa_exit(void) ++{ ++ DBG("%s, cleaning up\n",__func__); ++ ++ dmad_channel_free(&dma_chreq_tx); ++ dmad_channel_free(&dma_chreq_rx); ++ ++ snd_card_free(ftssp_cards[cardno]); ++} ++ ++module_init(ftssp_alsa_init); ++module_exit(ftssp_alsa_exit); +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.h linux-3.4.110/sound/nds32/FTSSP010_HDA.h +--- linux-3.4.110.orig/sound/nds32/FTSSP010_HDA.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_HDA.h 2016-04-07 10:20:51.062085666 +0200 +@@ -0,0 +1,34 @@ ++/* FTSSP010 - HDA supporting library header */ ++/* ++ * ++ * $log$ ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) ++#define FTSSP010_DATA_PA(x) (SSP_FTSSP010_pa_base[(x)]+0x18) ++ ++ ++/* Returns FTSSP010 status */ ++extern void ftssp010_set_int_control(int cardno, unsigned val); ++extern int ftssp010_get_status(int cardno); ++extern unsigned ftssp010_get_int_status(int cardno); ++/* Polls FIFO full register */ ++extern int ftssp010_tx_fifo_not_full(int cardno); ++ ++/* Configure FTSSP010 to a given sampling rate and channel number */ ++extern void ftssp010_config_hda_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit); ++ ++extern void ftssp010_config_hda_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit); ++ ++extern void ftssp010_stop_tx(int cardno); ++extern void ftssp010_stop_rx(int cardno); ++ ++ +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_HDA_lib.c linux-3.4.110/sound/nds32/FTSSP010_HDA_lib.c +--- linux-3.4.110.orig/sound/nds32/FTSSP010_HDA_lib.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_HDA_lib.c 2016-04-07 10:20:51.062085666 +0200 +@@ -0,0 +1,477 @@ ++/* FTSSP010 - UDA1345TS module ++ * ++ * $log$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "hda.h" ++ ++#if 0 ++MODULE_LICENSE("Faraday License"); ++MODULE_AUTHOR("Faraday Technology Corp."); ++MODULE_DESCRIPTION("FTSSP010 - UDA1345TS Linux 2.6 Library"); ++#endif ++#undef ERR ++#define ERR(vvar...) printk(KERN_ERR vvar) ++#define DBG(vvar...) printk(KERN_INFO vvar) ++ ++#define SSP_TXFCLR 0x8 ++#define SSP_RXFCLR 0x4 ++#define SSP_RFIEN 0x4 ++#define SSP_TFIEN 0x8 ++#define SSP_SSPEN 0x1 ++#define SSP_TXDOE 0x2 ++#define SSP_RXDMAEN 0x10 ++#define SSP_TXDMAEN 0x20 ++#define SSP_RFURIEN 0x1 ++#define SSP_TFURIEN 0x2 ++#define HDA_STRNUM_RX 1 ++#define HDA_STRNUM_TX 2 ++#define HDA_CHANUM 0 ++#define HDA_CRST_MASK 0x20 ++/* Initialize FTSSP010 to output to UDA1345TS via I2S */ ++#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0) ++#define FTSSP010_CONTROL0_OPM_STEREO 0xC ++#define FTSSP010_CONTROL0_OPM_MONO 0x8 ++ ++#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4) ++#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8) ++ ++#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10) ++#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC) ++#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14) ++#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) ++#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C) ++#define FTSSP010_AC_COMMAND(x) (SSP_FTSSP010_va_base[(x)]+0x28) ++#define FTSSP010_IRSPR(x) (SSP_FTSSP010_va_base[(x)]+0x2C) ++#define FTSSP010_ICMDST(x) (SSP_FTSSP010_va_base[(x)]+0x30) ++#define HDA_REG_OSDC(x) (SSP_FTSSP010_va_base[(x)]+0x50) ++#define HDA_REG_ISDC(x) (SSP_FTSSP010_va_base[(x)]+0x54) ++ ++static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE }; ++static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE }; ++ ++void SetSSP_Enable(int cardno, int enable) ++{ ++ volatile unsigned int ctrl = 0; ++ ++ ctrl = inl(FTSSP010_CONTROL2(cardno)); ++ if(enable) ++ ctrl |= SSP_SSPEN + SSP_TXDOE; ++ else ++ ctrl &= ~(SSP_SSPEN + SSP_TXDOE); ++ ++ outl(ctrl, FTSSP010_CONTROL2(cardno)); ++} ++void SetSSP_Enable_rx(int cardno, int enable) ++{ ++ volatile unsigned int ctrl = 0; ++ ++ ctrl = inl(FTSSP010_CONTROL2(cardno)); ++ if(enable) ++ ctrl |= SSP_SSPEN ; ++ else ++ ctrl &= ~(SSP_SSPEN); ++ ++ outl(ctrl, FTSSP010_CONTROL2(cardno)); ++} ++ ++void SetSSP_FIFO_Threshold(int cardno, unsigned int trans_len,unsigned int rec_len) ++{ ++ volatile unsigned int ctrl = 0; ++ ctrl = inl(FTSSP010_INT_CONTROL(cardno)); ++ ++ ctrl &= ~0x0000FF00; ++ ctrl |= ((trans_len << 12) + (rec_len << 8)) & 0x0000FF00; ++ ++ outl(ctrl, FTSSP010_INT_CONTROL(cardno)); ++} ++void SetSSP_IntMask(int cardno,int Mask) ++{ ++ volatile unsigned int ctrl = 0; ++ ctrl = inl(FTSSP010_INT_CONTROL(cardno)); ++ ctrl &= ~0x3F; ++ ctrl |= Mask; ++ outw(ctrl, FTSSP010_INT_CONTROL(cardno)); ++} ++void SetSSP_TXFIFO(int cardno, unsigned int threshold,unsigned int underrun) ++{ ++ volatile unsigned int data = 0; ++ ++ data = inl(FTSSP010_INT_CONTROL(cardno)); ++ ++ if (threshold) ++ data |= SSP_TFIEN; ++ else ++ data &= ~SSP_TFIEN; //Howard@2007-4-13 ++ ++ if (underrun) ++ data |= SSP_TFURIEN; ++ else ++ data &= ~SSP_TFURIEN; //Howard@2007-4-13 ++ ++ outl(data, FTSSP010_INT_CONTROL(cardno)); ++} ++void SetSSP_RXFIFO(int cardno,unsigned int threshold,unsigned int underrun) ++{ ++ volatile unsigned int data = 0; ++ ++ data = inl(FTSSP010_INT_CONTROL(cardno)); ++ ++ if (threshold) ++ data |= SSP_RFIEN; ++ else ++ data &= ~SSP_RFIEN; //Howard@2007-4-13 ++ ++ if (underrun) ++ data |= SSP_RFURIEN; ++ else ++ data &= ~SSP_RFURIEN; //Howard@2007-4-13 ++ ++ outl(data, FTSSP010_INT_CONTROL(cardno)); ++} ++void SetSSP_DMA(int cardno, unsigned int trans,unsigned int rec) ++{ ++ volatile unsigned int data = 0; ++ ++ data = inl(FTSSP010_INT_CONTROL(cardno)); ++ ++ if (trans) ++ data |= SSP_TXDMAEN; ++ else ++ data &= ~SSP_TXDMAEN; ++ ++ if (rec) ++ data |= SSP_RXDMAEN; ++ else ++ data &= ~SSP_RXDMAEN; ++ ++ outl(data, FTSSP010_INT_CONTROL(cardno)); ++} ++void SSPClearTxFIFO(int cardno) ++{ ++ volatile unsigned int data = 0; ++ ++ data = inl(FTSSP010_CONTROL2(cardno)); ++ data |= SSP_TXFCLR; ++ outl(data, FTSSP010_CONTROL2(cardno)); ++} ++ ++ ++void SSPClearRxFIFO(int cardno) ++{ ++ volatile unsigned int data = 0; ++ ++ data = inl(FTSSP010_CONTROL2(cardno)); ++ data |= SSP_RXFCLR; ++ outl(data, FTSSP010_CONTROL2(cardno)); ++} ++ ++void ftssp010_set_int_control(int cardno, unsigned val) ++{ ++ outl(val, FTSSP010_INT_CONTROL(cardno)); ++} ++ ++unsigned ftssp010_get_int_status(int cardno) ++{ ++ return (inl(FTSSP010_INT_STATUS(cardno))); ++} ++ ++int ftssp010_get_status(int cardno) ++{ ++ return (inl(FTSSP010_STATUS(cardno))); ++} ++ ++int ftssp010_tx_fifo_not_full(int cardno) ++{ ++ return (inl(FTSSP010_STATUS(cardno))&0x2)==0x2; ++} ++ ++int ftssp010_tx_fifo_vaild_entries(int cardno) ++{ ++ return (inl(FTSSP010_STATUS(cardno))>>12) & 0x1f; ++} ++ ++/* Configure FTSSP010 to a given sampling rate and channel number ++ * for HDA mode in playback mode ++ */ ++void init_hw(unsigned int cardno) ++{ ++ /* Step 1: Set HDA Mode & HDA Format */ ++ outl(HDA_MODE | 0x4000, FTSSP010_CONTROL0(cardno)); /* set FTSSP010 to HDA mode */ ++ mdelay(50); ++ outl(HDA_CRST_CLR | (5 << HDA_RST_FCNT_OFS), FTSSP010_CONTROL2(cardno)); /* Cold Reset AC-Link */ ++ mdelay(50); ++ while((inl(FTSSP010_CONTROL2(cardno)) & HDA_CRST_MASK) != HDA_CRST_CLR); ++ SetSSP_IntMask(cardno, 0); ++ ++} ++void SSPClearFIFO(int cardno, unsigned int tx, unsigned int rx) ++{ ++ unsigned int data; ++ ++ if (tx == 1) { ++ //clear TX ++ data = inl(FTSSP010_CONTROL2(cardno)); ++ //data = REG32(SSP_REG_CTRL2); ++ data |= SSP_TXFCLR; ++ outl(data, FTSSP010_CONTROL2(cardno)); ++ //REG32(SSP_REG_CTRL2) = data; ++ } ++ ++ if (rx == 1) { ++ //clear RX ++ data = inl(FTSSP010_CONTROL2(cardno)); ++ //data = REG32(SSP_REG_CTRL2); ++ data |= SSP_RXFCLR; ++ //REG32(SSP_REG_CTRL2) = data; ++ outl(data, FTSSP010_CONTROL2(cardno)); ++ } ++} ++void hda_cmd_rsp(int cardno, unsigned int node_num, unsigned int verb_num, unsigned int func_num) ++{ ++ //unsigned int HDA_REG_ICMDST; ++ volatile unsigned int hda_cmd = HDA_COD_DEVADDR | (node_num << 20) | (verb_num << 8) | func_num; ++ //Wait CMD Bus Not Busy ++ while((inl(FTSSP010_ICMDST(cardno)) & HDA_ICB_MASK) != 0); ++ //Write CMD into ICW ++ outl(hda_cmd, FTSSP010_AC_COMMAND(cardno)); ++ mdelay(50); ++ //Wait new resp is latched into IRR ++ while((inl(FTSSP010_ICMDST(cardno)) & HDA_IRV_MASK) == 0); ++ //Get Resp From IRR & Compare with Expected Resp ++ //clear IRV ++ outl(inl(FTSSP010_ICMDST(cardno)) | (1 << HDA_IRV_OFFSET), FTSSP010_ICMDST(cardno)); ++ mdelay(50); ++} ++void hda_cmdrsp_proc(int cardno, unsigned int node_num, unsigned int issue_cmd, unsigned int expect_rsp) ++{ ++ unsigned int hda_cmd = HDA_COD_DEVADDR | node_num | issue_cmd; ++ unsigned int HDA_REG_ICMDST; ++ //Wait CMD Bus Not Busy ++ while((inl(FTSSP010_ICMDST(cardno)) & HDA_ICB_MASK) != 0); ++ ++ //Write CMD into ICW ++ //REG32(HDA_REG_ICMDW) = hda_cmd; ++ outl(hda_cmd, FTSSP010_AC_COMMAND(cardno)); ++ mdelay(50); ++ //Wait new resp is latched into IRR ++ while((inl(FTSSP010_ICMDST(cardno)) & HDA_IRV_MASK) == 0); ++ //Get Resp From IRR & Compare with Expected Resp ++ if (inl(FTSSP010_IRSPR(cardno)) != expect_rsp) { ++ ERR("%s: unexpected rsp!",__func__); ++ } ++ else { ++ //clear IRV ++ outl(inl(FTSSP010_ICMDST(cardno)) | (1 << HDA_IRV_OFFSET), FTSSP010_ICMDST(cardno)); ++ } ++} ++unsigned int hda_covfmt_setup(unsigned int type, unsigned int base, unsigned int mult, unsigned int div, unsigned int bits, unsigned int chnum) ++{ ++ unsigned int hda_fmt = type << HDA_FMT_TYPE_OFS | ++ base << HDA_FMT_BASE_OFS | ++ mult << HDA_FMT_MULT_OFS | ++ div << HDA_FMT_DIV_OFS | ++ bits << HDA_FMT_BITS_OFS | ++ chnum << HDA_FMT_CHNUM_OFS; ++ return hda_fmt; ++} ++unsigned int hda_covstr_setup(unsigned int stream, unsigned int channel) ++{ ++ unsigned int hda_str = stream << HDA_STR_STR_OFS | ++ channel << HDA_STR_CHA_OFS ; ++ return hda_str; ++} ++unsigned int hda_converter_setup(int cardno, unsigned int mode, unsigned int type, unsigned int base, unsigned mult, unsigned int div, unsigned int bits, unsigned int chnum, unsigned int stream, unsigned int channel) ++{ ++ unsigned int hda_fmt = 0; ++ unsigned int hda_str = 0; ++ unsigned int exp_rsp = 0; ++ unsigned int node_num = 0; ++ ++ if (mode == HDA_OUT_STR) { ++ node_num = HDA_OUTCOV_NODE; ++ } ++ else { ++ node_num = HDA_INCOV_NODE; ++ } ++ //a: Set Converter Format to Converter ++ hda_fmt = hda_covfmt_setup(type, base, mult, div, bits, chnum); ++ exp_rsp = HDA_RESP_ZERO_VAL; ++ hda_cmdrsp_proc(cardno, node_num, (HDA_CMD_SETCVTFMT | hda_fmt), exp_rsp); ++ //b: Get Converter Format from Converter ++ exp_rsp = hda_fmt; ++ hda_cmdrsp_proc(cardno, node_num, HDA_CMD_GETCVTFMT, exp_rsp); ++ //c: Set Converter Stream to Converter ++ hda_str = hda_covstr_setup(stream, channel); ++ exp_rsp = HDA_RESP_ZERO_VAL; ++ hda_cmdrsp_proc(cardno, node_num, (HDA_CMD_SETCVTSTR | hda_str), exp_rsp); ++ //d: Get Converter Stream from Converter ++ exp_rsp = hda_str; ++ hda_cmdrsp_proc(cardno, node_num, HDA_CMD_GETCVTSTR, exp_rsp); ++ ++ return hda_fmt; ++} ++void hda_iosdc_setup(int cardno, unsigned int io_sel, unsigned int ctrl, unsigned int stream_num, unsigned int hda_fmt) ++{ ++ unsigned int hda_reg_base = (io_sel == 1)? HDA_REG_OSDC(cardno) : HDA_REG_ISDC(cardno); ++ if (ctrl == 1) {//run ++ outl((stream_num << HDA_SDC_STNUM_OFFSET) | hda_fmt, hda_reg_base); ++ outl((inl(hda_reg_base) | (1 << HDA_SDC_SRUN_OFFSET)),hda_reg_base); ++ } ++ ++} ++static void _ftssp010_config_hda(int cardno, unsigned is_stereo, unsigned speed, int is_rec) ++{ ++ unsigned int hda_fmt = 0; ++ unsigned int div = 0,mult = 0, base = 0; ++ switch (speed) { ++ case 44100: ++ base = 1; ++ div = 0; ++ break; ++ case 48000: ++ div = 0; ++ break; ++ case 96000: ++ mult = 1; ++ break; ++ case 192000: ++ mult = 3; ++ break; ++ } ++ ++ if (is_rec) { /* Recording */ ++ /* ------------------------------------------------ */ ++ /* Codec initialization */ ++ /* ------------------------------------------------ */ ++ /* Step 3: Codec Evaluation */ ++ /* root_node -> node 1(Audio Func Group) */ ++ /* -> node 2(Output Converter) */ ++ /* -> node 3(Input Converter) */ ++ /* ------------------------------------------------ */ ++ //input ++ hda_cmd_rsp(cardno, 0x1a, 0x707, 0x20); //pin complex => input enable, port-c LINE1 ++ hda_cmd_rsp(cardno, 0x08, 0x3f0, 0x3f);//pin amp => max LINE ADC amplifier gain ++ hda_cmd_rsp(cardno, 0x1a, 0x3f0, 0x00);//pin complex => no mute ++ hda_cmd_rsp(cardno, 0x23, 0x3f2, 0x3f);//pin complex => no mute ++ /* ------------------------------ */ ++ /* Step 4: Output Converter Setup */ ++ /* ------------------------------ */ ++ /* Set Converter Format & Stream to Node 2(Output Converter) */ ++ /* type = PCM, base = 48K, mult = xN, div = /M, bits = 8~32bits/sample, chnum = 1 */ ++ /* stream = 1, lowest channel = 0 */ ++ ++ hda_fmt = hda_converter_setup(cardno, HDA_IN_STR, //MODE ++ 0, base, mult, div, 1, 1, //FORMAT ++ HDA_STRNUM_RX, HDA_CHANUM); //STREAM ++ /* ---------------------------- */ ++ /* Step 5: Enable Output Stream */ ++ /* ---------------------------- */ ++ hda_iosdc_setup(cardno, HDA_IN_STR, HDA_STR_RUN, HDA_STRNUM_RX, hda_fmt); ++ SetSSP_Enable_rx(cardno, 1); ++ SetSSP_RXFIFO(cardno, 0, 0); ++ SetSSP_TXFIFO(cardno, 0, 0); ++ SetSSP_FIFO_Threshold(cardno,12,12); ++ SetSSP_DMA(cardno, 0, 1); ++ ++ SSPClearTxFIFO(cardno); ++ SSPClearRxFIFO(cardno); ++ ++ //SetSSP_Enable_rx(cardno, 0); ++ ++ } else { /* Playback */ ++ /* ------------------------------------------------ */ ++ /* Codec initialization */ ++ /* ------------------------------------------------ */ ++ /* Step 3: Codec Evaluation */ ++ /* root_node -> node 1(Audio Func Group) */ ++ /* -> node 2(Output Converter) */ ++ /* -> node 3(Input Converter) */ ++ /* ------------------------------------------------ */ ++ //DBG("%s before_cmd_rsp<<",__func__); ++ hda_cmd_rsp(cardno, 0x14, 0x707, 0x40);//pin complex => output ++ //DBG("%s after hda_cmd_rsp< output>>",__func__); ++ hda_cmd_rsp(cardno, 0x0c, 0x3f0, 0x3f);//pin amp => 0x3f ++ hda_cmd_rsp(cardno, 0x14, 0x3f0, 0x00);//pin complex => no mute ++ //DBG("%s after hda_cmd_rsp",__func__); ++ //msleep_interruptible(10); ++ /* ------------------------------ */ ++ /* Step 4: Output Converter Setup */ ++ /* ------------------------------ */ ++ /* Set Converter Format & Stream to Node 2(Output Converter) */ ++ /* type = PCM, base = 48K, mult = xN, div = /M, bits = 8~32bits/sample, chnum = 1 */ ++ /* stream = 1, lowest channel = 0 */ ++ hda_fmt = hda_converter_setup(cardno, HDA_OUT_STR, //MODE ++ 0, base, mult, div, 1, 1, //FORMAT ++ HDA_STRNUM_TX, HDA_CHANUM); //STREAM ++ //DBG("%s after hda_converter_setup",__func__); ++ /* ---------------------------- */ ++ /* Step 5: Enable Output Stream */ ++ /* ---------------------------- */ ++ hda_iosdc_setup(cardno, HDA_OUT_STR, HDA_STR_RUN, HDA_STRNUM_TX, hda_fmt); ++ SetSSP_Enable(cardno, 1); ++ SetSSP_RXFIFO(cardno, 0, 0); ++ SetSSP_TXFIFO(cardno, 0, 0); ++ //outl(0xC, FTSSP010_CONTROL2(cardno)); /* Disable FTSSP010, clear RX/TX Fifo. */ ++ SetSSP_FIFO_Threshold(cardno,12,12); ++ SetSSP_DMA(cardno,1,0); ++ ++ SSPClearTxFIFO(cardno); ++ SSPClearRxFIFO(cardno); ++ } ++ ++ while(inl(FTSSP010_INT_STATUS(cardno))&0x3); ++} ++/* for HDA */ ++void ftssp010_config_hda_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit) ++{ ++ _ftssp010_config_hda(cardno, is_stereo, speed, 0); ++} ++ ++void ftssp010_config_hda_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit) ++{ ++ _ftssp010_config_hda(cardno, is_stereo, speed, 1); ++} ++ ++ ++ ++void ftssp010_stop_tx(int cardno) ++{ ++ unsigned int hda_reg_base = HDA_REG_OSDC(cardno); ++ SetSSP_Enable(cardno,0); ++ SetSSP_DMA(cardno,0,0); ++ ++ /* turn off output node */ ++ hda_cmd_rsp(cardno,0x14, 0x707, 0); //pin complex => input enable, port-c LINE1 ++ hda_cmd_rsp(cardno,0x0c, 0x3f0, 0x80); //pin amp => max LINE ADC amplifier gain ++ hda_cmd_rsp(cardno,0x14, 0x3f0, 0x80); //pin complex => no mute ++ ++ outl(0, hda_reg_base); ++ SSPClearFIFO(cardno, 1, 0); ++ //outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x22), FTSSP010_INT_CONTROL(cardno)); ++} ++ ++void ftssp010_stop_rx(int cardno) ++{ ++ unsigned int hda_reg_base = HDA_REG_ISDC(cardno); ++ SetSSP_Enable_rx(cardno, 0); ++ SetSSP_DMA(cardno, 0, 0); ++ ++ /* turn off output node */ ++ hda_cmd_rsp(cardno,0x1a, 0x707, 0); //pin complex => input enable, port-c LINE1 ++ hda_cmd_rsp(cardno,0x08, 0x3f0, 0x80);//pin amp => LINE ADC amplifier gain ++ hda_cmd_rsp(cardno,0x1a, 0x3f0, 0x80);//pin complex => mute ++ hda_cmd_rsp(cardno,0x23, 0x3f2, 0x80);//pin complex => no mute ++ ++ outl(0, hda_reg_base); ++ SSPClearFIFO(cardno, 0, 1); ++ //outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x11), FTSSP010_INT_CONTROL(cardno)); ++} ++ +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_lib.c linux-3.4.110/sound/nds32/FTSSP010_lib.c +--- linux-3.4.110.orig/sound/nds32/FTSSP010_lib.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_lib.c 2016-04-07 10:20:51.062085666 +0200 +@@ -0,0 +1,795 @@ ++/* FTSSP010 - UDA1345TS module ++ * ++ * $log$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "FTSSP010_UDA1345TS.h" ++ ++#if 0 ++MODULE_LICENSE("Faraday License"); ++MODULE_AUTHOR("Faraday Technology Corp."); ++MODULE_DESCRIPTION("FTSSP010 - UDA1345TS Linux 2.6 Library"); ++#endif ++ ++#define PMU_PDLLCR1 (PMU_FTPMU010_VA_BASE+0x34) ++#define PMU_MFPSR (PMU_FTPMU010_VA_BASE+0x28) ++#define PMU_I2SAC97_REQACKCFG (PMU_FTPMU010_VA_BASE+0xbc) ++#define PMU_C4 (PMU_FTPMU010_VA_BASE+0xc4) ++ ++#define SSPCLK_TO_SCLKDIV(sspclk_div2,bps) ((sspclk_div2)/(bps)-1) ++ ++// Each client has this additional data ++struct alc5630_data { ++ struct i2c_client *client; ++ struct delayed_work work; ++ unsigned long gpio2_value; ++ struct mutex mtx; ++}; ++ ++//ADD by river 2011.01.26 ++static int i2s_alc5630_read(unsigned int raddr, char *data, struct i2c_client *client) ++{ ++#ifndef CONFIG_SND_FTSSP010_AC97 ++ struct i2c_adapter *adap = client->adapter; ++ int ret; ++#endif ++ struct i2c_msg msg; ++ int i2c_value; ++ ++ //Reading ALC5630 register ++ msg.addr = raddr; ++ msg.flags = (client->flags & I2C_M_TEN) | I2C_M_RD; ++ msg.len = 1; ++ msg.buf = (char *)data; ++ ++ //ret = i2c_transfer(adap, &msg, 1); ++#ifndef CONFIG_SND_FTSSP010_AC97 ++ ret = i2c_transfer(adap, &msg, 1); ++ if (ret != 0) { ++ printk("i2c read failed\n"); ++ return -1; ++ } ++ else ++#endif ++ { ++ i2c_value = (data[0]&0xff) << 8 | (data[1]&0xff); ++ return i2c_value; ++ } ++} ++ ++static void i2s_alc5630_write(unsigned int raddr, unsigned int data, struct i2c_client *client) ++{ ++#ifndef CONFIG_SND_FTSSP010_AC97 ++ struct i2c_adapter *adap = client->adapter; ++ int ret; ++#endif ++ struct i2c_msg msg; ++ char buf[3]; ++ ++ //Writing ALC5630 register ++ msg.addr = raddr; ++ msg.flags = (client->flags & I2C_M_TEN) | ~I2C_M_RD; ++ msg.len = 1; ++ ++ buf[0] = (data >> 8) & 0xff; ++ buf[1] = data & 0xff; ++ msg.buf = (char *)buf; ++ ++ //ret = i2c_transfer(adap, &msg, 1); ++#ifndef CONFIG_SND_FTSSP010_AC97 ++ ret = i2c_transfer(adap, &msg, 1); ++ if (ret != 0) ++ { ++ printk("i2c write failed\n"); ++ } ++#endif ++} ++ ++/* ++static void i2s_alc5630_master_stereo_mode(struct i2c_client *client) ++{ ++ //printk(">>>>>>>>> (7) i2s_alc5630_master_stereo_mode() is called.\n"); ++ i2s_alc5630_write(0x02, 0x5f5f, client); ++ mdelay(50); ++ i2s_alc5630_write(0x04, 0x5f5f, client); ++ mdelay(50); ++ i2s_alc5630_write(0x26, 0x000f, client); ++ mdelay(50); ++ i2s_alc5630_write(0x34, 0x0000, client); // codec master mode ++ //i2s_alc5630_write(0x34, 0x8000, client); // codec slave mode ++ mdelay(50); ++ i2s_alc5630_write(0x3a, 0x0801, client); ++ mdelay(50); ++ i2s_alc5630_write(0x3c, 0xffff, client); ++ mdelay(50); ++ i2s_alc5630_write(0x3e, 0xffff, client); ++ mdelay(50); ++ i2s_alc5630_write(0x60, 0x3075, client); // codec master mode. divider. ++ mdelay(50); ++ i2s_alc5630_write(0x62, 0x1010, client); // codec master mode. divider. ++ ++} ++*/ ++ ++/* ++static void i2s_alc5630_read_test(struct i2c_client *client) ++{ ++ char data[3]; ++ printk(">>>>> : i2s_alc5630_read_test().....\n"); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0, i2s_alc5630_read(0x0, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x02, i2s_alc5630_read(0x02, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x04, i2s_alc5630_read(0x04, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x06, i2s_alc5630_read(0x06, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x08, i2s_alc5630_read(0x08, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0a, i2s_alc5630_read(0x0a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0c, i2s_alc5630_read(0x0c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x0e, i2s_alc5630_read(0x0e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x10, i2s_alc5630_read(0x10, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x12, i2s_alc5630_read(0x12, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x14, i2s_alc5630_read(0x14, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x16, i2s_alc5630_read(0x16, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x18, i2s_alc5630_read(0x18, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x1a, i2s_alc5630_read(0x1a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x1c, i2s_alc5630_read(0x1c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x1e, i2s_alc5630_read(0x1e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x20, i2s_alc5630_read(0x20, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x22, i2s_alc5630_read(0x22, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x24, i2s_alc5630_read(0x24, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x26, i2s_alc5630_read(0x26, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x28, i2s_alc5630_read(0x28, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x2a, i2s_alc5630_read(0x2a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x2c, i2s_alc5630_read(0x2c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x2e, i2s_alc5630_read(0x2e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x30, i2s_alc5630_read(0x30, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x32, i2s_alc5630_read(0x32, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x34, i2s_alc5630_read(0x34, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x36, i2s_alc5630_read(0x36, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x38, i2s_alc5630_read(0x38, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x3a, i2s_alc5630_read(0x3a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x3c, i2s_alc5630_read(0x3c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x3e, i2s_alc5630_read(0x3e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x40, i2s_alc5630_read(0x40, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x42, i2s_alc5630_read(0x42, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x44, i2s_alc5630_read(0x44, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x46, i2s_alc5630_read(0x46, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x48, i2s_alc5630_read(0x48, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x4a, i2s_alc5630_read(0x4a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x4c, i2s_alc5630_read(0x4c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x4e, i2s_alc5630_read(0x4e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x50, i2s_alc5630_read(0x50, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x52, i2s_alc5630_read(0x52, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x54, i2s_alc5630_read(0x54, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x56, i2s_alc5630_read(0x56, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x58, i2s_alc5630_read(0x58, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x5a, i2s_alc5630_read(0x5a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x5c, i2s_alc5630_read(0x5c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x5e, i2s_alc5630_read(0x5e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x60, i2s_alc5630_read(0x60, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x62, i2s_alc5630_read(0x62, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x64, i2s_alc5630_read(0x64, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x66, i2s_alc5630_read(0x66, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x68, i2s_alc5630_read(0x68, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x6a, i2s_alc5630_read(0x6a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x6c, i2s_alc5630_read(0x6c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x6e, i2s_alc5630_read(0x6e, data,client)); ++ ++ printk("Reg 0x%02x = 0x%08x\n", 0x70, i2s_alc5630_read(0x70, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x72, i2s_alc5630_read(0x72, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x74, i2s_alc5630_read(0x74, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x76, i2s_alc5630_read(0x76, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x78, i2s_alc5630_read(0x78, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x7a, i2s_alc5630_read(0x7a, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x7c, i2s_alc5630_read(0x7c, data,client)); ++ printk("Reg 0x%02x = 0x%08x\n", 0x7e, i2s_alc5630_read(0x7e, data,client)); ++ ++} ++*/ ++ ++static void i2s_al5630_slave_stereo_mode(struct i2c_client *client) ++{ ++ ++ ++ i2s_alc5630_write(0x34, 0x8000, client); // codec slave mode ++ i2s_alc5630_write(0x0c, 0x1010, client); ++ i2s_alc5630_write(0x10, 0xee03, client); ++ i2s_alc5630_write(0x1c, 0x0748, client); ++ //i2s_alc5630_write(0x02, 0x8080, client); ++ //i2s_alc5630_write(0x04, 0x8888, client); ++ i2s_alc5630_write(0x62, 0x0000, client); ++ ++} ++ ++//End ADD by river 2011.01.26 ++ ++ ++/* Drive PMU to generate I2S main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ ++void pmu_set_i2s_clocking(unsigned int speed) ++{ ++ unsigned int pmu_pdllcr1; /* PLL/DLL Control Register 1 */ ++ /* Configure PMU to generate I2S main clock */ ++ #ifdef CONFIG_PLAT_AG101 ++ pmu_pdllcr1 = inl(PMU_PDLLCR1)&0xfff0ffff; /* Bit 19-16 are relevent */ ++ #endif ++ ++ switch (speed) { ++ case 8000: ++ pmu_pdllcr1 |= 0x00000000; /* 2.048MHz x2 */ ++ break; ++ case 11025: ++ pmu_pdllcr1 |= 0x00010000; /* 2.8224MHz x2 */ ++ break; ++ case 16000: ++ pmu_pdllcr1 |= 0x00020000; /* 4.096MHz x2 */ ++ break; ++ case 22050: ++ pmu_pdllcr1 |= 0x00030000; /* 5.6448MHz x2 */ ++ break; ++ case 32000: ++ pmu_pdllcr1 |= 0x00040000; /* 8.192MHz x2 */ ++ break; ++ case 44100: ++ pmu_pdllcr1 |= 0x00050000; /* 11.2896Mhz x2 */ ++ break; ++ case 48000: ++ pmu_pdllcr1 |= 0x00060000; /* 12.2880MHz x2 */ ++ break; ++ default: ++ printk("%s: Unknown i2s speed %d\n",__func__,speed); ++ }; ++ ++ #ifdef CONFIG_PLAT_AG101 ++ outl(pmu_pdllcr1, PMU_PDLLCR1); ++ /* Configure PMU to select I2S output (instead of AC97) */ ++ outl(inl(PMU_MFPSR)&(~(1<<3)), PMU_MFPSR); /* clear bit 3 of MFPSR*/ ++ #endif ++} ++ ++/* Drive PMU to generate AC97 main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ ++void pmu_set_ac97_clocking(unsigned int speed) ++{ ++ /* Configure PMU to select AC97 output (instead of I2S) */ ++ /* Set GPIO[26] to AC97 clock, use 49.152MHz main clock (AC97 CLK1) */ ++ //outl(inl(PMU_MFPSR)|((1<<13)|(1<<3)), PMU_MFPSR); /* Set bit 13 & 3 of MFPSR*/ ++ #ifndef CONFIG_PLAT_AG102 ++ outl(inl(PMU_MFPSR)|((1<<13)|(1<<3)), PMU_MFPSR); /* Set bit 13 & 3 of MFPSR*/ ++ #endif ++} ++ ++/* Programs PMU to set I2S/AC97 DMA Channel, ch=0-7 */ ++void pmu_set_i2s_dma_channel(unsigned ch) ++{ ++ #ifdef CONFIG_PLAT_AG101 ++ ch&=0x7; ++ //outl((inl(PMU_I2SAC97_REQACKCFG)&(~0x7))|ch, PMU_I2SAC97_REQACKCFG); ++ outl(0xa, PMU_I2SAC97_REQACKCFG); ++ outl(0xb, PMU_C4); ++ #endif ++} ++ ++/* Initialize FTSSP010 to output to UDA1345TS via I2S */ ++#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0) ++#define FTSSP010_CONTROL0_OPM_STEREO 0xC ++#define FTSSP010_CONTROL0_OPM_MONO 0x8 ++ ++#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4) ++#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8) ++ ++#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10) ++#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC) ++#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14) ++#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) ++#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C) ++ ++//static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE }; ++//static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE }; ++ ++//ADD by river 2011.02.11 ++static struct i2c_client *g_i2c_client; ++ ++ ++#define FTSSP010_ACLINK_SLOT_VALID(x) (SSP_FTSSP010_va_base[(x)]+0x20) ++ ++void ftssp010_set_int_control(int cardno, unsigned val) ++{ ++ outl(val, FTSSP010_INT_CONTROL(cardno)); ++} ++ ++unsigned ftssp010_get_int_status(int cardno) ++{ ++ return (inl(FTSSP010_INT_STATUS(cardno))); ++} ++ ++int ftssp010_get_status(int cardno) ++{ ++ return (inl(FTSSP010_STATUS(cardno))); ++} ++ ++int ftssp010_tx_fifo_not_full(int cardno) ++{ ++ return (inl(FTSSP010_STATUS(cardno))&0x2)==0x2; ++} ++ ++int ftssp010_tx_fifo_vaild_entries(int cardno) ++{ ++ return (inl(FTSSP010_STATUS(cardno))>>12) & 0x1f; ++} ++ ++#include "FTSSP010_W83972D.h" ++ ++// AC97 codec tags ++#define TAG_COMMAND 0xe000 ++#define TAG_DATA 0x9800 /* Slot 3/4 */ ++#define TAG_DATA_MONO 0x9000 /* Slot 3 */ ++//#define TAG_DATA_LINE_IN 0x9000 /* Slot 3 */ ++ ++void ftssp010_ac97_write_codec_start(unsigned int cardno) ++{ ++ outl(0x0, FTSSP010_INT_CONTROL(cardno));/*Disable interrupts & DMA req */ ++ outl(0xC, FTSSP010_CONTROL2(cardno)); /* Disable FTSSP010, clear RX/TX Fifo. */ ++ outl(TAG_COMMAND, FTSSP010_ACLINK_SLOT_VALID(cardno)); ++} ++ ++void ftssp010_ac97_write_codec(unsigned int cardno,unsigned int reg,unsigned int data) ++{ ++ outl(reg << 12, FTSSP010_DATA(cardno)); ++ mdelay(50); ++ outl(data << 4, FTSSP010_DATA(cardno)); ++ mdelay(50); ++} ++ ++void ftssp010_ac97_write_codec_commit(unsigned int cardno) ++{ ++ while((inl(FTSSP010_CONTROL2(cardno))&0x1)==0) { ++ outl(0x3 , FTSSP010_CONTROL2(cardno)); /* SSPEN + TXDOE */ ++ } ++ while(ftssp010_tx_fifo_vaild_entries(cardno)) ++ ; ++ /* Wait for frame completion */ ++ while((inl(FTSSP010_INT_STATUS(cardno))&0x10)==0) ++ ; ++ outl(0x0, FTSSP010_CONTROL2(cardno)); ++} ++ ++/* Configure FTSSP010 to a given sampling rate and channel number ++ * for AC97 mode in playback mode ++ */ ++void init_hw(unsigned int cardno,unsigned int ac97, struct i2c_client *client) ++{ ++ ++ //printk(">>>>>>>>>> (5) init_hw() is called.\n"); ++ g_i2c_client = client; ++ ++ if(ac97) ++ { ++ //pmu_set_ac97_clocking(48000); ++ #ifndef CONFIG_PLAT_AG102 ++ pmu_set_ac97_clocking(48000); ++ #endif ++ outl(0x400c, FTSSP010_CONTROL0(cardno)); /* set FTSSP010 to AC97 mode */ ++ mdelay(50); ++ outl(0xc400, FTSSP010_INT_CONTROL(cardno)); ++ mdelay(50); ++ outl(0x20, FTSSP010_CONTROL2(cardno)); /* Cold Reset AC-Link */ ++ mdelay(50); ++ while(inl(FTSSP010_CONTROL2(cardno))) ++ mdelay(50); ++ outl(0x40, FTSSP010_CONTROL2(cardno)); /* Reset AC-Link */ ++ mdelay(1500); ++ } ++ else ++ { ++ ++ //printk(">>>>>>>>> (6) I2S mode selected....YAYAYA......\n"); ++ #ifdef CONFIG_PLAT_AG101 ++ outl(inl(PMU_MFPSR)&(~(1<<3)), PMU_MFPSR); /* clear bit 3 of MFPSR*/ ++ outl(0xa, PMU_I2SAC97_REQACKCFG); ++ outl(0xb, PMU_C4); ++ #endif ++ ++ //MOD by river 2011.01.26 ++ //i2s_alc5630_master_stereo_mode(client); ++ i2s_al5630_slave_stereo_mode(client); ++ //ssp_slave_stereo_mode(); ++ //End MOD by river 2011.01.26 ++ outl(0x311c, FTSSP010_CONTROL0(cardno)); /* I2S Master */ ++ outl(0, FTSSP010_CONTROL1(cardno)); /* I2S Master */ ++ outl(0xc400, FTSSP010_INT_CONTROL(cardno)); /* I2S Master */ ++ outl(0x40, FTSSP010_CONTROL2(cardno)); /* Reset AC-Link */ ++ ++ //i2s_alc5630_read_test(client); ++ } ++} ++static void _ftssp010_config_ac97(int cardno, unsigned is_stereo, unsigned speed, int is_rec) ++{ ++ /* Codec initialization */ ++ ftssp010_ac97_write_codec_start(cardno); ++ ftssp010_ac97_write_codec(cardno, W83972D_RESET, 0); ++ ftssp010_ac97_write_codec_commit(cardno); ++ ++ msleep_interruptible(10); ++ ftssp010_ac97_write_codec_start(cardno); ++ ++ if (is_rec) { /* Recording */ ++ /* Mute output */ ++ //ftssp010_ac97_write_codec(cardno, W83972D_STEREO_OUTPUT_CONTROL, 0x8000); ++ /* Mute PCM */ ++ //ftssp010_ac97_write_codec(cardno, W83972D_PCM_OUTPUT_CONTROL, 0x8000); ++ ++ /* Register 0x10, Line-In/Mic Gain */ ++ ftssp010_ac97_write_codec(cardno, W83972D_LINE_IN_VOLUME, 0x808); ++ //ftssp010_ac97_write_codec(cardno, W83972D_AUX_INPUT_CONTROL, 0x808); ++ ftssp010_ac97_write_codec(cardno, W83972D_MIC_VOLUME, 0x8); ++ /* FIXME: REC from line-in only */ ++ ++ /* Register 0x1A, Record Select=StereoMix */ ++ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_SELECT, 0x505 /*404*/); ++ /* Register 0x1C, Record Gain=0db */ ++ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN, 0x808); ++ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN_MIC, 0x8); ++ } else { /* Playback */ ++ /* Register 0x10, Mute Line-In/Mic Gain */ ++ ftssp010_ac97_write_codec(cardno, W83972D_LINE_IN_VOLUME, 0x8000); ++ ftssp010_ac97_write_codec(cardno, W83972D_MIC_VOLUME, 0x8000); ++ ++ /* Register 0x1A, Mute Record Gains */ ++ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN, 0x8000); ++ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN_MIC, 0x8000); ++ ++ /* Output */ ++ ftssp010_ac97_write_codec(cardno, W83972D_STEREO_OUTPUT_CONTROL, 0); ++ ftssp010_ac97_write_codec(cardno, W83972D_PCM_OUTPUT_CONTROL, 0x808); ++ } ++ ++#if 0 ++ ftssp010_ac97_write_codec(cardno, W83972D_EXT_AUDIO_CONTROL, 0x1); ++ ftssp010_ac97_write_codec(cardno, W83972D_DAC_SAMPLE_RATE_CONTROL, speed); ++#endif ++ ++ ftssp010_ac97_write_codec_commit(cardno); ++ msleep_interruptible(10); ++ ++ /* Start data transfer */ ++// if(is_rec) { ++// outl(TAG_DATA_LINE_IN, FTSSP010_ACLINK_SLOT_VALID(cardno)); ++// } else { ++ if(is_stereo) ++ outl(TAG_DATA, FTSSP010_ACLINK_SLOT_VALID(cardno)); ++ else ++ outl(TAG_DATA_MONO, FTSSP010_ACLINK_SLOT_VALID(cardno)); ++// } ++ while(inl(FTSSP010_INT_STATUS(cardno))&0x3); ++// msleep_interruptible(10); ++} ++ ++void ftssp010_config_ac97_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit) ++{ ++ _ftssp010_config_ac97(cardno, is_stereo, speed, 0); ++} ++ ++void ftssp010_config_ac97_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit) ++{ ++ _ftssp010_config_ac97(cardno, is_stereo, speed, 1); ++} ++/* ++ * Configure FTSSP010 to a given sampling rate and channel number ++ * for I2S mode ++ */ ++void ftssp010_config(int cardno, unsigned is_stereo, unsigned speed, int width, int is_rec) ++{ ++ int use8bit = (width == 1 ? 1 : 0); ++ unsigned opm, bps = 2 * (use8bit ? 8 : 16); /* bits per 1 second audio data. */ ++ unsigned fpclkdiv = 0; ++ ++ //ADD by river 2011.06.02 ++ struct alc5630_data *alc5630; ++ char data[3]; ++ opm = is_stereo ? FTSSP010_CONTROL0_OPM_STEREO : FTSSP010_CONTROL0_OPM_MONO; ++ //MOD by river 2011.01.27 ++ outl(0x3100 | opm, FTSSP010_CONTROL0(cardno)); /* I2S Master */ ++ //End MOD by river 2011.01.27 ++ ++#if 0 ++ printk("%s: use %dHz %d-bit %s \n",__func__, ++ speed, ++ use8bit?8:16, ++ is_stereo?"stereo":"mono" ++ ); ++#endif ++ ++ /* configures CONTROL1 to use suitable clock divider. ++ the I2S clock is generated from PMU. */ ++ bps *= speed; ++ switch(speed) { ++ case 8000: /* SCLK : 256KHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //? ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ //i2s_alc5630_write(0x44, 0x6a0, g_i2c_client); //? ++ //i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ //i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0xBB; ++ ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(2048000, bps); ++ break; ++ case 11025: /* SCLK : 352.8KHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //? ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0x88; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(2822400, bps); ++ break; ++ case 16000: /* SCLK : 512KHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //? ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0x5f; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(4096000, bps); ++ break; ++ case 22050: /* SCLK : 705.6KHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0x45; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(5644800, bps); ++ break; ++ case 24000: /* SCLK : 768KHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0x3e; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(5644800, bps); ++ break; ++ case 32000: /* SCLK : 1024KHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ //fpclkdiv = 0x2e; ++ fpclkdiv = 0x2f; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(8192000, bps); ++ break; ++ case 44100: /* SCLK : 1.4112 MHZ */ /* 96 MHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0x22; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(11289600, bps); ++ break; ++ case 48000: /* SCLK : 1.536 MHZ */ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); ++ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); ++ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); ++ fpclkdiv = 0x1f; ++ //fpclkdiv=SSPCLK_TO_SCLKDIV(12288000, bps); ++ ++ break; ++ default: ++ printk("%s: unsupported speed %d\n", __func__,speed); ++ return; ++ }; ++ ++ ++ if(!use8bit) { ++ outl(0xf0000|fpclkdiv, FTSSP010_CONTROL1(cardno)); /* 16bits */ ++ //outl(0xf0000|0x10, FTSSP010_CONTROL1(cardno)); /* 16bits */ ++ //outl(0xf0000|0x22, FTSSP010_CONTROL1(cardno)); /* 16bits */ ++ } else { ++ outl(0x70000|fpclkdiv, FTSSP010_CONTROL1(cardno)); /* 8bits */ ++ } ++ ++ //printk("#####$$$$$ : bps = %d\n", bps); ++ //printk("#####$$$$$ : speed = %d\n", speed); ++ //printk("#####$$$$$ : fpclkdiv = 0x%08x\n", fpclkdiv); ++ //printk("#####$$$$$ : FTSSP010_CONTROL1(cardno) = 0x%08x\n", inl(FTSSP010_CONTROL1(cardno))); ++ ++ if(is_rec) ++ outl(inl(FTSSP010_INT_CONTROL(cardno))&(~0x0f15), FTSSP010_INT_CONTROL(cardno)); /* Disable all interrupts */ ++ else ++ outl(inl(FTSSP010_INT_CONTROL(cardno))&(~0xf02a) , FTSSP010_INT_CONTROL(cardno)); /* Disable all interrupts */ ++ ++ outl(0xc, FTSSP010_CONTROL2(cardno)); /* clear FIFOs */ ++ ++ //ADD by river 2011.06.02 ++ alc5630 = i2c_get_clientdata(g_i2c_client); ++ //End ++ ++ if(is_rec) { ++ printk("ftssp010_config() for I2S mode in record.\n"); ++ //ADD by river 2011.03.21 ++ //TEST by river 2011.03.22 for recording => workable ++ //i2s_alc5630_write(0x0e, 0x8888, g_i2c_client); ++ i2s_alc5630_write(0x0e, 0x0808, g_i2c_client); ++ i2s_alc5630_write(0x10, 0xee03, g_i2c_client); ++ i2s_alc5630_write(0x22, 0x0500, g_i2c_client); ++ i2s_alc5630_write(0x1c, 0x0748, g_i2c_client); ++ i2s_alc5630_write(0x14, 0x1f1f, g_i2c_client); ++ i2s_alc5630_write(0x12, 0xdfdf, g_i2c_client); ++ ++ i2s_alc5630_write(0x26, 0x000f, g_i2c_client); ++ i2s_alc5630_write(0x3a, 0xffff, g_i2c_client); ++ i2s_alc5630_write(0x3c, 0xffff, g_i2c_client); ++ //i2s_alc5630_write(0x3e, 0xffff, g_i2c_client); ++ i2s_alc5630_write(0x3e, 0x80cf, g_i2c_client); ++ ++ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); ++ i2s_alc5630_write(0x42, 0x2000, g_i2c_client); ++ i2s_alc5630_write(0x40, 0x8c0a, g_i2c_client); ++ ++ //i2s_alc5630_write(0x02, 0x0000, g_i2c_client); ++ i2s_alc5630_write(0x02, 0x8080, g_i2c_client); ++ i2s_alc5630_write(0x04, 0x0000, g_i2c_client); ++ //End TEST by river 2011.03.22 ++ ++ //printk("ftssp010_config() for I2S mode (Recording) ===> Dump register.\n"); ++ //i2s_alc5630_read_test(g_i2c_client); ++ ++ } ++ else { ++ //printk("ftssp010_config() for I2S mode in playback.\n"); ++ //ADD by river 2011.03.24 for record and playback case ++ i2s_alc5630_write(0x0e, 0x0808, g_i2c_client); ++ i2s_alc5630_write(0x12, 0xcbcb, g_i2c_client); ++ i2s_alc5630_write(0x14, 0x7f7f, g_i2c_client); ++ i2s_alc5630_write(0x22, 0x0000, g_i2c_client); ++ i2s_alc5630_write(0x3e, 0x8000, g_i2c_client); ++ i2s_alc5630_write(0x40, 0x0c0a, g_i2c_client); ++ i2s_alc5630_write(0x42, 0x0000, g_i2c_client); ++ //End ADD by river 2011.03.24 for record and playback case ++ ++ //TEST by river 2011.03.23 ++ i2s_alc5630_write(0x26, 0x0000, g_i2c_client); ++ i2s_alc5630_write(0x3c, 0x2000, g_i2c_client); ++ i2s_alc5630_write(0x3a, 0x0002, g_i2c_client); ++ i2s_alc5630_write(0x3c, 0xa330, g_i2c_client); ++ i2s_alc5630_write(0x3a, 0xc843, g_i2c_client); ++ //End TEST by river 2011.03.23 ++ ++ //ADD by river 2011.03.23 for HP Out De-pop ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0002 , g_i2c_client); ++ i2s_alc5630_write(0x04, i2s_alc5630_read(0x04, data,g_i2c_client)|0x8080 , g_i2c_client); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0040 , g_i2c_client); ++ i2s_alc5630_write(0x3c, i2s_alc5630_read(0x3C, data,g_i2c_client)|0x2000 , g_i2c_client); ++ i2s_alc5630_write(0x3E, i2s_alc5630_read(0x3E, data,g_i2c_client)|0xfC00 , g_i2c_client); ++ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x0100 , g_i2c_client); ++ mdelay(500); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0200 , g_i2c_client); ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0100 , g_i2c_client); ++ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)& 0xfeff ,g_i2c_client); ++ //End ADD by river 2011.03.23 for HP Out De-pop ++ ++ ++ //TEST by river 2011.03.22 ++ i2s_alc5630_write(0x1c, 0x0748, g_i2c_client); ++ //End TEST by river 2011.03.22 ++ ++ ++ //TEST by river 2011.03.16 ++ //i2s_alc5630_write(0x02, 0x8080, g_i2c_client); ++ i2s_alc5630_write(0x26, 0x000f, g_i2c_client); ++ //End TEST by river 2011.03.16 ++ ++ //ADD by river 2011.03.23 ++ if (alc5630->gpio2_value==0x0) ++ i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,g_i2c_client) & 0xFBFF)|0x0040 , g_i2c_client); ++ else ++ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0440 , g_i2c_client); ++ ++ ++ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x0020 , g_i2c_client); ++ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x00c0 , g_i2c_client); ++ i2s_alc5630_write(0x04, i2s_alc5630_read(0x04, data,g_i2c_client)& 0x7f7f , g_i2c_client); ++ mdelay(30); ++ ++ if (alc5630->gpio2_value==0x0) { ++ //printk(">>>>>>>>>>>> Turn off internal speaker.....\n"); ++ i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client); ++ //i2s_alc5630_write(0x02, 0x0000, g_i2c_client); ++ } ++ else { ++ //printk(">>>>>>>>>>>> Turn on internal speaker.....\n"); ++ i2s_alc5630_write(0x02, 0x0000, g_i2c_client); ++ //i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client); ++ } ++ //End ADD by river 2011.03.23 ++ ++ ++ //printk("ftssp010_config() for I2S mode (Playback) ===> Dump register.\n"); ++ //i2s_alc5630_read_test(g_i2c_client); ++ } ++ ++#if 0 ++ /* Stuff TX fifo */ ++ while(ftssp010_tx_fifo_not_full(cardno)) { ++ outl(0x0, FTSSP010_DATA(cardno)); ++ } ++#endif ++} ++ ++void ftssp010_config_tx(int cardno, unsigned is_stereo, unsigned speed, int width) ++{ ++ return ftssp010_config(cardno, is_stereo, speed, width, 0); ++} ++ ++void ftssp010_config_rx(int cardno, unsigned is_stereo, unsigned speed, int width) ++{ ++ return ftssp010_config(cardno, is_stereo, speed, width, 1); ++} ++ ++/* Configures FTSSP010 to start TX. If use_dma being nonzero, ++ * FTSSP010 will use hardware handshake for DMA */ ++void ftssp010_start_tx(int cardno, unsigned use_dma) ++{ ++ unsigned bogus=0x800*3; ++ if(use_dma) { ++ /* Enable H/W DMA Request and set TX DMA threshold to 12*/ ++// outl(0xC022, FTSSP010_INT_CONTROL(cardno)); ++ outl(inl(FTSSP010_INT_CONTROL(cardno)) | 0xc422, FTSSP010_INT_CONTROL(cardno)); ++#if 0 ++ printk("%s: enable DMA request\n", __func__); ++#endif ++ } ++// outl(0x3, FTSSP010_CONTROL2(cardno)); ++ outl(inl(FTSSP010_CONTROL2(cardno)) | 0x3, FTSSP010_CONTROL2(cardno)); ++// printk("%s\n",__func__); ++// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); ++// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); ++ if(!use_dma) { ++ while(bogus>0) { ++ while(!ftssp010_tx_fifo_not_full(cardno)) ++ udelay(50); ++ outl(0, FTSSP010_DATA(cardno)); ++ bogus--; ++ } ++ } ++} ++ ++/* Configures FTSSP010 to start RX. If use_dma being nonzero, ++ * FTSSP010 will use hardware handshake for DMA */ ++void ftssp010_start_rx(int cardno, unsigned use_dma) ++{ ++ if(use_dma) { ++ /* Enable H/W DMA Request and set RX DMA threshold to 2*/ ++// outl(0x0111, FTSSP010_INT_CONTROL(cardno)); ++ outl(inl(FTSSP010_INT_CONTROL(cardno)) | 0xc411, FTSSP010_INT_CONTROL(cardno)); ++#if 0 ++ printk("%s: enable DMA request\n", __func__); ++#endif ++ } ++// outl(0x3, FTSSP010_CONTROL2(cardno)); ++ outl(inl(FTSSP010_CONTROL2(cardno)) | 0x3, FTSSP010_CONTROL2(cardno)); ++// printk("%s\n",__func__); ++// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); ++// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); ++} ++ ++void ftssp010_stop_tx(int cardno) ++{ ++// outl(0, FTSSP010_CONTROL2(cardno)); ++ outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x22), FTSSP010_INT_CONTROL(cardno)); ++// printk("%s\n",__func__); ++// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); ++// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); ++} ++ ++void ftssp010_stop_rx(int cardno) ++{ ++ //outl(0, FTSSP010_CONTROL2(cardno)); ++ outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x11), FTSSP010_INT_CONTROL(cardno)); ++ //printk("%s\n",__func__); ++ //printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); ++ //printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); ++} ++ +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_UDA1345TS.h linux-3.4.110/sound/nds32/FTSSP010_UDA1345TS.h +--- linux-3.4.110.orig/sound/nds32/FTSSP010_UDA1345TS.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_UDA1345TS.h 2016-04-07 10:20:51.066085821 +0200 +@@ -0,0 +1,81 @@ ++/* FTSSP010 - UDA1345TS supporting library header */ ++/* ++ * ++ * $log$ ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Programming sequence: ++ * Suppose your playback format is 44.1KHz, 16 bit stereo ++ * PIO mode: ++ * pmu_set_i2s_clocking(44100); ++ * ftssp010_config(1, 44100, 0); ++ * ftssp010_start_tx(0); ++ * while(ftssp010_tx_fifo_not_full()) { ++ * Poke_your_PCM_data_to_FTSSP_data_port ++ * ++ * DMA mode: ++ * pmu_set_i2s_clocking(44100); ++ * ftssp010_config(1, 44100); ++ * ++ * pmu_set_i2s_dma_channel(ch); ++ * ftssp010_start_tx(1); ++ * ++ * ftssp010_stop_tx(); ++ */ ++#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) ++#define FTSSP010_DATA_PA(x) (SSP_FTSSP010_pa_base[(x)]+0x18) ++ ++/* Initialize FTSSP010 to output to UDA1345TS via I2S */ ++#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0) ++#define FTSSP010_CONTROL0_OPM_STEREO 0xC ++#define FTSSP010_CONTROL0_OPM_MONO 0x8 ++ ++#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4) ++#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8) ++ ++#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10) ++#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC) ++#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14) ++#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) ++#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C) ++ ++static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE }; ++static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE }; ++ ++/* Drive PMU to generate I2S main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ ++extern void pmu_set_i2s_clocking(unsigned int speed); ++/* Programs PMU to set I2S/AC97 DMA Channel, ch=0-7 */ ++extern void pmu_set_i2s_dma_channel(unsigned ch); ++ ++/* Drive PMU to generate AC97 main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ ++extern void pmu_set_ac97_clocking(unsigned int speed); ++ ++/* Returns FTSSP010 status */ ++extern void ftssp010_set_int_control(int cardno, unsigned val); ++extern int ftssp010_get_status(int cardno); ++extern unsigned ftssp010_get_int_status(int cardno); ++/* Polls FIFO full register */ ++extern int ftssp010_tx_fifo_not_full(int cardno); ++/* Configure FTSSP010 to a given sampling rate and channel number */ ++extern void ftssp010_config_tx(int cardno, unsigned is_stereo, unsigned speed, int use8bit); ++extern void ftssp010_config_rx(int cardno, unsigned is_stereo, unsigned speed, int use8bit); ++ ++/* Configure FTSSP010 to a given sampling rate and channel number */ ++extern void ftssp010_config_ac97_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit); ++ ++extern void ftssp010_config_ac97_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit); ++ ++/* Initialize FTSSP010 to output to UDA1345TS via I2S */ ++extern void ftssp010_start_tx(int cardno, unsigned use_dma); ++extern void ftssp010_start_rx(int cardno, unsigned use_dma); ++extern void ftssp010_stop_tx(int cardno); ++extern void ftssp010_stop_rx(int cardno); ++ ++ +diff -Nur linux-3.4.110.orig/sound/nds32/FTSSP010_W83972D.h linux-3.4.110/sound/nds32/FTSSP010_W83972D.h +--- linux-3.4.110.orig/sound/nds32/FTSSP010_W83972D.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/FTSSP010_W83972D.h 2016-04-07 10:20:51.066085821 +0200 +@@ -0,0 +1,17 @@ ++/* AC97 Codec related */ ++ ++ ++/* Register Index for Winbond W83972D AC97 Codec */ ++#define W83972D_RESET 0x0 ++#define W83972D_STEREO_OUTPUT_CONTROL 0x2 ++#define W83972D_MIC_VOLUME 0xE ++#define W83972D_LINE_IN_VOLUME 0x10 ++#define W83972D_AUX_INPUT_CONTROL 0x16 ++#define W83972D_PCM_OUTPUT_CONTROL 0x18 ++#define W83972D_RECORD_SELECT 0x1A ++#define W83972D_RECORD_GAIN 0x1C ++#define W83972D_RECORD_GAIN_MIC 0x1E ++#define W83972D_EXT_AUDIO_CONTROL 0x2A ++#define W83972D_DAC_SAMPLE_RATE_CONTROL 0x2C ++#define W83972D_VER1 0x7C ++#define W83972D_VER2 0x7E +diff -Nur linux-3.4.110.orig/sound/nds32/hda.h linux-3.4.110/sound/nds32/hda.h +--- linux-3.4.110.orig/sound/nds32/hda.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/hda.h 2016-04-07 10:20:51.066085821 +0200 +@@ -0,0 +1,106 @@ ++// HDA Mode definition ++ #define HDA_MODE 0x80000000 ++ ++ // HDA CTRL definition ++ #define HDA_CRST_SET 0x00 ++ #define HDA_CRST_CLR 0x20 ++ #define HDA_CRST_MASK 0x20 ++ #define HDA_RST_FCNT_OFS 8 ++ ++ // HDA LNKST definition ++ #define HDA_COD_ALIVE 0x20000000 ++ ++ // HDA INTC definition ++ #define HDA_INTC_USOLEN 0x40000 ++ #define HDA_INTC_SDIWEN 0x20000 ++ #define HDA_INTC_CRINTE 0x10000 ++ ++ // HDA INTST definition ++ #define HDA_INTST_USOLEN 0x80 ++ #define HDA_INTST_SDIWEN 0x40 ++ #define HDA_INTST_CRINTE 0x20 ++ ++ // HDA ICMDST mask & offset ++ #define HDA_IRRADD_MASK 0xf0 ++ #define HDA_IRRUNSOL_MASK 0x08 ++ #define HDA_IRV_MASK 0x02 ++ #define HDA_ICB_MASK 0x01 ++ #define HDA_IRRADD_OFFSET 4 ++ #define HDA_IRRUNSOL_OFFSET 3 ++ #define HDA_IRV_OFFSET 1 ++ #define HDA_ICB_OFFSET 0 ++ //HDA OSDC/ISDC bit offset ++ #define HDA_SDC_STNUM_OFFSET 28 ++ #define HDA_SDC_SRUN_OFFSET 15 ++ #define HDA_SDC_BASE_OFFSET 14 ++ #define HDA_SDC_MULT_OFFSET 11 ++ #define HDA_SDC_DIV_OFFSET 8 ++ #define HDA_SDC_BITS_OFFSET 4 ++ #define HDA_SDC_CHAN_OFFSET 0 ++ ++ // HDA Codec CMD ++ #define HDA_COD_DEVADDR 0x00000000 ++ #define HDA_ROOT_NODE 0x00000000 ++ #define HDA_AUDIO_NODE 0x00100000 ++ #define HDA_OUTCOV_NODE 0x00200000 ++ //#define HDA_INCOV_NODE 0x0FF00000 ++ #define HDA_INCOV_NODE 0x00800000 //kane, for real CODEC node mapping ++ #define HDA_CMD_FGRST 0x0007FF00 ++ #define HDA_CMD_GETVID 0x000F0000 ++ #define HDA_CMD_SUBNCNT 0x000F0004 ++ #define HDA_CMD_FGTYPE 0x000F0005 ++ #define HDA_CMD_AUDIOWCAP 0x000F0009 ++ #define HDA_CMD_SETCVTSTR 0x00070600 ++ #define HDA_CMD_GETCVTSTR 0x000F0600 ++ #define HDA_CMD_SETCVTFMT 0x00020000 ++ #define HDA_CMD_GETCVTFMT 0x000A0000 ++ #define HDA_CMD_SETPROCST 0x00070300 ++ #define HDA_CMD_TRIGUNSOL 0x00070400 ++ //HDA Codec Resp ++ #define HDA_RESP_ZERO_VAL 0x00000000 ++ #define HDA_RESP_EXP_VID 0x10ec0888 ++ #define HDA_RSP_NODNUM_MSK 0xff0000 ++ #define HDA_RSP_NODCNT_MSK 0x0000ff ++ #define HDA_RSP_NODNUM_OFS 16 ++ #define HDA_RSP_NODCNT_OFS 0 ++ #define HDA_RSP_FGNTYPE_MSK 0xff ++ #define HDA_RSP_FGNUSCAP_MSK 0x100 ++ #define HDA_RSP_FGNTYPE_OFS 0 ++ #define HDA_RSP_FGNUSCAP_OFS 8 ++ #define HDA_RSP_AWCTYPE_MSK 0xf00000 ++ #define HDA_RSP_AWCUSCAP_MSK 0x000080 ++ #define HDA_RSP_AWCSTE_MSK 0x000001 ++ #define HDA_RSP_AWCTYPE_OFS 20 ++ #define HDA_RSP_AWCUSCAP_OFS 7 ++ #define HDA_RSP_AWCSTE_OFS 0 ++ #define HDA_RSP_CVTCHA_MSK 0x00 ++ #define HDA_RSP_CVTSTR_MSK 0xf0 ++ #define HDA_RSP_FMTTYPE_MSK 0x8000 ++ #define HDA_RSP_FMTBASE_MSK 0x4000 ++ #define HDA_RSP_FMTMULT_MSK 0x3800 ++ #define HDA_RSP_FMTDIV_MSK 0x0700 ++ #define HDA_RSP_FMTBITS_MSK 0x0070 ++ #define HDA_RSP_FMTCHNUM_MSK 0x000f ++ //HDA Func Group definition ++ #define HDA_FG_AUDIO 0x1 ++ // HDA Audio Widiget definition ++ #define HDA_AWC_INPUT 0x1 ++ #define HDA_AWC_OUTPUT 0x0 ++ #define HDA_AWC_MONO 0x0 ++ #define HDA_AWC_STEREO 0x1 ++ // HDA Converter Format definition ++ #define HDA_FMT_TYPE_OFS 15 ++ #define HDA_FMT_BASE_OFS 14 ++ #define HDA_FMT_MULT_OFS 11 ++ #define HDA_FMT_DIV_OFS 8 ++ #define HDA_FMT_BITS_OFS 4 ++ #define HDA_FMT_CHNUM_OFS 0 ++ // HDA Coverter Stream definition ++ #define HDA_STR_STR_OFS 4 ++ #define HDA_STR_CHA_OFS 0 ++ // HDA IOSDC definition ++ #define HDA_IN_STR 0 ++ #define HDA_OUT_STR 1 ++ #define HDA_STR_STOP 0 ++ #define HDA_STR_RUN 1 ++ +diff -Nur linux-3.4.110.orig/sound/nds32/Kconfig linux-3.4.110/sound/nds32/Kconfig +--- linux-3.4.110.orig/sound/nds32/Kconfig 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/Kconfig 2016-04-07 10:20:51.066085821 +0200 +@@ -0,0 +1,22 @@ ++menu "ALSA NDS32 devices" ++ depends on SND!=n && NDS32 ++ ++config SND_FTSSP010 ++ tristate "Faraday FTSSP010 audio Driver" ++ depends on SND && NDS32 ++ select SND_PCM ++# select SND_AC97_CODEC ++ ++choice ++ prompt "AC97/I2S/HDA selection" ++ depends on SND_FTSSP010 ++ default SND_FTSSP010_AC97 ++config SND_FTSSP010_AC97 ++ bool "AC97" ++config SND_FTSSP010_I2S ++ bool "I2S" ++config SND_FTSSP010_HDA ++ bool "HDA" ++endchoice ++endmenu ++ +diff -Nur linux-3.4.110.orig/sound/nds32/Makefile linux-3.4.110/sound/nds32/Makefile +--- linux-3.4.110.orig/sound/nds32/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-3.4.110/sound/nds32/Makefile 2016-04-07 10:20:51.066085821 +0200 +@@ -0,0 +1,10 @@ ++ifeq ($(CONFIG_SND_FTSSP010_AC97),y) ++snd-ftssp010-objs := FTSSP010_ALSA.o FTSSP010_lib.o ++endif ++ifeq ($(CONFIG_SND_FTSSP010_I2S),y) ++snd-ftssp010-objs := FTSSP010_ALSA.o FTSSP010_lib.o ++endif ++ifeq ($(CONFIG_SND_FTSSP010_HDA),y) ++snd-ftssp010-objs := FTSSP010_HDA.o FTSSP010_HDA_lib.o ++endif ++obj-$(CONFIG_SND_FTSSP010) += snd-ftssp010.o diff --git a/target/nds32/Makefile b/target/nds32/Makefile index 3d8f8d42b..146491b3b 100644 --- a/target/nds32/Makefile +++ b/target/nds32/Makefile @@ -6,6 +6,9 @@ include $(ADK_TOPDIR)/mk/kernel-build.mk include $(ADK_TOPDIR)/mk/image.mk KERNEL:=$(LINUX_DIR)/$(ADK_TARGET_KERNEL) +ifeq ($(ADK_TARGET_KERNEL_IMAGE),y) +KERNEL:=$(LINUX_DIR)/arch/nds32/boot/Image +endif # target helper text ifeq ($(ADK_TARGET_FS),archive) diff --git a/target/nds32/kernel/andes-ag101p b/target/nds32/kernel/andes-ag101p new file mode 100644 index 000000000..2f9a5e3c8 --- /dev/null +++ b/target/nds32/kernel/andes-ag101p @@ -0,0 +1,5 @@ +CONFIG_NDS32=y +CONFIG_PLATFORM_AHBDMA=y +CONFIG_PLATFORM_APBDMA=y +CONFIG_UART_CLK=14745600 +CONFIG_DEBUG_USER=y diff --git a/target/nds32/kernel/generic-nds32 b/target/nds32/kernel/generic-nds32 new file mode 100644 index 000000000..3d59624f7 --- /dev/null +++ b/target/nds32/kernel/generic-nds32 @@ -0,0 +1,2 @@ +CONFIG_NDS32=y +CONFIG_EARLY_PRINTK=y diff --git a/target/nds32/systems/andes-ag101p b/target/nds32/systems/andes-ag101p new file mode 100644 index 000000000..31d35a479 --- /dev/null +++ b/target/nds32/systems/andes-ag101p @@ -0,0 +1,9 @@ +config ADK_TARGET_SYSTEM_ANDES_AG101P + bool "Andes Technology AG101P" + depends on ADK_TARGET_LITTLE_ENDIAN + select ADK_TARGET_WITH_SERIAL + select ADK_TARGET_WITH_NET + select ADK_TARGET_WITH_NETDEVICE + select ADK_TARGET_KERNEL_IMAGE + help + Andes Technology AG101P (ADP-XC7KFF676) diff --git a/target/nds32/uclibc-ng.config b/target/nds32/uclibc-ng.config new file mode 100644 index 000000000..91d933139 --- /dev/null +++ b/target/nds32/uclibc-ng.config @@ -0,0 +1,248 @@ +# +# Automatically generated file; DO NOT EDIT. +# uClibc-ng 1.0.14 C Library Configuration +# +# TARGET_alpha is not set +# TARGET_arc is not set +# TARGET_arm is not set +# TARGET_avr32 is not set +# TARGET_bfin is not set +# TARGET_c6x is not set +# TARGET_cris is not set +# TARGET_frv is not set +# TARGET_h8300 is not set +# TARGET_hppa is not set +# TARGET_i386 is not set +# TARGET_ia64 is not set +# TARGET_lm32 is not set +# TARGET_m68k is not set +# TARGET_metag is not set +# TARGET_microblaze is not set +# TARGET_mips is not set +TARGET_nds32=y +# TARGET_nios2 is not set +# TARGET_or1k is not set +# TARGET_powerpc is not set +# TARGET_sh is not set +# TARGET_sparc is not set +# TARGET_x86_64 is not set +# TARGET_xtensa is not set + +# +# Target Architecture Features and Options +# +TARGET_ARCH="nds32" +FORCE_OPTIONS_FOR_ARCH=y +CONFIG_NDS32_PAGE_SIZE_4K=y +# CONFIG_NDS32_PAGE_SIZE_8K is not set +TARGET_SUBARCH="" + +# +# Using ELF file format +# +ARCH_HAS_DEPRECATED_SYSCALLS=y +ARCH_ANY_ENDIAN=y +ARCH_LITTLE_ENDIAN=y +# ARCH_WANTS_BIG_ENDIAN is not set +ARCH_WANTS_LITTLE_ENDIAN=y +ARCH_HAS_MMU=y +ARCH_USE_MMU=y +UCLIBC_HAS_FLOATS=y +UCLIBC_HAS_FPU=y +DO_C99_MATH=y +# DO_XSI_MATH is not set +# UCLIBC_HAS_FENV is not set +KERNEL_HEADERS="" +HAVE_DOT_CONFIG=y + +# +# General Library Settings +# +DOPIC=y +HAVE_SHARED=y +# FORCE_SHAREABLE_TEXT_SEGMENTS is not set +LDSO_LDD_SUPPORT=y +LDSO_CACHE_SUPPORT=y +# LDSO_PRELOAD_ENV_SUPPORT is not set +# LDSO_PRELOAD_FILE_SUPPORT is not set +LDSO_BASE_FILENAME="ld.so" +# LDSO_STANDALONE_SUPPORT is not set +# LDSO_PRELINK_SUPPORT is not set +# UCLIBC_STATIC_LDCONFIG is not set +LDSO_RUNPATH=y +LDSO_RUNPATH_OF_EXECUTABLE=y +LDSO_SAFE_RUNPATH=y +LDSO_SEARCH_INTERP_PATH=y +LDSO_LD_LIBRARY_PATH=y +LDSO_NO_CLEANUP=y +UCLIBC_CTOR_DTOR=y +# LDSO_GNU_HASH_SUPPORT is not set +# HAS_NO_THREADS is not set +UCLIBC_HAS_LINUXTHREADS=y +UCLIBC_HAS_THREADS=y +PTHREADS_DEBUG_SUPPORT=y +UCLIBC_HAS_SYSLOG=y +UCLIBC_HAS_LFS=y +MALLOC=y +# MALLOC_SIMPLE is not set +# MALLOC_STANDARD is not set +MALLOC_GLIBC_COMPAT=y +# UCLIBC_HAS_OBSTACK is not set +UCLIBC_DYNAMIC_ATEXIT=y +COMPAT_ATEXIT=y +UCLIBC_HAS_UTMPX=y +UCLIBC_HAS_UTMP=y +UCLIBC_SUSV2_LEGACY=y +UCLIBC_SUSV3_LEGACY=y +# UCLIBC_SUSV3_LEGACY_MACROS is not set +UCLIBC_SUSV4_LEGACY=y +# UCLIBC_STRICT_HEADERS is not set +# UCLIBC_HAS_STUBS is not set +UCLIBC_HAS_SHADOW=y +UCLIBC_HAS_PROGRAM_INVOCATION_NAME=y +UCLIBC_HAS___PROGNAME=y +UCLIBC_HAS_PTY=y +ASSUME_DEVPTS=y +UNIX98PTY_ONLY=y +UCLIBC_HAS_GETPT=y +UCLIBC_HAS_LIBUTIL=y +UCLIBC_HAS_TM_EXTENSIONS=y +UCLIBC_HAS_TZ_CACHING=y +UCLIBC_HAS_TZ_FILE=y +UCLIBC_HAS_TZ_FILE_READ_MANY=y +UCLIBC_TZ_FILE_PATH="/etc/TZ" +UCLIBC_FALLBACK_TO_ETC_LOCALTIME=y + +# +# Advanced Library Settings +# +UCLIBC_PWD_BUFFER_SIZE=256 +UCLIBC_GRP_BUFFER_SIZE=256 + +# +# Support various families of functions +# +UCLIBC_LINUX_MODULE_26=y +# UCLIBC_LINUX_MODULE_24 is not set +UCLIBC_LINUX_SPECIFIC=y +UCLIBC_HAS_GNU_ERROR=y +UCLIBC_BSD_SPECIFIC=y +UCLIBC_HAS_BSD_ERR=y +UCLIBC_HAS_OBSOLETE_BSD_SIGNAL=y +# UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL is not set +# UCLIBC_NTP_LEGACY is not set +UCLIBC_SV4_DEPRECATED=y +UCLIBC_HAS_REALTIME=y +UCLIBC_HAS_ADVANCED_REALTIME=y +UCLIBC_HAS_EPOLL=y +UCLIBC_HAS_XATTR=y +# UCLIBC_HAS_PROFILING is not set +UCLIBC_HAS_CRYPT_IMPL=y +UCLIBC_HAS_SHA256_CRYPT_IMPL=y +# UCLIBC_HAS_SHA512_CRYPT_IMPL is not set +UCLIBC_HAS_CRYPT=y +UCLIBC_HAS_NETWORK_SUPPORT=y +UCLIBC_HAS_SOCKET=y +UCLIBC_HAS_IPV4=y +UCLIBC_HAS_IPV6=y +# UCLIBC_HAS_RPC is not set +UCLIBC_USE_NETLINK=y +UCLIBC_SUPPORT_AI_ADDRCONFIG=y +UCLIBC_HAS_BSD_RES_CLOSE=y +UCLIBC_HAS_COMPAT_RES_STATE=y +# UCLIBC_HAS_EXTRA_COMPAT_RES_STATE is not set +UCLIBC_HAS_RESOLVER_SUPPORT=y +UCLIBC_HAS_LIBRESOLV_STUB=y +UCLIBC_HAS_LIBNSL_STUB=y + +# +# String and Stdio Support +# +UCLIBC_HAS_STRING_GENERIC_OPT=y +UCLIBC_HAS_STRING_ARCH_OPT=y +UCLIBC_HAS_CTYPE_TABLES=y +UCLIBC_HAS_CTYPE_SIGNED=y +# UCLIBC_HAS_CTYPE_UNSAFE is not set +UCLIBC_HAS_CTYPE_CHECKED=y +# UCLIBC_HAS_CTYPE_ENFORCED is not set +UCLIBC_HAS_WCHAR=y +# UCLIBC_HAS_LOCALE is not set +UCLIBC_HAS_HEXADECIMAL_FLOATS=y +UCLIBC_HAS_GLIBC_CUSTOM_PRINTF=y +UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9 +# UCLIBC_HAS_STDIO_BUFSIZ_256 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_512 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_1024 is not set +# UCLIBC_HAS_STDIO_BUFSIZ_2048 is not set +UCLIBC_HAS_STDIO_BUFSIZ_4096=y +# UCLIBC_HAS_STDIO_BUFSIZ_8192 is not set +UCLIBC_HAS_STDIO_BUILTIN_BUFFER_NONE=y +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_4 is not set +# UCLIBC_HAS_STDIO_BUILTIN_BUFFER_8 is not set +# UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT is not set +UCLIBC_HAS_STDIO_GETC_MACRO=y +UCLIBC_HAS_STDIO_PUTC_MACRO=y +UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION=y +# UCLIBC_HAS_FOPEN_LARGEFILE_MODE is not set +UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE=y +# UCLIBC_HAS_FOPEN_CLOSEEXEC_MODE is not set +UCLIBC_HAS_GLIBC_CUSTOM_STREAMS=y +UCLIBC_HAS_PRINTF_M_SPEC=y +UCLIBC_HAS_ERRNO_MESSAGES=y +# UCLIBC_HAS_SYS_ERRLIST is not set +UCLIBC_HAS_SIGNUM_MESSAGES=y +# UCLIBC_HAS_SYS_SIGLIST is not set +UCLIBC_HAS_GNU_GETOPT=y +UCLIBC_HAS_GETOPT_LONG=y +UCLIBC_HAS_GNU_GETSUBOPT=y +UCLIBC_HAS_ARGP=y + +# +# Big and Tall +# +UCLIBC_HAS_REGEX=y +# UCLIBC_HAS_REGEX_OLD is not set +UCLIBC_HAS_FNMATCH=y +# UCLIBC_HAS_FNMATCH_OLD is not set +UCLIBC_HAS_WORDEXP=y +UCLIBC_HAS_NFTW=y +UCLIBC_HAS_FTW=y +UCLIBC_HAS_FTS=y +UCLIBC_HAS_GLOB=y +UCLIBC_HAS_GNU_GLOB=y + +# +# Library Installation Options +# +RUNTIME_PREFIX="/" +DEVEL_PREFIX="/usr/" +MULTILIB_DIR="lib" +HARDWIRED_ABSPATH=y + +# +# Security options +# +# UCLIBC_BUILD_PIE is not set +UCLIBC_HAS_ARC4RANDOM=y +# ARC4RANDOM_USES_NODEV is not set +# UCLIBC_HAS_SSP is not set +UCLIBC_BUILD_RELRO=y +UCLIBC_BUILD_NOW=y +UCLIBC_BUILD_NOEXECSTACK=y + +# +# Development/debugging options +# +CROSS_COMPILER_PREFIX="" +UCLIBC_EXTRA_CFLAGS="" +# DODEBUG is not set +# DODEBUG_PT is not set +# DOSTRIP is not set +# DOASSERTS is not set +# SUPPORT_LD_DEBUG is not set +# SUPPORT_LD_DEBUG_EARLY is not set +# UCLIBC_MALLOC_DEBUGGING is not set +# UCLIBC_HAS_BACKTRACE is not set +WARNINGS="-Wall" +# EXTRA_WARNINGS is not set +# DOMULTI is not set diff --git a/toolchain/Makefile b/toolchain/Makefile index 5e19998eb..3d9986974 100644 --- a/toolchain/Makefile +++ b/toolchain/Makefile @@ -46,7 +46,7 @@ ELF2FLT:=elf2flt-install endif # disable gdb for some architectures -ifeq ($(ADK_TARGET_ARCH_ARC)$(ADK_TARGET_ARCH_EPIPHANY)$(ADK_TARGET_ARCH_NDS32)$(ADK_TARGET_ARCH_METAG)$(ADK_TARGET_ARCH_OR1K),) +ifeq ($(ADK_TARGET_ARCH_ARC)$(ADK_TARGET_ARCH_EPIPHANY)$(ADK_TARGET_ARCH_METAG)$(ADK_TARGET_ARCH_NDS32)$(ADK_TARGET_ARCH_OR1K),) TARGETS+=gdb GDB:=gdb-install endif diff --git a/toolchain/binutils/Makefile b/toolchain/binutils/Makefile index 581dffe68..1000a1c03 100644 --- a/toolchain/binutils/Makefile +++ b/toolchain/binutils/Makefile @@ -66,7 +66,7 @@ $(WRKBUILD)/.compiled: $(WRKBUILD)/.configured $(WRKBUILD)/.installed: $(WRKBUILD)/.compiled $(MAKE) -C $(WRKBUILD) install -ifeq ($(ADK_TARGET_ARCH_H8300),y) +ifeq ($(ADK_TARGET_ARCH_H8300)$(ADK_TARGET_ARCH_NDS32),y) $(INSTALL_DIR) $(STAGING_TARGET_DIR)/usr/lib/ldscripts $(CP) $(WRKBUILD)/ld/ldscripts/* $(STAGING_TARGET_DIR)/usr/lib/ldscripts/ endif diff --git a/toolchain/binutils/patches/2.24/binutils.nds32 b/toolchain/binutils/patches/2.24/binutils.nds32 new file mode 100644 index 000000000..4610dc0d8 --- /dev/null +++ b/toolchain/binutils/patches/2.24/binutils.nds32 @@ -0,0 +1,409259 @@ +diff -Nur binutils-2.24.orig/.cvsignore binutils-2.24/.cvsignore +--- binutils-2.24.orig/.cvsignore 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/.cvsignore 2016-04-10 20:30:47.000000000 +0200 +@@ -0,0 +1,33 @@ ++*-all ++*-co ++*-dirs ++*-done ++*-install-info ++*-src ++*-stamp-* ++*-tagged ++blockit ++cfg-paper.info ++config.status ++configure.aux ++configure.cp ++configure.cps ++configure.dvi ++configure.fn ++configure.fns ++configure.ky ++configure.kys ++configure.log ++configure.pg ++configure.pgs ++configure.toc ++configure.tp ++configure.tps ++configure.vr ++configure.vrs ++dir.info ++Makefile ++lost+found ++update.out ++update.sourceware ++autom4te.cache +diff -Nur binutils-2.24.orig/COPYING.LIBGLOSS binutils-2.24/COPYING.LIBGLOSS +--- binutils-2.24.orig/COPYING.LIBGLOSS 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/COPYING.LIBGLOSS 2016-04-10 20:30:47.000000000 +0200 +@@ -0,0 +1,354 @@ ++The libgloss subdirectory is a collection of software from several sources. ++ ++Each file may have its own copyright/license that is embedded in the source ++file. Unless otherwise noted in the body of the source file(s), the following copyright ++notices will apply to the contents of the libgloss subdirectory: ++ ++(1) Red Hat Incorporated ++ ++Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. ++ ++This copyrighted material is made available to anyone wishing to use, modify, ++copy, or redistribute it subject to the terms and conditions of the BSD ++License. This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties ++of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this license ++is available at http://www.opensource.org/licenses. Any Red Hat trademarks that ++are incorporated in the source code or documentation are not subject to the BSD ++License and may only be used or replicated with the express permission of ++Red Hat, Inc. ++ ++(2) University of California, Berkeley ++ ++Copyright (c) 1981-2000 The Regents of the University of California. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright notice, ++ this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright notice, ++ this list of conditions and the following disclaimer in the documentation ++ and/or other materials provided with the distribution. ++ * Neither the name of the University nor the names of its contributors may ++ be used to endorse or promote products derived from this software without ++ specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE 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. ++ ++(3) DJ Delorie ++ ++Copyright (C) 1993 DJ Delorie ++All rights reserved. ++ ++Redistribution, modification, and use in source and binary forms is permitted ++provided that the above copyright notice and following paragraph are ++duplicated in all such forms. ++ ++This file is distributed WITHOUT ANY WARRANTY; without even the implied ++warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++(4) (formerly GPL for fr30) ++ ++The GPL is no longer applicable to the fr30 platform. The piece of ++code (syscalls.c) referencing the GPL has been officially relicensed. ++ ++(5) Advanced Micro Devices ++ ++Copyright 1989, 1990 Advanced Micro Devices, Inc. ++ ++This software is the property of Advanced Micro Devices, Inc (AMD) which ++specifically grants the user the right to modify, use and distribute this ++software provided this notice is not removed or altered. All other rights ++are reserved by AMD. ++ ++AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS ++SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL ++DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR ++USE OF THIS SOFTWARE. ++ ++So that all may benefit from your experience, please report any problems ++or suggestions about this software to the 29K Technical Support Center at ++800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or ++0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118. ++ ++Advanced Micro Devices, Inc. ++29K Support Products ++Mail Stop 573 ++5900 E. Ben White Blvd. ++Austin, TX 78741 ++800-292-9263 ++ ++(6) - Analog Devices, Inc. (bfin-* targets) ++ ++Copyright (C) 2006, 2008, 2009, 2011, 2012 Analog Devices, Inc. ++ ++The authors hereby grant permission to use, copy, modify, distribute, ++and license this software and its documentation for any purpose, provided ++that existing copyright notices are retained in all copies and that this ++notice is included verbatim in any distributions. No written agreement, ++license, or royalty fee is required for any of the authorized uses. ++Modifications to this software may be copyrighted by their authors ++and need not follow the licensing terms described here, provided that ++the new terms are clearly indicated on the first page of each file where ++they apply. ++ ++(7) University of Utah and the Computer Systems Laboratory (CSL) ++ [applies only to hppa*-*-pro* targets] ++Copyright (c) 1990,1994 The University of Utah and ++the Computer Systems Laboratory (CSL). All rights reserved. ++ ++Permission to use, copy, modify and distribute this software is hereby ++granted provided that (1) source code retains these copyright, permission, ++and disclaimer notices, and (2) redistributions including binaries ++reproduce the notices in supporting documentation, and (3) all advertising ++materials mentioning features or use of this software display the following ++acknowledgement: ``This product includes software developed by the ++Computer Systems Laboratory at the University of Utah.'' ++ ++THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ++IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ++ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ++ ++CSL requests users of this software to return to csl-dist@cs.utah.edu any ++improvements that they make and grant CSL redistribution rights. ++ ++(8) Sun Microsystems ++ ++Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. ++ ++Developed at SunPro, a Sun Microsystems, Inc. business. ++Permission to use, copy, modify, and distribute this ++software is freely granted, provided that this notice is preserved. ++ ++(9) Hewlett Packard ++ ++(c) Copyright 1986 HEWLETT-PACKARD COMPANY ++ ++To anyone who acknowledges that this file is provided "AS IS" ++without any express or implied warranty: ++ ++permission to use, copy, modify, and distribute this file ++for any purpose is hereby granted without fee, provided that ++the above copyright notice and this notice appears in all ++copies, and that the name of Hewlett-Packard Company not be ++used in advertising or publicity pertaining to distribution ++of the software without specific, written prior permission. ++Hewlett-Packard Company makes no representations about the ++suitability of this software for any purpose. ++ ++(10) Hans-Peter Nilsson ++ ++Copyright (C) 2001 Hans-Peter Nilsson ++ ++Permission to use, copy, modify, and distribute this software is ++freely granted, provided that the above copyright notice, this notice ++and the following disclaimer are preserved with no changes. ++ ++THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++PURPOSE. ++ ++(11) IBM Corp. spu processor (only spu-* targets) ++ ++(C) Copyright IBM Corp. 2005, 2006 ++ ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright notice, ++this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright ++notice, this list of conditions and the following disclaimer in the ++documentation and/or other materials provided with the distribution. ++ * Neither the name of IBM 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. ++ ++(12) Jon Beniston (only lm32-* targets) ++ ++ Contributed by Jon Beniston ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++ ++(13) - Xilinx, Inc. (microblaze-* and powerpc-* targets) ++ ++Copyright (c) 2004, 2009 Xilinx, Inc. All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are ++met: ++ ++1. Redistributions source code must retain the above copyright notice, ++this list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright ++notice, this list of conditions and the following disclaimer in the ++documentation and/or other materials provided with the distribution. ++ ++3. Neither the name of Xilinx 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 HOLDER 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 ++HOLDER 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. ++ ++ ++(14) - National Semiconductor Corporation ++ ++Copyright (c) 2004 National Semiconductor Corporation ++ ++The authors hereby grant permission to use, copy, modify, distribute, ++and license this software and its documentation for any purpose, provided ++that existing copyright notices are retained in all copies and that this ++notice is included verbatim in any distributions. No written agreement, ++license, or royalty fee is required for any of the authorized uses. ++Modifications to this software may be copyrighted by their authors ++and need not follow the licensing terms described here, provided that ++the new terms are clearly indicated on the first page of each file where ++they apply. ++ ++ ++(15) - CodeSourcery, Inc. (tic6x-* targets) ++ ++Copyright (c) 2010 CodeSourcery, Inc. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ * Neither the name of CodeSourcery 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 CODESOURCERY, INC. ``AS IS'' AND ANY ++EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++DISCLAIMED. IN NO EVENT SHALL CODESOURCERY BE LIABLE FOR ANY ++DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ++ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++ ++(16) - GPL with exception (sparc-*leon*, crx-*, cr16-* targets only) ++ ++ Copyright (C) 1992 Free Software Foundation, Inc. ++ Written By David Vinayak Henkel-Wallace, June 1992 ++ ++This file 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, or (at your option) any ++later version. ++ ++In addition to the permissions in the GNU General Public License, the ++Free Software Foundation gives you unlimited permission to link the ++compiled version of this file with other programs, and to distribute ++those programs without any restriction coming from the use of this ++file. (The General Public License restrictions do apply in other ++respects; for example, they cover modification of the file, and ++distribution when not linked into another program.) ++ ++This file 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; see the file COPYING. If not, write to ++the Free Software Foundation, 59 Temple Place - Suite 330, ++Boston, MA 02111-1307, USA. ++ ++ As a special exception, if you link this library with files ++ compiled with GCC to produce an executable, this does not cause ++ the resulting executable to be covered by the GNU General Public License. ++ This exception does not however invalidate any other reasons why ++ the executable file might be covered by the GNU General Public License. ++ ++ ++(17) - Adapteva, Inc. (epiphany-* targets) ++ ++Copyright (c) 2011, Adapteva, Inc. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ * Redistributions of source code must retain the above copyright notice, this ++ list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright notice, ++ this list of conditions and the following disclaimer in the documentation ++ and/or other materials provided with the distribution. ++ * Neither the name of Adapteva 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 HOLDER 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. ++ +diff -Nur binutils-2.24.orig/COPYING.NEWLIB binutils-2.24/COPYING.NEWLIB +--- binutils-2.24.orig/COPYING.NEWLIB 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/COPYING.NEWLIB 2016-04-10 20:30:47.000000000 +0200 +@@ -0,0 +1,927 @@ ++The newlib subdirectory is a collection of software from several sources. ++ ++Each file may have its own copyright/license that is embedded in the source ++file. Unless otherwise noted in the body of the source file(s), the following copyright ++notices will apply to the contents of the newlib subdirectory: ++ ++(1) Red Hat Incorporated ++ ++Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved. ++ ++This copyrighted material is made available to anyone wishing to use, ++modify, copy, or redistribute it subject to the terms and conditions ++of the BSD License. This program is distributed in the hope that ++it will be useful, but WITHOUT ANY WARRANTY expressed or implied, ++including the implied warranties of MERCHANTABILITY or FITNESS FOR ++A PARTICULAR PURPOSE. A copy of this license is available at ++http://www.opensource.org/licenses. Any Red Hat trademarks that are ++incorporated in the source code or documentation are not subject to ++the BSD License and may only be used or replicated with the express ++permission of Red Hat, Inc. ++ ++(2) University of California, Berkeley ++ ++Copyright (c) 1981-2000 The Regents of the University of California. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without modification, ++are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright notice, ++ this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright notice, ++ this list of conditions and the following disclaimer in the documentation ++ and/or other materials provided with the distribution. ++ * Neither the name of the University nor the names of its contributors ++ may be used to endorse or promote products derived from this software ++ without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE 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. ++ ++(3) David M. Gay (AT&T 1991, Lucent 1998) ++ ++The author of this software is David M. Gay. ++ ++Copyright (c) 1991 by AT&T. ++ ++Permission to use, copy, modify, and distribute this software for any ++purpose without fee is hereby granted, provided that this entire notice ++is included in all copies of any software which is or includes a copy ++or modification of this software and in all copies of the supporting ++documentation for such software. ++ ++THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED ++WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY ++REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY ++OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. ++ ++------------------------------------------------------------------- ++ ++The author of this software is David M. Gay. ++ ++Copyright (C) 1998-2001 by Lucent Technologies ++All Rights Reserved ++ ++Permission to use, copy, modify, and distribute this software and ++its documentation for any purpose and without fee is hereby ++granted, provided that the above copyright notice appear in all ++copies and that both that the copyright notice and this ++permission notice and warranty disclaimer appear in supporting ++documentation, and that the name of Lucent or any of its entities ++not be used in advertising or publicity pertaining to ++distribution of the software without specific, written prior ++permission. ++ ++LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, ++INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. ++IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY ++SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER ++IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ++ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF ++THIS SOFTWARE. ++ ++ ++(4) Advanced Micro Devices ++ ++Copyright 1989, 1990 Advanced Micro Devices, Inc. ++ ++This software is the property of Advanced Micro Devices, Inc (AMD) which ++specifically grants the user the right to modify, use and distribute this ++software provided this notice is not removed or altered. All other rights ++are reserved by AMD. ++ ++AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS ++SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL ++DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR ++USE OF THIS SOFTWARE. ++ ++So that all may benefit from your experience, please report any problems ++or suggestions about this software to the 29K Technical Support Center at ++800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or ++0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118. ++ ++Advanced Micro Devices, Inc. ++29K Support Products ++Mail Stop 573 ++5900 E. Ben White Blvd. ++Austin, TX 78741 ++800-292-9263 ++ ++(5) ++ ++(6) ++ ++(7) Sun Microsystems ++ ++Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. ++ ++Developed at SunPro, a Sun Microsystems, Inc. business. ++Permission to use, copy, modify, and distribute this ++software is freely granted, provided that this notice is preserved. ++ ++(8) Hewlett Packard ++ ++(c) Copyright 1986 HEWLETT-PACKARD COMPANY ++ ++To anyone who acknowledges that this file is provided "AS IS" ++without any express or implied warranty: ++ permission to use, copy, modify, and distribute this file ++for any purpose is hereby granted without fee, provided that ++the above copyright notice and this notice appears in all ++copies, and that the name of Hewlett-Packard Company not be ++used in advertising or publicity pertaining to distribution ++of the software without specific, written prior permission. ++Hewlett-Packard Company makes no representations about the ++suitability of this software for any purpose. ++ ++(9) Hans-Peter Nilsson ++ ++Copyright (C) 2001 Hans-Peter Nilsson ++ ++Permission to use, copy, modify, and distribute this software is ++freely granted, provided that the above copyright notice, this notice ++and the following disclaimer are preserved with no changes. ++ ++THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ++IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ++WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ++PURPOSE. ++ ++(10) Stephane Carrez (m68hc11-elf/m68hc12-elf targets only) ++ ++Copyright (C) 1999, 2000, 2001, 2002 Stephane Carrez (stcarrez@nerim.fr) ++ ++The authors hereby grant permission to use, copy, modify, distribute, ++and license this software and its documentation for any purpose, provided ++that existing copyright notices are retained in all copies and that this ++notice is included verbatim in any distributions. No written agreement, ++license, or royalty fee is required for any of the authorized uses. ++Modifications to this software may be copyrighted by their authors ++and need not follow the licensing terms described here, provided that ++the new terms are clearly indicated on the first page of each file where ++they apply. ++ ++(11) Christopher G. Demetriou ++ ++Copyright (c) 2001 Christopher G. Demetriou ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must 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. The name of the author may not be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ++IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++(12) SuperH, Inc. ++ ++Copyright 2002 SuperH, Inc. All rights reserved ++ ++This software is the property of SuperH, Inc (SuperH) which specifically ++grants the user the right to modify, use and distribute this software ++provided this notice is not removed or altered. All other rights are ++reserved by SuperH. ++ ++SUPERH MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO ++THIS SOFTWARE. IN NO EVENT SHALL SUPERH BE LIABLE FOR INDIRECT, SPECIAL, ++INCIDENTAL OR CONSEQUENTIAL DAMAGES IN CONNECTION WITH OR ARISING FROM ++THE FURNISHING, PERFORMANCE, OR USE OF THIS SOFTWARE. ++ ++So that all may benefit from your experience, please report any problems ++or suggestions about this software to the SuperH Support Center via ++e-mail at softwaresupport@superh.com . ++ ++SuperH, Inc. ++405 River Oaks Parkway ++San Jose ++CA 95134 ++USA ++ ++(13) Royal Institute of Technology ++ ++Copyright (c) 1999 Kungliga Tekniska Högskolan ++(Royal Institute of Technology, Stockholm, Sweden). ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++ ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++3. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. ++ ++(14) Alexey Zelkin ++ ++Copyright (c) 2000, 2001 Alexey Zelkin ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++(15) Andrey A. Chernov ++ ++Copyright (C) 1997 by Andrey A. Chernov, Moscow, Russia. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++(16) FreeBSD ++ ++Copyright (c) 1997-2002 FreeBSD Project. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++(17) S. L. Moshier ++ ++Author: S. L. Moshier. ++ ++Copyright (c) 1984,2000 S.L. Moshier ++ ++Permission to use, copy, modify, and distribute this software for any ++purpose without fee is hereby granted, provided that this entire notice ++is included in all copies of any software which is or includes a copy ++or modification of this software and in all copies of the supporting ++documentation for such software. ++ ++THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED ++WARRANTY. IN PARTICULAR, THE AUTHOR MAKES NO REPRESENTATION ++OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY OF THIS ++SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. ++ ++(18) Citrus Project ++ ++Copyright (c)1999 Citrus Project, ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++(19) Todd C. Miller ++ ++Copyright (c) 1998 Todd C. Miller ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must 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. The name of the author may not be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, ++INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ++AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ++THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ++EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ++PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ++OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ++WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ++OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ++ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++(20) DJ Delorie (i386) ++Copyright (C) 1991 DJ Delorie ++All rights reserved. ++ ++Redistribution, modification, and use in source and binary forms is permitted ++provided that the above copyright notice and following paragraph are ++duplicated in all such forms. ++ ++This file is distributed WITHOUT ANY WARRANTY; without even the implied ++warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ++ ++(21) Free Software Foundation LGPL License (*-linux* targets only) ++ ++ Copyright (C) 1990-1999, 2000, 2001 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Mark Kettenis , 1997. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, write to the Free ++ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ 02110-1301 USA. ++ ++(22) Xavier Leroy LGPL License (i[3456]86-*-linux* targets only) ++ ++Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) ++ ++This program is free software; you can redistribute it and/or ++modify it under the terms of the GNU Library 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 Library General Public License for more details. ++ ++(23) Intel (i960) ++ ++Copyright (c) 1993 Intel Corporation ++ ++Intel hereby grants you permission to copy, modify, and distribute this ++software and its documentation. Intel grants this permission provided ++that the above copyright notice appears in all copies and that both the ++copyright notice and this permission notice appear in supporting ++documentation. In addition, Intel grants this permission provided that ++you prominently mark as "not part of the original" any modifications ++made to this software or documentation, and that the name of Intel ++Corporation not be used in advertising or publicity pertaining to ++distribution of the software or the documentation without specific, ++written prior permission. ++ ++Intel Corporation provides this AS IS, WITHOUT ANY WARRANTY, EXPRESS OR ++IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY ++OR FITNESS FOR A PARTICULAR PURPOSE. Intel makes no guarantee or ++representations regarding the use of, or the results of the use of, ++the software and documentation in terms of correctness, accuracy, ++reliability, currentness, or otherwise; and you rely on the software, ++documentation and results solely at your own risk. ++ ++IN NO EVENT SHALL INTEL BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS, ++LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES ++OF ANY KIND. IN NO EVENT SHALL INTEL'S TOTAL LIABILITY EXCEED THE SUM ++PAID TO INTEL FOR THE PRODUCT LICENSED HEREUNDER. ++ ++(24) Hewlett-Packard (hppa targets only) ++ ++(c) Copyright 1986 HEWLETT-PACKARD COMPANY ++ ++To anyone who acknowledges that this file is provided "AS IS" ++without any express or implied warranty: ++ permission to use, copy, modify, and distribute this file ++for any purpose is hereby granted without fee, provided that ++the above copyright notice and this notice appears in all ++copies, and that the name of Hewlett-Packard Company not be ++used in advertising or publicity pertaining to distribution ++of the software without specific, written prior permission. ++Hewlett-Packard Company makes no representations about the ++suitability of this software for any purpose. ++ ++(25) Henry Spencer (only *-linux targets) ++ ++Copyright 1992, 1993, 1994 Henry Spencer. All rights reserved. ++This software is not subject to any license of the American Telephone ++and Telegraph Company or of the Regents of the University of California. ++ ++Permission is granted to anyone to use this software for any purpose on ++any computer system, and to alter it and redistribute it, subject ++to the following restrictions: ++ ++1. The author is not responsible for the consequences of use of this ++ software, no matter how awful, even if they arise from flaws in it. ++ ++2. The origin of this software must not be misrepresented, either by ++ explicit claim or by omission. Since few users ever read sources, ++ credits must appear in the documentation. ++ ++3. Altered versions must be plainly marked as such, and must not be ++ misrepresented as being the original software. Since few users ++ ever read sources, credits must appear in the documentation. ++ ++4. This notice may not be removed or altered. ++ ++(26) Mike Barcroft ++ ++Copyright (c) 2001 Mike Barcroft ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++(27) Konstantin Chuguev (--enable-newlib-iconv) ++ ++Copyright (c) 1999, 2000 ++ Konstantin Chuguev. All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++ iconv (Charset Conversion Library) v2.0 ++ ++(28) Artem Bityuckiy (--enable-newlib-iconv) ++ ++Copyright (c) 2003, Artem B. Bityuckiy, SoftMine Corporation. ++Rights transferred to Franklin Electronic Publishers. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++SUCH DAMAGE. ++ ++(29) IBM, Sony, Toshiba (only spu-* targets) ++ ++ (C) Copyright 2001,2006, ++ International Business Machines Corporation, ++ Sony Computer Entertainment, Incorporated, ++ Toshiba Corporation, ++ ++ All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions are met: ++ ++ * Redistributions of source code must retain the above copyright notice, ++ this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ * Neither the names of the copyright holders nor the names of their ++ 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. ++ ++(30) - Alex Tatmanjants (targets using libc/posix) ++ ++ Copyright (c) 1995 Alex Tatmanjants ++ at Electronni Visti IA, Kiev, Ukraine. ++ All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++ ++(31) - M. Warner Losh (targets using libc/posix) ++ ++ Copyright (c) 1998, M. Warner Losh ++ All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++ ++(32) - Andrey A. Chernov (targets using libc/posix) ++ ++ Copyright (C) 1996 by Andrey A. Chernov, Moscow, Russia. ++ All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++ ++(33) - Daniel Eischen (targets using libc/posix) ++ ++ Copyright (c) 2001 Daniel Eischen . ++ All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++ ++ ++(34) - Jon Beniston (only lm32-* targets) ++ ++ Contributed by Jon Beniston ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ ++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ++ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE ++ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ SUCH DAMAGE. ++ ++ ++(35) - ARM Ltd (arm and thumb variant targets only) ++ ++ Copyright (c) 2009 ARM Ltd ++ All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ 1. Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ 2. Redistributions in binary form must 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. The name of the company may not be used to endorse or promote ++ products derived from this software without specific prior written ++ permission. ++ ++ THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ ++(36) - Xilinx, Inc. (microblaze-* and powerpc-* targets) ++ ++Copyright (c) 2004, 2009 Xilinx, Inc. All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are ++met: ++ ++1. Redistributions source code must retain the above copyright notice, ++this list of conditions and the following disclaimer. ++ ++2. Redistributions in binary form must reproduce the above copyright ++notice, this list of conditions and the following disclaimer in the ++documentation and/or other materials provided with the distribution. ++ ++3. Neither the name of Xilinx 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 HOLDER 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 ++HOLDER 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. ++ ++ ++(37) Texas Instruments Incorporated (tic6x-* targets) ++ ++Copyright (c) 1996-2010 Texas Instruments Incorporated ++http://www.ti.com/ ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ ++ Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ ++ Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in ++ the documentation and/or other materials provided with the ++ distribution. ++ ++ Neither the name of Texas Instruments Incorporated 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. ++ ++(38) National Semiconductor (cr16-* and crx-* targets) ++ ++Copyright (c) 2004 National Semiconductor Corporation ++ ++The authors hereby grant permission to use, copy, modify, distribute, ++and license this software and its documentation for any purpose, provided ++that existing copyright notices are retained in all copies and that this ++notice is included verbatim in any distributions. No written agreement, ++license, or royalty fee is required for any of the authorized uses. ++Modifications to this software may be copyrighted by their authors ++and need not follow the licensing terms described here, provided that ++the new terms are clearly indicated on the first page of each file where ++they apply. ++ ++(39) - Adapteva, Inc. (epiphany-* targets) ++ ++Copyright (c) 2011, Adapteva, Inc. ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are met: ++ * Redistributions of source code must retain the above copyright notice, this ++ list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright notice, ++ this list of conditions and the following disclaimer in the documentation ++ and/or other materials provided with the distribution. ++ * Neither the name of Adapteva 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 HOLDER 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. ++ ++(40) - Altera Corportion (nios2-* targets) ++ ++Copyright (c) 2003 Altera Corporation ++All rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions ++are met: ++ ++ o Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ o Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ o Neither the name of Altera Corporation 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 ALTERA CORPORATION, THE COPYRIGHT HOLDER, ++AND ITS 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 HOLDER 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. ++ +diff -Nur binutils-2.24.orig/bfd/Makefile.am binutils-2.24/bfd/Makefile.am +--- binutils-2.24.orig/bfd/Makefile.am 2013-12-02 10:30:28.000000000 +0100 ++++ binutils-2.24/bfd/Makefile.am 2016-04-10 20:30:46.000000000 +0200 +@@ -136,6 +136,7 @@ + cpu-moxie.lo \ + cpu-msp430.lo \ + cpu-mt.lo \ ++ cpu-nds32.lo \ + cpu-nios2.lo \ + cpu-ns32k.lo \ + cpu-openrisc.lo \ +@@ -220,6 +221,7 @@ + cpu-moxie.c \ + cpu-msp430.c \ + cpu-mt.c \ ++ cpu-nds32.c \ + cpu-ns32k.c \ + cpu-nios2.c \ + cpu-openrisc.c \ +@@ -349,6 +351,7 @@ + elf32-moxie.lo \ + elf32-msp430.lo \ + elf32-mt.lo \ ++ elf32-nds32.lo \ + elf32-nios2.lo \ + elf32-openrisc.lo \ + elf32-or32.lo \ +@@ -537,6 +540,7 @@ + elf32-moxie.c \ + elf32-msp430.c \ + elf32-mt.c \ ++ elf32-nds32.c \ + elf32-nios2.c \ + elf32-openrisc.c \ + elf32-or32.c \ +diff -Nur binutils-2.24.orig/bfd/Makefile.in binutils-2.24/bfd/Makefile.in +--- binutils-2.24.orig/bfd/Makefile.in 2013-12-02 10:30:30.000000000 +0100 ++++ binutils-2.24/bfd/Makefile.in 2016-04-10 20:30:46.000000000 +0200 +@@ -437,6 +437,7 @@ + cpu-moxie.lo \ + cpu-msp430.lo \ + cpu-mt.lo \ ++ cpu-nds32.lo \ + cpu-nios2.lo \ + cpu-ns32k.lo \ + cpu-openrisc.lo \ +@@ -521,6 +522,7 @@ + cpu-moxie.c \ + cpu-msp430.c \ + cpu-mt.c \ ++ cpu-nds32.c \ + cpu-ns32k.c \ + cpu-nios2.c \ + cpu-openrisc.c \ +@@ -651,6 +653,7 @@ + elf32-moxie.lo \ + elf32-msp430.lo \ + elf32-mt.lo \ ++ elf32-nds32.lo \ + elf32-nios2.lo \ + elf32-openrisc.lo \ + elf32-or32.lo \ +@@ -839,6 +842,7 @@ + elf32-moxie.c \ + elf32-msp430.c \ + elf32-mt.c \ ++ elf32-nds32.c \ + elf32-nios2.c \ + elf32-openrisc.c \ + elf32-or32.c \ +@@ -1352,6 +1356,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-moxie.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-msp430.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-mt.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-nds32.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-nios2.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-ns32k.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu-openrisc.Plo@am__quote@ +@@ -1442,6 +1447,7 @@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-moxie.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-msp430.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-mt.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nds32.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-nios2.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-openrisc.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf32-or32.Plo@am__quote@ +diff -Nur binutils-2.24.orig/bfd/archures.c binutils-2.24/bfd/archures.c +--- binutils-2.24.orig/bfd/archures.c 2013-11-08 11:02:26.000000000 +0100 ++++ binutils-2.24/bfd/archures.c 2016-04-10 20:30:46.000000000 +0200 +@@ -316,6 +316,12 @@ + .#define bfd_mach_arm_ep9312 11 + .#define bfd_mach_arm_iWMMXt 12 + .#define bfd_mach_arm_iWMMXt2 13 ++. bfd_arch_nds32, {* Andes NDS32 *} ++.#define bfd_mach_n1 1 ++.#define bfd_mach_n1h 2 ++.#define bfd_mach_n1h_v2 3 ++.#define bfd_mach_n1h_v3 4 ++.#define bfd_mach_n1h_v3m 5 + . bfd_arch_ns32k, {* National Semiconductors ns32000 *} + . bfd_arch_w65, {* WDC 65816 *} + . bfd_arch_tic30, {* Texas Instruments TMS320C30 *} +@@ -574,6 +580,7 @@ + extern const bfd_arch_info_type bfd_moxie_arch; + extern const bfd_arch_info_type bfd_msp430_arch; + extern const bfd_arch_info_type bfd_mt_arch; ++extern const bfd_arch_info_type bfd_nds32_arch; + extern const bfd_arch_info_type bfd_nios2_arch; + extern const bfd_arch_info_type bfd_ns32k_arch; + extern const bfd_arch_info_type bfd_openrisc_arch; +@@ -663,6 +670,7 @@ + &bfd_moxie_arch, + &bfd_msp430_arch, + &bfd_mt_arch, ++ &bfd_nds32_arch, + &bfd_nios2_arch, + &bfd_ns32k_arch, + &bfd_openrisc_arch, +diff -Nur binutils-2.24.orig/bfd/bfd-in.h binutils-2.24/bfd/bfd-in.h +--- binutils-2.24.orig/bfd/bfd-in.h 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/bfd/bfd-in.h 2016-04-10 20:30:46.000000000 +0200 +@@ -292,9 +292,6 @@ + + #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) + +-#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) +-#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) +-#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) + /* Find the address one past the end of SEC. */ + #define bfd_get_section_limit(bfd, sec) \ + (((bfd)->direction != write_direction && (sec)->rawsize != 0 \ +@@ -517,8 +514,6 @@ + + #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) + +-#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) +- + extern bfd_boolean bfd_cache_close + (bfd *abfd); + /* NB: This declaration should match the autogenerated one in libbfd.h. */ +diff -Nur binutils-2.24.orig/bfd/bfd-in2.h binutils-2.24/bfd/bfd-in2.h +--- binutils-2.24.orig/bfd/bfd-in2.h 2013-11-18 09:40:15.000000000 +0100 ++++ binutils-2.24/bfd/bfd-in2.h 2016-04-10 20:30:46.000000000 +0200 +@@ -299,9 +299,6 @@ + + #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0) + +-#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)), ((ptr)->user_set_vma = TRUE), TRUE) +-#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power = (val)),TRUE) +-#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE) + /* Find the address one past the end of SEC. */ + #define bfd_get_section_limit(bfd, sec) \ + (((bfd)->direction != write_direction && (sec)->rawsize != 0 \ +@@ -524,8 +521,6 @@ + + #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char) + +-#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE) +- + extern bfd_boolean bfd_cache_close + (bfd *abfd); + /* NB: This declaration should match the autogenerated one in libbfd.h. */ +@@ -1594,6 +1589,32 @@ + int size; + }; + ++/* Note: the following are provided as inline functions rather than macros ++ because not all callers use the return value. A macro implementation ++ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some ++ compilers will complain about comma expressions that have no effect. */ ++static inline bfd_boolean ++bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val) ++{ ++ ptr->userdata = val; ++ return TRUE; ++} ++ ++static inline bfd_boolean ++bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val) ++{ ++ ptr->vma = ptr->lma = val; ++ ptr->user_set_vma = TRUE; ++ return TRUE; ++} ++ ++static inline bfd_boolean ++bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val) ++{ ++ ptr->alignment_power = val; ++ return TRUE; ++} ++ + /* These sections are global, and are managed by BFD. The application + and target back end are not permitted to change the values in + these sections. */ +@@ -2071,6 +2092,12 @@ + #define bfd_mach_arm_ep9312 11 + #define bfd_mach_arm_iWMMXt 12 + #define bfd_mach_arm_iWMMXt2 13 ++ bfd_arch_nds32, /* Andes NDS32 */ ++#define bfd_mach_n1 1 ++#define bfd_mach_n1h 2 ++#define bfd_mach_n1h_v2 3 ++#define bfd_mach_n1h_v3 4 ++#define bfd_mach_n1h_v3m 5 + bfd_arch_ns32k, /* National Semiconductors ns32000 */ + bfd_arch_w65, /* WDC 65816 */ + bfd_arch_tic30, /* Texas Instruments TMS320C30 */ +@@ -3794,6 +3821,229 @@ + BFD_RELOC_M32R_GOTPC_HI_SLO, + BFD_RELOC_M32R_GOTPC_LO, + ++/* NDS32 relocs. ++This is a 20 bit absolute address. */ ++ BFD_RELOC_NDS32_20, ++ ++/* This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0. */ ++ BFD_RELOC_NDS32_9_PCREL, ++ ++/* This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0. */ ++ BFD_RELOC_NDS32_WORD_9_PCREL, ++ ++/* This is an 15-bit reloc with the right 1 bit assumed to be 0. */ ++ BFD_RELOC_NDS32_15_PCREL, ++ ++/* This is an 17-bit reloc with the right 1 bit assumed to be 0. */ ++ BFD_RELOC_NDS32_17_PCREL, ++ ++/* This is a 25-bit reloc with the right 1 bit assumed to be 0. */ ++ BFD_RELOC_NDS32_25_PCREL, ++ ++/* This is a 20-bit reloc containing the high 20 bits of an address ++used with the lower 12 bits */ ++ BFD_RELOC_NDS32_HI20, ++ ++/* This is a 12-bit reloc containing the lower 12 bits of an address ++then shift right by 3. This is used with ldi,sdi... */ ++ BFD_RELOC_NDS32_LO12S3, ++ ++/* This is a 12-bit reloc containing the lower 12 bits of an address ++then shift left by 2. This is used with lwi,swi... */ ++ BFD_RELOC_NDS32_LO12S2, ++ ++/* This is a 12-bit reloc containing the lower 12 bits of an address ++then shift left by 1. This is used with lhi,shi... */ ++ BFD_RELOC_NDS32_LO12S1, ++ ++/* This is a 12-bit reloc containing the lower 12 bits of an address ++then shift left by 0. This is used with lbisbi... */ ++ BFD_RELOC_NDS32_LO12S0, ++ ++/* This is a 12-bit reloc containing the lower 12 bits of an address ++then shift left by 0. This is only used with branch relaxations */ ++ BFD_RELOC_NDS32_LO12S0_ORI, ++ ++/* This is a 15-bit reloc containing the small data area 18-bit signed offset ++and shift left by 3 for use in ldi, sdi... */ ++ BFD_RELOC_NDS32_SDA15S3, ++ ++/* This is a 15-bit reloc containing the small data area 17-bit signed offset ++and shift left by 2 for use in lwi, swi... */ ++ BFD_RELOC_NDS32_SDA15S2, ++ ++/* This is a 15-bit reloc containing the small data area 16-bit signed offset ++and shift left by 1 for use in lhi, shi... */ ++ BFD_RELOC_NDS32_SDA15S1, ++ ++/* This is a 15-bit reloc containing the small data area 15-bit signed offset ++and shift left by 0 for use in lbi, sbi... */ ++ BFD_RELOC_NDS32_SDA15S0, ++ ++/* This is a 16-bit reloc containing the small data area 16-bit signed offset ++and shift left by 3 */ ++ BFD_RELOC_NDS32_SDA16S3, ++ ++/* This is a 17-bit reloc containing the small data area 17-bit signed offset ++and shift left by 2 for use in lwi.gp, swi.gp... */ ++ BFD_RELOC_NDS32_SDA17S2, ++ ++/* This is a 18-bit reloc containing the small data area 18-bit signed offset ++and shift left by 1 for use in lhi.gp, shi.gp... */ ++ BFD_RELOC_NDS32_SDA18S1, ++ ++/* This is a 19-bit reloc containing the small data area 19-bit signed offset ++and shift left by 0 for use in lbi.gp, sbi.gp... */ ++ BFD_RELOC_NDS32_SDA19S0, ++ ++/* This is a 24-bit reloc for security check sum. */ ++ BFD_RELOC_NDS32_SECURITY_16, ++ ++/* for PIC */ ++ BFD_RELOC_NDS32_GOT20, ++ BFD_RELOC_NDS32_9_PLTREL, ++ BFD_RELOC_NDS32_25_PLTREL, ++ BFD_RELOC_NDS32_COPY, ++ BFD_RELOC_NDS32_GLOB_DAT, ++ BFD_RELOC_NDS32_JMP_SLOT, ++ BFD_RELOC_NDS32_RELATIVE, ++ BFD_RELOC_NDS32_GOTOFF, ++ BFD_RELOC_NDS32_GOTOFF_HI20, ++ BFD_RELOC_NDS32_GOTOFF_LO12, ++ BFD_RELOC_NDS32_GOTPC20, ++ BFD_RELOC_NDS32_GOT_HI20, ++ BFD_RELOC_NDS32_GOT_LO12, ++ BFD_RELOC_NDS32_GOTPC_HI20, ++ BFD_RELOC_NDS32_GOTPC_LO12, ++ ++/* for relax */ ++ BFD_RELOC_NDS32_INSN16, ++ BFD_RELOC_NDS32_LABEL, ++ BFD_RELOC_NDS32_LONGCALL1, ++ BFD_RELOC_NDS32_LONGCALL2, ++ BFD_RELOC_NDS32_LONGCALL3, ++ BFD_RELOC_NDS32_LONGJUMP1, ++ BFD_RELOC_NDS32_LONGJUMP2, ++ BFD_RELOC_NDS32_LONGJUMP3, ++ BFD_RELOC_NDS32_LOADSTORE, ++ BFD_RELOC_NDS32_9_FIXED, ++ BFD_RELOC_NDS32_15_FIXED, ++ BFD_RELOC_NDS32_17_FIXED, ++ BFD_RELOC_NDS32_25_FIXED, ++ BFD_RELOC_NDS32_LONGCALL4, ++ BFD_RELOC_NDS32_LONGCALL5, ++ BFD_RELOC_NDS32_LONGCALL6, ++ BFD_RELOC_NDS32_LONGJUMP4, ++ BFD_RELOC_NDS32_LONGJUMP5, ++ BFD_RELOC_NDS32_LONGJUMP6, ++ BFD_RELOC_NDS32_LONGJUMP7, ++ ++/* for PIC */ ++ BFD_RELOC_NDS32_PLTREL_HI20, ++ BFD_RELOC_NDS32_PLTREL_LO12, ++ BFD_RELOC_NDS32_PLT_GOTREL_HI20, ++ BFD_RELOC_NDS32_PLT_GOTREL_LO12, ++ ++/* for floating point */ ++ BFD_RELOC_NDS32_SDA12S2_DP, ++ BFD_RELOC_NDS32_SDA12S2_SP, ++ BFD_RELOC_NDS32_LO12S2_DP, ++ BFD_RELOC_NDS32_LO12S2_SP, ++ ++/* for dwarf2 debug_line. */ ++ BFD_RELOC_NDS32_DWARF2_OP1, ++ BFD_RELOC_NDS32_DWARF2_OP2, ++ BFD_RELOC_NDS32_DWARF2_LEB, ++ ++/* for eliminate 16-bit instructions */ ++ BFD_RELOC_NDS32_UPDATE_TA, ++ ++/* for PIC object relaxation */ ++ BFD_RELOC_NDS32_PLT_GOTREL_LO20, ++ BFD_RELOC_NDS32_PLT_GOTREL_LO15, ++ BFD_RELOC_NDS32_PLT_GOTREL_LO19, ++ BFD_RELOC_NDS32_GOT_LO15, ++ BFD_RELOC_NDS32_GOT_LO19, ++ BFD_RELOC_NDS32_GOTOFF_LO15, ++ BFD_RELOC_NDS32_GOTOFF_LO19, ++ BFD_RELOC_NDS32_GOT15S2, ++ BFD_RELOC_NDS32_GOT17S2, ++ ++/* NDS32 relocs. ++This is a 5 bit absolute address. */ ++ BFD_RELOC_NDS32_5, ++ ++/* This is a 10-bit unsigned pc-relative reloc with the right 1 bit assumed to be 0. */ ++ BFD_RELOC_NDS32_10_UPCREL, ++ ++/* If fp were omitted, fp can used as another gp. */ ++ BFD_RELOC_NDS32_SDA_FP7U2_RELA, ++ ++/* relaxation relative relocation types */ ++ BFD_RELOC_NDS32_RELAX_ENTRY, ++ BFD_RELOC_NDS32_GOT_SUFF, ++ BFD_RELOC_NDS32_GOTOFF_SUFF, ++ BFD_RELOC_NDS32_PLT_GOT_SUFF, ++ BFD_RELOC_NDS32_MULCALL_SUFF, ++ BFD_RELOC_NDS32_PTR, ++ BFD_RELOC_NDS32_PTR_COUNT, ++ BFD_RELOC_NDS32_PTR_RESOLVED, ++ BFD_RELOC_NDS32_PLTBLOCK, ++ BFD_RELOC_NDS32_RELAX_REGION_BEGIN, ++ BFD_RELOC_NDS32_RELAX_REGION_END, ++ BFD_RELOC_NDS32_MINUEND, ++ BFD_RELOC_NDS32_SUBTRAHEND, ++ BFD_RELOC_NDS32_DIFF8, ++ BFD_RELOC_NDS32_DIFF16, ++ BFD_RELOC_NDS32_DIFF32, ++ BFD_RELOC_NDS32_DIFF_ULEB128, ++ BFD_RELOC_NDS32_EMPTY, ++ ++/* This is a 25 bit absolute address. */ ++ BFD_RELOC_NDS32_25_ABS, ++ ++/* For ex9 and ifc using. */ ++ BFD_RELOC_NDS32_DATA, ++ BFD_RELOC_NDS32_TRAN, ++ BFD_RELOC_NDS32_17IFC_PCREL, ++ BFD_RELOC_NDS32_10IFCU_PCREL, ++ ++/* For TLS. */ ++ BFD_RELOC_NDS32_TPOFF, ++ BFD_RELOC_NDS32_GOTTPOFF, ++ BFD_RELOC_NDS32_TLS_LE_HI20, ++ BFD_RELOC_NDS32_TLS_LE_LO12, ++ BFD_RELOC_NDS32_TLS_LE_20, ++ BFD_RELOC_NDS32_TLS_LE_15S0, ++ BFD_RELOC_NDS32_TLS_LE_15S1, ++ BFD_RELOC_NDS32_TLS_LE_15S2, ++ BFD_RELOC_NDS32_TLS_LE_ADD, ++ BFD_RELOC_NDS32_TLS_LE_LS, ++ BFD_RELOC_NDS32_TLS_IE_HI20, ++ BFD_RELOC_NDS32_TLS_IE_LO12, ++ BFD_RELOC_NDS32_TLS_IE_LO12S2, ++ BFD_RELOC_NDS32_TLS_IEGP_HI20, ++ BFD_RELOC_NDS32_TLS_IEGP_LO12, ++ BFD_RELOC_NDS32_TLS_IEGP_LO12S2, ++ BFD_RELOC_NDS32_TLS_IEGP_LW, ++ BFD_RELOC_NDS32_TLS_DESC, ++ BFD_RELOC_NDS32_TLS_DESC_HI20, ++ BFD_RELOC_NDS32_TLS_DESC_LO12, ++ BFD_RELOC_NDS32_TLS_DESC_20, ++ BFD_RELOC_NDS32_TLS_DESC_SDA17S2, ++ BFD_RELOC_NDS32_TLS_DESC_ADD, ++ BFD_RELOC_NDS32_TLS_DESC_FUNC, ++ BFD_RELOC_NDS32_TLS_DESC_CALL, ++ BFD_RELOC_NDS32_TLS_DESC_MEM, ++ BFD_RELOC_NDS32_REMOVE, ++ BFD_RELOC_NDS32_GROUP, ++ ++/* Jump-patch table relative relocations. */ ++ BFD_RELOC_NDS32_ICT, ++ BFD_RELOC_NDS32_ICT_HI20, ++ BFD_RELOC_NDS32_ICT_LO12, ++ BFD_RELOC_NDS32_ICT_25PC, ++ + /* This is a 9-bit reloc */ + BFD_RELOC_V850_9_PCREL, + +@@ -6235,6 +6485,14 @@ + unsigned int selective_search : 1; + }; + ++/* See note beside bfd_set_section_userdata. */ ++static inline bfd_boolean ++bfd_set_cacheable (bfd * abfd, bfd_boolean val) ++{ ++ abfd->cacheable = val; ++ return TRUE; ++} ++ + typedef enum bfd_error + { + bfd_error_no_error = 0, +diff -Nur binutils-2.24.orig/bfd/bfd.c binutils-2.24/bfd/bfd.c +--- binutils-2.24.orig/bfd/bfd.c 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/bfd/bfd.c 2016-04-10 20:30:46.000000000 +0200 +@@ -311,6 +311,14 @@ + . unsigned int selective_search : 1; + .}; + . ++.{* See note beside bfd_set_section_userdata. *} ++.static inline bfd_boolean ++.bfd_set_cacheable (bfd * abfd, bfd_boolean val) ++.{ ++. abfd->cacheable = val; ++. return TRUE; ++.} ++. + */ + + #include "sysdep.h" +diff -Nur binutils-2.24.orig/bfd/config.bfd binutils-2.24/bfd/config.bfd +--- binutils-2.24.orig/bfd/config.bfd 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/bfd/config.bfd 2016-04-10 20:30:46.000000000 +0200 +@@ -6,12 +6,12 @@ + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 3 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; see the file COPYING3. If not see + # . +@@ -109,6 +109,7 @@ + m88*) targ_archs=bfd_m88k_arch ;; + microblaze*) targ_archs=bfd_microblaze_arch ;; + mips*) targ_archs=bfd_mips_arch ;; ++nds32*) targ_archs=bfd_nds32_arch ;; + nios2*) targ_archs=bfd_nios2_arch ;; + or32*) targ_archs=bfd_or32_arch ;; + pdp11*) targ_archs=bfd_pdp11_arch ;; +@@ -1120,6 +1121,28 @@ + targ_selvecs=bfd_elf32_msp430_ti_vec + ;; + ++ nds32*le-*-linux*) ++ targ_defvec=bfd_elf32_nds32lelin_vec ++ targ_selvecs=bfd_elf32_nds32belin_vec ++ targ_cflags=-DNDS32_LINUX_TOOLCHAIN ++ ;; ++ ++ nds32*be-*-linux*) ++ targ_defvec=bfd_elf32_nds32belin_vec ++ targ_selvecs=bfd_elf32_nds32lelin_vec ++ targ_cflags=-DNDS32_LINUX_TOOLCHAIN ++ ;; ++ ++ nds32*le-*-*) ++ targ_defvec=bfd_elf32_nds32le_vec ++ targ_selvecs=bfd_elf32_nds32be_vec ++ ;; ++ ++ nds32*be-*-*) ++ targ_defvec=bfd_elf32_nds32be_vec ++ targ_selvecs=bfd_elf32_nds32le_vec ++ ;; ++ + ns32k-pc532-mach* | ns32k-pc532-ux*) + targ_defvec=pc532machaout_vec + targ_underscore=yes +@@ -1640,12 +1663,12 @@ + w65-*-*) + targ_defvec=w65_vec + ;; +- ++ + xgate-*-*) + targ_defvec=bfd_elf32_xgate_vec + targ_selvecs="bfd_elf32_xgate_vec" + ;; +- ++ + xstormy16-*-elf) + targ_defvec=bfd_elf32_xstormy16_vec + ;; +diff -Nur binutils-2.24.orig/bfd/configure binutils-2.24/bfd/configure +--- binutils-2.24.orig/bfd/configure 2013-12-02 10:30:30.000000000 +0100 ++++ binutils-2.24/bfd/configure 2016-04-10 20:30:46.000000000 +0200 +@@ -15307,6 +15307,10 @@ + tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; + bfd_elf32_ntradlittlemips_vec | bfd_elf32_ntradlittlemips_freebsd_vec) + tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; ++ bfd_elf32_nds32le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; ++ bfd_elf32_nds32be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; ++ bfd_elf32_nds32lelin_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; ++ bfd_elf32_nds32belin_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; + bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;; + bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;; + bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";; +diff -Nur binutils-2.24.orig/bfd/configure.in binutils-2.24/bfd/configure.in +--- binutils-2.24.orig/bfd/configure.in 2013-12-02 10:30:28.000000000 +0100 ++++ binutils-2.24/bfd/configure.in 2016-04-10 20:30:46.000000000 +0200 +@@ -796,6 +796,10 @@ + tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; + bfd_elf32_ntradlittlemips_vec | bfd_elf32_ntradlittlemips_freebsd_vec) + tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;; ++ bfd_elf32_nds32be_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; ++ bfd_elf32_nds32le_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; ++ bfd_elf32_nds32belin_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; ++ bfd_elf32_nds32lelin_vec) tb="$tb elf32-nds32.lo elf32.lo $elf" ;; + bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;; + bfd_elf32_or32_big_vec) tb="$tb elf32-or32.lo elf32.lo $elf" ;; + bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";; +diff -Nur binutils-2.24.orig/bfd/cpu-nds32.c binutils-2.24/bfd/cpu-nds32.c +--- binutils-2.24.orig/bfd/cpu-nds32.c 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/bfd/cpu-nds32.c 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1,44 @@ ++/* BFD support for the NDS32 processor ++ Copyright (C) 2012-2013 Free Software Foundation, Inc. ++ Contributed by Andes Technology Corporation. ++ ++ 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 3 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. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "libbfd.h" ++#include "elf-bfd.h" ++ ++#define N(number, print, default, next) \ ++ {32, 32, 8, bfd_arch_nds32, number, "nds32", print, 4, default, \ ++ bfd_default_compatible, bfd_default_scan, bfd_arch_default_fill, next } ++ ++#define NEXT &arch_info_struct[0] ++#define NDS32V2_NEXT &arch_info_struct[1] ++#define NDS32V3_NEXT &arch_info_struct[2] ++#define NDS32V3M_NEXT &arch_info_struct[3] ++ ++static const bfd_arch_info_type arch_info_struct[] = { ++ N (bfd_mach_n1h, "n1h", FALSE, NDS32V2_NEXT), ++ N (bfd_mach_n1h_v2, "n1h_v2", FALSE, NDS32V3_NEXT), ++ N (bfd_mach_n1h_v3, "n1h_v3", FALSE, NDS32V3M_NEXT), ++ N (bfd_mach_n1h_v3m, "n1h_v3m", FALSE, NULL), ++}; ++ ++const bfd_arch_info_type bfd_nds32_arch = ++ N (bfd_mach_n1, "n1h", TRUE, NEXT); +diff -Nur binutils-2.24.orig/bfd/doc/aoutx.texi binutils-2.24/bfd/doc/aoutx.texi +--- binutils-2.24.orig/bfd/doc/aoutx.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/aoutx.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,213 +0,0 @@ +-@section a.out backends +- +- +-@strong{Description}@* +-BFD supports a number of different flavours of a.out format, +-though the major differences are only the sizes of the +-structures on disk, and the shape of the relocation +-information. +- +-The support is split into a basic support file @file{aoutx.h} +-and other files which derive functions from the base. One +-derivation file is @file{aoutf1.h} (for a.out flavour 1), and +-adds to the basic a.out functions support for sun3, sun4, 386 +-and 29k a.out files, to create a target jump vector for a +-specific target. +- +-This information is further split out into more specific files +-for each machine, including @file{sunos.c} for sun3 and sun4, +-@file{newsos3.c} for the Sony NEWS, and @file{demo64.c} for a +-demonstration of a 64 bit a.out format. +- +-The base file @file{aoutx.h} defines general mechanisms for +-reading and writing records to and from disk and various +-other methods which BFD requires. It is included by +-@file{aout32.c} and @file{aout64.c} to form the names +-@code{aout_32_swap_exec_header_in}, @code{aout_64_swap_exec_header_in}, etc. +- +-As an example, this is what goes on to make the back end for a +-sun4, from @file{aout32.c}: +- +-@example +- #define ARCH_SIZE 32 +- #include "aoutx.h" +-@end example +- +-Which exports names: +- +-@example +- ... +- aout_32_canonicalize_reloc +- aout_32_find_nearest_line +- aout_32_get_lineno +- aout_32_get_reloc_upper_bound +- ... +-@end example +- +-from @file{sunos.c}: +- +-@example +- #define TARGET_NAME "a.out-sunos-big" +- #define VECNAME sunos_big_vec +- #include "aoutf1.h" +-@end example +- +-requires all the names from @file{aout32.c}, and produces the jump vector +- +-@example +- sunos_big_vec +-@end example +- +-The file @file{host-aout.c} is a special case. It is for a large set +-of hosts that use ``more or less standard'' a.out files, and +-for which cross-debugging is not interesting. It uses the +-standard 32-bit a.out support routines, but determines the +-file offsets and addresses of the text, data, and BSS +-sections, the machine architecture and machine type, and the +-entry point address, in a host-dependent manner. Once these +-values have been determined, generic code is used to handle +-the object file. +- +-When porting it to run on a new system, you must supply: +- +-@example +- HOST_PAGE_SIZE +- HOST_SEGMENT_SIZE +- HOST_MACHINE_ARCH (optional) +- HOST_MACHINE_MACHINE (optional) +- HOST_TEXT_START_ADDR +- HOST_STACK_END_ADDR +-@end example +- +-in the file @file{../include/sys/h-@var{XXX}.h} (for your host). These +-values, plus the structures and macros defined in @file{a.out.h} on +-your host system, will produce a BFD target that will access +-ordinary a.out files on your host. To configure a new machine +-to use @file{host-aout.c}, specify: +- +-@example +- TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec +- TDEPFILES= host-aout.o trad-core.o +-@end example +- +-in the @file{config/@var{XXX}.mt} file, and modify @file{configure.in} +-to use the +-@file{@var{XXX}.mt} file (by setting "@code{bfd_target=XXX}") when your +-configuration is selected. +- +-@subsection Relocations +- +- +-@strong{Description}@* +-The file @file{aoutx.h} provides for both the @emph{standard} +-and @emph{extended} forms of a.out relocation records. +- +-The standard records contain only an +-address, a symbol index, and a type field. The extended records +-(used on 29ks and sparcs) also have a full integer for an +-addend. +- +-@subsection Internal entry points +- +- +-@strong{Description}@* +-@file{aoutx.h} exports several routines for accessing the +-contents of an a.out file, which are gathered and exported in +-turn by various format specific files (eg sunos.c). +- +-@findex aout_@var{size}_swap_exec_header_in +-@subsubsection @code{aout_@var{size}_swap_exec_header_in} +-@strong{Synopsis} +-@example +-void aout_@var{size}_swap_exec_header_in, +- (bfd *abfd, +- struct external_exec *bytes, +- struct internal_exec *execp); +-@end example +-@strong{Description}@* +-Swap the information in an executable header @var{raw_bytes} taken +-from a raw byte stream memory image into the internal exec header +-structure @var{execp}. +- +-@findex aout_@var{size}_swap_exec_header_out +-@subsubsection @code{aout_@var{size}_swap_exec_header_out} +-@strong{Synopsis} +-@example +-void aout_@var{size}_swap_exec_header_out +- (bfd *abfd, +- struct internal_exec *execp, +- struct external_exec *raw_bytes); +-@end example +-@strong{Description}@* +-Swap the information in an internal exec header structure +-@var{execp} into the buffer @var{raw_bytes} ready for writing to disk. +- +-@findex aout_@var{size}_some_aout_object_p +-@subsubsection @code{aout_@var{size}_some_aout_object_p} +-@strong{Synopsis} +-@example +-const bfd_target *aout_@var{size}_some_aout_object_p +- (bfd *abfd, +- struct internal_exec *execp, +- const bfd_target *(*callback_to_real_object_p) (bfd *)); +-@end example +-@strong{Description}@* +-Some a.out variant thinks that the file open in @var{abfd} +-checking is an a.out file. Do some more checking, and set up +-for access if it really is. Call back to the calling +-environment's "finish up" function just before returning, to +-handle any last-minute setup. +- +-@findex aout_@var{size}_mkobject +-@subsubsection @code{aout_@var{size}_mkobject} +-@strong{Synopsis} +-@example +-bfd_boolean aout_@var{size}_mkobject, (bfd *abfd); +-@end example +-@strong{Description}@* +-Initialize BFD @var{abfd} for use with a.out files. +- +-@findex aout_@var{size}_machine_type +-@subsubsection @code{aout_@var{size}_machine_type} +-@strong{Synopsis} +-@example +-enum machine_type aout_@var{size}_machine_type +- (enum bfd_architecture arch, +- unsigned long machine, +- bfd_boolean *unknown); +-@end example +-@strong{Description}@* +-Keep track of machine architecture and machine type for +-a.out's. Return the @code{machine_type} for a particular +-architecture and machine, or @code{M_UNKNOWN} if that exact architecture +-and machine can't be represented in a.out format. +- +-If the architecture is understood, machine type 0 (default) +-is always understood. +- +-@findex aout_@var{size}_set_arch_mach +-@subsubsection @code{aout_@var{size}_set_arch_mach} +-@strong{Synopsis} +-@example +-bfd_boolean aout_@var{size}_set_arch_mach, +- (bfd *, +- enum bfd_architecture arch, +- unsigned long machine); +-@end example +-@strong{Description}@* +-Set the architecture and the machine of the BFD @var{abfd} to the +-values @var{arch} and @var{machine}. Verify that @var{abfd}'s format +-can support the architecture required. +- +-@findex aout_@var{size}_new_section_hook +-@subsubsection @code{aout_@var{size}_new_section_hook} +-@strong{Synopsis} +-@example +-bfd_boolean aout_@var{size}_new_section_hook, +- (bfd *abfd, +- asection *newsect); +-@end example +-@strong{Description}@* +-Called by the BFD in response to a @code{bfd_make_section} +-request. +- +diff -Nur binutils-2.24.orig/bfd/doc/archive.texi binutils-2.24/bfd/doc/archive.texi +--- binutils-2.24.orig/bfd/doc/archive.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/archive.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,105 +0,0 @@ +-@section Archives +- +- +-@strong{Description}@* +-An archive (or library) is just another BFD. It has a symbol +-table, although there's not much a user program will do with it. +- +-The big difference between an archive BFD and an ordinary BFD +-is that the archive doesn't have sections. Instead it has a +-chain of BFDs that are considered its contents. These BFDs can +-be manipulated like any other. The BFDs contained in an +-archive opened for reading will all be opened for reading. You +-may put either input or output BFDs into an archive opened for +-output; they will be handled correctly when the archive is closed. +- +-Use @code{bfd_openr_next_archived_file} to step through +-the contents of an archive opened for input. You don't +-have to read the entire archive if you don't want +-to! Read it until you find what you want. +- +-A BFD returned by @code{bfd_openr_next_archived_file} can be +-closed manually with @code{bfd_close}. If you do not close it, +-then a second iteration through the members of an archive may +-return the same BFD. If you close the archive BFD, then all +-the member BFDs will automatically be closed as well. +- +-Archive contents of output BFDs are chained through the +-@code{archive_next} pointer in a BFD. The first one is findable +-through the @code{archive_head} slot of the archive. Set it with +-@code{bfd_set_archive_head} (q.v.). A given BFD may be in only +-one open output archive at a time. +- +-As expected, the BFD archive code is more general than the +-archive code of any given environment. BFD archives may +-contain files of different formats (e.g., a.out and coff) and +-even different architectures. You may even place archives +-recursively into archives! +- +-This can cause unexpected confusion, since some archive +-formats are more expressive than others. For instance, Intel +-COFF archives can preserve long filenames; SunOS a.out archives +-cannot. If you move a file from the first to the second +-format and back again, the filename may be truncated. +-Likewise, different a.out environments have different +-conventions as to how they truncate filenames, whether they +-preserve directory names in filenames, etc. When +-interoperating with native tools, be sure your files are +-homogeneous. +- +-Beware: most of these formats do not react well to the +-presence of spaces in filenames. We do the best we can, but +-can't always handle this case due to restrictions in the format of +-archives. Many Unix utilities are braindead in regards to +-spaces and such in filenames anyway, so this shouldn't be much +-of a restriction. +- +-Archives are supported in BFD in @code{archive.c}. +- +-@subsection Archive functions +- +- +-@findex bfd_get_next_mapent +-@subsubsection @code{bfd_get_next_mapent} +-@strong{Synopsis} +-@example +-symindex bfd_get_next_mapent +- (bfd *abfd, symindex previous, carsym **sym); +-@end example +-@strong{Description}@* +-Step through archive @var{abfd}'s symbol table (if it +-has one). Successively update @var{sym} with the next symbol's +-information, returning that symbol's (internal) index into the +-symbol table. +- +-Supply @code{BFD_NO_MORE_SYMBOLS} as the @var{previous} entry to get +-the first one; returns @code{BFD_NO_MORE_SYMBOLS} when you've already +-got the last one. +- +-A @code{carsym} is a canonical archive symbol. The only +-user-visible element is its name, a null-terminated string. +- +-@findex bfd_set_archive_head +-@subsubsection @code{bfd_set_archive_head} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); +-@end example +-@strong{Description}@* +-Set the head of the chain of +-BFDs contained in the archive @var{output} to @var{new_head}. +- +-@findex bfd_openr_next_archived_file +-@subsubsection @code{bfd_openr_next_archived_file} +-@strong{Synopsis} +-@example +-bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); +-@end example +-@strong{Description}@* +-Provided a BFD, @var{archive}, containing an archive and NULL, open +-an input BFD on the first contained element and returns that. +-Subsequent calls should pass +-the archive and the previous return value to return a created +-BFD to the next contained element. NULL is returned when there +-are no more. +- +diff -Nur binutils-2.24.orig/bfd/doc/archures.texi binutils-2.24/bfd/doc/archures.texi +--- binutils-2.24.orig/bfd/doc/archures.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/archures.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,706 +0,0 @@ +-@section Architectures +-BFD keeps one atom in a BFD describing the +-architecture of the data attached to the BFD: a pointer to a +-@code{bfd_arch_info_type}. +- +-Pointers to structures can be requested independently of a BFD +-so that an architecture's information can be interrogated +-without access to an open BFD. +- +-The architecture information is provided by each architecture package. +-The set of default architectures is selected by the macro +-@code{SELECT_ARCHITECTURES}. This is normally set up in the +-@file{config/@var{target}.mt} file of your choice. If the name is not +-defined, then all the architectures supported are included. +- +-When BFD starts up, all the architectures are called with an +-initialize method. It is up to the architecture back end to +-insert as many items into the list of architectures as it wants to; +-generally this would be one for each machine and one for the +-default case (an item with a machine field of 0). +- +-BFD's idea of an architecture is implemented in @file{archures.c}. +- +-@subsection bfd_architecture +- +- +-@strong{Description}@* +-This enum gives the object file's CPU architecture, in a +-global sense---i.e., what processor family does it belong to? +-Another field indicates which processor within +-the family is in use. The machine gives a number which +-distinguishes different versions of the architecture, +-containing, for example, 2 and 3 for Intel i960 KA and i960 KB, +-and 68020 and 68030 for Motorola 68020 and 68030. +-@example +-enum bfd_architecture +-@{ +- bfd_arch_unknown, /* File arch not known. */ +- bfd_arch_obscure, /* Arch known, not one of these. */ +- bfd_arch_m68k, /* Motorola 68xxx */ +-#define bfd_mach_m68000 1 +-#define bfd_mach_m68008 2 +-#define bfd_mach_m68010 3 +-#define bfd_mach_m68020 4 +-#define bfd_mach_m68030 5 +-#define bfd_mach_m68040 6 +-#define bfd_mach_m68060 7 +-#define bfd_mach_cpu32 8 +-#define bfd_mach_fido 9 +-#define bfd_mach_mcf_isa_a_nodiv 10 +-#define bfd_mach_mcf_isa_a 11 +-#define bfd_mach_mcf_isa_a_mac 12 +-#define bfd_mach_mcf_isa_a_emac 13 +-#define bfd_mach_mcf_isa_aplus 14 +-#define bfd_mach_mcf_isa_aplus_mac 15 +-#define bfd_mach_mcf_isa_aplus_emac 16 +-#define bfd_mach_mcf_isa_b_nousp 17 +-#define bfd_mach_mcf_isa_b_nousp_mac 18 +-#define bfd_mach_mcf_isa_b_nousp_emac 19 +-#define bfd_mach_mcf_isa_b 20 +-#define bfd_mach_mcf_isa_b_mac 21 +-#define bfd_mach_mcf_isa_b_emac 22 +-#define bfd_mach_mcf_isa_b_float 23 +-#define bfd_mach_mcf_isa_b_float_mac 24 +-#define bfd_mach_mcf_isa_b_float_emac 25 +-#define bfd_mach_mcf_isa_c 26 +-#define bfd_mach_mcf_isa_c_mac 27 +-#define bfd_mach_mcf_isa_c_emac 28 +-#define bfd_mach_mcf_isa_c_nodiv 29 +-#define bfd_mach_mcf_isa_c_nodiv_mac 30 +-#define bfd_mach_mcf_isa_c_nodiv_emac 31 +- bfd_arch_vax, /* DEC Vax */ +- bfd_arch_i960, /* Intel 960 */ +- /* The order of the following is important. +- lower number indicates a machine type that +- only accepts a subset of the instructions +- available to machines with higher numbers. +- The exception is the "ca", which is +- incompatible with all other machines except +- "core". */ +- +-#define bfd_mach_i960_core 1 +-#define bfd_mach_i960_ka_sa 2 +-#define bfd_mach_i960_kb_sb 3 +-#define bfd_mach_i960_mc 4 +-#define bfd_mach_i960_xa 5 +-#define bfd_mach_i960_ca 6 +-#define bfd_mach_i960_jx 7 +-#define bfd_mach_i960_hx 8 +- +- bfd_arch_or32, /* OpenRISC 32 */ +- +- bfd_arch_sparc, /* SPARC */ +-#define bfd_mach_sparc 1 +-/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ +-#define bfd_mach_sparc_sparclet 2 +-#define bfd_mach_sparc_sparclite 3 +-#define bfd_mach_sparc_v8plus 4 +-#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ +-#define bfd_mach_sparc_sparclite_le 6 +-#define bfd_mach_sparc_v9 7 +-#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ +-#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ +-#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ +-/* Nonzero if MACH has the v9 instruction set. */ +-#define bfd_mach_sparc_v9_p(mach) \ +- ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ +- && (mach) != bfd_mach_sparc_sparclite_le) +-/* Nonzero if MACH is a 64 bit sparc architecture. */ +-#define bfd_mach_sparc_64bit_p(mach) \ +- ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) +- bfd_arch_spu, /* PowerPC SPU */ +-#define bfd_mach_spu 256 +- bfd_arch_mips, /* MIPS Rxxxx */ +-#define bfd_mach_mips3000 3000 +-#define bfd_mach_mips3900 3900 +-#define bfd_mach_mips4000 4000 +-#define bfd_mach_mips4010 4010 +-#define bfd_mach_mips4100 4100 +-#define bfd_mach_mips4111 4111 +-#define bfd_mach_mips4120 4120 +-#define bfd_mach_mips4300 4300 +-#define bfd_mach_mips4400 4400 +-#define bfd_mach_mips4600 4600 +-#define bfd_mach_mips4650 4650 +-#define bfd_mach_mips5000 5000 +-#define bfd_mach_mips5400 5400 +-#define bfd_mach_mips5500 5500 +-#define bfd_mach_mips5900 5900 +-#define bfd_mach_mips6000 6000 +-#define bfd_mach_mips7000 7000 +-#define bfd_mach_mips8000 8000 +-#define bfd_mach_mips9000 9000 +-#define bfd_mach_mips10000 10000 +-#define bfd_mach_mips12000 12000 +-#define bfd_mach_mips14000 14000 +-#define bfd_mach_mips16000 16000 +-#define bfd_mach_mips16 16 +-#define bfd_mach_mips5 5 +-#define bfd_mach_mips_loongson_2e 3001 +-#define bfd_mach_mips_loongson_2f 3002 +-#define bfd_mach_mips_loongson_3a 3003 +-#define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ +-#define bfd_mach_mips_octeon 6501 +-#define bfd_mach_mips_octeonp 6601 +-#define bfd_mach_mips_octeon2 6502 +-#define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */ +-#define bfd_mach_mipsisa32 32 +-#define bfd_mach_mipsisa32r2 33 +-#define bfd_mach_mipsisa64 64 +-#define bfd_mach_mipsisa64r2 65 +-#define bfd_mach_mips_micromips 96 +- bfd_arch_i386, /* Intel 386 */ +-#define bfd_mach_i386_intel_syntax (1 << 0) +-#define bfd_mach_i386_i8086 (1 << 1) +-#define bfd_mach_i386_i386 (1 << 2) +-#define bfd_mach_x86_64 (1 << 3) +-#define bfd_mach_x64_32 (1 << 4) +-#define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax) +-#define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax) +-#define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax) +- bfd_arch_l1om, /* Intel L1OM */ +-#define bfd_mach_l1om (1 << 5) +-#define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax) +- bfd_arch_k1om, /* Intel K1OM */ +-#define bfd_mach_k1om (1 << 6) +-#define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax) +-#define bfd_mach_i386_nacl (1 << 7) +-#define bfd_mach_i386_i386_nacl (bfd_mach_i386_i386 | bfd_mach_i386_nacl) +-#define bfd_mach_x86_64_nacl (bfd_mach_x86_64 | bfd_mach_i386_nacl) +-#define bfd_mach_x64_32_nacl (bfd_mach_x64_32 | bfd_mach_i386_nacl) +- bfd_arch_we32k, /* AT&T WE32xxx */ +- bfd_arch_tahoe, /* CCI/Harris Tahoe */ +- bfd_arch_i860, /* Intel 860 */ +- bfd_arch_i370, /* IBM 360/370 Mainframes */ +- bfd_arch_romp, /* IBM ROMP PC/RT */ +- bfd_arch_convex, /* Convex */ +- bfd_arch_m88k, /* Motorola 88xxx */ +- bfd_arch_m98k, /* Motorola 98xxx */ +- bfd_arch_pyramid, /* Pyramid Technology */ +- bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ +-#define bfd_mach_h8300 1 +-#define bfd_mach_h8300h 2 +-#define bfd_mach_h8300s 3 +-#define bfd_mach_h8300hn 4 +-#define bfd_mach_h8300sn 5 +-#define bfd_mach_h8300sx 6 +-#define bfd_mach_h8300sxn 7 +- bfd_arch_pdp11, /* DEC PDP-11 */ +- bfd_arch_plugin, +- bfd_arch_powerpc, /* PowerPC */ +-#define bfd_mach_ppc 32 +-#define bfd_mach_ppc64 64 +-#define bfd_mach_ppc_403 403 +-#define bfd_mach_ppc_403gc 4030 +-#define bfd_mach_ppc_405 405 +-#define bfd_mach_ppc_505 505 +-#define bfd_mach_ppc_601 601 +-#define bfd_mach_ppc_602 602 +-#define bfd_mach_ppc_603 603 +-#define bfd_mach_ppc_ec603e 6031 +-#define bfd_mach_ppc_604 604 +-#define bfd_mach_ppc_620 620 +-#define bfd_mach_ppc_630 630 +-#define bfd_mach_ppc_750 750 +-#define bfd_mach_ppc_860 860 +-#define bfd_mach_ppc_a35 35 +-#define bfd_mach_ppc_rs64ii 642 +-#define bfd_mach_ppc_rs64iii 643 +-#define bfd_mach_ppc_7400 7400 +-#define bfd_mach_ppc_e500 500 +-#define bfd_mach_ppc_e500mc 5001 +-#define bfd_mach_ppc_e500mc64 5005 +-#define bfd_mach_ppc_e5500 5006 +-#define bfd_mach_ppc_e6500 5007 +-#define bfd_mach_ppc_titan 83 +-#define bfd_mach_ppc_vle 84 +- bfd_arch_rs6000, /* IBM RS/6000 */ +-#define bfd_mach_rs6k 6000 +-#define bfd_mach_rs6k_rs1 6001 +-#define bfd_mach_rs6k_rsc 6003 +-#define bfd_mach_rs6k_rs2 6002 +- bfd_arch_hppa, /* HP PA RISC */ +-#define bfd_mach_hppa10 10 +-#define bfd_mach_hppa11 11 +-#define bfd_mach_hppa20 20 +-#define bfd_mach_hppa20w 25 +- bfd_arch_d10v, /* Mitsubishi D10V */ +-#define bfd_mach_d10v 1 +-#define bfd_mach_d10v_ts2 2 +-#define bfd_mach_d10v_ts3 3 +- bfd_arch_d30v, /* Mitsubishi D30V */ +- bfd_arch_dlx, /* DLX */ +- bfd_arch_m68hc11, /* Motorola 68HC11 */ +- bfd_arch_m68hc12, /* Motorola 68HC12 */ +-#define bfd_mach_m6812_default 0 +-#define bfd_mach_m6812 1 +-#define bfd_mach_m6812s 2 +- bfd_arch_m9s12x, /* Freescale S12X */ +- bfd_arch_m9s12xg, /* Freescale XGATE */ +- bfd_arch_z8k, /* Zilog Z8000 */ +-#define bfd_mach_z8001 1 +-#define bfd_mach_z8002 2 +- bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ +- bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ +-#define bfd_mach_sh 1 +-#define bfd_mach_sh2 0x20 +-#define bfd_mach_sh_dsp 0x2d +-#define bfd_mach_sh2a 0x2a +-#define bfd_mach_sh2a_nofpu 0x2b +-#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 +-#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 +-#define bfd_mach_sh2a_or_sh4 0x2a3 +-#define bfd_mach_sh2a_or_sh3e 0x2a4 +-#define bfd_mach_sh2e 0x2e +-#define bfd_mach_sh3 0x30 +-#define bfd_mach_sh3_nommu 0x31 +-#define bfd_mach_sh3_dsp 0x3d +-#define bfd_mach_sh3e 0x3e +-#define bfd_mach_sh4 0x40 +-#define bfd_mach_sh4_nofpu 0x41 +-#define bfd_mach_sh4_nommu_nofpu 0x42 +-#define bfd_mach_sh4a 0x4a +-#define bfd_mach_sh4a_nofpu 0x4b +-#define bfd_mach_sh4al_dsp 0x4d +-#define bfd_mach_sh5 0x50 +- bfd_arch_alpha, /* Dec Alpha */ +-#define bfd_mach_alpha_ev4 0x10 +-#define bfd_mach_alpha_ev5 0x20 +-#define bfd_mach_alpha_ev6 0x30 +- bfd_arch_arm, /* Advanced Risc Machines ARM. */ +-#define bfd_mach_arm_unknown 0 +-#define bfd_mach_arm_2 1 +-#define bfd_mach_arm_2a 2 +-#define bfd_mach_arm_3 3 +-#define bfd_mach_arm_3M 4 +-#define bfd_mach_arm_4 5 +-#define bfd_mach_arm_4T 6 +-#define bfd_mach_arm_5 7 +-#define bfd_mach_arm_5T 8 +-#define bfd_mach_arm_5TE 9 +-#define bfd_mach_arm_XScale 10 +-#define bfd_mach_arm_ep9312 11 +-#define bfd_mach_arm_iWMMXt 12 +-#define bfd_mach_arm_iWMMXt2 13 +- bfd_arch_ns32k, /* National Semiconductors ns32000 */ +- bfd_arch_w65, /* WDC 65816 */ +- bfd_arch_tic30, /* Texas Instruments TMS320C30 */ +- bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ +-#define bfd_mach_tic3x 30 +-#define bfd_mach_tic4x 40 +- bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ +- bfd_arch_tic6x, /* Texas Instruments TMS320C6X */ +- bfd_arch_tic80, /* TI TMS320c80 (MVP) */ +- bfd_arch_v850, /* NEC V850 */ +- bfd_arch_v850_rh850,/* NEC V850 (using RH850 ABI) */ +-#define bfd_mach_v850 1 +-#define bfd_mach_v850e 'E' +-#define bfd_mach_v850e1 '1' +-#define bfd_mach_v850e2 0x4532 +-#define bfd_mach_v850e2v3 0x45325633 +-#define bfd_mach_v850e3v5 0x45335635 /* ('E'|'3'|'V'|'5') */ +- bfd_arch_arc, /* ARC Cores */ +-#define bfd_mach_arc_5 5 +-#define bfd_mach_arc_6 6 +-#define bfd_mach_arc_7 7 +-#define bfd_mach_arc_8 8 +- bfd_arch_m32c, /* Renesas M16C/M32C. */ +-#define bfd_mach_m16c 0x75 +-#define bfd_mach_m32c 0x78 +- bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ +-#define bfd_mach_m32r 1 /* For backwards compatibility. */ +-#define bfd_mach_m32rx 'x' +-#define bfd_mach_m32r2 '2' +- bfd_arch_mn10200, /* Matsushita MN10200 */ +- bfd_arch_mn10300, /* Matsushita MN10300 */ +-#define bfd_mach_mn10300 300 +-#define bfd_mach_am33 330 +-#define bfd_mach_am33_2 332 +- bfd_arch_fr30, +-#define bfd_mach_fr30 0x46523330 +- bfd_arch_frv, +-#define bfd_mach_frv 1 +-#define bfd_mach_frvsimple 2 +-#define bfd_mach_fr300 300 +-#define bfd_mach_fr400 400 +-#define bfd_mach_fr450 450 +-#define bfd_mach_frvtomcat 499 /* fr500 prototype */ +-#define bfd_mach_fr500 500 +-#define bfd_mach_fr550 550 +- bfd_arch_moxie, /* The moxie processor */ +-#define bfd_mach_moxie 1 +- bfd_arch_mcore, +- bfd_arch_mep, +-#define bfd_mach_mep 1 +-#define bfd_mach_mep_h1 0x6831 +-#define bfd_mach_mep_c5 0x6335 +- bfd_arch_metag, +-#define bfd_mach_metag 1 +- bfd_arch_ia64, /* HP/Intel ia64 */ +-#define bfd_mach_ia64_elf64 64 +-#define bfd_mach_ia64_elf32 32 +- bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ +-#define bfd_mach_ip2022 1 +-#define bfd_mach_ip2022ext 2 +- bfd_arch_iq2000, /* Vitesse IQ2000. */ +-#define bfd_mach_iq2000 1 +-#define bfd_mach_iq10 2 +- bfd_arch_epiphany, /* Adapteva EPIPHANY */ +-#define bfd_mach_epiphany16 1 +-#define bfd_mach_epiphany32 2 +- bfd_arch_mt, +-#define bfd_mach_ms1 1 +-#define bfd_mach_mrisc2 2 +-#define bfd_mach_ms2 3 +- bfd_arch_pj, +- bfd_arch_avr, /* Atmel AVR microcontrollers. */ +-#define bfd_mach_avr1 1 +-#define bfd_mach_avr2 2 +-#define bfd_mach_avr25 25 +-#define bfd_mach_avr3 3 +-#define bfd_mach_avr31 31 +-#define bfd_mach_avr35 35 +-#define bfd_mach_avr4 4 +-#define bfd_mach_avr5 5 +-#define bfd_mach_avr51 51 +-#define bfd_mach_avr6 6 +-#define bfd_mach_avrxmega1 101 +-#define bfd_mach_avrxmega2 102 +-#define bfd_mach_avrxmega3 103 +-#define bfd_mach_avrxmega4 104 +-#define bfd_mach_avrxmega5 105 +-#define bfd_mach_avrxmega6 106 +-#define bfd_mach_avrxmega7 107 +- bfd_arch_bfin, /* ADI Blackfin */ +-#define bfd_mach_bfin 1 +- bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ +-#define bfd_mach_cr16 1 +- bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ +-#define bfd_mach_cr16c 1 +- bfd_arch_crx, /* National Semiconductor CRX. */ +-#define bfd_mach_crx 1 +- bfd_arch_cris, /* Axis CRIS */ +-#define bfd_mach_cris_v0_v10 255 +-#define bfd_mach_cris_v32 32 +-#define bfd_mach_cris_v10_v32 1032 +- bfd_arch_rl78, +-#define bfd_mach_rl78 0x75 +- bfd_arch_rx, /* Renesas RX. */ +-#define bfd_mach_rx 0x75 +- bfd_arch_s390, /* IBM s390 */ +-#define bfd_mach_s390_31 31 +-#define bfd_mach_s390_64 64 +- bfd_arch_score, /* Sunplus score */ +-#define bfd_mach_score3 3 +-#define bfd_mach_score7 7 +- bfd_arch_openrisc, /* OpenRISC */ +- bfd_arch_mmix, /* Donald Knuth's educational processor. */ +- bfd_arch_xstormy16, +-#define bfd_mach_xstormy16 1 +- bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ +-#define bfd_mach_msp11 11 +-#define bfd_mach_msp110 110 +-#define bfd_mach_msp12 12 +-#define bfd_mach_msp13 13 +-#define bfd_mach_msp14 14 +-#define bfd_mach_msp15 15 +-#define bfd_mach_msp16 16 +-#define bfd_mach_msp20 20 +-#define bfd_mach_msp21 21 +-#define bfd_mach_msp22 22 +-#define bfd_mach_msp23 23 +-#define bfd_mach_msp24 24 +-#define bfd_mach_msp26 26 +-#define bfd_mach_msp31 31 +-#define bfd_mach_msp32 32 +-#define bfd_mach_msp33 33 +-#define bfd_mach_msp41 41 +-#define bfd_mach_msp42 42 +-#define bfd_mach_msp43 43 +-#define bfd_mach_msp44 44 +-#define bfd_mach_msp430x 45 +-#define bfd_mach_msp46 46 +-#define bfd_mach_msp47 47 +-#define bfd_mach_msp54 54 +- bfd_arch_xc16x, /* Infineon's XC16X Series. */ +-#define bfd_mach_xc16x 1 +-#define bfd_mach_xc16xl 2 +-#define bfd_mach_xc16xs 3 +- bfd_arch_xgate, /* Freescale XGATE */ +-#define bfd_mach_xgate 1 +- bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ +-#define bfd_mach_xtensa 1 +- bfd_arch_z80, +-#define bfd_mach_z80strict 1 /* No undocumented opcodes. */ +-#define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */ +-#define bfd_mach_z80full 7 /* All undocumented instructions. */ +-#define bfd_mach_r800 11 /* R800: successor with multiplication. */ +- bfd_arch_lm32, /* Lattice Mico32 */ +-#define bfd_mach_lm32 1 +- bfd_arch_microblaze,/* Xilinx MicroBlaze. */ +- bfd_arch_tilepro, /* Tilera TILEPro */ +- bfd_arch_tilegx, /* Tilera TILE-Gx */ +-#define bfd_mach_tilepro 1 +-#define bfd_mach_tilegx 1 +-#define bfd_mach_tilegx32 2 +- bfd_arch_aarch64, /* AArch64 */ +-#define bfd_mach_aarch64 0 +-#define bfd_mach_aarch64_ilp32 32 +- bfd_arch_nios2, +-#define bfd_mach_nios2 0 +- bfd_arch_last +- @}; +-@end example +- +-@subsection bfd_arch_info +- +- +-@strong{Description}@* +-This structure contains information on architectures for use +-within BFD. +-@example +- +-typedef struct bfd_arch_info +-@{ +- int bits_per_word; +- int bits_per_address; +- int bits_per_byte; +- enum bfd_architecture arch; +- unsigned long mach; +- const char *arch_name; +- const char *printable_name; +- unsigned int section_align_power; +- /* TRUE if this is the default machine for the architecture. +- The default arch should be the first entry for an arch so that +- all the entries for that arch can be accessed via @code{next}. */ +- bfd_boolean the_default; +- const struct bfd_arch_info * (*compatible) +- (const struct bfd_arch_info *a, const struct bfd_arch_info *b); +- +- bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); +- +- /* Allocate via bfd_malloc and return a fill buffer of size COUNT. If +- IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is +- TRUE, the buffer contains code. */ +- void *(*fill) (bfd_size_type count, bfd_boolean is_bigendian, +- bfd_boolean code); +- +- const struct bfd_arch_info *next; +-@} +-bfd_arch_info_type; +- +-@end example +- +-@findex bfd_printable_name +-@subsubsection @code{bfd_printable_name} +-@strong{Synopsis} +-@example +-const char *bfd_printable_name (bfd *abfd); +-@end example +-@strong{Description}@* +-Return a printable string representing the architecture and machine +-from the pointer to the architecture info structure. +- +-@findex bfd_scan_arch +-@subsubsection @code{bfd_scan_arch} +-@strong{Synopsis} +-@example +-const bfd_arch_info_type *bfd_scan_arch (const char *string); +-@end example +-@strong{Description}@* +-Figure out if BFD supports any cpu which could be described with +-the name @var{string}. Return a pointer to an @code{arch_info} +-structure if a machine is found, otherwise NULL. +- +-@findex bfd_arch_list +-@subsubsection @code{bfd_arch_list} +-@strong{Synopsis} +-@example +-const char **bfd_arch_list (void); +-@end example +-@strong{Description}@* +-Return a freshly malloced NULL-terminated vector of the names +-of all the valid BFD architectures. Do not modify the names. +- +-@findex bfd_arch_get_compatible +-@subsubsection @code{bfd_arch_get_compatible} +-@strong{Synopsis} +-@example +-const bfd_arch_info_type *bfd_arch_get_compatible +- (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); +-@end example +-@strong{Description}@* +-Determine whether two BFDs' architectures and machine types +-are compatible. Calculates the lowest common denominator +-between the two architectures and machine types implied by +-the BFDs and returns a pointer to an @code{arch_info} structure +-describing the compatible machine. +- +-@findex bfd_default_arch_struct +-@subsubsection @code{bfd_default_arch_struct} +-@strong{Description}@* +-The @code{bfd_default_arch_struct} is an item of +-@code{bfd_arch_info_type} which has been initialized to a fairly +-generic state. A BFD starts life by pointing to this +-structure, until the correct back end has determined the real +-architecture of the file. +-@example +-extern const bfd_arch_info_type bfd_default_arch_struct; +-@end example +- +-@findex bfd_set_arch_info +-@subsubsection @code{bfd_set_arch_info} +-@strong{Synopsis} +-@example +-void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); +-@end example +-@strong{Description}@* +-Set the architecture info of @var{abfd} to @var{arg}. +- +-@findex bfd_default_set_arch_mach +-@subsubsection @code{bfd_default_set_arch_mach} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_default_set_arch_mach +- (bfd *abfd, enum bfd_architecture arch, unsigned long mach); +-@end example +-@strong{Description}@* +-Set the architecture and machine type in BFD @var{abfd} +-to @var{arch} and @var{mach}. Find the correct +-pointer to a structure and insert it into the @code{arch_info} +-pointer. +- +-@findex bfd_get_arch +-@subsubsection @code{bfd_get_arch} +-@strong{Synopsis} +-@example +-enum bfd_architecture bfd_get_arch (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the enumerated type which describes the BFD @var{abfd}'s +-architecture. +- +-@findex bfd_get_mach +-@subsubsection @code{bfd_get_mach} +-@strong{Synopsis} +-@example +-unsigned long bfd_get_mach (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the long type which describes the BFD @var{abfd}'s +-machine. +- +-@findex bfd_arch_bits_per_byte +-@subsubsection @code{bfd_arch_bits_per_byte} +-@strong{Synopsis} +-@example +-unsigned int bfd_arch_bits_per_byte (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the number of bits in one of the BFD @var{abfd}'s +-architecture's bytes. +- +-@findex bfd_arch_bits_per_address +-@subsubsection @code{bfd_arch_bits_per_address} +-@strong{Synopsis} +-@example +-unsigned int bfd_arch_bits_per_address (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the number of bits in one of the BFD @var{abfd}'s +-architecture's addresses. +- +-@findex bfd_default_compatible +-@subsubsection @code{bfd_default_compatible} +-@strong{Synopsis} +-@example +-const bfd_arch_info_type *bfd_default_compatible +- (const bfd_arch_info_type *a, const bfd_arch_info_type *b); +-@end example +-@strong{Description}@* +-The default function for testing for compatibility. +- +-@findex bfd_default_scan +-@subsubsection @code{bfd_default_scan} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_default_scan +- (const struct bfd_arch_info *info, const char *string); +-@end example +-@strong{Description}@* +-The default function for working out whether this is an +-architecture hit and a machine hit. +- +-@findex bfd_get_arch_info +-@subsubsection @code{bfd_get_arch_info} +-@strong{Synopsis} +-@example +-const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the architecture info struct in @var{abfd}. +- +-@findex bfd_lookup_arch +-@subsubsection @code{bfd_lookup_arch} +-@strong{Synopsis} +-@example +-const bfd_arch_info_type *bfd_lookup_arch +- (enum bfd_architecture arch, unsigned long machine); +-@end example +-@strong{Description}@* +-Look for the architecture info structure which matches the +-arguments @var{arch} and @var{machine}. A machine of 0 matches the +-machine/architecture structure which marks itself as the +-default. +- +-@findex bfd_printable_arch_mach +-@subsubsection @code{bfd_printable_arch_mach} +-@strong{Synopsis} +-@example +-const char *bfd_printable_arch_mach +- (enum bfd_architecture arch, unsigned long machine); +-@end example +-@strong{Description}@* +-Return a printable string representing the architecture and +-machine type. +- +-This routine is depreciated. +- +-@findex bfd_octets_per_byte +-@subsubsection @code{bfd_octets_per_byte} +-@strong{Synopsis} +-@example +-unsigned int bfd_octets_per_byte (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the number of octets (8-bit quantities) per target byte +-(minimum addressable unit). In most cases, this will be one, but some +-DSP targets have 16, 32, or even 48 bits per byte. +- +-@findex bfd_arch_mach_octets_per_byte +-@subsubsection @code{bfd_arch_mach_octets_per_byte} +-@strong{Synopsis} +-@example +-unsigned int bfd_arch_mach_octets_per_byte +- (enum bfd_architecture arch, unsigned long machine); +-@end example +-@strong{Description}@* +-See bfd_octets_per_byte. +- +-This routine is provided for those cases where a bfd * is not +-available +- +-@findex bfd_arch_default_fill +-@subsubsection @code{bfd_arch_default_fill} +-@strong{Synopsis} +-@example +-void *bfd_arch_default_fill (bfd_size_type count, +- bfd_boolean is_bigendian, +- bfd_boolean code); +-@end example +-@strong{Description}@* +-Allocate via bfd_malloc and return a fill buffer of size COUNT. +-If IS_BIGENDIAN is TRUE, the order of bytes is big endian. If +-CODE is TRUE, the buffer contains code. +- +diff -Nur binutils-2.24.orig/bfd/doc/bfd.info binutils-2.24/bfd/doc/bfd.info +--- binutils-2.24.orig/bfd/doc/bfd.info 2013-12-02 10:32:19.000000000 +0100 ++++ binutils-2.24/bfd/doc/bfd.info 1970-01-01 01:00:00.000000000 +0100 +@@ -1,13242 +0,0 @@ +-This is bfd.info, produced by makeinfo version 4.8 from bfd.texinfo. +- +-INFO-DIR-SECTION Software development +-START-INFO-DIR-ENTRY +-* Bfd: (bfd). The Binary File Descriptor library. +-END-INFO-DIR-ENTRY +- +- This file documents the BFD library. +- +- Copyright (C) 1991 - 2013 Free Software Foundation, Inc. +- +- Permission is granted to copy, distribute and/or modify this document +-under the terms of the GNU Free Documentation License, Version 1.3 or +-any later version published by the Free Software Foundation; with the +-Invariant Sections being "GNU General Public License" and "Funding Free +-Software", the Front-Cover texts being (a) (see below), and with the +-Back-Cover Texts being (b) (see below). A copy of the license is +-included in the section entitled "GNU Free Documentation License". +- +- (a) The FSF's Front-Cover Text is: +- +- A GNU Manual +- +- (b) The FSF's Back-Cover Text is: +- +- You have freedom to copy and modify this GNU Manual, like GNU +-software. Copies published by the Free Software Foundation raise +-funds for GNU development. +- +- +-File: bfd.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) +- +- This file documents the binary file descriptor library libbfd. +- +-* Menu: +- +-* Overview:: Overview of BFD +-* BFD front end:: BFD front end +-* BFD back ends:: BFD back ends +-* GNU Free Documentation License:: GNU Free Documentation License +-* BFD Index:: BFD Index +- +- +-File: bfd.info, Node: Overview, Next: BFD front end, Prev: Top, Up: Top +- +-1 Introduction +-************** +- +-BFD is a package which allows applications to use the same routines to +-operate on object files whatever the object file format. A new object +-file format can be supported simply by creating a new BFD back end and +-adding it to the library. +- +- BFD is split into two parts: the front end, and the back ends (one +-for each object file format). +- * The front end of BFD provides the interface to the user. It manages +- memory and various canonical data structures. The front end also +- decides which back end to use and when to call back end routines. +- +- * The back ends provide BFD its view of the real world. Each back +- end provides a set of calls which the BFD front end can use to +- maintain its canonical form. The back ends also may keep around +- information for their own use, for greater efficiency. +- +-* Menu: +- +-* History:: History +-* How It Works:: How It Works +-* What BFD Version 2 Can Do:: What BFD Version 2 Can Do +- +- +-File: bfd.info, Node: History, Next: How It Works, Prev: Overview, Up: Overview +- +-1.1 History +-=========== +- +-One spur behind BFD was the desire, on the part of the GNU 960 team at +-Intel Oregon, for interoperability of applications on their COFF and +-b.out file formats. Cygnus was providing GNU support for the team, and +-was contracted to provide the required functionality. +- +- The name came from a conversation David Wallace was having with +-Richard Stallman about the library: RMS said that it would be quite +-hard--David said "BFD". Stallman was right, but the name stuck. +- +- At the same time, Ready Systems wanted much the same thing, but for +-different object file formats: IEEE-695, Oasys, Srecords, a.out and 68k +-coff. +- +- BFD was first implemented by members of Cygnus Support; Steve +-Chamberlain (`sac@cygnus.com'), John Gilmore (`gnu@cygnus.com'), K. +-Richard Pixley (`rich@cygnus.com') and David Henkel-Wallace +-(`gumby@cygnus.com'). +- +- +-File: bfd.info, Node: How It Works, Next: What BFD Version 2 Can Do, Prev: History, Up: Overview +- +-1.2 How To Use BFD +-================== +- +-To use the library, include `bfd.h' and link with `libbfd.a'. +- +- BFD provides a common interface to the parts of an object file for a +-calling application. +- +- When an application successfully opens a target file (object, +-archive, or whatever), a pointer to an internal structure is returned. +-This pointer points to a structure called `bfd', described in `bfd.h'. +-Our convention is to call this pointer a BFD, and instances of it +-within code `abfd'. All operations on the target object file are +-applied as methods to the BFD. The mapping is defined within `bfd.h' +-in a set of macros, all beginning with `bfd_' to reduce namespace +-pollution. +- +- For example, this sequence does what you would probably expect: +-return the number of sections in an object file attached to a BFD +-`abfd'. +- +- #include "bfd.h" +- +- unsigned int number_of_sections (abfd) +- bfd *abfd; +- { +- return bfd_count_sections (abfd); +- } +- +- The abstraction used within BFD is that an object file has: +- +- * a header, +- +- * a number of sections containing raw data (*note Sections::), +- +- * a set of relocations (*note Relocations::), and +- +- * some symbol information (*note Symbols::). +- Also, BFDs opened for archives have the additional attribute of an +-index and contain subordinate BFDs. This approach is fine for a.out and +-coff, but loses efficiency when applied to formats such as S-records and +-IEEE-695. +- +- +-File: bfd.info, Node: What BFD Version 2 Can Do, Prev: How It Works, Up: Overview +- +-1.3 What BFD Version 2 Can Do +-============================= +- +-When an object file is opened, BFD subroutines automatically determine +-the format of the input object file. They then build a descriptor in +-memory with pointers to routines that will be used to access elements of +-the object file's data structures. +- +- As different information from the object files is required, BFD +-reads from different sections of the file and processes them. For +-example, a very common operation for the linker is processing symbol +-tables. Each BFD back end provides a routine for converting between +-the object file's representation of symbols and an internal canonical +-format. When the linker asks for the symbol table of an object file, it +-calls through a memory pointer to the routine from the relevant BFD +-back end which reads and converts the table into a canonical form. The +-linker then operates upon the canonical form. When the link is finished +-and the linker writes the output file's symbol table, another BFD back +-end routine is called to take the newly created symbol table and +-convert it into the chosen output format. +- +-* Menu: +- +-* BFD information loss:: Information Loss +-* Canonical format:: The BFD canonical object-file format +- +- +-File: bfd.info, Node: BFD information loss, Next: Canonical format, Up: What BFD Version 2 Can Do +- +-1.3.1 Information Loss +----------------------- +- +-_Information can be lost during output._ The output formats supported +-by BFD do not provide identical facilities, and information which can +-be described in one form has nowhere to go in another format. One +-example of this is alignment information in `b.out'. There is nowhere +-in an `a.out' format file to store alignment information on the +-contained data, so when a file is linked from `b.out' and an `a.out' +-image is produced, alignment information will not propagate to the +-output file. (The linker will still use the alignment information +-internally, so the link is performed correctly). +- +- Another example is COFF section names. COFF files may contain an +-unlimited number of sections, each one with a textual section name. If +-the target of the link is a format which does not have many sections +-(e.g., `a.out') or has sections without names (e.g., the Oasys format), +-the link cannot be done simply. You can circumvent this problem by +-describing the desired input-to-output section mapping with the linker +-command language. +- +- _Information can be lost during canonicalization._ The BFD internal +-canonical form of the external formats is not exhaustive; there are +-structures in input formats for which there is no direct representation +-internally. This means that the BFD back ends cannot maintain all +-possible data richness through the transformation between external to +-internal and back to external formats. +- +- This limitation is only a problem when an application reads one +-format and writes another. Each BFD back end is responsible for +-maintaining as much data as possible, and the internal BFD canonical +-form has structures which are opaque to the BFD core, and exported only +-to the back ends. When a file is read in one format, the canonical form +-is generated for BFD and the application. At the same time, the back +-end saves away any information which may otherwise be lost. If the data +-is then written back in the same format, the back end routine will be +-able to use the canonical form provided by the BFD core as well as the +-information it prepared earlier. Since there is a great deal of +-commonality between back ends, there is no information lost when +-linking or copying big endian COFF to little endian COFF, or `a.out' to +-`b.out'. When a mixture of formats is linked, the information is only +-lost from the files whose format differs from the destination. +- +- +-File: bfd.info, Node: Canonical format, Prev: BFD information loss, Up: What BFD Version 2 Can Do +- +-1.3.2 The BFD canonical object-file format +------------------------------------------- +- +-The greatest potential for loss of information occurs when there is the +-least overlap between the information provided by the source format, +-that stored by the canonical format, and that needed by the destination +-format. A brief description of the canonical form may help you +-understand which kinds of data you can count on preserving across +-conversions. +- +-_files_ +- Information stored on a per-file basis includes target machine +- architecture, particular implementation format type, a demand +- pageable bit, and a write protected bit. Information like Unix +- magic numbers is not stored here--only the magic numbers' meaning, +- so a `ZMAGIC' file would have both the demand pageable bit and the +- write protected text bit set. The byte order of the target is +- stored on a per-file basis, so that big- and little-endian object +- files may be used with one another. +- +-_sections_ +- Each section in the input file contains the name of the section, +- the section's original address in the object file, size and +- alignment information, various flags, and pointers into other BFD +- data structures. +- +-_symbols_ +- Each symbol contains a pointer to the information for the object +- file which originally defined it, its name, its value, and various +- flag bits. When a BFD back end reads in a symbol table, it +- relocates all symbols to make them relative to the base of the +- section where they were defined. Doing this ensures that each +- symbol points to its containing section. Each symbol also has a +- varying amount of hidden private data for the BFD back end. Since +- the symbol points to the original file, the private data format +- for that symbol is accessible. `ld' can operate on a collection +- of symbols of wildly different formats without problems. +- +- Normal global and simple local symbols are maintained on output, +- so an output file (no matter its format) will retain symbols +- pointing to functions and to global, static, and common variables. +- Some symbol information is not worth retaining; in `a.out', type +- information is stored in the symbol table as long symbol names. +- This information would be useless to most COFF debuggers; the +- linker has command line switches to allow users to throw it away. +- +- There is one word of type information within the symbol, so if the +- format supports symbol type information within symbols (for +- example, COFF, IEEE, Oasys) and the type is simple enough to fit +- within one word (nearly everything but aggregates), the +- information will be preserved. +- +-_relocation level_ +- Each canonical BFD relocation record contains a pointer to the +- symbol to relocate to, the offset of the data to relocate, the +- section the data is in, and a pointer to a relocation type +- descriptor. Relocation is performed by passing messages through +- the relocation type descriptor and the symbol pointer. Therefore, +- relocations can be performed on output data using a relocation +- method that is only available in one of the input formats. For +- instance, Oasys provides a byte relocation format. A relocation +- record requesting this relocation type would point indirectly to a +- routine to perform this, so the relocation may be performed on a +- byte being written to a 68k COFF file, even though 68k COFF has no +- such relocation type. +- +-_line numbers_ +- Object formats can contain, for debugging purposes, some form of +- mapping between symbols, source line numbers, and addresses in the +- output file. These addresses have to be relocated along with the +- symbol information. Each symbol with an associated list of line +- number records points to the first record of the list. The head +- of a line number list consists of a pointer to the symbol, which +- allows finding out the address of the function whose line number +- is being described. The rest of the list is made up of pairs: +- offsets into the section and line numbers. Any format which can +- simply derive this information can pass it successfully between +- formats (COFF, IEEE and Oasys). +- +- +-File: bfd.info, Node: BFD front end, Next: BFD back ends, Prev: Overview, Up: Top +- +-2 BFD Front End +-*************** +- +-* Menu: +- +-* typedef bfd:: +-* Error reporting:: +-* Miscellaneous:: +-* Memory Usage:: +-* Initialization:: +-* Sections:: +-* Symbols:: +-* Archives:: +-* Formats:: +-* Relocations:: +-* Core Files:: +-* Targets:: +-* Architectures:: +-* Opening and Closing:: +-* Internal:: +-* File Caching:: +-* Linker Functions:: +-* Hash Tables:: +- +- +-File: bfd.info, Node: typedef bfd, Next: Error reporting, Prev: BFD front end, Up: BFD front end +- +-2.1 `typedef bfd' +-================= +- +-A BFD has type `bfd'; objects of this type are the cornerstone of any +-application using BFD. Using BFD consists of making references though +-the BFD and to data in the BFD. +- +- Here is the structure that defines the type `bfd'. It contains the +-major data about the file and pointers to the rest of the data. +- +- +- enum bfd_direction +- { +- no_direction = 0, +- read_direction = 1, +- write_direction = 2, +- both_direction = 3 +- }; +- +- struct bfd +- { +- /* A unique identifier of the BFD */ +- unsigned int id; +- +- /* The filename the application opened the BFD with. */ +- const char *filename; +- +- /* A pointer to the target jump table. */ +- const struct bfd_target *xvec; +- +- /* The IOSTREAM, and corresponding IO vector that provide access +- to the file backing the BFD. */ +- void *iostream; +- const struct bfd_iovec *iovec; +- +- /* The caching routines use these to maintain a +- least-recently-used list of BFDs. */ +- struct bfd *lru_prev, *lru_next; +- +- /* When a file is closed by the caching routines, BFD retains +- state information on the file here... */ +- ufile_ptr where; +- +- /* File modified time, if mtime_set is TRUE. */ +- long mtime; +- +- /* Reserved for an unimplemented file locking extension. */ +- int ifd; +- +- /* The format which belongs to the BFD. (object, core, etc.) */ +- bfd_format format; +- +- /* The direction with which the BFD was opened. */ +- enum bfd_direction direction; +- +- /* Format_specific flags. */ +- flagword flags; +- +- /* Values that may appear in the flags field of a BFD. These also +- appear in the object_flags field of the bfd_target structure, where +- they indicate the set of flags used by that backend (not all flags +- are meaningful for all object file formats) (FIXME: at the moment, +- the object_flags values have mostly just been copied from backend +- to another, and are not necessarily correct). */ +- +- #define BFD_NO_FLAGS 0x00 +- +- /* BFD contains relocation entries. */ +- #define HAS_RELOC 0x01 +- +- /* BFD is directly executable. */ +- #define EXEC_P 0x02 +- +- /* BFD has line number information (basically used for F_LNNO in a +- COFF header). */ +- #define HAS_LINENO 0x04 +- +- /* BFD has debugging information. */ +- #define HAS_DEBUG 0x08 +- +- /* BFD has symbols. */ +- #define HAS_SYMS 0x10 +- +- /* BFD has local symbols (basically used for F_LSYMS in a COFF +- header). */ +- #define HAS_LOCALS 0x20 +- +- /* BFD is a dynamic object. */ +- #define DYNAMIC 0x40 +- +- /* Text section is write protected (if D_PAGED is not set, this is +- like an a.out NMAGIC file) (the linker sets this by default, but +- clears it for -r or -N). */ +- #define WP_TEXT 0x80 +- +- /* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the +- linker sets this by default, but clears it for -r or -n or -N). */ +- #define D_PAGED 0x100 +- +- /* BFD is relaxable (this means that bfd_relax_section may be able to +- do something) (sometimes bfd_relax_section can do something even if +- this is not set). */ +- #define BFD_IS_RELAXABLE 0x200 +- +- /* This may be set before writing out a BFD to request using a +- traditional format. For example, this is used to request that when +- writing out an a.out object the symbols not be hashed to eliminate +- duplicates. */ +- #define BFD_TRADITIONAL_FORMAT 0x400 +- +- /* This flag indicates that the BFD contents are actually cached +- in memory. If this is set, iostream points to a bfd_in_memory +- struct. */ +- #define BFD_IN_MEMORY 0x800 +- +- /* The sections in this BFD specify a memory page. */ +- #define HAS_LOAD_PAGE 0x1000 +- +- /* This BFD has been created by the linker and doesn't correspond +- to any input file. */ +- #define BFD_LINKER_CREATED 0x2000 +- +- /* This may be set before writing out a BFD to request that it +- be written using values for UIDs, GIDs, timestamps, etc. that +- will be consistent from run to run. */ +- #define BFD_DETERMINISTIC_OUTPUT 0x4000 +- +- /* Compress sections in this BFD. */ +- #define BFD_COMPRESS 0x8000 +- +- /* Decompress sections in this BFD. */ +- #define BFD_DECOMPRESS 0x10000 +- +- /* BFD is a dummy, for plugins. */ +- #define BFD_PLUGIN 0x20000 +- +- /* Flags bits to be saved in bfd_preserve_save. */ +- #define BFD_FLAGS_SAVED \ +- (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN) +- +- /* Flags bits which are for BFD use only. */ +- #define BFD_FLAGS_FOR_BFD_USE_MASK \ +- (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ +- | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT) +- +- /* Currently my_archive is tested before adding origin to +- anything. I believe that this can become always an add of +- origin, with origin set to 0 for non archive files. */ +- ufile_ptr origin; +- +- /* The origin in the archive of the proxy entry. This will +- normally be the same as origin, except for thin archives, +- when it will contain the current offset of the proxy in the +- thin archive rather than the offset of the bfd in its actual +- container. */ +- ufile_ptr proxy_origin; +- +- /* A hash table for section names. */ +- struct bfd_hash_table section_htab; +- +- /* Pointer to linked list of sections. */ +- struct bfd_section *sections; +- +- /* The last section on the section list. */ +- struct bfd_section *section_last; +- +- /* The number of sections. */ +- unsigned int section_count; +- +- /* Stuff only useful for object files: +- The start address. */ +- bfd_vma start_address; +- +- /* Used for input and output. */ +- unsigned int symcount; +- +- /* Symbol table for output BFD (with symcount entries). +- Also used by the linker to cache input BFD symbols. */ +- struct bfd_symbol **outsymbols; +- +- /* Used for slurped dynamic symbol tables. */ +- unsigned int dynsymcount; +- +- /* Pointer to structure which contains architecture information. */ +- const struct bfd_arch_info *arch_info; +- +- /* Stuff only useful for archives. */ +- void *arelt_data; +- struct bfd *my_archive; /* The containing archive BFD. */ +- struct bfd *archive_next; /* The next BFD in the archive. */ +- struct bfd *archive_head; /* The first BFD in the archive. */ +- struct bfd *nested_archives; /* List of nested archive in a flattened +- thin archive. */ +- +- /* A chain of BFD structures involved in a link. */ +- struct bfd *link_next; +- +- /* A field used by _bfd_generic_link_add_archive_symbols. This will +- be used only for archive elements. */ +- int archive_pass; +- +- /* Used by the back end to hold private data. */ +- union +- { +- struct aout_data_struct *aout_data; +- struct artdata *aout_ar_data; +- struct _oasys_data *oasys_obj_data; +- struct _oasys_ar_data *oasys_ar_data; +- struct coff_tdata *coff_obj_data; +- struct pe_tdata *pe_obj_data; +- struct xcoff_tdata *xcoff_obj_data; +- struct ecoff_tdata *ecoff_obj_data; +- struct ieee_data_struct *ieee_data; +- struct ieee_ar_data_struct *ieee_ar_data; +- struct srec_data_struct *srec_data; +- struct verilog_data_struct *verilog_data; +- struct ihex_data_struct *ihex_data; +- struct tekhex_data_struct *tekhex_data; +- struct elf_obj_tdata *elf_obj_data; +- struct nlm_obj_tdata *nlm_obj_data; +- struct bout_data_struct *bout_data; +- struct mmo_data_struct *mmo_data; +- struct sun_core_struct *sun_core_data; +- struct sco5_core_struct *sco5_core_data; +- struct trad_core_struct *trad_core_data; +- struct som_data_struct *som_data; +- struct hpux_core_struct *hpux_core_data; +- struct hppabsd_core_struct *hppabsd_core_data; +- struct sgi_core_struct *sgi_core_data; +- struct lynx_core_struct *lynx_core_data; +- struct osf_core_struct *osf_core_data; +- struct cisco_core_struct *cisco_core_data; +- struct versados_data_struct *versados_data; +- struct netbsd_core_struct *netbsd_core_data; +- struct mach_o_data_struct *mach_o_data; +- struct mach_o_fat_data_struct *mach_o_fat_data; +- struct plugin_data_struct *plugin_data; +- struct bfd_pef_data_struct *pef_data; +- struct bfd_pef_xlib_data_struct *pef_xlib_data; +- struct bfd_sym_data_struct *sym_data; +- void *any; +- } +- tdata; +- +- /* Used by the application to hold private data. */ +- void *usrdata; +- +- /* Where all the allocated stuff under this BFD goes. This is a +- struct objalloc *, but we use void * to avoid requiring the inclusion +- of objalloc.h. */ +- void *memory; +- +- /* Is the file descriptor being cached? That is, can it be closed as +- needed, and re-opened when accessed later? */ +- unsigned int cacheable : 1; +- +- /* Marks whether there was a default target specified when the +- BFD was opened. This is used to select which matching algorithm +- to use to choose the back end. */ +- unsigned int target_defaulted : 1; +- +- /* ... and here: (``once'' means at least once). */ +- unsigned int opened_once : 1; +- +- /* Set if we have a locally maintained mtime value, rather than +- getting it from the file each time. */ +- unsigned int mtime_set : 1; +- +- /* Flag set if symbols from this BFD should not be exported. */ +- unsigned int no_export : 1; +- +- /* Remember when output has begun, to stop strange things +- from happening. */ +- unsigned int output_has_begun : 1; +- +- /* Have archive map. */ +- unsigned int has_armap : 1; +- +- /* Set if this is a thin archive. */ +- unsigned int is_thin_archive : 1; +- +- /* Set if only required symbols should be added in the link hash table for +- this object. Used by VMS linkers. */ +- unsigned int selective_search : 1; +- }; +- +- +-File: bfd.info, Node: Error reporting, Next: Miscellaneous, Prev: typedef bfd, Up: BFD front end +- +-2.2 Error reporting +-=================== +- +-Most BFD functions return nonzero on success (check their individual +-documentation for precise semantics). On an error, they call +-`bfd_set_error' to set an error condition that callers can check by +-calling `bfd_get_error'. If that returns `bfd_error_system_call', then +-check `errno'. +- +- The easiest way to report a BFD error to the user is to use +-`bfd_perror'. +- +-2.2.1 Type `bfd_error_type' +---------------------------- +- +-The values returned by `bfd_get_error' are defined by the enumerated +-type `bfd_error_type'. +- +- +- typedef enum bfd_error +- { +- bfd_error_no_error = 0, +- bfd_error_system_call, +- bfd_error_invalid_target, +- bfd_error_wrong_format, +- bfd_error_wrong_object_format, +- bfd_error_invalid_operation, +- bfd_error_no_memory, +- bfd_error_no_symbols, +- bfd_error_no_armap, +- bfd_error_no_more_archived_files, +- bfd_error_malformed_archive, +- bfd_error_missing_dso, +- bfd_error_file_not_recognized, +- bfd_error_file_ambiguously_recognized, +- bfd_error_no_contents, +- bfd_error_nonrepresentable_section, +- bfd_error_no_debug_section, +- bfd_error_bad_value, +- bfd_error_file_truncated, +- bfd_error_file_too_big, +- bfd_error_on_input, +- bfd_error_invalid_error_code +- } +- bfd_error_type; +- +-2.2.1.1 `bfd_get_error' +-....................... +- +-*Synopsis* +- bfd_error_type bfd_get_error (void); +- *Description* +-Return the current BFD error condition. +- +-2.2.1.2 `bfd_set_error' +-....................... +- +-*Synopsis* +- void bfd_set_error (bfd_error_type error_tag, ...); +- *Description* +-Set the BFD error condition to be ERROR_TAG. If ERROR_TAG is +-bfd_error_on_input, then this function takes two more parameters, the +-input bfd where the error occurred, and the bfd_error_type error. +- +-2.2.1.3 `bfd_errmsg' +-.................... +- +-*Synopsis* +- const char *bfd_errmsg (bfd_error_type error_tag); +- *Description* +-Return a string describing the error ERROR_TAG, or the system error if +-ERROR_TAG is `bfd_error_system_call'. +- +-2.2.1.4 `bfd_perror' +-.................... +- +-*Synopsis* +- void bfd_perror (const char *message); +- *Description* +-Print to the standard error stream a string describing the last BFD +-error that occurred, or the last system error if the last BFD error was +-a system call failure. If MESSAGE is non-NULL and non-empty, the error +-string printed is preceded by MESSAGE, a colon, and a space. It is +-followed by a newline. +- +-2.2.2 BFD error handler +------------------------ +- +-Some BFD functions want to print messages describing the problem. They +-call a BFD error handler function. This function may be overridden by +-the program. +- +- The BFD error handler acts like printf. +- +- +- typedef void (*bfd_error_handler_type) (const char *, ...); +- +-2.2.2.1 `bfd_set_error_handler' +-............................... +- +-*Synopsis* +- bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); +- *Description* +-Set the BFD error handler function. Returns the previous function. +- +-2.2.2.2 `bfd_set_error_program_name' +-.................................... +- +-*Synopsis* +- void bfd_set_error_program_name (const char *); +- *Description* +-Set the program name to use when printing a BFD error. This is printed +-before the error message followed by a colon and space. The string +-must not be changed after it is passed to this function. +- +-2.2.2.3 `bfd_get_error_handler' +-............................... +- +-*Synopsis* +- bfd_error_handler_type bfd_get_error_handler (void); +- *Description* +-Return the BFD error handler function. +- +-2.2.3 BFD assert handler +------------------------- +- +-If BFD finds an internal inconsistency, the bfd assert handler is +-called with information on the BFD version, BFD source file and line. +-If this happens, most programs linked against BFD are expected to want +-to exit with an error, or mark the current BFD operation as failed, so +-it is recommended to override the default handler, which just calls +-_bfd_error_handler and continues. +- +- +- typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg, +- const char *bfd_version, +- const char *bfd_file, +- int bfd_line); +- +-2.2.3.1 `bfd_set_assert_handler' +-................................ +- +-*Synopsis* +- bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type); +- *Description* +-Set the BFD assert handler function. Returns the previous function. +- +-2.2.3.2 `bfd_get_assert_handler' +-................................ +- +-*Synopsis* +- bfd_assert_handler_type bfd_get_assert_handler (void); +- *Description* +-Return the BFD assert handler function. +- +- +-File: bfd.info, Node: Miscellaneous, Next: Memory Usage, Prev: Error reporting, Up: BFD front end +- +-2.3 Miscellaneous +-================= +- +-2.3.1 Miscellaneous functions +------------------------------ +- +-2.3.1.1 `bfd_get_reloc_upper_bound' +-................................... +- +-*Synopsis* +- long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); +- *Description* +-Return the number of bytes required to store the relocation information +-associated with section SECT attached to bfd ABFD. If an error occurs, +-return -1. +- +-2.3.1.2 `bfd_canonicalize_reloc' +-................................ +- +-*Synopsis* +- long bfd_canonicalize_reloc +- (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); +- *Description* +-Call the back end associated with the open BFD ABFD and translate the +-external form of the relocation information attached to SEC into the +-internal canonical form. Place the table into memory at LOC, which has +-been preallocated, usually by a call to `bfd_get_reloc_upper_bound'. +-Returns the number of relocs, or -1 on error. +- +- The SYMS table is also needed for horrible internal magic reasons. +- +-2.3.1.3 `bfd_set_reloc' +-....................... +- +-*Synopsis* +- void bfd_set_reloc +- (bfd *abfd, asection *sec, arelent **rel, unsigned int count); +- *Description* +-Set the relocation pointer and count within section SEC to the values +-REL and COUNT. The argument ABFD is ignored. +- +-2.3.1.4 `bfd_set_file_flags' +-............................ +- +-*Synopsis* +- bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); +- *Description* +-Set the flag word in the BFD ABFD to the value FLAGS. +- +- Possible errors are: +- * `bfd_error_wrong_format' - The target bfd was not of object format. +- +- * `bfd_error_invalid_operation' - The target bfd was open for +- reading. +- +- * `bfd_error_invalid_operation' - The flag word contained a bit +- which was not applicable to the type of file. E.g., an attempt +- was made to set the `D_PAGED' bit on a BFD format which does not +- support demand paging. +- +-2.3.1.5 `bfd_get_arch_size' +-........................... +- +-*Synopsis* +- int bfd_get_arch_size (bfd *abfd); +- *Description* +-Returns the architecture address size, in bits, as determined by the +-object file's format. For ELF, this information is included in the +-header. +- +- *Returns* +-Returns the arch size in bits if known, `-1' otherwise. +- +-2.3.1.6 `bfd_get_sign_extend_vma' +-................................. +- +-*Synopsis* +- int bfd_get_sign_extend_vma (bfd *abfd); +- *Description* +-Indicates if the target architecture "naturally" sign extends an +-address. Some architectures implicitly sign extend address values when +-they are converted to types larger than the size of an address. For +-instance, bfd_get_start_address() will return an address sign extended +-to fill a bfd_vma when this is the case. +- +- *Returns* +-Returns `1' if the target architecture is known to sign extend +-addresses, `0' if the target architecture is known to not sign extend +-addresses, and `-1' otherwise. +- +-2.3.1.7 `bfd_set_start_address' +-............................... +- +-*Synopsis* +- bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); +- *Description* +-Make VMA the entry point of output BFD ABFD. +- +- *Returns* +-Returns `TRUE' on success, `FALSE' otherwise. +- +-2.3.1.8 `bfd_get_gp_size' +-......................... +- +-*Synopsis* +- unsigned int bfd_get_gp_size (bfd *abfd); +- *Description* +-Return the maximum size of objects to be optimized using the GP +-register under MIPS ECOFF. This is typically set by the `-G' argument +-to the compiler, assembler or linker. +- +-2.3.1.9 `bfd_set_gp_size' +-......................... +- +-*Synopsis* +- void bfd_set_gp_size (bfd *abfd, unsigned int i); +- *Description* +-Set the maximum size of objects to be optimized using the GP register +-under ECOFF or MIPS ELF. This is typically set by the `-G' argument to +-the compiler, assembler or linker. +- +-2.3.1.10 `bfd_scan_vma' +-....................... +- +-*Synopsis* +- bfd_vma bfd_scan_vma (const char *string, const char **end, int base); +- *Description* +-Convert, like `strtoul', a numerical expression STRING into a `bfd_vma' +-integer, and return that integer. (Though without as many bells and +-whistles as `strtoul'.) The expression is assumed to be unsigned +-(i.e., positive). If given a BASE, it is used as the base for +-conversion. A base of 0 causes the function to interpret the string in +-hex if a leading "0x" or "0X" is found, otherwise in octal if a leading +-zero is found, otherwise in decimal. +- +- If the value would overflow, the maximum `bfd_vma' value is returned. +- +-2.3.1.11 `bfd_copy_private_header_data' +-....................................... +- +-*Synopsis* +- bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); +- *Description* +-Copy private BFD header information from the BFD IBFD to the the BFD +-OBFD. This copies information that may require sections to exist, but +-does not require symbol tables. Return `true' on success, `false' on +-error. Possible error returns are: +- +- * `bfd_error_no_memory' - Not enough memory exists to create private +- data for OBFD. +- +- #define bfd_copy_private_header_data(ibfd, obfd) \ +- BFD_SEND (obfd, _bfd_copy_private_header_data, \ +- (ibfd, obfd)) +- +-2.3.1.12 `bfd_copy_private_bfd_data' +-.................................... +- +-*Synopsis* +- bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); +- *Description* +-Copy private BFD information from the BFD IBFD to the the BFD OBFD. +-Return `TRUE' on success, `FALSE' on error. Possible error returns are: +- +- * `bfd_error_no_memory' - Not enough memory exists to create private +- data for OBFD. +- +- #define bfd_copy_private_bfd_data(ibfd, obfd) \ +- BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ +- (ibfd, obfd)) +- +-2.3.1.13 `bfd_merge_private_bfd_data' +-..................................... +- +-*Synopsis* +- bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); +- *Description* +-Merge private BFD information from the BFD IBFD to the the output file +-BFD OBFD when linking. Return `TRUE' on success, `FALSE' on error. +-Possible error returns are: +- +- * `bfd_error_no_memory' - Not enough memory exists to create private +- data for OBFD. +- +- #define bfd_merge_private_bfd_data(ibfd, obfd) \ +- BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ +- (ibfd, obfd)) +- +-2.3.1.14 `bfd_set_private_flags' +-................................ +- +-*Synopsis* +- bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); +- *Description* +-Set private BFD flag information in the BFD ABFD. Return `TRUE' on +-success, `FALSE' on error. Possible error returns are: +- +- * `bfd_error_no_memory' - Not enough memory exists to create private +- data for OBFD. +- +- #define bfd_set_private_flags(abfd, flags) \ +- BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) +- +-2.3.1.15 `Other functions' +-.......................... +- +-*Description* +-The following functions exist but have not yet been documented. +- #define bfd_sizeof_headers(abfd, info) \ +- BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info)) +- +- #define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ +- BFD_SEND (abfd, _bfd_find_nearest_line, \ +- (abfd, sec, syms, off, file, func, line)) +- +- #define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ +- line, disc) \ +- BFD_SEND (abfd, _bfd_find_nearest_line_discriminator, \ +- (abfd, sec, syms, off, file, func, line, disc)) +- +- #define bfd_find_line(abfd, syms, sym, file, line) \ +- BFD_SEND (abfd, _bfd_find_line, \ +- (abfd, syms, sym, file, line)) +- +- #define bfd_find_inliner_info(abfd, file, func, line) \ +- BFD_SEND (abfd, _bfd_find_inliner_info, \ +- (abfd, file, func, line)) +- +- #define bfd_debug_info_start(abfd) \ +- BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) +- +- #define bfd_debug_info_end(abfd) \ +- BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) +- +- #define bfd_debug_info_accumulate(abfd, section) \ +- BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) +- +- #define bfd_stat_arch_elt(abfd, stat) \ +- BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) +- +- #define bfd_update_armap_timestamp(abfd) \ +- BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) +- +- #define bfd_set_arch_mach(abfd, arch, mach)\ +- BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) +- +- #define bfd_relax_section(abfd, section, link_info, again) \ +- BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) +- +- #define bfd_gc_sections(abfd, link_info) \ +- BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) +- +- #define bfd_lookup_section_flags(link_info, flag_info, section) \ +- BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section)) +- +- #define bfd_merge_sections(abfd, link_info) \ +- BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) +- +- #define bfd_is_group_section(abfd, sec) \ +- BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) +- +- #define bfd_discard_group(abfd, sec) \ +- BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) +- +- #define bfd_link_hash_table_create(abfd) \ +- BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) +- +- #define bfd_link_hash_table_free(abfd, hash) \ +- BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) +- +- #define bfd_link_add_symbols(abfd, info) \ +- BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) +- +- #define bfd_link_just_syms(abfd, sec, info) \ +- BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) +- +- #define bfd_final_link(abfd, info) \ +- BFD_SEND (abfd, _bfd_final_link, (abfd, info)) +- +- #define bfd_free_cached_info(abfd) \ +- BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) +- +- #define bfd_get_dynamic_symtab_upper_bound(abfd) \ +- BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) +- +- #define bfd_print_private_bfd_data(abfd, file)\ +- BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) +- +- #define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ +- BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) +- +- #define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ +- BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ +- dyncount, dynsyms, ret)) +- +- #define bfd_get_dynamic_reloc_upper_bound(abfd) \ +- BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) +- +- #define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ +- BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) +- +- extern bfd_byte *bfd_get_relocated_section_contents +- (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, +- bfd_boolean, asymbol **); +- +-2.3.1.16 `bfd_alt_mach_code' +-............................ +- +-*Synopsis* +- bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); +- *Description* +-When more than one machine code number is available for the same +-machine type, this function can be used to switch between the preferred +-one (alternative == 0) and any others. Currently, only ELF supports +-this feature, with up to two alternate machine codes. +- +-2.3.1.17 `bfd_emul_get_maxpagesize' +-................................... +- +-*Synopsis* +- bfd_vma bfd_emul_get_maxpagesize (const char *); +- *Description* +-Returns the maximum page size, in bytes, as determined by emulation. +- +- *Returns* +-Returns the maximum page size in bytes for ELF, 0 otherwise. +- +-2.3.1.18 `bfd_emul_set_maxpagesize' +-................................... +- +-*Synopsis* +- void bfd_emul_set_maxpagesize (const char *, bfd_vma); +- *Description* +-For ELF, set the maximum page size for the emulation. It is a no-op +-for other formats. +- +-2.3.1.19 `bfd_emul_get_commonpagesize' +-...................................... +- +-*Synopsis* +- bfd_vma bfd_emul_get_commonpagesize (const char *); +- *Description* +-Returns the common page size, in bytes, as determined by emulation. +- +- *Returns* +-Returns the common page size in bytes for ELF, 0 otherwise. +- +-2.3.1.20 `bfd_emul_set_commonpagesize' +-...................................... +- +-*Synopsis* +- void bfd_emul_set_commonpagesize (const char *, bfd_vma); +- *Description* +-For ELF, set the common page size for the emulation. It is a no-op for +-other formats. +- +-2.3.1.21 `bfd_demangle' +-....................... +- +-*Synopsis* +- char *bfd_demangle (bfd *, const char *, int); +- *Description* +-Wrapper around cplus_demangle. Strips leading underscores and other +-such chars that would otherwise confuse the demangler. If passed a g++ +-v3 ABI mangled name, returns a buffer allocated with malloc holding the +-demangled name. Returns NULL otherwise and on memory alloc failure. +- +-2.3.1.22 `struct bfd_iovec' +-........................... +- +-*Description* +-The `struct bfd_iovec' contains the internal file I/O class. Each +-`BFD' has an instance of this class and all file I/O is routed through +-it (it is assumed that the instance implements all methods listed +-below). +- struct bfd_iovec +- { +- /* To avoid problems with macros, a "b" rather than "f" +- prefix is prepended to each method name. */ +- /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching +- bytes starting at PTR. Return the number of bytes actually +- transfered (a read past end-of-file returns less than NBYTES), +- or -1 (setting `bfd_error') if an error occurs. */ +- file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes); +- file_ptr (*bwrite) (struct bfd *abfd, const void *ptr, +- file_ptr nbytes); +- /* Return the current IOSTREAM file offset, or -1 (setting `bfd_error' +- if an error occurs. */ +- file_ptr (*btell) (struct bfd *abfd); +- /* For the following, on successful completion a value of 0 is returned. +- Otherwise, a value of -1 is returned (and `bfd_error' is set). */ +- int (*bseek) (struct bfd *abfd, file_ptr offset, int whence); +- int (*bclose) (struct bfd *abfd); +- int (*bflush) (struct bfd *abfd); +- int (*bstat) (struct bfd *abfd, struct stat *sb); +- /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual +- mmap parameter, except that LEN and OFFSET do not need to be page +- aligned. Returns (void *)-1 on failure, mmapped address on success. +- Also write in MAP_ADDR the address of the page aligned buffer and in +- MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and +- MAP_LEN to unmap. */ +- void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, +- int prot, int flags, file_ptr offset, +- void **map_addr, bfd_size_type *map_len); +- }; +- extern const struct bfd_iovec _bfd_memory_iovec; +- +-2.3.1.23 `bfd_get_mtime' +-........................ +- +-*Synopsis* +- long bfd_get_mtime (bfd *abfd); +- *Description* +-Return the file modification time (as read from the file system, or +-from the archive header for archive members). +- +-2.3.1.24 `bfd_get_size' +-....................... +- +-*Synopsis* +- file_ptr bfd_get_size (bfd *abfd); +- *Description* +-Return the file size (as read from file system) for the file associated +-with BFD ABFD. +- +- The initial motivation for, and use of, this routine is not so we +-can get the exact size of the object the BFD applies to, since that +-might not be generally possible (archive members for example). It +-would be ideal if someone could eventually modify it so that such +-results were guaranteed. +- +- Instead, we want to ask questions like "is this NNN byte sized +-object I'm about to try read from file offset YYY reasonable?" As as +-example of where we might do this, some object formats use string +-tables for which the first `sizeof (long)' bytes of the table contain +-the size of the table itself, including the size bytes. If an +-application tries to read what it thinks is one of these string tables, +-without some way to validate the size, and for some reason the size is +-wrong (byte swapping error, wrong location for the string table, etc.), +-the only clue is likely to be a read error when it tries to read the +-table, or a "virtual memory exhausted" error when it tries to allocate +-15 bazillon bytes of space for the 15 bazillon byte table it is about +-to read. This function at least allows us to answer the question, "is +-the size reasonable?". +- +-2.3.1.25 `bfd_mmap' +-................... +- +-*Synopsis* +- void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, +- int prot, int flags, file_ptr offset, +- void **map_addr, bfd_size_type *map_len); +- *Description* +-Return mmap()ed region of the file, if possible and implemented. LEN +-and OFFSET do not need to be page aligned. The page aligned address +-and length are written to MAP_ADDR and MAP_LEN. +- +- +-File: bfd.info, Node: Memory Usage, Next: Initialization, Prev: Miscellaneous, Up: BFD front end +- +-2.4 Memory Usage +-================ +- +-BFD keeps all of its internal structures in obstacks. There is one +-obstack per open BFD file, into which the current state is stored. When +-a BFD is closed, the obstack is deleted, and so everything which has +-been allocated by BFD for the closing file is thrown away. +- +- BFD does not free anything created by an application, but pointers +-into `bfd' structures become invalid on a `bfd_close'; for example, +-after a `bfd_close' the vector passed to `bfd_canonicalize_symtab' is +-still around, since it has been allocated by the application, but the +-data that it pointed to are lost. +- +- The general rule is to not close a BFD until all operations dependent +-upon data from the BFD have been completed, or all the data from within +-the file has been copied. To help with the management of memory, there +-is a function (`bfd_alloc_size') which returns the number of bytes in +-obstacks associated with the supplied BFD. This could be used to select +-the greediest open BFD, close it to reclaim the memory, perform some +-operation and reopen the BFD again, to get a fresh copy of the data +-structures. +- +- +-File: bfd.info, Node: Initialization, Next: Sections, Prev: Memory Usage, Up: BFD front end +- +-2.5 Initialization +-================== +- +-2.5.1 Initialization functions +------------------------------- +- +-These are the functions that handle initializing a BFD. +- +-2.5.1.1 `bfd_init' +-.................. +- +-*Synopsis* +- void bfd_init (void); +- *Description* +-This routine must be called before any other BFD function to initialize +-magical internal data structures. +- +- +-File: bfd.info, Node: Sections, Next: Symbols, Prev: Initialization, Up: BFD front end +- +-2.6 Sections +-============ +- +-The raw data contained within a BFD is maintained through the section +-abstraction. A single BFD may have any number of sections. It keeps +-hold of them by pointing to the first; each one points to the next in +-the list. +- +- Sections are supported in BFD in `section.c'. +- +-* Menu: +- +-* Section Input:: +-* Section Output:: +-* typedef asection:: +-* section prototypes:: +- +- +-File: bfd.info, Node: Section Input, Next: Section Output, Prev: Sections, Up: Sections +- +-2.6.1 Section input +-------------------- +- +-When a BFD is opened for reading, the section structures are created +-and attached to the BFD. +- +- Each section has a name which describes the section in the outside +-world--for example, `a.out' would contain at least three sections, +-called `.text', `.data' and `.bss'. +- +- Names need not be unique; for example a COFF file may have several +-sections named `.data'. +- +- Sometimes a BFD will contain more than the "natural" number of +-sections. A back end may attach other sections containing constructor +-data, or an application may add a section (using `bfd_make_section') to +-the sections attached to an already open BFD. For example, the linker +-creates an extra section `COMMON' for each input file's BFD to hold +-information about common storage. +- +- The raw data is not necessarily read in when the section descriptor +-is created. Some targets may leave the data in place until a +-`bfd_get_section_contents' call is made. Other back ends may read in +-all the data at once. For example, an S-record file has to be read +-once to determine the size of the data. An IEEE-695 file doesn't +-contain raw data in sections, but data and relocation expressions +-intermixed, so the data area has to be parsed to get out the data and +-relocations. +- +- +-File: bfd.info, Node: Section Output, Next: typedef asection, Prev: Section Input, Up: Sections +- +-2.6.2 Section output +--------------------- +- +-To write a new object style BFD, the various sections to be written +-have to be created. They are attached to the BFD in the same way as +-input sections; data is written to the sections using +-`bfd_set_section_contents'. +- +- Any program that creates or combines sections (e.g., the assembler +-and linker) must use the `asection' fields `output_section' and +-`output_offset' to indicate the file sections to which each section +-must be written. (If the section is being created from scratch, +-`output_section' should probably point to the section itself and +-`output_offset' should probably be zero.) +- +- The data to be written comes from input sections attached (via +-`output_section' pointers) to the output sections. The output section +-structure can be considered a filter for the input section: the output +-section determines the vma of the output data and the name, but the +-input section determines the offset into the output section of the data +-to be written. +- +- E.g., to create a section "O", starting at 0x100, 0x123 long, +-containing two subsections, "A" at offset 0x0 (i.e., at vma 0x100) and +-"B" at offset 0x20 (i.e., at vma 0x120) the `asection' structures would +-look like: +- +- section name "A" +- output_offset 0x00 +- size 0x20 +- output_section -----------> section name "O" +- | vma 0x100 +- section name "B" | size 0x123 +- output_offset 0x20 | +- size 0x103 | +- output_section --------| +- +-2.6.3 Link orders +------------------ +- +-The data within a section is stored in a "link_order". These are much +-like the fixups in `gas'. The link_order abstraction allows a section +-to grow and shrink within itself. +- +- A link_order knows how big it is, and which is the next link_order +-and where the raw data for it is; it also points to a list of +-relocations which apply to it. +- +- The link_order is used by the linker to perform relaxing on final +-code. The compiler creates code which is as big as necessary to make +-it work without relaxing, and the user can select whether to relax. +-Sometimes relaxing takes a lot of time. The linker runs around the +-relocations to see if any are attached to data which can be shrunk, if +-so it does it on a link_order by link_order basis. +- +- +-File: bfd.info, Node: typedef asection, Next: section prototypes, Prev: Section Output, Up: Sections +- +-2.6.4 typedef asection +----------------------- +- +-Here is the section structure: +- +- +- typedef struct bfd_section +- { +- /* The name of the section; the name isn't a copy, the pointer is +- the same as that passed to bfd_make_section. */ +- const char *name; +- +- /* A unique sequence number. */ +- int id; +- +- /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ +- int index; +- +- /* The next section in the list belonging to the BFD, or NULL. */ +- struct bfd_section *next; +- +- /* The previous section in the list belonging to the BFD, or NULL. */ +- struct bfd_section *prev; +- +- /* The field flags contains attributes of the section. Some +- flags are read in from the object file, and some are +- synthesized from other information. */ +- flagword flags; +- +- #define SEC_NO_FLAGS 0x000 +- +- /* Tells the OS to allocate space for this section when loading. +- This is clear for a section containing debug information only. */ +- #define SEC_ALLOC 0x001 +- +- /* Tells the OS to load the section from the file when loading. +- This is clear for a .bss section. */ +- #define SEC_LOAD 0x002 +- +- /* The section contains data still to be relocated, so there is +- some relocation information too. */ +- #define SEC_RELOC 0x004 +- +- /* A signal to the OS that the section contains read only data. */ +- #define SEC_READONLY 0x008 +- +- /* The section contains code only. */ +- #define SEC_CODE 0x010 +- +- /* The section contains data only. */ +- #define SEC_DATA 0x020 +- +- /* The section will reside in ROM. */ +- #define SEC_ROM 0x040 +- +- /* The section contains constructor information. This section +- type is used by the linker to create lists of constructors and +- destructors used by `g++'. When a back end sees a symbol +- which should be used in a constructor list, it creates a new +- section for the type of name (e.g., `__CTOR_LIST__'), attaches +- the symbol to it, and builds a relocation. To build the lists +- of constructors, all the linker has to do is catenate all the +- sections called `__CTOR_LIST__' and relocate the data +- contained within - exactly the operations it would peform on +- standard data. */ +- #define SEC_CONSTRUCTOR 0x080 +- +- /* The section has contents - a data section could be +- `SEC_ALLOC' | `SEC_HAS_CONTENTS'; a debug section could be +- `SEC_HAS_CONTENTS' */ +- #define SEC_HAS_CONTENTS 0x100 +- +- /* An instruction to the linker to not output the section +- even if it has information which would normally be written. */ +- #define SEC_NEVER_LOAD 0x200 +- +- /* The section contains thread local data. */ +- #define SEC_THREAD_LOCAL 0x400 +- +- /* The section has GOT references. This flag is only for the +- linker, and is currently only used by the elf32-hppa back end. +- It will be set if global offset table references were detected +- in this section, which indicate to the linker that the section +- contains PIC code, and must be handled specially when doing a +- static link. */ +- #define SEC_HAS_GOT_REF 0x800 +- +- /* The section contains common symbols (symbols may be defined +- multiple times, the value of a symbol is the amount of +- space it requires, and the largest symbol value is the one +- used). Most targets have exactly one of these (which we +- translate to bfd_com_section_ptr), but ECOFF has two. */ +- #define SEC_IS_COMMON 0x1000 +- +- /* The section contains only debugging information. For +- example, this is set for ELF .debug and .stab sections. +- strip tests this flag to see if a section can be +- discarded. */ +- #define SEC_DEBUGGING 0x2000 +- +- /* The contents of this section are held in memory pointed to +- by the contents field. This is checked by bfd_get_section_contents, +- and the data is retrieved from memory if appropriate. */ +- #define SEC_IN_MEMORY 0x4000 +- +- /* The contents of this section are to be excluded by the +- linker for executable and shared objects unless those +- objects are to be further relocated. */ +- #define SEC_EXCLUDE 0x8000 +- +- /* The contents of this section are to be sorted based on the sum of +- the symbol and addend values specified by the associated relocation +- entries. Entries without associated relocation entries will be +- appended to the end of the section in an unspecified order. */ +- #define SEC_SORT_ENTRIES 0x10000 +- +- /* When linking, duplicate sections of the same name should be +- discarded, rather than being combined into a single section as +- is usually done. This is similar to how common symbols are +- handled. See SEC_LINK_DUPLICATES below. */ +- #define SEC_LINK_ONCE 0x20000 +- +- /* If SEC_LINK_ONCE is set, this bitfield describes how the linker +- should handle duplicate sections. */ +- #define SEC_LINK_DUPLICATES 0xc0000 +- +- /* This value for SEC_LINK_DUPLICATES means that duplicate +- sections with the same name should simply be discarded. */ +- #define SEC_LINK_DUPLICATES_DISCARD 0x0 +- +- /* This value for SEC_LINK_DUPLICATES means that the linker +- should warn if there are any duplicate sections, although +- it should still only link one copy. */ +- #define SEC_LINK_DUPLICATES_ONE_ONLY 0x40000 +- +- /* This value for SEC_LINK_DUPLICATES means that the linker +- should warn if any duplicate sections are a different size. */ +- #define SEC_LINK_DUPLICATES_SAME_SIZE 0x80000 +- +- /* This value for SEC_LINK_DUPLICATES means that the linker +- should warn if any duplicate sections contain different +- contents. */ +- #define SEC_LINK_DUPLICATES_SAME_CONTENTS \ +- (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE) +- +- /* This section was created by the linker as part of dynamic +- relocation or other arcane processing. It is skipped when +- going through the first-pass output, trusting that someone +- else up the line will take care of it later. */ +- #define SEC_LINKER_CREATED 0x100000 +- +- /* This section should not be subject to garbage collection. +- Also set to inform the linker that this section should not be +- listed in the link map as discarded. */ +- #define SEC_KEEP 0x200000 +- +- /* This section contains "short" data, and should be placed +- "near" the GP. */ +- #define SEC_SMALL_DATA 0x400000 +- +- /* Attempt to merge identical entities in the section. +- Entity size is given in the entsize field. */ +- #define SEC_MERGE 0x800000 +- +- /* If given with SEC_MERGE, entities to merge are zero terminated +- strings where entsize specifies character size instead of fixed +- size entries. */ +- #define SEC_STRINGS 0x1000000 +- +- /* This section contains data about section groups. */ +- #define SEC_GROUP 0x2000000 +- +- /* The section is a COFF shared library section. This flag is +- only for the linker. If this type of section appears in +- the input file, the linker must copy it to the output file +- without changing the vma or size. FIXME: Although this +- was originally intended to be general, it really is COFF +- specific (and the flag was renamed to indicate this). It +- might be cleaner to have some more general mechanism to +- allow the back end to control what the linker does with +- sections. */ +- #define SEC_COFF_SHARED_LIBRARY 0x4000000 +- +- /* This input section should be copied to output in reverse order +- as an array of pointers. This is for ELF linker internal use +- only. */ +- #define SEC_ELF_REVERSE_COPY 0x4000000 +- +- /* This section contains data which may be shared with other +- executables or shared objects. This is for COFF only. */ +- #define SEC_COFF_SHARED 0x8000000 +- +- /* When a section with this flag is being linked, then if the size of +- the input section is less than a page, it should not cross a page +- boundary. If the size of the input section is one page or more, +- it should be aligned on a page boundary. This is for TI +- TMS320C54X only. */ +- #define SEC_TIC54X_BLOCK 0x10000000 +- +- /* Conditionally link this section; do not link if there are no +- references found to any symbol in the section. This is for TI +- TMS320C54X only. */ +- #define SEC_TIC54X_CLINK 0x20000000 +- +- /* Indicate that section has the no read flag set. This happens +- when memory read flag isn't set. */ +- #define SEC_COFF_NOREAD 0x40000000 +- +- /* End of section flags. */ +- +- /* Some internal packed boolean fields. */ +- +- /* See the vma field. */ +- unsigned int user_set_vma : 1; +- +- /* A mark flag used by some of the linker backends. */ +- unsigned int linker_mark : 1; +- +- /* Another mark flag used by some of the linker backends. Set for +- output sections that have an input section. */ +- unsigned int linker_has_input : 1; +- +- /* Mark flag used by some linker backends for garbage collection. */ +- unsigned int gc_mark : 1; +- +- /* Section compression status. */ +- unsigned int compress_status : 2; +- #define COMPRESS_SECTION_NONE 0 +- #define COMPRESS_SECTION_DONE 1 +- #define DECOMPRESS_SECTION_SIZED 2 +- +- /* The following flags are used by the ELF linker. */ +- +- /* Mark sections which have been allocated to segments. */ +- unsigned int segment_mark : 1; +- +- /* Type of sec_info information. */ +- unsigned int sec_info_type:3; +- #define SEC_INFO_TYPE_NONE 0 +- #define SEC_INFO_TYPE_STABS 1 +- #define SEC_INFO_TYPE_MERGE 2 +- #define SEC_INFO_TYPE_EH_FRAME 3 +- #define SEC_INFO_TYPE_JUST_SYMS 4 +- +- /* Nonzero if this section uses RELA relocations, rather than REL. */ +- unsigned int use_rela_p:1; +- +- /* Bits used by various backends. The generic code doesn't touch +- these fields. */ +- +- unsigned int sec_flg0:1; +- unsigned int sec_flg1:1; +- unsigned int sec_flg2:1; +- unsigned int sec_flg3:1; +- unsigned int sec_flg4:1; +- unsigned int sec_flg5:1; +- +- /* End of internal packed boolean fields. */ +- +- /* The virtual memory address of the section - where it will be +- at run time. The symbols are relocated against this. The +- user_set_vma flag is maintained by bfd; if it's not set, the +- backend can assign addresses (for example, in `a.out', where +- the default address for `.data' is dependent on the specific +- target and various flags). */ +- bfd_vma vma; +- +- /* The load address of the section - where it would be in a +- rom image; really only used for writing section header +- information. */ +- bfd_vma lma; +- +- /* The size of the section in octets, as it will be output. +- Contains a value even if the section has no contents (e.g., the +- size of `.bss'). */ +- bfd_size_type size; +- +- /* For input sections, the original size on disk of the section, in +- octets. This field should be set for any section whose size is +- changed by linker relaxation. It is required for sections where +- the linker relaxation scheme doesn't cache altered section and +- reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing +- targets), and thus the original size needs to be kept to read the +- section multiple times. For output sections, rawsize holds the +- section size calculated on a previous linker relaxation pass. */ +- bfd_size_type rawsize; +- +- /* The compressed size of the section in octets. */ +- bfd_size_type compressed_size; +- +- /* Relaxation table. */ +- struct relax_table *relax; +- +- /* Count of used relaxation table entries. */ +- int relax_count; +- +- +- /* If this section is going to be output, then this value is the +- offset in *bytes* into the output section of the first byte in the +- input section (byte ==> smallest addressable unit on the +- target). In most cases, if this was going to start at the +- 100th octet (8-bit quantity) in the output section, this value +- would be 100. However, if the target byte size is 16 bits +- (bfd_octets_per_byte is "2"), this value would be 50. */ +- bfd_vma output_offset; +- +- /* The output section through which to map on output. */ +- struct bfd_section *output_section; +- +- /* The alignment requirement of the section, as an exponent of 2 - +- e.g., 3 aligns to 2^3 (or 8). */ +- unsigned int alignment_power; +- +- /* If an input section, a pointer to a vector of relocation +- records for the data in this section. */ +- struct reloc_cache_entry *relocation; +- +- /* If an output section, a pointer to a vector of pointers to +- relocation records for the data in this section. */ +- struct reloc_cache_entry **orelocation; +- +- /* The number of relocation records in one of the above. */ +- unsigned reloc_count; +- +- /* Information below is back end specific - and not always used +- or updated. */ +- +- /* File position of section data. */ +- file_ptr filepos; +- +- /* File position of relocation info. */ +- file_ptr rel_filepos; +- +- /* File position of line data. */ +- file_ptr line_filepos; +- +- /* Pointer to data for applications. */ +- void *userdata; +- +- /* If the SEC_IN_MEMORY flag is set, this points to the actual +- contents. */ +- unsigned char *contents; +- +- /* Attached line number information. */ +- alent *lineno; +- +- /* Number of line number records. */ +- unsigned int lineno_count; +- +- /* Entity size for merging purposes. */ +- unsigned int entsize; +- +- /* Points to the kept section if this section is a link-once section, +- and is discarded. */ +- struct bfd_section *kept_section; +- +- /* When a section is being output, this value changes as more +- linenumbers are written out. */ +- file_ptr moving_line_filepos; +- +- /* What the section number is in the target world. */ +- int target_index; +- +- void *used_by_bfd; +- +- /* If this is a constructor section then here is a list of the +- relocations created to relocate items within it. */ +- struct relent_chain *constructor_chain; +- +- /* The BFD which owns the section. */ +- bfd *owner; +- +- /* A symbol which points at this section only. */ +- struct bfd_symbol *symbol; +- struct bfd_symbol **symbol_ptr_ptr; +- +- /* Early in the link process, map_head and map_tail are used to build +- a list of input sections attached to an output section. Later, +- output sections use these fields for a list of bfd_link_order +- structs. */ +- union { +- struct bfd_link_order *link_order; +- struct bfd_section *s; +- } map_head, map_tail; +- } asection; +- +- /* Relax table contains information about instructions which can +- be removed by relaxation -- replacing a long address with a +- short address. */ +- struct relax_table { +- /* Address where bytes may be deleted. */ +- bfd_vma addr; +- +- /* Number of bytes to be deleted. */ +- int size; +- }; +- +- /* These sections are global, and are managed by BFD. The application +- and target back end are not permitted to change the values in +- these sections. */ +- extern asection _bfd_std_section[4]; +- +- #define BFD_ABS_SECTION_NAME "*ABS*" +- #define BFD_UND_SECTION_NAME "*UND*" +- #define BFD_COM_SECTION_NAME "*COM*" +- #define BFD_IND_SECTION_NAME "*IND*" +- +- /* Pointer to the common section. */ +- #define bfd_com_section_ptr (&_bfd_std_section[0]) +- /* Pointer to the undefined section. */ +- #define bfd_und_section_ptr (&_bfd_std_section[1]) +- /* Pointer to the absolute section. */ +- #define bfd_abs_section_ptr (&_bfd_std_section[2]) +- /* Pointer to the indirect section. */ +- #define bfd_ind_section_ptr (&_bfd_std_section[3]) +- +- #define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) +- #define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) +- #define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) +- +- #define bfd_is_const_section(SEC) \ +- ( ((SEC) == bfd_abs_section_ptr) \ +- || ((SEC) == bfd_und_section_ptr) \ +- || ((SEC) == bfd_com_section_ptr) \ +- || ((SEC) == bfd_ind_section_ptr)) +- +- /* Macros to handle insertion and deletion of a bfd's sections. These +- only handle the list pointers, ie. do not adjust section_count, +- target_index etc. */ +- #define bfd_section_list_remove(ABFD, S) \ +- do \ +- { \ +- asection *_s = S; \ +- asection *_next = _s->next; \ +- asection *_prev = _s->prev; \ +- if (_prev) \ +- _prev->next = _next; \ +- else \ +- (ABFD)->sections = _next; \ +- if (_next) \ +- _next->prev = _prev; \ +- else \ +- (ABFD)->section_last = _prev; \ +- } \ +- while (0) +- #define bfd_section_list_append(ABFD, S) \ +- do \ +- { \ +- asection *_s = S; \ +- bfd *_abfd = ABFD; \ +- _s->next = NULL; \ +- if (_abfd->section_last) \ +- { \ +- _s->prev = _abfd->section_last; \ +- _abfd->section_last->next = _s; \ +- } \ +- else \ +- { \ +- _s->prev = NULL; \ +- _abfd->sections = _s; \ +- } \ +- _abfd->section_last = _s; \ +- } \ +- while (0) +- #define bfd_section_list_prepend(ABFD, S) \ +- do \ +- { \ +- asection *_s = S; \ +- bfd *_abfd = ABFD; \ +- _s->prev = NULL; \ +- if (_abfd->sections) \ +- { \ +- _s->next = _abfd->sections; \ +- _abfd->sections->prev = _s; \ +- } \ +- else \ +- { \ +- _s->next = NULL; \ +- _abfd->section_last = _s; \ +- } \ +- _abfd->sections = _s; \ +- } \ +- while (0) +- #define bfd_section_list_insert_after(ABFD, A, S) \ +- do \ +- { \ +- asection *_a = A; \ +- asection *_s = S; \ +- asection *_next = _a->next; \ +- _s->next = _next; \ +- _s->prev = _a; \ +- _a->next = _s; \ +- if (_next) \ +- _next->prev = _s; \ +- else \ +- (ABFD)->section_last = _s; \ +- } \ +- while (0) +- #define bfd_section_list_insert_before(ABFD, B, S) \ +- do \ +- { \ +- asection *_b = B; \ +- asection *_s = S; \ +- asection *_prev = _b->prev; \ +- _s->prev = _prev; \ +- _s->next = _b; \ +- _b->prev = _s; \ +- if (_prev) \ +- _prev->next = _s; \ +- else \ +- (ABFD)->sections = _s; \ +- } \ +- while (0) +- #define bfd_section_removed_from_list(ABFD, S) \ +- ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) +- +- #define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ +- /* name, id, index, next, prev, flags, user_set_vma, */ \ +- { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ +- \ +- /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \ +- 0, 0, 1, 0, \ +- \ +- /* segment_mark, sec_info_type, use_rela_p, */ \ +- 0, 0, 0, \ +- \ +- /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \ +- 0, 0, 0, 0, 0, 0, \ +- \ +- /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \ +- 0, 0, 0, 0, 0, 0, 0, \ +- \ +- /* output_offset, output_section, alignment_power, */ \ +- 0, &SEC, 0, \ +- \ +- /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ +- NULL, NULL, 0, 0, 0, \ +- \ +- /* line_filepos, userdata, contents, lineno, lineno_count, */ \ +- 0, NULL, NULL, NULL, 0, \ +- \ +- /* entsize, kept_section, moving_line_filepos, */ \ +- 0, NULL, 0, \ +- \ +- /* target_index, used_by_bfd, constructor_chain, owner, */ \ +- 0, NULL, NULL, NULL, \ +- \ +- /* symbol, symbol_ptr_ptr, */ \ +- (struct bfd_symbol *) SYM, &SEC.symbol, \ +- \ +- /* map_head, map_tail */ \ +- { NULL }, { NULL } \ +- } +- +- +-File: bfd.info, Node: section prototypes, Prev: typedef asection, Up: Sections +- +-2.6.5 Section prototypes +------------------------- +- +-These are the functions exported by the section handling part of BFD. +- +-2.6.5.1 `bfd_section_list_clear' +-................................ +- +-*Synopsis* +- void bfd_section_list_clear (bfd *); +- *Description* +-Clears the section list, and also resets the section count and hash +-table entries. +- +-2.6.5.2 `bfd_get_section_by_name' +-................................. +- +-*Synopsis* +- asection *bfd_get_section_by_name (bfd *abfd, const char *name); +- *Description* +-Return the most recently created section attached to ABFD named NAME. +-Return NULL if no such section exists. +- +-2.6.5.3 `bfd_get_next_section_by_name' +-...................................... +- +-*Synopsis* +- asection *bfd_get_next_section_by_name (asection *sec); +- *Description* +-Given SEC is a section returned by `bfd_get_section_by_name', return +-the next most recently created section attached to the same BFD with +-the same name. Return NULL if no such section exists. +- +-2.6.5.4 `bfd_get_linker_section' +-................................ +- +-*Synopsis* +- asection *bfd_get_linker_section (bfd *abfd, const char *name); +- *Description* +-Return the linker created section attached to ABFD named NAME. Return +-NULL if no such section exists. +- +-2.6.5.5 `bfd_get_section_by_name_if' +-.................................... +- +-*Synopsis* +- asection *bfd_get_section_by_name_if +- (bfd *abfd, +- const char *name, +- bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), +- void *obj); +- *Description* +-Call the provided function FUNC for each section attached to the BFD +-ABFD whose name matches NAME, passing OBJ as an argument. The function +-will be called as if by +- +- func (abfd, the_section, obj); +- +- It returns the first section for which FUNC returns true, otherwise +-`NULL'. +- +-2.6.5.6 `bfd_get_unique_section_name' +-..................................... +- +-*Synopsis* +- char *bfd_get_unique_section_name +- (bfd *abfd, const char *templat, int *count); +- *Description* +-Invent a section name that is unique in ABFD by tacking a dot and a +-digit suffix onto the original TEMPLAT. If COUNT is non-NULL, then it +-specifies the first number tried as a suffix to generate a unique name. +-The value pointed to by COUNT will be incremented in this case. +- +-2.6.5.7 `bfd_make_section_old_way' +-.................................. +- +-*Synopsis* +- asection *bfd_make_section_old_way (bfd *abfd, const char *name); +- *Description* +-Create a new empty section called NAME and attach it to the end of the +-chain of sections for the BFD ABFD. An attempt to create a section with +-a name which is already in use returns its pointer without changing the +-section chain. +- +- It has the funny name since this is the way it used to be before it +-was rewritten.... +- +- Possible errors are: +- * `bfd_error_invalid_operation' - If output has already started for +- this BFD. +- +- * `bfd_error_no_memory' - If memory allocation fails. +- +-2.6.5.8 `bfd_make_section_anyway_with_flags' +-............................................ +- +-*Synopsis* +- asection *bfd_make_section_anyway_with_flags +- (bfd *abfd, const char *name, flagword flags); +- *Description* +-Create a new empty section called NAME and attach it to the end of the +-chain of sections for ABFD. Create a new section even if there is +-already a section with that name. Also set the attributes of the new +-section to the value FLAGS. +- +- Return `NULL' and set `bfd_error' on error; possible errors are: +- * `bfd_error_invalid_operation' - If output has already started for +- ABFD. +- +- * `bfd_error_no_memory' - If memory allocation fails. +- +-2.6.5.9 `bfd_make_section_anyway' +-................................. +- +-*Synopsis* +- asection *bfd_make_section_anyway (bfd *abfd, const char *name); +- *Description* +-Create a new empty section called NAME and attach it to the end of the +-chain of sections for ABFD. Create a new section even if there is +-already a section with that name. +- +- Return `NULL' and set `bfd_error' on error; possible errors are: +- * `bfd_error_invalid_operation' - If output has already started for +- ABFD. +- +- * `bfd_error_no_memory' - If memory allocation fails. +- +-2.6.5.10 `bfd_make_section_with_flags' +-...................................... +- +-*Synopsis* +- asection *bfd_make_section_with_flags +- (bfd *, const char *name, flagword flags); +- *Description* +-Like `bfd_make_section_anyway', but return `NULL' (without calling +-bfd_set_error ()) without changing the section chain if there is +-already a section named NAME. Also set the attributes of the new +-section to the value FLAGS. If there is an error, return `NULL' and set +-`bfd_error'. +- +-2.6.5.11 `bfd_make_section' +-........................... +- +-*Synopsis* +- asection *bfd_make_section (bfd *, const char *name); +- *Description* +-Like `bfd_make_section_anyway', but return `NULL' (without calling +-bfd_set_error ()) without changing the section chain if there is +-already a section named NAME. If there is an error, return `NULL' and +-set `bfd_error'. +- +-2.6.5.12 `bfd_set_section_flags' +-................................ +- +-*Synopsis* +- bfd_boolean bfd_set_section_flags +- (bfd *abfd, asection *sec, flagword flags); +- *Description* +-Set the attributes of the section SEC in the BFD ABFD to the value +-FLAGS. Return `TRUE' on success, `FALSE' on error. Possible error +-returns are: +- +- * `bfd_error_invalid_operation' - The section cannot have one or +- more of the attributes requested. For example, a .bss section in +- `a.out' may not have the `SEC_HAS_CONTENTS' field set. +- +-2.6.5.13 `bfd_rename_section' +-............................. +- +-*Synopsis* +- void bfd_rename_section +- (bfd *abfd, asection *sec, const char *newname); +- *Description* +-Rename section SEC in ABFD to NEWNAME. +- +-2.6.5.14 `bfd_map_over_sections' +-................................ +- +-*Synopsis* +- void bfd_map_over_sections +- (bfd *abfd, +- void (*func) (bfd *abfd, asection *sect, void *obj), +- void *obj); +- *Description* +-Call the provided function FUNC for each section attached to the BFD +-ABFD, passing OBJ as an argument. The function will be called as if by +- +- func (abfd, the_section, obj); +- +- This is the preferred method for iterating over sections; an +-alternative would be to use a loop: +- +- asection *p; +- for (p = abfd->sections; p != NULL; p = p->next) +- func (abfd, p, ...) +- +-2.6.5.15 `bfd_sections_find_if' +-............................... +- +-*Synopsis* +- asection *bfd_sections_find_if +- (bfd *abfd, +- bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), +- void *obj); +- *Description* +-Call the provided function OPERATION for each section attached to the +-BFD ABFD, passing OBJ as an argument. The function will be called as if +-by +- +- operation (abfd, the_section, obj); +- +- It returns the first section for which OPERATION returns true. +- +-2.6.5.16 `bfd_set_section_size' +-............................... +- +-*Synopsis* +- bfd_boolean bfd_set_section_size +- (bfd *abfd, asection *sec, bfd_size_type val); +- *Description* +-Set SEC to the size VAL. If the operation is ok, then `TRUE' is +-returned, else `FALSE'. +- +- Possible error returns: +- * `bfd_error_invalid_operation' - Writing has started to the BFD, so +- setting the size is invalid. +- +-2.6.5.17 `bfd_set_section_contents' +-................................... +- +-*Synopsis* +- bfd_boolean bfd_set_section_contents +- (bfd *abfd, asection *section, const void *data, +- file_ptr offset, bfd_size_type count); +- *Description* +-Sets the contents of the section SECTION in BFD ABFD to the data +-starting in memory at DATA. The data is written to the output section +-starting at offset OFFSET for COUNT octets. +- +- Normally `TRUE' is returned, else `FALSE'. Possible error returns +-are: +- * `bfd_error_no_contents' - The output section does not have the +- `SEC_HAS_CONTENTS' attribute, so nothing can be written to it. +- +- * and some more too +- This routine is front end to the back end function +-`_bfd_set_section_contents'. +- +-2.6.5.18 `bfd_get_section_contents' +-................................... +- +-*Synopsis* +- bfd_boolean bfd_get_section_contents +- (bfd *abfd, asection *section, void *location, file_ptr offset, +- bfd_size_type count); +- *Description* +-Read data from SECTION in BFD ABFD into memory starting at LOCATION. +-The data is read at an offset of OFFSET from the start of the input +-section, and is read for COUNT bytes. +- +- If the contents of a constructor with the `SEC_CONSTRUCTOR' flag set +-are requested or if the section does not have the `SEC_HAS_CONTENTS' +-flag set, then the LOCATION is filled with zeroes. If no errors occur, +-`TRUE' is returned, else `FALSE'. +- +-2.6.5.19 `bfd_malloc_and_get_section' +-..................................... +- +-*Synopsis* +- bfd_boolean bfd_malloc_and_get_section +- (bfd *abfd, asection *section, bfd_byte **buf); +- *Description* +-Read all data from SECTION in BFD ABFD into a buffer, *BUF, malloc'd by +-this function. +- +-2.6.5.20 `bfd_copy_private_section_data' +-........................................ +- +-*Synopsis* +- bfd_boolean bfd_copy_private_section_data +- (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); +- *Description* +-Copy private section information from ISEC in the BFD IBFD to the +-section OSEC in the BFD OBFD. Return `TRUE' on success, `FALSE' on +-error. Possible error returns are: +- +- * `bfd_error_no_memory' - Not enough memory exists to create private +- data for OSEC. +- +- #define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ +- BFD_SEND (obfd, _bfd_copy_private_section_data, \ +- (ibfd, isection, obfd, osection)) +- +-2.6.5.21 `bfd_generic_is_group_section' +-....................................... +- +-*Synopsis* +- bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); +- *Description* +-Returns TRUE if SEC is a member of a group. +- +-2.6.5.22 `bfd_generic_discard_group' +-.................................... +- +-*Synopsis* +- bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); +- *Description* +-Remove all members of GROUP from the output. +- +- +-File: bfd.info, Node: Symbols, Next: Archives, Prev: Sections, Up: BFD front end +- +-2.7 Symbols +-=========== +- +-BFD tries to maintain as much symbol information as it can when it +-moves information from file to file. BFD passes information to +-applications though the `asymbol' structure. When the application +-requests the symbol table, BFD reads the table in the native form and +-translates parts of it into the internal format. To maintain more than +-the information passed to applications, some targets keep some +-information "behind the scenes" in a structure only the particular back +-end knows about. For example, the coff back end keeps the original +-symbol table structure as well as the canonical structure when a BFD is +-read in. On output, the coff back end can reconstruct the output symbol +-table so that no information is lost, even information unique to coff +-which BFD doesn't know or understand. If a coff symbol table were read, +-but were written through an a.out back end, all the coff specific +-information would be lost. The symbol table of a BFD is not necessarily +-read in until a canonicalize request is made. Then the BFD back end +-fills in a table provided by the application with pointers to the +-canonical information. To output symbols, the application provides BFD +-with a table of pointers to pointers to `asymbol's. This allows +-applications like the linker to output a symbol as it was read, since +-the "behind the scenes" information will be still available. +- +-* Menu: +- +-* Reading Symbols:: +-* Writing Symbols:: +-* Mini Symbols:: +-* typedef asymbol:: +-* symbol handling functions:: +- +- +-File: bfd.info, Node: Reading Symbols, Next: Writing Symbols, Prev: Symbols, Up: Symbols +- +-2.7.1 Reading symbols +---------------------- +- +-There are two stages to reading a symbol table from a BFD: allocating +-storage, and the actual reading process. This is an excerpt from an +-application which reads the symbol table: +- +- long storage_needed; +- asymbol **symbol_table; +- long number_of_symbols; +- long i; +- +- storage_needed = bfd_get_symtab_upper_bound (abfd); +- +- if (storage_needed < 0) +- FAIL +- +- if (storage_needed == 0) +- return; +- +- symbol_table = xmalloc (storage_needed); +- ... +- number_of_symbols = +- bfd_canonicalize_symtab (abfd, symbol_table); +- +- if (number_of_symbols < 0) +- FAIL +- +- for (i = 0; i < number_of_symbols; i++) +- process_symbol (symbol_table[i]); +- +- All storage for the symbols themselves is in an objalloc connected +-to the BFD; it is freed when the BFD is closed. +- +- +-File: bfd.info, Node: Writing Symbols, Next: Mini Symbols, Prev: Reading Symbols, Up: Symbols +- +-2.7.2 Writing symbols +---------------------- +- +-Writing of a symbol table is automatic when a BFD open for writing is +-closed. The application attaches a vector of pointers to pointers to +-symbols to the BFD being written, and fills in the symbol count. The +-close and cleanup code reads through the table provided and performs +-all the necessary operations. The BFD output code must always be +-provided with an "owned" symbol: one which has come from another BFD, +-or one which has been created using `bfd_make_empty_symbol'. Here is an +-example showing the creation of a symbol table with only one element: +- +- #include "sysdep.h" +- #include "bfd.h" +- int main (void) +- { +- bfd *abfd; +- asymbol *ptrs[2]; +- asymbol *new; +- +- abfd = bfd_openw ("foo","a.out-sunos-big"); +- bfd_set_format (abfd, bfd_object); +- new = bfd_make_empty_symbol (abfd); +- new->name = "dummy_symbol"; +- new->section = bfd_make_section_old_way (abfd, ".text"); +- new->flags = BSF_GLOBAL; +- new->value = 0x12345; +- +- ptrs[0] = new; +- ptrs[1] = 0; +- +- bfd_set_symtab (abfd, ptrs, 1); +- bfd_close (abfd); +- return 0; +- } +- +- ./makesym +- nm foo +- 00012345 A dummy_symbol +- +- Many formats cannot represent arbitrary symbol information; for +-instance, the `a.out' object format does not allow an arbitrary number +-of sections. A symbol pointing to a section which is not one of +-`.text', `.data' or `.bss' cannot be described. +- +- +-File: bfd.info, Node: Mini Symbols, Next: typedef asymbol, Prev: Writing Symbols, Up: Symbols +- +-2.7.3 Mini Symbols +------------------- +- +-Mini symbols provide read-only access to the symbol table. They use +-less memory space, but require more time to access. They can be useful +-for tools like nm or objdump, which may have to handle symbol tables of +-extremely large executables. +- +- The `bfd_read_minisymbols' function will read the symbols into +-memory in an internal form. It will return a `void *' pointer to a +-block of memory, a symbol count, and the size of each symbol. The +-pointer is allocated using `malloc', and should be freed by the caller +-when it is no longer needed. +- +- The function `bfd_minisymbol_to_symbol' will take a pointer to a +-minisymbol, and a pointer to a structure returned by +-`bfd_make_empty_symbol', and return a `asymbol' structure. The return +-value may or may not be the same as the value from +-`bfd_make_empty_symbol' which was passed in. +- +- +-File: bfd.info, Node: typedef asymbol, Next: symbol handling functions, Prev: Mini Symbols, Up: Symbols +- +-2.7.4 typedef asymbol +---------------------- +- +-An `asymbol' has the form: +- +- +- typedef struct bfd_symbol +- { +- /* A pointer to the BFD which owns the symbol. This information +- is necessary so that a back end can work out what additional +- information (invisible to the application writer) is carried +- with the symbol. +- +- This field is *almost* redundant, since you can use section->owner +- instead, except that some symbols point to the global sections +- bfd_{abs,com,und}_section. This could be fixed by making +- these globals be per-bfd (or per-target-flavor). FIXME. */ +- struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ +- +- /* The text of the symbol. The name is left alone, and not copied; the +- application may not alter it. */ +- const char *name; +- +- /* The value of the symbol. This really should be a union of a +- numeric value with a pointer, since some flags indicate that +- a pointer to another symbol is stored here. */ +- symvalue value; +- +- /* Attributes of a symbol. */ +- #define BSF_NO_FLAGS 0x00 +- +- /* The symbol has local scope; `static' in `C'. The value +- is the offset into the section of the data. */ +- #define BSF_LOCAL (1 << 0) +- +- /* The symbol has global scope; initialized data in `C'. The +- value is the offset into the section of the data. */ +- #define BSF_GLOBAL (1 << 1) +- +- /* The symbol has global scope and is exported. The value is +- the offset into the section of the data. */ +- #define BSF_EXPORT BSF_GLOBAL /* No real difference. */ +- +- /* A normal C symbol would be one of: +- `BSF_LOCAL', `BSF_COMMON', `BSF_UNDEFINED' or +- `BSF_GLOBAL'. */ +- +- /* The symbol is a debugging record. The value has an arbitrary +- meaning, unless BSF_DEBUGGING_RELOC is also set. */ +- #define BSF_DEBUGGING (1 << 2) +- +- /* The symbol denotes a function entry point. Used in ELF, +- perhaps others someday. */ +- #define BSF_FUNCTION (1 << 3) +- +- /* Used by the linker. */ +- #define BSF_KEEP (1 << 5) +- #define BSF_KEEP_G (1 << 6) +- +- /* A weak global symbol, overridable without warnings by +- a regular global symbol of the same name. */ +- #define BSF_WEAK (1 << 7) +- +- /* This symbol was created to point to a section, e.g. ELF's +- STT_SECTION symbols. */ +- #define BSF_SECTION_SYM (1 << 8) +- +- /* The symbol used to be a common symbol, but now it is +- allocated. */ +- #define BSF_OLD_COMMON (1 << 9) +- +- /* In some files the type of a symbol sometimes alters its +- location in an output file - ie in coff a `ISFCN' symbol +- which is also `C_EXT' symbol appears where it was +- declared and not at the end of a section. This bit is set +- by the target BFD part to convey this information. */ +- #define BSF_NOT_AT_END (1 << 10) +- +- /* Signal that the symbol is the label of constructor section. */ +- #define BSF_CONSTRUCTOR (1 << 11) +- +- /* Signal that the symbol is a warning symbol. The name is a +- warning. The name of the next symbol is the one to warn about; +- if a reference is made to a symbol with the same name as the next +- symbol, a warning is issued by the linker. */ +- #define BSF_WARNING (1 << 12) +- +- /* Signal that the symbol is indirect. This symbol is an indirect +- pointer to the symbol with the same name as the next symbol. */ +- #define BSF_INDIRECT (1 << 13) +- +- /* BSF_FILE marks symbols that contain a file name. This is used +- for ELF STT_FILE symbols. */ +- #define BSF_FILE (1 << 14) +- +- /* Symbol is from dynamic linking information. */ +- #define BSF_DYNAMIC (1 << 15) +- +- /* The symbol denotes a data object. Used in ELF, and perhaps +- others someday. */ +- #define BSF_OBJECT (1 << 16) +- +- /* This symbol is a debugging symbol. The value is the offset +- into the section of the data. BSF_DEBUGGING should be set +- as well. */ +- #define BSF_DEBUGGING_RELOC (1 << 17) +- +- /* This symbol is thread local. Used in ELF. */ +- #define BSF_THREAD_LOCAL (1 << 18) +- +- /* This symbol represents a complex relocation expression, +- with the expression tree serialized in the symbol name. */ +- #define BSF_RELC (1 << 19) +- +- /* This symbol represents a signed complex relocation expression, +- with the expression tree serialized in the symbol name. */ +- #define BSF_SRELC (1 << 20) +- +- /* This symbol was created by bfd_get_synthetic_symtab. */ +- #define BSF_SYNTHETIC (1 << 21) +- +- /* This symbol is an indirect code object. Unrelated to BSF_INDIRECT. +- The dynamic linker will compute the value of this symbol by +- calling the function that it points to. BSF_FUNCTION must +- also be also set. */ +- #define BSF_GNU_INDIRECT_FUNCTION (1 << 22) +- /* This symbol is a globally unique data object. The dynamic linker +- will make sure that in the entire process there is just one symbol +- with this name and type in use. BSF_OBJECT must also be set. */ +- #define BSF_GNU_UNIQUE (1 << 23) +- +- flagword flags; +- +- /* A pointer to the section to which this symbol is +- relative. This will always be non NULL, there are special +- sections for undefined and absolute symbols. */ +- struct bfd_section *section; +- +- /* Back end special data. */ +- union +- { +- void *p; +- bfd_vma i; +- } +- udata; +- } +- asymbol; +- +- +-File: bfd.info, Node: symbol handling functions, Prev: typedef asymbol, Up: Symbols +- +-2.7.5 Symbol handling functions +-------------------------------- +- +-2.7.5.1 `bfd_get_symtab_upper_bound' +-.................................... +- +-*Description* +-Return the number of bytes required to store a vector of pointers to +-`asymbols' for all the symbols in the BFD ABFD, including a terminal +-NULL pointer. If there are no symbols in the BFD, then return 0. If an +-error occurs, return -1. +- #define bfd_get_symtab_upper_bound(abfd) \ +- BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) +- +-2.7.5.2 `bfd_is_local_label' +-............................ +- +-*Synopsis* +- bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); +- *Description* +-Return TRUE if the given symbol SYM in the BFD ABFD is a compiler +-generated local label, else return FALSE. +- +-2.7.5.3 `bfd_is_local_label_name' +-................................. +- +-*Synopsis* +- bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); +- *Description* +-Return TRUE if a symbol with the name NAME in the BFD ABFD is a +-compiler generated local label, else return FALSE. This just checks +-whether the name has the form of a local label. +- #define bfd_is_local_label_name(abfd, name) \ +- BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) +- +-2.7.5.4 `bfd_is_target_special_symbol' +-...................................... +- +-*Synopsis* +- bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); +- *Description* +-Return TRUE iff a symbol SYM in the BFD ABFD is something special to +-the particular target represented by the BFD. Such symbols should +-normally not be mentioned to the user. +- #define bfd_is_target_special_symbol(abfd, sym) \ +- BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) +- +-2.7.5.5 `bfd_canonicalize_symtab' +-................................. +- +-*Description* +-Read the symbols from the BFD ABFD, and fills in the vector LOCATION +-with pointers to the symbols and a trailing NULL. Return the actual +-number of symbol pointers, not including the NULL. +- #define bfd_canonicalize_symtab(abfd, location) \ +- BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) +- +-2.7.5.6 `bfd_set_symtab' +-........................ +- +-*Synopsis* +- bfd_boolean bfd_set_symtab +- (bfd *abfd, asymbol **location, unsigned int count); +- *Description* +-Arrange that when the output BFD ABFD is closed, the table LOCATION of +-COUNT pointers to symbols will be written. +- +-2.7.5.7 `bfd_print_symbol_vandf' +-................................ +- +-*Synopsis* +- void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); +- *Description* +-Print the value and flags of the SYMBOL supplied to the stream FILE. +- +-2.7.5.8 `bfd_make_empty_symbol' +-............................... +- +-*Description* +-Create a new `asymbol' structure for the BFD ABFD and return a pointer +-to it. +- +- This routine is necessary because each back end has private +-information surrounding the `asymbol'. Building your own `asymbol' and +-pointing to it will not create the private information, and will cause +-problems later on. +- #define bfd_make_empty_symbol(abfd) \ +- BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) +- +-2.7.5.9 `_bfd_generic_make_empty_symbol' +-........................................ +- +-*Synopsis* +- asymbol *_bfd_generic_make_empty_symbol (bfd *); +- *Description* +-Create a new `asymbol' structure for the BFD ABFD and return a pointer +-to it. Used by core file routines, binary back-end and anywhere else +-where no private info is needed. +- +-2.7.5.10 `bfd_make_debug_symbol' +-................................ +- +-*Description* +-Create a new `asymbol' structure for the BFD ABFD, to be used as a +-debugging symbol. Further details of its use have yet to be worked out. +- #define bfd_make_debug_symbol(abfd,ptr,size) \ +- BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) +- +-2.7.5.11 `bfd_decode_symclass' +-.............................. +- +-*Description* +-Return a character corresponding to the symbol class of SYMBOL, or '?' +-for an unknown class. +- +- *Synopsis* +- int bfd_decode_symclass (asymbol *symbol); +- +-2.7.5.12 `bfd_is_undefined_symclass' +-.................................... +- +-*Description* +-Returns non-zero if the class symbol returned by bfd_decode_symclass +-represents an undefined symbol. Returns zero otherwise. +- +- *Synopsis* +- bfd_boolean bfd_is_undefined_symclass (int symclass); +- +-2.7.5.13 `bfd_symbol_info' +-.......................... +- +-*Description* +-Fill in the basic info about symbol that nm needs. Additional info may +-be added by the back-ends after calling this function. +- +- *Synopsis* +- void bfd_symbol_info (asymbol *symbol, symbol_info *ret); +- +-2.7.5.14 `bfd_copy_private_symbol_data' +-....................................... +- +-*Synopsis* +- bfd_boolean bfd_copy_private_symbol_data +- (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); +- *Description* +-Copy private symbol information from ISYM in the BFD IBFD to the symbol +-OSYM in the BFD OBFD. Return `TRUE' on success, `FALSE' on error. +-Possible error returns are: +- +- * `bfd_error_no_memory' - Not enough memory exists to create private +- data for OSEC. +- +- #define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ +- BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ +- (ibfd, isymbol, obfd, osymbol)) +- +- +-File: bfd.info, Node: Archives, Next: Formats, Prev: Symbols, Up: BFD front end +- +-2.8 Archives +-============ +- +-*Description* +-An archive (or library) is just another BFD. It has a symbol table, +-although there's not much a user program will do with it. +- +- The big difference between an archive BFD and an ordinary BFD is +-that the archive doesn't have sections. Instead it has a chain of BFDs +-that are considered its contents. These BFDs can be manipulated like +-any other. The BFDs contained in an archive opened for reading will +-all be opened for reading. You may put either input or output BFDs +-into an archive opened for output; they will be handled correctly when +-the archive is closed. +- +- Use `bfd_openr_next_archived_file' to step through the contents of +-an archive opened for input. You don't have to read the entire archive +-if you don't want to! Read it until you find what you want. +- +- A BFD returned by `bfd_openr_next_archived_file' can be closed +-manually with `bfd_close'. If you do not close it, then a second +-iteration through the members of an archive may return the same BFD. +-If you close the archive BFD, then all the member BFDs will +-automatically be closed as well. +- +- Archive contents of output BFDs are chained through the +-`archive_next' pointer in a BFD. The first one is findable through the +-`archive_head' slot of the archive. Set it with `bfd_set_archive_head' +-(q.v.). A given BFD may be in only one open output archive at a time. +- +- As expected, the BFD archive code is more general than the archive +-code of any given environment. BFD archives may contain files of +-different formats (e.g., a.out and coff) and even different +-architectures. You may even place archives recursively into archives! +- +- This can cause unexpected confusion, since some archive formats are +-more expressive than others. For instance, Intel COFF archives can +-preserve long filenames; SunOS a.out archives cannot. If you move a +-file from the first to the second format and back again, the filename +-may be truncated. Likewise, different a.out environments have different +-conventions as to how they truncate filenames, whether they preserve +-directory names in filenames, etc. When interoperating with native +-tools, be sure your files are homogeneous. +- +- Beware: most of these formats do not react well to the presence of +-spaces in filenames. We do the best we can, but can't always handle +-this case due to restrictions in the format of archives. Many Unix +-utilities are braindead in regards to spaces and such in filenames +-anyway, so this shouldn't be much of a restriction. +- +- Archives are supported in BFD in `archive.c'. +- +-2.8.1 Archive functions +------------------------ +- +-2.8.1.1 `bfd_get_next_mapent' +-............................. +- +-*Synopsis* +- symindex bfd_get_next_mapent +- (bfd *abfd, symindex previous, carsym **sym); +- *Description* +-Step through archive ABFD's symbol table (if it has one). Successively +-update SYM with the next symbol's information, returning that symbol's +-(internal) index into the symbol table. +- +- Supply `BFD_NO_MORE_SYMBOLS' as the PREVIOUS entry to get the first +-one; returns `BFD_NO_MORE_SYMBOLS' when you've already got the last one. +- +- A `carsym' is a canonical archive symbol. The only user-visible +-element is its name, a null-terminated string. +- +-2.8.1.2 `bfd_set_archive_head' +-.............................. +- +-*Synopsis* +- bfd_boolean bfd_set_archive_head (bfd *output, bfd *new_head); +- *Description* +-Set the head of the chain of BFDs contained in the archive OUTPUT to +-NEW_HEAD. +- +-2.8.1.3 `bfd_openr_next_archived_file' +-...................................... +- +-*Synopsis* +- bfd *bfd_openr_next_archived_file (bfd *archive, bfd *previous); +- *Description* +-Provided a BFD, ARCHIVE, containing an archive and NULL, open an input +-BFD on the first contained element and returns that. Subsequent calls +-should pass the archive and the previous return value to return a +-created BFD to the next contained element. NULL is returned when there +-are no more. +- +- +-File: bfd.info, Node: Formats, Next: Relocations, Prev: Archives, Up: BFD front end +- +-2.9 File formats +-================ +- +-A format is a BFD concept of high level file contents type. The formats +-supported by BFD are: +- +- * `bfd_object' +- The BFD may contain data, symbols, relocations and debug info. +- +- * `bfd_archive' +- The BFD contains other BFDs and an optional index. +- +- * `bfd_core' +- The BFD contains the result of an executable core dump. +- +-2.9.1 File format functions +---------------------------- +- +-2.9.1.1 `bfd_check_format' +-.......................... +- +-*Synopsis* +- bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); +- *Description* +-Verify if the file attached to the BFD ABFD is compatible with the +-format FORMAT (i.e., one of `bfd_object', `bfd_archive' or `bfd_core'). +- +- If the BFD has been set to a specific target before the call, only +-the named target and format combination is checked. If the target has +-not been set, or has been set to `default', then all the known target +-backends is interrogated to determine a match. If the default target +-matches, it is used. If not, exactly one target must recognize the +-file, or an error results. +- +- The function returns `TRUE' on success, otherwise `FALSE' with one +-of the following error codes: +- +- * `bfd_error_invalid_operation' - if `format' is not one of +- `bfd_object', `bfd_archive' or `bfd_core'. +- +- * `bfd_error_system_call' - if an error occured during a read - even +- some file mismatches can cause bfd_error_system_calls. +- +- * `file_not_recognised' - none of the backends recognised the file +- format. +- +- * `bfd_error_file_ambiguously_recognized' - more than one backend +- recognised the file format. +- +-2.9.1.2 `bfd_check_format_matches' +-.................................. +- +-*Synopsis* +- bfd_boolean bfd_check_format_matches +- (bfd *abfd, bfd_format format, char ***matching); +- *Description* +-Like `bfd_check_format', except when it returns FALSE with `bfd_errno' +-set to `bfd_error_file_ambiguously_recognized'. In that case, if +-MATCHING is not NULL, it will be filled in with a NULL-terminated list +-of the names of the formats that matched, allocated with `malloc'. +-Then the user may choose a format and try again. +- +- When done with the list that MATCHING points to, the caller should +-free it. +- +-2.9.1.3 `bfd_set_format' +-........................ +- +-*Synopsis* +- bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); +- *Description* +-This function sets the file format of the BFD ABFD to the format +-FORMAT. If the target set in the BFD does not support the format +-requested, the format is invalid, or the BFD is not open for writing, +-then an error occurs. +- +-2.9.1.4 `bfd_format_string' +-........................... +- +-*Synopsis* +- const char *bfd_format_string (bfd_format format); +- *Description* +-Return a pointer to a const string `invalid', `object', `archive', +-`core', or `unknown', depending upon the value of FORMAT. +- +- +-File: bfd.info, Node: Relocations, Next: Core Files, Prev: Formats, Up: BFD front end +- +-2.10 Relocations +-================ +- +-BFD maintains relocations in much the same way it maintains symbols: +-they are left alone until required, then read in en-masse and +-translated into an internal form. A common routine +-`bfd_perform_relocation' acts upon the canonical form to do the fixup. +- +- Relocations are maintained on a per section basis, while symbols are +-maintained on a per BFD basis. +- +- All that a back end has to do to fit the BFD interface is to create +-a `struct reloc_cache_entry' for each relocation in a particular +-section, and fill in the right bits of the structures. +- +-* Menu: +- +-* typedef arelent:: +-* howto manager:: +- +- +-File: bfd.info, Node: typedef arelent, Next: howto manager, Prev: Relocations, Up: Relocations +- +-2.10.1 typedef arelent +----------------------- +- +-This is the structure of a relocation entry: +- +- +- typedef enum bfd_reloc_status +- { +- /* No errors detected. */ +- bfd_reloc_ok, +- +- /* The relocation was performed, but there was an overflow. */ +- bfd_reloc_overflow, +- +- /* The address to relocate was not within the section supplied. */ +- bfd_reloc_outofrange, +- +- /* Used by special functions. */ +- bfd_reloc_continue, +- +- /* Unsupported relocation size requested. */ +- bfd_reloc_notsupported, +- +- /* Unused. */ +- bfd_reloc_other, +- +- /* The symbol to relocate against was undefined. */ +- bfd_reloc_undefined, +- +- /* The relocation was performed, but may not be ok - presently +- generated only when linking i960 coff files with i960 b.out +- symbols. If this type is returned, the error_message argument +- to bfd_perform_relocation will be set. */ +- bfd_reloc_dangerous +- } +- bfd_reloc_status_type; +- +- +- typedef struct reloc_cache_entry +- { +- /* A pointer into the canonical table of pointers. */ +- struct bfd_symbol **sym_ptr_ptr; +- +- /* offset in section. */ +- bfd_size_type address; +- +- /* addend for relocation value. */ +- bfd_vma addend; +- +- /* Pointer to how to perform the required relocation. */ +- reloc_howto_type *howto; +- +- } +- arelent; +- *Description* +-Here is a description of each of the fields within an `arelent': +- +- * `sym_ptr_ptr' +- The symbol table pointer points to a pointer to the symbol +-associated with the relocation request. It is the pointer into the +-table returned by the back end's `canonicalize_symtab' action. *Note +-Symbols::. The symbol is referenced through a pointer to a pointer so +-that tools like the linker can fix up all the symbols of the same name +-by modifying only one pointer. The relocation routine looks in the +-symbol and uses the base of the section the symbol is attached to and +-the value of the symbol as the initial relocation offset. If the symbol +-pointer is zero, then the section provided is looked up. +- +- * `address' +- The `address' field gives the offset in bytes from the base of the +-section data which owns the relocation record to the first byte of +-relocatable information. The actual data relocated will be relative to +-this point; for example, a relocation type which modifies the bottom +-two bytes of a four byte word would not touch the first byte pointed to +-in a big endian world. +- +- * `addend' +- The `addend' is a value provided by the back end to be added (!) to +-the relocation offset. Its interpretation is dependent upon the howto. +-For example, on the 68k the code: +- +- char foo[]; +- main() +- { +- return foo[0x12345678]; +- } +- +- Could be compiled into: +- +- linkw fp,#-4 +- moveb @#12345678,d0 +- extbl d0 +- unlk fp +- rts +- +- This could create a reloc pointing to `foo', but leave the offset in +-the data, something like: +- +- RELOCATION RECORDS FOR [.text]: +- offset type value +- 00000006 32 _foo +- +- 00000000 4e56 fffc ; linkw fp,#-4 +- 00000004 1039 1234 5678 ; moveb @#12345678,d0 +- 0000000a 49c0 ; extbl d0 +- 0000000c 4e5e ; unlk fp +- 0000000e 4e75 ; rts +- +- Using coff and an 88k, some instructions don't have enough space in +-them to represent the full address range, and pointers have to be +-loaded in two parts. So you'd get something like: +- +- or.u r13,r0,hi16(_foo+0x12345678) +- ld.b r2,r13,lo16(_foo+0x12345678) +- jmp r1 +- +- This should create two relocs, both pointing to `_foo', and with +-0x12340000 in their addend field. The data would consist of: +- +- RELOCATION RECORDS FOR [.text]: +- offset type value +- 00000002 HVRT16 _foo+0x12340000 +- 00000006 LVRT16 _foo+0x12340000 +- +- 00000000 5da05678 ; or.u r13,r0,0x5678 +- 00000004 1c4d5678 ; ld.b r2,r13,0x5678 +- 00000008 f400c001 ; jmp r1 +- +- The relocation routine digs out the value from the data, adds it to +-the addend to get the original offset, and then adds the value of +-`_foo'. Note that all 32 bits have to be kept around somewhere, to cope +-with carry from bit 15 to bit 16. +- +- One further example is the sparc and the a.out format. The sparc has +-a similar problem to the 88k, in that some instructions don't have room +-for an entire offset, but on the sparc the parts are created in odd +-sized lumps. The designers of the a.out format chose to not use the +-data within the section for storing part of the offset; all the offset +-is kept within the reloc. Anything in the data should be ignored. +- +- save %sp,-112,%sp +- sethi %hi(_foo+0x12345678),%g2 +- ldsb [%g2+%lo(_foo+0x12345678)],%i0 +- ret +- restore +- +- Both relocs contain a pointer to `foo', and the offsets contain junk. +- +- RELOCATION RECORDS FOR [.text]: +- offset type value +- 00000004 HI22 _foo+0x12345678 +- 00000008 LO10 _foo+0x12345678 +- +- 00000000 9de3bf90 ; save %sp,-112,%sp +- 00000004 05000000 ; sethi %hi(_foo+0),%g2 +- 00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0 +- 0000000c 81c7e008 ; ret +- 00000010 81e80000 ; restore +- +- * `howto' +- The `howto' field can be imagined as a relocation instruction. It is +-a pointer to a structure which contains information on what to do with +-all of the other information in the reloc record and data section. A +-back end would normally have a relocation instruction set and turn +-relocations into pointers to the correct structure on input - but it +-would be possible to create each howto field on demand. +- +-2.10.1.1 `enum complain_overflow' +-................................. +- +-Indicates what sort of overflow checking should be done when performing +-a relocation. +- +- +- enum complain_overflow +- { +- /* Do not complain on overflow. */ +- complain_overflow_dont, +- +- /* Complain if the value overflows when considered as a signed +- number one bit larger than the field. ie. A bitfield of N bits +- is allowed to represent -2**n to 2**n-1. */ +- complain_overflow_bitfield, +- +- /* Complain if the value overflows when considered as a signed +- number. */ +- complain_overflow_signed, +- +- /* Complain if the value overflows when considered as an +- unsigned number. */ +- complain_overflow_unsigned +- }; +- +-2.10.1.2 `reloc_howto_type' +-........................... +- +-The `reloc_howto_type' is a structure which contains all the +-information that libbfd needs to know to tie up a back end's data. +- +- struct bfd_symbol; /* Forward declaration. */ +- +- struct reloc_howto_struct +- { +- /* The type field has mainly a documentary use - the back end can +- do what it wants with it, though normally the back end's +- external idea of what a reloc number is stored +- in this field. For example, a PC relative word relocation +- in a coff environment has the type 023 - because that's +- what the outside world calls a R_PCRWORD reloc. */ +- unsigned int type; +- +- /* The value the final relocation is shifted right by. This drops +- unwanted data from the relocation. */ +- unsigned int rightshift; +- +- /* The size of the item to be relocated. This is *not* a +- power-of-two measure. To get the number of bytes operated +- on by a type of relocation, use bfd_get_reloc_size. */ +- int size; +- +- /* The number of bits in the item to be relocated. This is used +- when doing overflow checking. */ +- unsigned int bitsize; +- +- /* The relocation is relative to the field being relocated. */ +- bfd_boolean pc_relative; +- +- /* The bit position of the reloc value in the destination. +- The relocated value is left shifted by this amount. */ +- unsigned int bitpos; +- +- /* What type of overflow error should be checked for when +- relocating. */ +- enum complain_overflow complain_on_overflow; +- +- /* If this field is non null, then the supplied function is +- called rather than the normal function. This allows really +- strange relocation methods to be accommodated (e.g., i960 callj +- instructions). */ +- bfd_reloc_status_type (*special_function) +- (bfd *, arelent *, struct bfd_symbol *, void *, asection *, +- bfd *, char **); +- +- /* The textual name of the relocation type. */ +- char *name; +- +- /* Some formats record a relocation addend in the section contents +- rather than with the relocation. For ELF formats this is the +- distinction between USE_REL and USE_RELA (though the code checks +- for USE_REL == 1/0). The value of this field is TRUE if the +- addend is recorded with the section contents; when performing a +- partial link (ld -r) the section contents (the data) will be +- modified. The value of this field is FALSE if addends are +- recorded with the relocation (in arelent.addend); when performing +- a partial link the relocation will be modified. +- All relocations for all ELF USE_RELA targets should set this field +- to FALSE (values of TRUE should be looked on with suspicion). +- However, the converse is not true: not all relocations of all ELF +- USE_REL targets set this field to TRUE. Why this is so is peculiar +- to each particular target. For relocs that aren't used in partial +- links (e.g. GOT stuff) it doesn't matter what this is set to. */ +- bfd_boolean partial_inplace; +- +- /* src_mask selects the part of the instruction (or data) to be used +- in the relocation sum. If the target relocations don't have an +- addend in the reloc, eg. ELF USE_REL, src_mask will normally equal +- dst_mask to extract the addend from the section contents. If +- relocations do have an addend in the reloc, eg. ELF USE_RELA, this +- field should be zero. Non-zero values for ELF USE_RELA targets are +- bogus as in those cases the value in the dst_mask part of the +- section contents should be treated as garbage. */ +- bfd_vma src_mask; +- +- /* dst_mask selects which parts of the instruction (or data) are +- replaced with a relocated value. */ +- bfd_vma dst_mask; +- +- /* When some formats create PC relative instructions, they leave +- the value of the pc of the place being relocated in the offset +- slot of the instruction, so that a PC relative relocation can +- be made just by adding in an ordinary offset (e.g., sun3 a.out). +- Some formats leave the displacement part of an instruction +- empty (e.g., m88k bcs); this flag signals the fact. */ +- bfd_boolean pcrel_offset; +- }; +- +-2.10.1.3 `The HOWTO Macro' +-.......................... +- +-*Description* +-The HOWTO define is horrible and will go away. +- #define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ +- { (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC } +- +- *Description* +-And will be replaced with the totally magic way. But for the moment, we +-are compatible, so do it this way. +- #define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ +- HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ +- NAME, FALSE, 0, 0, IN) +- +- *Description* +-This is used to fill in an empty howto entry in an array. +- #define EMPTY_HOWTO(C) \ +- HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ +- NULL, FALSE, 0, 0, FALSE) +- +- *Description* +-Helper routine to turn a symbol into a relocation value. +- #define HOWTO_PREPARE(relocation, symbol) \ +- { \ +- if (symbol != NULL) \ +- { \ +- if (bfd_is_com_section (symbol->section)) \ +- { \ +- relocation = 0; \ +- } \ +- else \ +- { \ +- relocation = symbol->value; \ +- } \ +- } \ +- } +- +-2.10.1.4 `bfd_get_reloc_size' +-............................. +- +-*Synopsis* +- unsigned int bfd_get_reloc_size (reloc_howto_type *); +- *Description* +-For a reloc_howto_type that operates on a fixed number of bytes, this +-returns the number of bytes operated on. +- +-2.10.1.5 `arelent_chain' +-........................ +- +-*Description* +-How relocs are tied together in an `asection': +- typedef struct relent_chain +- { +- arelent relent; +- struct relent_chain *next; +- } +- arelent_chain; +- +-2.10.1.6 `bfd_check_overflow' +-............................. +- +-*Synopsis* +- bfd_reloc_status_type bfd_check_overflow +- (enum complain_overflow how, +- unsigned int bitsize, +- unsigned int rightshift, +- unsigned int addrsize, +- bfd_vma relocation); +- *Description* +-Perform overflow checking on RELOCATION which has BITSIZE significant +-bits and will be shifted right by RIGHTSHIFT bits, on a machine with +-addresses containing ADDRSIZE significant bits. The result is either of +-`bfd_reloc_ok' or `bfd_reloc_overflow'. +- +-2.10.1.7 `bfd_perform_relocation' +-................................. +- +-*Synopsis* +- bfd_reloc_status_type bfd_perform_relocation +- (bfd *abfd, +- arelent *reloc_entry, +- void *data, +- asection *input_section, +- bfd *output_bfd, +- char **error_message); +- *Description* +-If OUTPUT_BFD is supplied to this function, the generated image will be +-relocatable; the relocations are copied to the output file after they +-have been changed to reflect the new state of the world. There are two +-ways of reflecting the results of partial linkage in an output file: by +-modifying the output data in place, and by modifying the relocation +-record. Some native formats (e.g., basic a.out and basic coff) have no +-way of specifying an addend in the relocation type, so the addend has +-to go in the output data. This is no big deal since in these formats +-the output data slot will always be big enough for the addend. Complex +-reloc types with addends were invented to solve just this problem. The +-ERROR_MESSAGE argument is set to an error message if this return +-`bfd_reloc_dangerous'. +- +-2.10.1.8 `bfd_install_relocation' +-................................. +- +-*Synopsis* +- bfd_reloc_status_type bfd_install_relocation +- (bfd *abfd, +- arelent *reloc_entry, +- void *data, bfd_vma data_start, +- asection *input_section, +- char **error_message); +- *Description* +-This looks remarkably like `bfd_perform_relocation', except it does not +-expect that the section contents have been filled in. I.e., it's +-suitable for use when creating, rather than applying a relocation. +- +- For now, this function should be considered reserved for the +-assembler. +- +- +-File: bfd.info, Node: howto manager, Prev: typedef arelent, Up: Relocations +- +-2.10.2 The howto manager +------------------------- +- +-When an application wants to create a relocation, but doesn't know what +-the target machine might call it, it can find out by using this bit of +-code. +- +-2.10.2.1 `bfd_reloc_code_type' +-.............................. +- +-*Description* +-The insides of a reloc code. The idea is that, eventually, there will +-be one enumerator for every type of relocation we ever do. Pass one of +-these values to `bfd_reloc_type_lookup', and it'll return a howto +-pointer. +- +- This does mean that the application must determine the correct +-enumerator value; you can't get a howto pointer from a random set of +-attributes. +- +- Here are the possible values for `enum bfd_reloc_code_real': +- +- -- : BFD_RELOC_64 +- -- : BFD_RELOC_32 +- -- : BFD_RELOC_26 +- -- : BFD_RELOC_24 +- -- : BFD_RELOC_16 +- -- : BFD_RELOC_14 +- -- : BFD_RELOC_8 +- Basic absolute relocations of N bits. +- +- -- : BFD_RELOC_64_PCREL +- -- : BFD_RELOC_32_PCREL +- -- : BFD_RELOC_24_PCREL +- -- : BFD_RELOC_16_PCREL +- -- : BFD_RELOC_12_PCREL +- -- : BFD_RELOC_8_PCREL +- PC-relative relocations. Sometimes these are relative to the +- address of the relocation itself; sometimes they are relative to +- the start of the section containing the relocation. It depends on +- the specific target. +- +- The 24-bit relocation is used in some Intel 960 configurations. +- +- -- : BFD_RELOC_32_SECREL +- Section relative relocations. Some targets need this for DWARF2. +- +- -- : BFD_RELOC_32_GOT_PCREL +- -- : BFD_RELOC_16_GOT_PCREL +- -- : BFD_RELOC_8_GOT_PCREL +- -- : BFD_RELOC_32_GOTOFF +- -- : BFD_RELOC_16_GOTOFF +- -- : BFD_RELOC_LO16_GOTOFF +- -- : BFD_RELOC_HI16_GOTOFF +- -- : BFD_RELOC_HI16_S_GOTOFF +- -- : BFD_RELOC_8_GOTOFF +- -- : BFD_RELOC_64_PLT_PCREL +- -- : BFD_RELOC_32_PLT_PCREL +- -- : BFD_RELOC_24_PLT_PCREL +- -- : BFD_RELOC_16_PLT_PCREL +- -- : BFD_RELOC_8_PLT_PCREL +- -- : BFD_RELOC_64_PLTOFF +- -- : BFD_RELOC_32_PLTOFF +- -- : BFD_RELOC_16_PLTOFF +- -- : BFD_RELOC_LO16_PLTOFF +- -- : BFD_RELOC_HI16_PLTOFF +- -- : BFD_RELOC_HI16_S_PLTOFF +- -- : BFD_RELOC_8_PLTOFF +- For ELF. +- +- -- : BFD_RELOC_SIZE32 +- -- : BFD_RELOC_SIZE64 +- Size relocations. +- +- -- : BFD_RELOC_68K_GLOB_DAT +- -- : BFD_RELOC_68K_JMP_SLOT +- -- : BFD_RELOC_68K_RELATIVE +- -- : BFD_RELOC_68K_TLS_GD32 +- -- : BFD_RELOC_68K_TLS_GD16 +- -- : BFD_RELOC_68K_TLS_GD8 +- -- : BFD_RELOC_68K_TLS_LDM32 +- -- : BFD_RELOC_68K_TLS_LDM16 +- -- : BFD_RELOC_68K_TLS_LDM8 +- -- : BFD_RELOC_68K_TLS_LDO32 +- -- : BFD_RELOC_68K_TLS_LDO16 +- -- : BFD_RELOC_68K_TLS_LDO8 +- -- : BFD_RELOC_68K_TLS_IE32 +- -- : BFD_RELOC_68K_TLS_IE16 +- -- : BFD_RELOC_68K_TLS_IE8 +- -- : BFD_RELOC_68K_TLS_LE32 +- -- : BFD_RELOC_68K_TLS_LE16 +- -- : BFD_RELOC_68K_TLS_LE8 +- Relocations used by 68K ELF. +- +- -- : BFD_RELOC_32_BASEREL +- -- : BFD_RELOC_16_BASEREL +- -- : BFD_RELOC_LO16_BASEREL +- -- : BFD_RELOC_HI16_BASEREL +- -- : BFD_RELOC_HI16_S_BASEREL +- -- : BFD_RELOC_8_BASEREL +- -- : BFD_RELOC_RVA +- Linkage-table relative. +- +- -- : BFD_RELOC_8_FFnn +- Absolute 8-bit relocation, but used to form an address like 0xFFnn. +- +- -- : BFD_RELOC_32_PCREL_S2 +- -- : BFD_RELOC_16_PCREL_S2 +- -- : BFD_RELOC_23_PCREL_S2 +- These PC-relative relocations are stored as word displacements - +- i.e., byte displacements shifted right two bits. The 30-bit word +- displacement (<<32_PCREL_S2>> - 32 bits, shifted 2) is used on the +- SPARC. (SPARC tools generally refer to this as <>.) The +- signed 16-bit displacement is used on the MIPS, and the 23-bit +- displacement is used on the Alpha. +- +- -- : BFD_RELOC_HI22 +- -- : BFD_RELOC_LO10 +- High 22 bits and low 10 bits of 32-bit value, placed into lower +- bits of the target word. These are used on the SPARC. +- +- -- : BFD_RELOC_GPREL16 +- -- : BFD_RELOC_GPREL32 +- For systems that allocate a Global Pointer register, these are +- displacements off that register. These relocation types are +- handled specially, because the value the register will have is +- decided relatively late. +- +- -- : BFD_RELOC_I960_CALLJ +- Reloc types used for i960/b.out. +- +- -- : BFD_RELOC_NONE +- -- : BFD_RELOC_SPARC_WDISP22 +- -- : BFD_RELOC_SPARC22 +- -- : BFD_RELOC_SPARC13 +- -- : BFD_RELOC_SPARC_GOT10 +- -- : BFD_RELOC_SPARC_GOT13 +- -- : BFD_RELOC_SPARC_GOT22 +- -- : BFD_RELOC_SPARC_PC10 +- -- : BFD_RELOC_SPARC_PC22 +- -- : BFD_RELOC_SPARC_WPLT30 +- -- : BFD_RELOC_SPARC_COPY +- -- : BFD_RELOC_SPARC_GLOB_DAT +- -- : BFD_RELOC_SPARC_JMP_SLOT +- -- : BFD_RELOC_SPARC_RELATIVE +- -- : BFD_RELOC_SPARC_UA16 +- -- : BFD_RELOC_SPARC_UA32 +- -- : BFD_RELOC_SPARC_UA64 +- -- : BFD_RELOC_SPARC_GOTDATA_HIX22 +- -- : BFD_RELOC_SPARC_GOTDATA_LOX10 +- -- : BFD_RELOC_SPARC_GOTDATA_OP_HIX22 +- -- : BFD_RELOC_SPARC_GOTDATA_OP_LOX10 +- -- : BFD_RELOC_SPARC_GOTDATA_OP +- -- : BFD_RELOC_SPARC_JMP_IREL +- -- : BFD_RELOC_SPARC_IRELATIVE +- SPARC ELF relocations. There is probably some overlap with other +- relocation types already defined. +- +- -- : BFD_RELOC_SPARC_BASE13 +- -- : BFD_RELOC_SPARC_BASE22 +- I think these are specific to SPARC a.out (e.g., Sun 4). +- +- -- : BFD_RELOC_SPARC_64 +- -- : BFD_RELOC_SPARC_10 +- -- : BFD_RELOC_SPARC_11 +- -- : BFD_RELOC_SPARC_OLO10 +- -- : BFD_RELOC_SPARC_HH22 +- -- : BFD_RELOC_SPARC_HM10 +- -- : BFD_RELOC_SPARC_LM22 +- -- : BFD_RELOC_SPARC_PC_HH22 +- -- : BFD_RELOC_SPARC_PC_HM10 +- -- : BFD_RELOC_SPARC_PC_LM22 +- -- : BFD_RELOC_SPARC_WDISP16 +- -- : BFD_RELOC_SPARC_WDISP19 +- -- : BFD_RELOC_SPARC_7 +- -- : BFD_RELOC_SPARC_6 +- -- : BFD_RELOC_SPARC_5 +- -- : BFD_RELOC_SPARC_DISP64 +- -- : BFD_RELOC_SPARC_PLT32 +- -- : BFD_RELOC_SPARC_PLT64 +- -- : BFD_RELOC_SPARC_HIX22 +- -- : BFD_RELOC_SPARC_LOX10 +- -- : BFD_RELOC_SPARC_H44 +- -- : BFD_RELOC_SPARC_M44 +- -- : BFD_RELOC_SPARC_L44 +- -- : BFD_RELOC_SPARC_REGISTER +- -- : BFD_RELOC_SPARC_H34 +- -- : BFD_RELOC_SPARC_SIZE32 +- -- : BFD_RELOC_SPARC_SIZE64 +- -- : BFD_RELOC_SPARC_WDISP10 +- SPARC64 relocations +- +- -- : BFD_RELOC_SPARC_REV32 +- SPARC little endian relocation +- +- -- : BFD_RELOC_SPARC_TLS_GD_HI22 +- -- : BFD_RELOC_SPARC_TLS_GD_LO10 +- -- : BFD_RELOC_SPARC_TLS_GD_ADD +- -- : BFD_RELOC_SPARC_TLS_GD_CALL +- -- : BFD_RELOC_SPARC_TLS_LDM_HI22 +- -- : BFD_RELOC_SPARC_TLS_LDM_LO10 +- -- : BFD_RELOC_SPARC_TLS_LDM_ADD +- -- : BFD_RELOC_SPARC_TLS_LDM_CALL +- -- : BFD_RELOC_SPARC_TLS_LDO_HIX22 +- -- : BFD_RELOC_SPARC_TLS_LDO_LOX10 +- -- : BFD_RELOC_SPARC_TLS_LDO_ADD +- -- : BFD_RELOC_SPARC_TLS_IE_HI22 +- -- : BFD_RELOC_SPARC_TLS_IE_LO10 +- -- : BFD_RELOC_SPARC_TLS_IE_LD +- -- : BFD_RELOC_SPARC_TLS_IE_LDX +- -- : BFD_RELOC_SPARC_TLS_IE_ADD +- -- : BFD_RELOC_SPARC_TLS_LE_HIX22 +- -- : BFD_RELOC_SPARC_TLS_LE_LOX10 +- -- : BFD_RELOC_SPARC_TLS_DTPMOD32 +- -- : BFD_RELOC_SPARC_TLS_DTPMOD64 +- -- : BFD_RELOC_SPARC_TLS_DTPOFF32 +- -- : BFD_RELOC_SPARC_TLS_DTPOFF64 +- -- : BFD_RELOC_SPARC_TLS_TPOFF32 +- -- : BFD_RELOC_SPARC_TLS_TPOFF64 +- SPARC TLS relocations +- +- -- : BFD_RELOC_SPU_IMM7 +- -- : BFD_RELOC_SPU_IMM8 +- -- : BFD_RELOC_SPU_IMM10 +- -- : BFD_RELOC_SPU_IMM10W +- -- : BFD_RELOC_SPU_IMM16 +- -- : BFD_RELOC_SPU_IMM16W +- -- : BFD_RELOC_SPU_IMM18 +- -- : BFD_RELOC_SPU_PCREL9a +- -- : BFD_RELOC_SPU_PCREL9b +- -- : BFD_RELOC_SPU_PCREL16 +- -- : BFD_RELOC_SPU_LO16 +- -- : BFD_RELOC_SPU_HI16 +- -- : BFD_RELOC_SPU_PPU32 +- -- : BFD_RELOC_SPU_PPU64 +- -- : BFD_RELOC_SPU_ADD_PIC +- SPU Relocations. +- +- -- : BFD_RELOC_ALPHA_GPDISP_HI16 +- Alpha ECOFF and ELF relocations. Some of these treat the symbol or +- "addend" in some special way. For GPDISP_HI16 ("gpdisp") +- relocations, the symbol is ignored when writing; when reading, it +- will be the absolute section symbol. The addend is the +- displacement in bytes of the "lda" instruction from the "ldah" +- instruction (which is at the address of this reloc). +- +- -- : BFD_RELOC_ALPHA_GPDISP_LO16 +- For GPDISP_LO16 ("ignore") relocations, the symbol is handled as +- with GPDISP_HI16 relocs. The addend is ignored when writing the +- relocations out, and is filled in with the file's GP value on +- reading, for convenience. +- +- -- : BFD_RELOC_ALPHA_GPDISP +- The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 +- relocation except that there is no accompanying GPDISP_LO16 +- relocation. +- +- -- : BFD_RELOC_ALPHA_LITERAL +- -- : BFD_RELOC_ALPHA_ELF_LITERAL +- -- : BFD_RELOC_ALPHA_LITUSE +- The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; +- the assembler turns it into a LDQ instruction to load the address +- of the symbol, and then fills in a register in the real +- instruction. +- +- The LITERAL reloc, at the LDQ instruction, refers to the .lita +- section symbol. The addend is ignored when writing, but is filled +- in with the file's GP value on reading, for convenience, as with +- the GPDISP_LO16 reloc. +- +- The ELF_LITERAL reloc is somewhere between 16_GOTOFF and +- GPDISP_LO16. It should refer to the symbol to be referenced, as +- with 16_GOTOFF, but it generates output not based on the position +- within the .got section, but relative to the GP value chosen for +- the file during the final link stage. +- +- The LITUSE reloc, on the instruction using the loaded address, +- gives information to the linker that it might be able to use to +- optimize away some literal section references. The symbol is +- ignored (read as the absolute section symbol), and the "addend" +- indicates the type of instruction using the register: 1 - "memory" +- fmt insn 2 - byte-manipulation (byte offset reg) 3 - jsr (target +- of branch) +- +- -- : BFD_RELOC_ALPHA_HINT +- The HINT relocation indicates a value that should be filled into +- the "hint" field of a jmp/jsr/ret instruction, for possible branch- +- prediction logic which may be provided on some processors. +- +- -- : BFD_RELOC_ALPHA_LINKAGE +- The LINKAGE relocation outputs a linkage pair in the object file, +- which is filled by the linker. +- +- -- : BFD_RELOC_ALPHA_CODEADDR +- The CODEADDR relocation outputs a STO_CA in the object file, which +- is filled by the linker. +- +- -- : BFD_RELOC_ALPHA_GPREL_HI16 +- -- : BFD_RELOC_ALPHA_GPREL_LO16 +- The GPREL_HI/LO relocations together form a 32-bit offset from the +- GP register. +- +- -- : BFD_RELOC_ALPHA_BRSGP +- Like BFD_RELOC_23_PCREL_S2, except that the source and target must +- share a common GP, and the target address is adjusted for +- STO_ALPHA_STD_GPLOAD. +- +- -- : BFD_RELOC_ALPHA_NOP +- The NOP relocation outputs a NOP if the longword displacement +- between two procedure entry points is < 2^21. +- +- -- : BFD_RELOC_ALPHA_BSR +- The BSR relocation outputs a BSR if the longword displacement +- between two procedure entry points is < 2^21. +- +- -- : BFD_RELOC_ALPHA_LDA +- The LDA relocation outputs a LDA if the longword displacement +- between two procedure entry points is < 2^16. +- +- -- : BFD_RELOC_ALPHA_BOH +- The BOH relocation outputs a BSR if the longword displacement +- between two procedure entry points is < 2^21, or else a hint. +- +- -- : BFD_RELOC_ALPHA_TLSGD +- -- : BFD_RELOC_ALPHA_TLSLDM +- -- : BFD_RELOC_ALPHA_DTPMOD64 +- -- : BFD_RELOC_ALPHA_GOTDTPREL16 +- -- : BFD_RELOC_ALPHA_DTPREL64 +- -- : BFD_RELOC_ALPHA_DTPREL_HI16 +- -- : BFD_RELOC_ALPHA_DTPREL_LO16 +- -- : BFD_RELOC_ALPHA_DTPREL16 +- -- : BFD_RELOC_ALPHA_GOTTPREL16 +- -- : BFD_RELOC_ALPHA_TPREL64 +- -- : BFD_RELOC_ALPHA_TPREL_HI16 +- -- : BFD_RELOC_ALPHA_TPREL_LO16 +- -- : BFD_RELOC_ALPHA_TPREL16 +- Alpha thread-local storage relocations. +- +- -- : BFD_RELOC_MIPS_JMP +- -- : BFD_RELOC_MICROMIPS_JMP +- The MIPS jump instruction. +- +- -- : BFD_RELOC_MIPS16_JMP +- The MIPS16 jump instruction. +- +- -- : BFD_RELOC_MIPS16_GPREL +- MIPS16 GP relative reloc. +- +- -- : BFD_RELOC_HI16 +- High 16 bits of 32-bit value; simple reloc. +- +- -- : BFD_RELOC_HI16_S +- High 16 bits of 32-bit value but the low 16 bits will be sign +- extended and added to form the final result. If the low 16 bits +- form a negative number, we need to add one to the high value to +- compensate for the borrow when the low bits are added. +- +- -- : BFD_RELOC_LO16 +- Low 16 bits. +- +- -- : BFD_RELOC_HI16_PCREL +- High 16 bits of 32-bit pc-relative value +- +- -- : BFD_RELOC_HI16_S_PCREL +- High 16 bits of 32-bit pc-relative value, adjusted +- +- -- : BFD_RELOC_LO16_PCREL +- Low 16 bits of pc-relative value +- +- -- : BFD_RELOC_MIPS16_GOT16 +- -- : BFD_RELOC_MIPS16_CALL16 +- Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of +- 16-bit immediate fields +- +- -- : BFD_RELOC_MIPS16_HI16 +- MIPS16 high 16 bits of 32-bit value. +- +- -- : BFD_RELOC_MIPS16_HI16_S +- MIPS16 high 16 bits of 32-bit value but the low 16 bits will be +- sign extended and added to form the final result. If the low 16 +- bits form a negative number, we need to add one to the high value +- to compensate for the borrow when the low bits are added. +- +- -- : BFD_RELOC_MIPS16_LO16 +- MIPS16 low 16 bits. +- +- -- : BFD_RELOC_MIPS16_TLS_GD +- -- : BFD_RELOC_MIPS16_TLS_LDM +- -- : BFD_RELOC_MIPS16_TLS_DTPREL_HI16 +- -- : BFD_RELOC_MIPS16_TLS_DTPREL_LO16 +- -- : BFD_RELOC_MIPS16_TLS_GOTTPREL +- -- : BFD_RELOC_MIPS16_TLS_TPREL_HI16 +- -- : BFD_RELOC_MIPS16_TLS_TPREL_LO16 +- MIPS16 TLS relocations +- +- -- : BFD_RELOC_MIPS_LITERAL +- -- : BFD_RELOC_MICROMIPS_LITERAL +- Relocation against a MIPS literal section. +- +- -- : BFD_RELOC_MICROMIPS_7_PCREL_S1 +- -- : BFD_RELOC_MICROMIPS_10_PCREL_S1 +- -- : BFD_RELOC_MICROMIPS_16_PCREL_S1 +- microMIPS PC-relative relocations. +- +- -- : BFD_RELOC_MICROMIPS_GPREL16 +- -- : BFD_RELOC_MICROMIPS_HI16 +- -- : BFD_RELOC_MICROMIPS_HI16_S +- -- : BFD_RELOC_MICROMIPS_LO16 +- microMIPS versions of generic BFD relocs. +- +- -- : BFD_RELOC_MIPS_GOT16 +- -- : BFD_RELOC_MICROMIPS_GOT16 +- -- : BFD_RELOC_MIPS_CALL16 +- -- : BFD_RELOC_MICROMIPS_CALL16 +- -- : BFD_RELOC_MIPS_GOT_HI16 +- -- : BFD_RELOC_MICROMIPS_GOT_HI16 +- -- : BFD_RELOC_MIPS_GOT_LO16 +- -- : BFD_RELOC_MICROMIPS_GOT_LO16 +- -- : BFD_RELOC_MIPS_CALL_HI16 +- -- : BFD_RELOC_MICROMIPS_CALL_HI16 +- -- : BFD_RELOC_MIPS_CALL_LO16 +- -- : BFD_RELOC_MICROMIPS_CALL_LO16 +- -- : BFD_RELOC_MIPS_SUB +- -- : BFD_RELOC_MICROMIPS_SUB +- -- : BFD_RELOC_MIPS_GOT_PAGE +- -- : BFD_RELOC_MICROMIPS_GOT_PAGE +- -- : BFD_RELOC_MIPS_GOT_OFST +- -- : BFD_RELOC_MICROMIPS_GOT_OFST +- -- : BFD_RELOC_MIPS_GOT_DISP +- -- : BFD_RELOC_MICROMIPS_GOT_DISP +- -- : BFD_RELOC_MIPS_SHIFT5 +- -- : BFD_RELOC_MIPS_SHIFT6 +- -- : BFD_RELOC_MIPS_INSERT_A +- -- : BFD_RELOC_MIPS_INSERT_B +- -- : BFD_RELOC_MIPS_DELETE +- -- : BFD_RELOC_MIPS_HIGHEST +- -- : BFD_RELOC_MICROMIPS_HIGHEST +- -- : BFD_RELOC_MIPS_HIGHER +- -- : BFD_RELOC_MICROMIPS_HIGHER +- -- : BFD_RELOC_MIPS_SCN_DISP +- -- : BFD_RELOC_MICROMIPS_SCN_DISP +- -- : BFD_RELOC_MIPS_REL16 +- -- : BFD_RELOC_MIPS_RELGOT +- -- : BFD_RELOC_MIPS_JALR +- -- : BFD_RELOC_MICROMIPS_JALR +- -- : BFD_RELOC_MIPS_TLS_DTPMOD32 +- -- : BFD_RELOC_MIPS_TLS_DTPREL32 +- -- : BFD_RELOC_MIPS_TLS_DTPMOD64 +- -- : BFD_RELOC_MIPS_TLS_DTPREL64 +- -- : BFD_RELOC_MIPS_TLS_GD +- -- : BFD_RELOC_MICROMIPS_TLS_GD +- -- : BFD_RELOC_MIPS_TLS_LDM +- -- : BFD_RELOC_MICROMIPS_TLS_LDM +- -- : BFD_RELOC_MIPS_TLS_DTPREL_HI16 +- -- : BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16 +- -- : BFD_RELOC_MIPS_TLS_DTPREL_LO16 +- -- : BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16 +- -- : BFD_RELOC_MIPS_TLS_GOTTPREL +- -- : BFD_RELOC_MICROMIPS_TLS_GOTTPREL +- -- : BFD_RELOC_MIPS_TLS_TPREL32 +- -- : BFD_RELOC_MIPS_TLS_TPREL64 +- -- : BFD_RELOC_MIPS_TLS_TPREL_HI16 +- -- : BFD_RELOC_MICROMIPS_TLS_TPREL_HI16 +- -- : BFD_RELOC_MIPS_TLS_TPREL_LO16 +- -- : BFD_RELOC_MICROMIPS_TLS_TPREL_LO16 +- -- : BFD_RELOC_MIPS_EH +- MIPS ELF relocations. +- +- -- : BFD_RELOC_MIPS_COPY +- -- : BFD_RELOC_MIPS_JUMP_SLOT +- MIPS ELF relocations (VxWorks and PLT extensions). +- +- -- : BFD_RELOC_MOXIE_10_PCREL +- Moxie ELF relocations. +- +- -- : BFD_RELOC_FRV_LABEL16 +- -- : BFD_RELOC_FRV_LABEL24 +- -- : BFD_RELOC_FRV_LO16 +- -- : BFD_RELOC_FRV_HI16 +- -- : BFD_RELOC_FRV_GPREL12 +- -- : BFD_RELOC_FRV_GPRELU12 +- -- : BFD_RELOC_FRV_GPREL32 +- -- : BFD_RELOC_FRV_GPRELHI +- -- : BFD_RELOC_FRV_GPRELLO +- -- : BFD_RELOC_FRV_GOT12 +- -- : BFD_RELOC_FRV_GOTHI +- -- : BFD_RELOC_FRV_GOTLO +- -- : BFD_RELOC_FRV_FUNCDESC +- -- : BFD_RELOC_FRV_FUNCDESC_GOT12 +- -- : BFD_RELOC_FRV_FUNCDESC_GOTHI +- -- : BFD_RELOC_FRV_FUNCDESC_GOTLO +- -- : BFD_RELOC_FRV_FUNCDESC_VALUE +- -- : BFD_RELOC_FRV_FUNCDESC_GOTOFF12 +- -- : BFD_RELOC_FRV_FUNCDESC_GOTOFFHI +- -- : BFD_RELOC_FRV_FUNCDESC_GOTOFFLO +- -- : BFD_RELOC_FRV_GOTOFF12 +- -- : BFD_RELOC_FRV_GOTOFFHI +- -- : BFD_RELOC_FRV_GOTOFFLO +- -- : BFD_RELOC_FRV_GETTLSOFF +- -- : BFD_RELOC_FRV_TLSDESC_VALUE +- -- : BFD_RELOC_FRV_GOTTLSDESC12 +- -- : BFD_RELOC_FRV_GOTTLSDESCHI +- -- : BFD_RELOC_FRV_GOTTLSDESCLO +- -- : BFD_RELOC_FRV_TLSMOFF12 +- -- : BFD_RELOC_FRV_TLSMOFFHI +- -- : BFD_RELOC_FRV_TLSMOFFLO +- -- : BFD_RELOC_FRV_GOTTLSOFF12 +- -- : BFD_RELOC_FRV_GOTTLSOFFHI +- -- : BFD_RELOC_FRV_GOTTLSOFFLO +- -- : BFD_RELOC_FRV_TLSOFF +- -- : BFD_RELOC_FRV_TLSDESC_RELAX +- -- : BFD_RELOC_FRV_GETTLSOFF_RELAX +- -- : BFD_RELOC_FRV_TLSOFF_RELAX +- -- : BFD_RELOC_FRV_TLSMOFF +- Fujitsu Frv Relocations. +- +- -- : BFD_RELOC_MN10300_GOTOFF24 +- This is a 24bit GOT-relative reloc for the mn10300. +- +- -- : BFD_RELOC_MN10300_GOT32 +- This is a 32bit GOT-relative reloc for the mn10300, offset by two +- bytes in the instruction. +- +- -- : BFD_RELOC_MN10300_GOT24 +- This is a 24bit GOT-relative reloc for the mn10300, offset by two +- bytes in the instruction. +- +- -- : BFD_RELOC_MN10300_GOT16 +- This is a 16bit GOT-relative reloc for the mn10300, offset by two +- bytes in the instruction. +- +- -- : BFD_RELOC_MN10300_COPY +- Copy symbol at runtime. +- +- -- : BFD_RELOC_MN10300_GLOB_DAT +- Create GOT entry. +- +- -- : BFD_RELOC_MN10300_JMP_SLOT +- Create PLT entry. +- +- -- : BFD_RELOC_MN10300_RELATIVE +- Adjust by program base. +- +- -- : BFD_RELOC_MN10300_SYM_DIFF +- Together with another reloc targeted at the same location, allows +- for a value that is the difference of two symbols in the same +- section. +- +- -- : BFD_RELOC_MN10300_ALIGN +- The addend of this reloc is an alignment power that must be +- honoured at the offset's location, regardless of linker relaxation. +- +- -- : BFD_RELOC_MN10300_TLS_GD +- -- : BFD_RELOC_MN10300_TLS_LD +- -- : BFD_RELOC_MN10300_TLS_LDO +- -- : BFD_RELOC_MN10300_TLS_GOTIE +- -- : BFD_RELOC_MN10300_TLS_IE +- -- : BFD_RELOC_MN10300_TLS_LE +- -- : BFD_RELOC_MN10300_TLS_DTPMOD +- -- : BFD_RELOC_MN10300_TLS_DTPOFF +- -- : BFD_RELOC_MN10300_TLS_TPOFF +- Various TLS-related relocations. +- +- -- : BFD_RELOC_MN10300_32_PCREL +- This is a 32bit pcrel reloc for the mn10300, offset by two bytes +- in the instruction. +- +- -- : BFD_RELOC_MN10300_16_PCREL +- This is a 16bit pcrel reloc for the mn10300, offset by two bytes +- in the instruction. +- +- -- : BFD_RELOC_386_GOT32 +- -- : BFD_RELOC_386_PLT32 +- -- : BFD_RELOC_386_COPY +- -- : BFD_RELOC_386_GLOB_DAT +- -- : BFD_RELOC_386_JUMP_SLOT +- -- : BFD_RELOC_386_RELATIVE +- -- : BFD_RELOC_386_GOTOFF +- -- : BFD_RELOC_386_GOTPC +- -- : BFD_RELOC_386_TLS_TPOFF +- -- : BFD_RELOC_386_TLS_IE +- -- : BFD_RELOC_386_TLS_GOTIE +- -- : BFD_RELOC_386_TLS_LE +- -- : BFD_RELOC_386_TLS_GD +- -- : BFD_RELOC_386_TLS_LDM +- -- : BFD_RELOC_386_TLS_LDO_32 +- -- : BFD_RELOC_386_TLS_IE_32 +- -- : BFD_RELOC_386_TLS_LE_32 +- -- : BFD_RELOC_386_TLS_DTPMOD32 +- -- : BFD_RELOC_386_TLS_DTPOFF32 +- -- : BFD_RELOC_386_TLS_TPOFF32 +- -- : BFD_RELOC_386_TLS_GOTDESC +- -- : BFD_RELOC_386_TLS_DESC_CALL +- -- : BFD_RELOC_386_TLS_DESC +- -- : BFD_RELOC_386_IRELATIVE +- i386/elf relocations +- +- -- : BFD_RELOC_X86_64_GOT32 +- -- : BFD_RELOC_X86_64_PLT32 +- -- : BFD_RELOC_X86_64_COPY +- -- : BFD_RELOC_X86_64_GLOB_DAT +- -- : BFD_RELOC_X86_64_JUMP_SLOT +- -- : BFD_RELOC_X86_64_RELATIVE +- -- : BFD_RELOC_X86_64_GOTPCREL +- -- : BFD_RELOC_X86_64_32S +- -- : BFD_RELOC_X86_64_DTPMOD64 +- -- : BFD_RELOC_X86_64_DTPOFF64 +- -- : BFD_RELOC_X86_64_TPOFF64 +- -- : BFD_RELOC_X86_64_TLSGD +- -- : BFD_RELOC_X86_64_TLSLD +- -- : BFD_RELOC_X86_64_DTPOFF32 +- -- : BFD_RELOC_X86_64_GOTTPOFF +- -- : BFD_RELOC_X86_64_TPOFF32 +- -- : BFD_RELOC_X86_64_GOTOFF64 +- -- : BFD_RELOC_X86_64_GOTPC32 +- -- : BFD_RELOC_X86_64_GOT64 +- -- : BFD_RELOC_X86_64_GOTPCREL64 +- -- : BFD_RELOC_X86_64_GOTPC64 +- -- : BFD_RELOC_X86_64_GOTPLT64 +- -- : BFD_RELOC_X86_64_PLTOFF64 +- -- : BFD_RELOC_X86_64_GOTPC32_TLSDESC +- -- : BFD_RELOC_X86_64_TLSDESC_CALL +- -- : BFD_RELOC_X86_64_TLSDESC +- -- : BFD_RELOC_X86_64_IRELATIVE +- -- : BFD_RELOC_X86_64_PC32_BND +- -- : BFD_RELOC_X86_64_PLT32_BND +- x86-64/elf relocations +- +- -- : BFD_RELOC_NS32K_IMM_8 +- -- : BFD_RELOC_NS32K_IMM_16 +- -- : BFD_RELOC_NS32K_IMM_32 +- -- : BFD_RELOC_NS32K_IMM_8_PCREL +- -- : BFD_RELOC_NS32K_IMM_16_PCREL +- -- : BFD_RELOC_NS32K_IMM_32_PCREL +- -- : BFD_RELOC_NS32K_DISP_8 +- -- : BFD_RELOC_NS32K_DISP_16 +- -- : BFD_RELOC_NS32K_DISP_32 +- -- : BFD_RELOC_NS32K_DISP_8_PCREL +- -- : BFD_RELOC_NS32K_DISP_16_PCREL +- -- : BFD_RELOC_NS32K_DISP_32_PCREL +- ns32k relocations +- +- -- : BFD_RELOC_PDP11_DISP_8_PCREL +- -- : BFD_RELOC_PDP11_DISP_6_PCREL +- PDP11 relocations +- +- -- : BFD_RELOC_PJ_CODE_HI16 +- -- : BFD_RELOC_PJ_CODE_LO16 +- -- : BFD_RELOC_PJ_CODE_DIR16 +- -- : BFD_RELOC_PJ_CODE_DIR32 +- -- : BFD_RELOC_PJ_CODE_REL16 +- -- : BFD_RELOC_PJ_CODE_REL32 +- Picojava relocs. Not all of these appear in object files. +- +- -- : BFD_RELOC_PPC_B26 +- -- : BFD_RELOC_PPC_BA26 +- -- : BFD_RELOC_PPC_TOC16 +- -- : BFD_RELOC_PPC_B16 +- -- : BFD_RELOC_PPC_B16_BRTAKEN +- -- : BFD_RELOC_PPC_B16_BRNTAKEN +- -- : BFD_RELOC_PPC_BA16 +- -- : BFD_RELOC_PPC_BA16_BRTAKEN +- -- : BFD_RELOC_PPC_BA16_BRNTAKEN +- -- : BFD_RELOC_PPC_COPY +- -- : BFD_RELOC_PPC_GLOB_DAT +- -- : BFD_RELOC_PPC_JMP_SLOT +- -- : BFD_RELOC_PPC_RELATIVE +- -- : BFD_RELOC_PPC_LOCAL24PC +- -- : BFD_RELOC_PPC_EMB_NADDR32 +- -- : BFD_RELOC_PPC_EMB_NADDR16 +- -- : BFD_RELOC_PPC_EMB_NADDR16_LO +- -- : BFD_RELOC_PPC_EMB_NADDR16_HI +- -- : BFD_RELOC_PPC_EMB_NADDR16_HA +- -- : BFD_RELOC_PPC_EMB_SDAI16 +- -- : BFD_RELOC_PPC_EMB_SDA2I16 +- -- : BFD_RELOC_PPC_EMB_SDA2REL +- -- : BFD_RELOC_PPC_EMB_SDA21 +- -- : BFD_RELOC_PPC_EMB_MRKREF +- -- : BFD_RELOC_PPC_EMB_RELSEC16 +- -- : BFD_RELOC_PPC_EMB_RELST_LO +- -- : BFD_RELOC_PPC_EMB_RELST_HI +- -- : BFD_RELOC_PPC_EMB_RELST_HA +- -- : BFD_RELOC_PPC_EMB_BIT_FLD +- -- : BFD_RELOC_PPC_EMB_RELSDA +- -- : BFD_RELOC_PPC_VLE_REL8 +- -- : BFD_RELOC_PPC_VLE_REL15 +- -- : BFD_RELOC_PPC_VLE_REL24 +- -- : BFD_RELOC_PPC_VLE_LO16A +- -- : BFD_RELOC_PPC_VLE_LO16D +- -- : BFD_RELOC_PPC_VLE_HI16A +- -- : BFD_RELOC_PPC_VLE_HI16D +- -- : BFD_RELOC_PPC_VLE_HA16A +- -- : BFD_RELOC_PPC_VLE_HA16D +- -- : BFD_RELOC_PPC_VLE_SDA21 +- -- : BFD_RELOC_PPC_VLE_SDA21_LO +- -- : BFD_RELOC_PPC_VLE_SDAREL_LO16A +- -- : BFD_RELOC_PPC_VLE_SDAREL_LO16D +- -- : BFD_RELOC_PPC_VLE_SDAREL_HI16A +- -- : BFD_RELOC_PPC_VLE_SDAREL_HI16D +- -- : BFD_RELOC_PPC_VLE_SDAREL_HA16A +- -- : BFD_RELOC_PPC_VLE_SDAREL_HA16D +- -- : BFD_RELOC_PPC64_HIGHER +- -- : BFD_RELOC_PPC64_HIGHER_S +- -- : BFD_RELOC_PPC64_HIGHEST +- -- : BFD_RELOC_PPC64_HIGHEST_S +- -- : BFD_RELOC_PPC64_TOC16_LO +- -- : BFD_RELOC_PPC64_TOC16_HI +- -- : BFD_RELOC_PPC64_TOC16_HA +- -- : BFD_RELOC_PPC64_TOC +- -- : BFD_RELOC_PPC64_PLTGOT16 +- -- : BFD_RELOC_PPC64_PLTGOT16_LO +- -- : BFD_RELOC_PPC64_PLTGOT16_HI +- -- : BFD_RELOC_PPC64_PLTGOT16_HA +- -- : BFD_RELOC_PPC64_ADDR16_DS +- -- : BFD_RELOC_PPC64_ADDR16_LO_DS +- -- : BFD_RELOC_PPC64_GOT16_DS +- -- : BFD_RELOC_PPC64_GOT16_LO_DS +- -- : BFD_RELOC_PPC64_PLT16_LO_DS +- -- : BFD_RELOC_PPC64_SECTOFF_DS +- -- : BFD_RELOC_PPC64_SECTOFF_LO_DS +- -- : BFD_RELOC_PPC64_TOC16_DS +- -- : BFD_RELOC_PPC64_TOC16_LO_DS +- -- : BFD_RELOC_PPC64_PLTGOT16_DS +- -- : BFD_RELOC_PPC64_PLTGOT16_LO_DS +- -- : BFD_RELOC_PPC64_ADDR16_HIGH +- -- : BFD_RELOC_PPC64_ADDR16_HIGHA +- Power(rs6000) and PowerPC relocations. +- +- -- : BFD_RELOC_PPC_TLS +- -- : BFD_RELOC_PPC_TLSGD +- -- : BFD_RELOC_PPC_TLSLD +- -- : BFD_RELOC_PPC_DTPMOD +- -- : BFD_RELOC_PPC_TPREL16 +- -- : BFD_RELOC_PPC_TPREL16_LO +- -- : BFD_RELOC_PPC_TPREL16_HI +- -- : BFD_RELOC_PPC_TPREL16_HA +- -- : BFD_RELOC_PPC_TPREL +- -- : BFD_RELOC_PPC_DTPREL16 +- -- : BFD_RELOC_PPC_DTPREL16_LO +- -- : BFD_RELOC_PPC_DTPREL16_HI +- -- : BFD_RELOC_PPC_DTPREL16_HA +- -- : BFD_RELOC_PPC_DTPREL +- -- : BFD_RELOC_PPC_GOT_TLSGD16 +- -- : BFD_RELOC_PPC_GOT_TLSGD16_LO +- -- : BFD_RELOC_PPC_GOT_TLSGD16_HI +- -- : BFD_RELOC_PPC_GOT_TLSGD16_HA +- -- : BFD_RELOC_PPC_GOT_TLSLD16 +- -- : BFD_RELOC_PPC_GOT_TLSLD16_LO +- -- : BFD_RELOC_PPC_GOT_TLSLD16_HI +- -- : BFD_RELOC_PPC_GOT_TLSLD16_HA +- -- : BFD_RELOC_PPC_GOT_TPREL16 +- -- : BFD_RELOC_PPC_GOT_TPREL16_LO +- -- : BFD_RELOC_PPC_GOT_TPREL16_HI +- -- : BFD_RELOC_PPC_GOT_TPREL16_HA +- -- : BFD_RELOC_PPC_GOT_DTPREL16 +- -- : BFD_RELOC_PPC_GOT_DTPREL16_LO +- -- : BFD_RELOC_PPC_GOT_DTPREL16_HI +- -- : BFD_RELOC_PPC_GOT_DTPREL16_HA +- -- : BFD_RELOC_PPC64_TPREL16_DS +- -- : BFD_RELOC_PPC64_TPREL16_LO_DS +- -- : BFD_RELOC_PPC64_TPREL16_HIGHER +- -- : BFD_RELOC_PPC64_TPREL16_HIGHERA +- -- : BFD_RELOC_PPC64_TPREL16_HIGHEST +- -- : BFD_RELOC_PPC64_TPREL16_HIGHESTA +- -- : BFD_RELOC_PPC64_DTPREL16_DS +- -- : BFD_RELOC_PPC64_DTPREL16_LO_DS +- -- : BFD_RELOC_PPC64_DTPREL16_HIGHER +- -- : BFD_RELOC_PPC64_DTPREL16_HIGHERA +- -- : BFD_RELOC_PPC64_DTPREL16_HIGHEST +- -- : BFD_RELOC_PPC64_DTPREL16_HIGHESTA +- -- : BFD_RELOC_PPC64_TPREL16_HIGH +- -- : BFD_RELOC_PPC64_TPREL16_HIGHA +- -- : BFD_RELOC_PPC64_DTPREL16_HIGH +- -- : BFD_RELOC_PPC64_DTPREL16_HIGHA +- PowerPC and PowerPC64 thread-local storage relocations. +- +- -- : BFD_RELOC_I370_D12 +- IBM 370/390 relocations +- +- -- : BFD_RELOC_CTOR +- The type of reloc used to build a constructor table - at the moment +- probably a 32 bit wide absolute relocation, but the target can +- choose. It generally does map to one of the other relocation +- types. +- +- -- : BFD_RELOC_ARM_PCREL_BRANCH +- ARM 26 bit pc-relative branch. The lowest two bits must be zero +- and are not stored in the instruction. +- +- -- : BFD_RELOC_ARM_PCREL_BLX +- ARM 26 bit pc-relative branch. The lowest bit must be zero and is +- not stored in the instruction. The 2nd lowest bit comes from a 1 +- bit field in the instruction. +- +- -- : BFD_RELOC_THUMB_PCREL_BLX +- Thumb 22 bit pc-relative branch. The lowest bit must be zero and +- is not stored in the instruction. The 2nd lowest bit comes from a +- 1 bit field in the instruction. +- +- -- : BFD_RELOC_ARM_PCREL_CALL +- ARM 26-bit pc-relative branch for an unconditional BL or BLX +- instruction. +- +- -- : BFD_RELOC_ARM_PCREL_JUMP +- ARM 26-bit pc-relative branch for B or conditional BL instruction. +- +- -- : BFD_RELOC_THUMB_PCREL_BRANCH7 +- -- : BFD_RELOC_THUMB_PCREL_BRANCH9 +- -- : BFD_RELOC_THUMB_PCREL_BRANCH12 +- -- : BFD_RELOC_THUMB_PCREL_BRANCH20 +- -- : BFD_RELOC_THUMB_PCREL_BRANCH23 +- -- : BFD_RELOC_THUMB_PCREL_BRANCH25 +- Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. The +- lowest bit must be zero and is not stored in the instruction. +- Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an +- "nn" one smaller in all cases. Note further that BRANCH23 +- corresponds to R_ARM_THM_CALL. +- +- -- : BFD_RELOC_ARM_OFFSET_IMM +- 12-bit immediate offset, used in ARM-format ldr and str +- instructions. +- +- -- : BFD_RELOC_ARM_THUMB_OFFSET +- 5-bit immediate offset, used in Thumb-format ldr and str +- instructions. +- +- -- : BFD_RELOC_ARM_TARGET1 +- Pc-relative or absolute relocation depending on target. Used for +- entries in .init_array sections. +- +- -- : BFD_RELOC_ARM_ROSEGREL32 +- Read-only segment base relative address. +- +- -- : BFD_RELOC_ARM_SBREL32 +- Data segment base relative address. +- +- -- : BFD_RELOC_ARM_TARGET2 +- This reloc is used for references to RTTI data from exception +- handling tables. The actual definition depends on the target. It +- may be a pc-relative or some form of GOT-indirect relocation. +- +- -- : BFD_RELOC_ARM_PREL31 +- 31-bit PC relative address. +- +- -- : BFD_RELOC_ARM_MOVW +- -- : BFD_RELOC_ARM_MOVT +- -- : BFD_RELOC_ARM_MOVW_PCREL +- -- : BFD_RELOC_ARM_MOVT_PCREL +- -- : BFD_RELOC_ARM_THUMB_MOVW +- -- : BFD_RELOC_ARM_THUMB_MOVT +- -- : BFD_RELOC_ARM_THUMB_MOVW_PCREL +- -- : BFD_RELOC_ARM_THUMB_MOVT_PCREL +- Low and High halfword relocations for MOVW and MOVT instructions. +- +- -- : BFD_RELOC_ARM_JUMP_SLOT +- -- : BFD_RELOC_ARM_GLOB_DAT +- -- : BFD_RELOC_ARM_GOT32 +- -- : BFD_RELOC_ARM_PLT32 +- -- : BFD_RELOC_ARM_RELATIVE +- -- : BFD_RELOC_ARM_GOTOFF +- -- : BFD_RELOC_ARM_GOTPC +- -- : BFD_RELOC_ARM_GOT_PREL +- Relocations for setting up GOTs and PLTs for shared libraries. +- +- -- : BFD_RELOC_ARM_TLS_GD32 +- -- : BFD_RELOC_ARM_TLS_LDO32 +- -- : BFD_RELOC_ARM_TLS_LDM32 +- -- : BFD_RELOC_ARM_TLS_DTPOFF32 +- -- : BFD_RELOC_ARM_TLS_DTPMOD32 +- -- : BFD_RELOC_ARM_TLS_TPOFF32 +- -- : BFD_RELOC_ARM_TLS_IE32 +- -- : BFD_RELOC_ARM_TLS_LE32 +- -- : BFD_RELOC_ARM_TLS_GOTDESC +- -- : BFD_RELOC_ARM_TLS_CALL +- -- : BFD_RELOC_ARM_THM_TLS_CALL +- -- : BFD_RELOC_ARM_TLS_DESCSEQ +- -- : BFD_RELOC_ARM_THM_TLS_DESCSEQ +- -- : BFD_RELOC_ARM_TLS_DESC +- ARM thread-local storage relocations. +- +- -- : BFD_RELOC_ARM_ALU_PC_G0_NC +- -- : BFD_RELOC_ARM_ALU_PC_G0 +- -- : BFD_RELOC_ARM_ALU_PC_G1_NC +- -- : BFD_RELOC_ARM_ALU_PC_G1 +- -- : BFD_RELOC_ARM_ALU_PC_G2 +- -- : BFD_RELOC_ARM_LDR_PC_G0 +- -- : BFD_RELOC_ARM_LDR_PC_G1 +- -- : BFD_RELOC_ARM_LDR_PC_G2 +- -- : BFD_RELOC_ARM_LDRS_PC_G0 +- -- : BFD_RELOC_ARM_LDRS_PC_G1 +- -- : BFD_RELOC_ARM_LDRS_PC_G2 +- -- : BFD_RELOC_ARM_LDC_PC_G0 +- -- : BFD_RELOC_ARM_LDC_PC_G1 +- -- : BFD_RELOC_ARM_LDC_PC_G2 +- -- : BFD_RELOC_ARM_ALU_SB_G0_NC +- -- : BFD_RELOC_ARM_ALU_SB_G0 +- -- : BFD_RELOC_ARM_ALU_SB_G1_NC +- -- : BFD_RELOC_ARM_ALU_SB_G1 +- -- : BFD_RELOC_ARM_ALU_SB_G2 +- -- : BFD_RELOC_ARM_LDR_SB_G0 +- -- : BFD_RELOC_ARM_LDR_SB_G1 +- -- : BFD_RELOC_ARM_LDR_SB_G2 +- -- : BFD_RELOC_ARM_LDRS_SB_G0 +- -- : BFD_RELOC_ARM_LDRS_SB_G1 +- -- : BFD_RELOC_ARM_LDRS_SB_G2 +- -- : BFD_RELOC_ARM_LDC_SB_G0 +- -- : BFD_RELOC_ARM_LDC_SB_G1 +- -- : BFD_RELOC_ARM_LDC_SB_G2 +- ARM group relocations. +- +- -- : BFD_RELOC_ARM_V4BX +- Annotation of BX instructions. +- +- -- : BFD_RELOC_ARM_IRELATIVE +- ARM support for STT_GNU_IFUNC. +- +- -- : BFD_RELOC_ARM_IMMEDIATE +- -- : BFD_RELOC_ARM_ADRL_IMMEDIATE +- -- : BFD_RELOC_ARM_T32_IMMEDIATE +- -- : BFD_RELOC_ARM_T32_ADD_IMM +- -- : BFD_RELOC_ARM_T32_IMM12 +- -- : BFD_RELOC_ARM_T32_ADD_PC12 +- -- : BFD_RELOC_ARM_SHIFT_IMM +- -- : BFD_RELOC_ARM_SMC +- -- : BFD_RELOC_ARM_HVC +- -- : BFD_RELOC_ARM_SWI +- -- : BFD_RELOC_ARM_MULTI +- -- : BFD_RELOC_ARM_CP_OFF_IMM +- -- : BFD_RELOC_ARM_CP_OFF_IMM_S2 +- -- : BFD_RELOC_ARM_T32_CP_OFF_IMM +- -- : BFD_RELOC_ARM_T32_CP_OFF_IMM_S2 +- -- : BFD_RELOC_ARM_ADR_IMM +- -- : BFD_RELOC_ARM_LDR_IMM +- -- : BFD_RELOC_ARM_LITERAL +- -- : BFD_RELOC_ARM_IN_POOL +- -- : BFD_RELOC_ARM_OFFSET_IMM8 +- -- : BFD_RELOC_ARM_T32_OFFSET_U8 +- -- : BFD_RELOC_ARM_T32_OFFSET_IMM +- -- : BFD_RELOC_ARM_HWLITERAL +- -- : BFD_RELOC_ARM_THUMB_ADD +- -- : BFD_RELOC_ARM_THUMB_IMM +- -- : BFD_RELOC_ARM_THUMB_SHIFT +- These relocs are only used within the ARM assembler. They are not +- (at present) written to any object files. +- +- -- : BFD_RELOC_SH_PCDISP8BY2 +- -- : BFD_RELOC_SH_PCDISP12BY2 +- -- : BFD_RELOC_SH_IMM3 +- -- : BFD_RELOC_SH_IMM3U +- -- : BFD_RELOC_SH_DISP12 +- -- : BFD_RELOC_SH_DISP12BY2 +- -- : BFD_RELOC_SH_DISP12BY4 +- -- : BFD_RELOC_SH_DISP12BY8 +- -- : BFD_RELOC_SH_DISP20 +- -- : BFD_RELOC_SH_DISP20BY8 +- -- : BFD_RELOC_SH_IMM4 +- -- : BFD_RELOC_SH_IMM4BY2 +- -- : BFD_RELOC_SH_IMM4BY4 +- -- : BFD_RELOC_SH_IMM8 +- -- : BFD_RELOC_SH_IMM8BY2 +- -- : BFD_RELOC_SH_IMM8BY4 +- -- : BFD_RELOC_SH_PCRELIMM8BY2 +- -- : BFD_RELOC_SH_PCRELIMM8BY4 +- -- : BFD_RELOC_SH_SWITCH16 +- -- : BFD_RELOC_SH_SWITCH32 +- -- : BFD_RELOC_SH_USES +- -- : BFD_RELOC_SH_COUNT +- -- : BFD_RELOC_SH_ALIGN +- -- : BFD_RELOC_SH_CODE +- -- : BFD_RELOC_SH_DATA +- -- : BFD_RELOC_SH_LABEL +- -- : BFD_RELOC_SH_LOOP_START +- -- : BFD_RELOC_SH_LOOP_END +- -- : BFD_RELOC_SH_COPY +- -- : BFD_RELOC_SH_GLOB_DAT +- -- : BFD_RELOC_SH_JMP_SLOT +- -- : BFD_RELOC_SH_RELATIVE +- -- : BFD_RELOC_SH_GOTPC +- -- : BFD_RELOC_SH_GOT_LOW16 +- -- : BFD_RELOC_SH_GOT_MEDLOW16 +- -- : BFD_RELOC_SH_GOT_MEDHI16 +- -- : BFD_RELOC_SH_GOT_HI16 +- -- : BFD_RELOC_SH_GOTPLT_LOW16 +- -- : BFD_RELOC_SH_GOTPLT_MEDLOW16 +- -- : BFD_RELOC_SH_GOTPLT_MEDHI16 +- -- : BFD_RELOC_SH_GOTPLT_HI16 +- -- : BFD_RELOC_SH_PLT_LOW16 +- -- : BFD_RELOC_SH_PLT_MEDLOW16 +- -- : BFD_RELOC_SH_PLT_MEDHI16 +- -- : BFD_RELOC_SH_PLT_HI16 +- -- : BFD_RELOC_SH_GOTOFF_LOW16 +- -- : BFD_RELOC_SH_GOTOFF_MEDLOW16 +- -- : BFD_RELOC_SH_GOTOFF_MEDHI16 +- -- : BFD_RELOC_SH_GOTOFF_HI16 +- -- : BFD_RELOC_SH_GOTPC_LOW16 +- -- : BFD_RELOC_SH_GOTPC_MEDLOW16 +- -- : BFD_RELOC_SH_GOTPC_MEDHI16 +- -- : BFD_RELOC_SH_GOTPC_HI16 +- -- : BFD_RELOC_SH_COPY64 +- -- : BFD_RELOC_SH_GLOB_DAT64 +- -- : BFD_RELOC_SH_JMP_SLOT64 +- -- : BFD_RELOC_SH_RELATIVE64 +- -- : BFD_RELOC_SH_GOT10BY4 +- -- : BFD_RELOC_SH_GOT10BY8 +- -- : BFD_RELOC_SH_GOTPLT10BY4 +- -- : BFD_RELOC_SH_GOTPLT10BY8 +- -- : BFD_RELOC_SH_GOTPLT32 +- -- : BFD_RELOC_SH_SHMEDIA_CODE +- -- : BFD_RELOC_SH_IMMU5 +- -- : BFD_RELOC_SH_IMMS6 +- -- : BFD_RELOC_SH_IMMS6BY32 +- -- : BFD_RELOC_SH_IMMU6 +- -- : BFD_RELOC_SH_IMMS10 +- -- : BFD_RELOC_SH_IMMS10BY2 +- -- : BFD_RELOC_SH_IMMS10BY4 +- -- : BFD_RELOC_SH_IMMS10BY8 +- -- : BFD_RELOC_SH_IMMS16 +- -- : BFD_RELOC_SH_IMMU16 +- -- : BFD_RELOC_SH_IMM_LOW16 +- -- : BFD_RELOC_SH_IMM_LOW16_PCREL +- -- : BFD_RELOC_SH_IMM_MEDLOW16 +- -- : BFD_RELOC_SH_IMM_MEDLOW16_PCREL +- -- : BFD_RELOC_SH_IMM_MEDHI16 +- -- : BFD_RELOC_SH_IMM_MEDHI16_PCREL +- -- : BFD_RELOC_SH_IMM_HI16 +- -- : BFD_RELOC_SH_IMM_HI16_PCREL +- -- : BFD_RELOC_SH_PT_16 +- -- : BFD_RELOC_SH_TLS_GD_32 +- -- : BFD_RELOC_SH_TLS_LD_32 +- -- : BFD_RELOC_SH_TLS_LDO_32 +- -- : BFD_RELOC_SH_TLS_IE_32 +- -- : BFD_RELOC_SH_TLS_LE_32 +- -- : BFD_RELOC_SH_TLS_DTPMOD32 +- -- : BFD_RELOC_SH_TLS_DTPOFF32 +- -- : BFD_RELOC_SH_TLS_TPOFF32 +- -- : BFD_RELOC_SH_GOT20 +- -- : BFD_RELOC_SH_GOTOFF20 +- -- : BFD_RELOC_SH_GOTFUNCDESC +- -- : BFD_RELOC_SH_GOTFUNCDESC20 +- -- : BFD_RELOC_SH_GOTOFFFUNCDESC +- -- : BFD_RELOC_SH_GOTOFFFUNCDESC20 +- -- : BFD_RELOC_SH_FUNCDESC +- Renesas / SuperH SH relocs. Not all of these appear in object +- files. +- +- -- : BFD_RELOC_ARC_B22_PCREL +- ARC Cores relocs. ARC 22 bit pc-relative branch. The lowest two +- bits must be zero and are not stored in the instruction. The high +- 20 bits are installed in bits 26 through 7 of the instruction. +- +- -- : BFD_RELOC_ARC_B26 +- ARC 26 bit absolute branch. The lowest two bits must be zero and +- are not stored in the instruction. The high 24 bits are installed +- in bits 23 through 0. +- +- -- : BFD_RELOC_BFIN_16_IMM +- ADI Blackfin 16 bit immediate absolute reloc. +- +- -- : BFD_RELOC_BFIN_16_HIGH +- ADI Blackfin 16 bit immediate absolute reloc higher 16 bits. +- +- -- : BFD_RELOC_BFIN_4_PCREL +- ADI Blackfin 'a' part of LSETUP. +- +- -- : BFD_RELOC_BFIN_5_PCREL +- ADI Blackfin. +- +- -- : BFD_RELOC_BFIN_16_LOW +- ADI Blackfin 16 bit immediate absolute reloc lower 16 bits. +- +- -- : BFD_RELOC_BFIN_10_PCREL +- ADI Blackfin. +- +- -- : BFD_RELOC_BFIN_11_PCREL +- ADI Blackfin 'b' part of LSETUP. +- +- -- : BFD_RELOC_BFIN_12_PCREL_JUMP +- ADI Blackfin. +- +- -- : BFD_RELOC_BFIN_12_PCREL_JUMP_S +- ADI Blackfin Short jump, pcrel. +- +- -- : BFD_RELOC_BFIN_24_PCREL_CALL_X +- ADI Blackfin Call.x not implemented. +- +- -- : BFD_RELOC_BFIN_24_PCREL_JUMP_L +- ADI Blackfin Long Jump pcrel. +- +- -- : BFD_RELOC_BFIN_GOT17M4 +- -- : BFD_RELOC_BFIN_GOTHI +- -- : BFD_RELOC_BFIN_GOTLO +- -- : BFD_RELOC_BFIN_FUNCDESC +- -- : BFD_RELOC_BFIN_FUNCDESC_GOT17M4 +- -- : BFD_RELOC_BFIN_FUNCDESC_GOTHI +- -- : BFD_RELOC_BFIN_FUNCDESC_GOTLO +- -- : BFD_RELOC_BFIN_FUNCDESC_VALUE +- -- : BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4 +- -- : BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI +- -- : BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO +- -- : BFD_RELOC_BFIN_GOTOFF17M4 +- -- : BFD_RELOC_BFIN_GOTOFFHI +- -- : BFD_RELOC_BFIN_GOTOFFLO +- ADI Blackfin FD-PIC relocations. +- +- -- : BFD_RELOC_BFIN_GOT +- ADI Blackfin GOT relocation. +- +- -- : BFD_RELOC_BFIN_PLTPC +- ADI Blackfin PLTPC relocation. +- +- -- : BFD_ARELOC_BFIN_PUSH +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_CONST +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_ADD +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_SUB +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_MULT +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_DIV +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_MOD +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_LSHIFT +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_RSHIFT +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_AND +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_OR +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_XOR +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_LAND +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_LOR +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_LEN +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_NEG +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_COMP +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_PAGE +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_HWPAGE +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_ARELOC_BFIN_ADDR +- ADI Blackfin arithmetic relocation. +- +- -- : BFD_RELOC_D10V_10_PCREL_R +- Mitsubishi D10V relocs. This is a 10-bit reloc with the right 2 +- bits assumed to be 0. +- +- -- : BFD_RELOC_D10V_10_PCREL_L +- Mitsubishi D10V relocs. This is a 10-bit reloc with the right 2 +- bits assumed to be 0. This is the same as the previous reloc +- except it is in the left container, i.e., shifted left 15 bits. +- +- -- : BFD_RELOC_D10V_18 +- This is an 18-bit reloc with the right 2 bits assumed to be 0. +- +- -- : BFD_RELOC_D10V_18_PCREL +- This is an 18-bit reloc with the right 2 bits assumed to be 0. +- +- -- : BFD_RELOC_D30V_6 +- Mitsubishi D30V relocs. This is a 6-bit absolute reloc. +- +- -- : BFD_RELOC_D30V_9_PCREL +- This is a 6-bit pc-relative reloc with the right 3 bits assumed to +- be 0. +- +- -- : BFD_RELOC_D30V_9_PCREL_R +- This is a 6-bit pc-relative reloc with the right 3 bits assumed to +- be 0. Same as the previous reloc but on the right side of the +- container. +- +- -- : BFD_RELOC_D30V_15 +- This is a 12-bit absolute reloc with the right 3 bitsassumed to be +- 0. +- +- -- : BFD_RELOC_D30V_15_PCREL +- This is a 12-bit pc-relative reloc with the right 3 bits assumed +- to be 0. +- +- -- : BFD_RELOC_D30V_15_PCREL_R +- This is a 12-bit pc-relative reloc with the right 3 bits assumed +- to be 0. Same as the previous reloc but on the right side of the +- container. +- +- -- : BFD_RELOC_D30V_21 +- This is an 18-bit absolute reloc with the right 3 bits assumed to +- be 0. +- +- -- : BFD_RELOC_D30V_21_PCREL +- This is an 18-bit pc-relative reloc with the right 3 bits assumed +- to be 0. +- +- -- : BFD_RELOC_D30V_21_PCREL_R +- This is an 18-bit pc-relative reloc with the right 3 bits assumed +- to be 0. Same as the previous reloc but on the right side of the +- container. +- +- -- : BFD_RELOC_D30V_32 +- This is a 32-bit absolute reloc. +- +- -- : BFD_RELOC_D30V_32_PCREL +- This is a 32-bit pc-relative reloc. +- +- -- : BFD_RELOC_DLX_HI16_S +- DLX relocs +- +- -- : BFD_RELOC_DLX_LO16 +- DLX relocs +- +- -- : BFD_RELOC_DLX_JMP26 +- DLX relocs +- +- -- : BFD_RELOC_M32C_HI8 +- -- : BFD_RELOC_M32C_RL_JUMP +- -- : BFD_RELOC_M32C_RL_1ADDR +- -- : BFD_RELOC_M32C_RL_2ADDR +- Renesas M16C/M32C Relocations. +- +- -- : BFD_RELOC_M32R_24 +- Renesas M32R (formerly Mitsubishi M32R) relocs. This is a 24 bit +- absolute address. +- +- -- : BFD_RELOC_M32R_10_PCREL +- This is a 10-bit pc-relative reloc with the right 2 bits assumed +- to be 0. +- +- -- : BFD_RELOC_M32R_18_PCREL +- This is an 18-bit reloc with the right 2 bits assumed to be 0. +- +- -- : BFD_RELOC_M32R_26_PCREL +- This is a 26-bit reloc with the right 2 bits assumed to be 0. +- +- -- : BFD_RELOC_M32R_HI16_ULO +- This is a 16-bit reloc containing the high 16 bits of an address +- used when the lower 16 bits are treated as unsigned. +- +- -- : BFD_RELOC_M32R_HI16_SLO +- This is a 16-bit reloc containing the high 16 bits of an address +- used when the lower 16 bits are treated as signed. +- +- -- : BFD_RELOC_M32R_LO16 +- This is a 16-bit reloc containing the lower 16 bits of an address. +- +- -- : BFD_RELOC_M32R_SDA16 +- This is a 16-bit reloc containing the small data area offset for +- use in add3, load, and store instructions. +- +- -- : BFD_RELOC_M32R_GOT24 +- -- : BFD_RELOC_M32R_26_PLTREL +- -- : BFD_RELOC_M32R_COPY +- -- : BFD_RELOC_M32R_GLOB_DAT +- -- : BFD_RELOC_M32R_JMP_SLOT +- -- : BFD_RELOC_M32R_RELATIVE +- -- : BFD_RELOC_M32R_GOTOFF +- -- : BFD_RELOC_M32R_GOTOFF_HI_ULO +- -- : BFD_RELOC_M32R_GOTOFF_HI_SLO +- -- : BFD_RELOC_M32R_GOTOFF_LO +- -- : BFD_RELOC_M32R_GOTPC24 +- -- : BFD_RELOC_M32R_GOT16_HI_ULO +- -- : BFD_RELOC_M32R_GOT16_HI_SLO +- -- : BFD_RELOC_M32R_GOT16_LO +- -- : BFD_RELOC_M32R_GOTPC_HI_ULO +- -- : BFD_RELOC_M32R_GOTPC_HI_SLO +- -- : BFD_RELOC_M32R_GOTPC_LO +- For PIC. +- +- -- : BFD_RELOC_V850_9_PCREL +- This is a 9-bit reloc +- +- -- : BFD_RELOC_V850_22_PCREL +- This is a 22-bit reloc +- +- -- : BFD_RELOC_V850_SDA_16_16_OFFSET +- This is a 16 bit offset from the short data area pointer. +- +- -- : BFD_RELOC_V850_SDA_15_16_OFFSET +- This is a 16 bit offset (of which only 15 bits are used) from the +- short data area pointer. +- +- -- : BFD_RELOC_V850_ZDA_16_16_OFFSET +- This is a 16 bit offset from the zero data area pointer. +- +- -- : BFD_RELOC_V850_ZDA_15_16_OFFSET +- This is a 16 bit offset (of which only 15 bits are used) from the +- zero data area pointer. +- +- -- : BFD_RELOC_V850_TDA_6_8_OFFSET +- This is an 8 bit offset (of which only 6 bits are used) from the +- tiny data area pointer. +- +- -- : BFD_RELOC_V850_TDA_7_8_OFFSET +- This is an 8bit offset (of which only 7 bits are used) from the +- tiny data area pointer. +- +- -- : BFD_RELOC_V850_TDA_7_7_OFFSET +- This is a 7 bit offset from the tiny data area pointer. +- +- -- : BFD_RELOC_V850_TDA_16_16_OFFSET +- This is a 16 bit offset from the tiny data area pointer. +- +- -- : BFD_RELOC_V850_TDA_4_5_OFFSET +- This is a 5 bit offset (of which only 4 bits are used) from the +- tiny data area pointer. +- +- -- : BFD_RELOC_V850_TDA_4_4_OFFSET +- This is a 4 bit offset from the tiny data area pointer. +- +- -- : BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET +- This is a 16 bit offset from the short data area pointer, with the +- bits placed non-contiguously in the instruction. +- +- -- : BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET +- This is a 16 bit offset from the zero data area pointer, with the +- bits placed non-contiguously in the instruction. +- +- -- : BFD_RELOC_V850_CALLT_6_7_OFFSET +- This is a 6 bit offset from the call table base pointer. +- +- -- : BFD_RELOC_V850_CALLT_16_16_OFFSET +- This is a 16 bit offset from the call table base pointer. +- +- -- : BFD_RELOC_V850_LONGCALL +- Used for relaxing indirect function calls. +- +- -- : BFD_RELOC_V850_LONGJUMP +- Used for relaxing indirect jumps. +- +- -- : BFD_RELOC_V850_ALIGN +- Used to maintain alignment whilst relaxing. +- +- -- : BFD_RELOC_V850_LO16_SPLIT_OFFSET +- This is a variation of BFD_RELOC_LO16 that can be used in v850e +- ld.bu instructions. +- +- -- : BFD_RELOC_V850_16_PCREL +- This is a 16-bit reloc. +- +- -- : BFD_RELOC_V850_17_PCREL +- This is a 17-bit reloc. +- +- -- : BFD_RELOC_V850_23 +- This is a 23-bit reloc. +- +- -- : BFD_RELOC_V850_32_PCREL +- This is a 32-bit reloc. +- +- -- : BFD_RELOC_V850_32_ABS +- This is a 32-bit reloc. +- +- -- : BFD_RELOC_V850_16_SPLIT_OFFSET +- This is a 16-bit reloc. +- +- -- : BFD_RELOC_V850_16_S1 +- This is a 16-bit reloc. +- +- -- : BFD_RELOC_V850_LO16_S1 +- Low 16 bits. 16 bit shifted by 1. +- +- -- : BFD_RELOC_V850_CALLT_15_16_OFFSET +- This is a 16 bit offset from the call table base pointer. +- +- -- : BFD_RELOC_V850_32_GOTPCREL +- DSO relocations. +- +- -- : BFD_RELOC_V850_16_GOT +- DSO relocations. +- +- -- : BFD_RELOC_V850_32_GOT +- DSO relocations. +- +- -- : BFD_RELOC_V850_22_PLT_PCREL +- DSO relocations. +- +- -- : BFD_RELOC_V850_32_PLT_PCREL +- DSO relocations. +- +- -- : BFD_RELOC_V850_COPY +- DSO relocations. +- +- -- : BFD_RELOC_V850_GLOB_DAT +- DSO relocations. +- +- -- : BFD_RELOC_V850_JMP_SLOT +- DSO relocations. +- +- -- : BFD_RELOC_V850_RELATIVE +- DSO relocations. +- +- -- : BFD_RELOC_V850_16_GOTOFF +- DSO relocations. +- +- -- : BFD_RELOC_V850_32_GOTOFF +- DSO relocations. +- +- -- : BFD_RELOC_V850_CODE +- start code. +- +- -- : BFD_RELOC_V850_DATA +- start data in text. +- +- -- : BFD_RELOC_TIC30_LDP +- This is a 8bit DP reloc for the tms320c30, where the most +- significant 8 bits of a 24 bit word are placed into the least +- significant 8 bits of the opcode. +- +- -- : BFD_RELOC_TIC54X_PARTLS7 +- This is a 7bit reloc for the tms320c54x, where the least +- significant 7 bits of a 16 bit word are placed into the least +- significant 7 bits of the opcode. +- +- -- : BFD_RELOC_TIC54X_PARTMS9 +- This is a 9bit DP reloc for the tms320c54x, where the most +- significant 9 bits of a 16 bit word are placed into the least +- significant 9 bits of the opcode. +- +- -- : BFD_RELOC_TIC54X_23 +- This is an extended address 23-bit reloc for the tms320c54x. +- +- -- : BFD_RELOC_TIC54X_16_OF_23 +- This is a 16-bit reloc for the tms320c54x, where the least +- significant 16 bits of a 23-bit extended address are placed into +- the opcode. +- +- -- : BFD_RELOC_TIC54X_MS7_OF_23 +- This is a reloc for the tms320c54x, where the most significant 7 +- bits of a 23-bit extended address are placed into the opcode. +- +- -- : BFD_RELOC_C6000_PCR_S21 +- -- : BFD_RELOC_C6000_PCR_S12 +- -- : BFD_RELOC_C6000_PCR_S10 +- -- : BFD_RELOC_C6000_PCR_S7 +- -- : BFD_RELOC_C6000_ABS_S16 +- -- : BFD_RELOC_C6000_ABS_L16 +- -- : BFD_RELOC_C6000_ABS_H16 +- -- : BFD_RELOC_C6000_SBR_U15_B +- -- : BFD_RELOC_C6000_SBR_U15_H +- -- : BFD_RELOC_C6000_SBR_U15_W +- -- : BFD_RELOC_C6000_SBR_S16 +- -- : BFD_RELOC_C6000_SBR_L16_B +- -- : BFD_RELOC_C6000_SBR_L16_H +- -- : BFD_RELOC_C6000_SBR_L16_W +- -- : BFD_RELOC_C6000_SBR_H16_B +- -- : BFD_RELOC_C6000_SBR_H16_H +- -- : BFD_RELOC_C6000_SBR_H16_W +- -- : BFD_RELOC_C6000_SBR_GOT_U15_W +- -- : BFD_RELOC_C6000_SBR_GOT_L16_W +- -- : BFD_RELOC_C6000_SBR_GOT_H16_W +- -- : BFD_RELOC_C6000_DSBT_INDEX +- -- : BFD_RELOC_C6000_PREL31 +- -- : BFD_RELOC_C6000_COPY +- -- : BFD_RELOC_C6000_JUMP_SLOT +- -- : BFD_RELOC_C6000_EHTYPE +- -- : BFD_RELOC_C6000_PCR_H16 +- -- : BFD_RELOC_C6000_PCR_L16 +- -- : BFD_RELOC_C6000_ALIGN +- -- : BFD_RELOC_C6000_FPHEAD +- -- : BFD_RELOC_C6000_NOCMP +- TMS320C6000 relocations. +- +- -- : BFD_RELOC_FR30_48 +- This is a 48 bit reloc for the FR30 that stores 32 bits. +- +- -- : BFD_RELOC_FR30_20 +- This is a 32 bit reloc for the FR30 that stores 20 bits split up +- into two sections. +- +- -- : BFD_RELOC_FR30_6_IN_4 +- This is a 16 bit reloc for the FR30 that stores a 6 bit word +- offset in 4 bits. +- +- -- : BFD_RELOC_FR30_8_IN_8 +- This is a 16 bit reloc for the FR30 that stores an 8 bit byte +- offset into 8 bits. +- +- -- : BFD_RELOC_FR30_9_IN_8 +- This is a 16 bit reloc for the FR30 that stores a 9 bit short +- offset into 8 bits. +- +- -- : BFD_RELOC_FR30_10_IN_8 +- This is a 16 bit reloc for the FR30 that stores a 10 bit word +- offset into 8 bits. +- +- -- : BFD_RELOC_FR30_9_PCREL +- This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative +- short offset into 8 bits. +- +- -- : BFD_RELOC_FR30_12_PCREL +- This is a 16 bit reloc for the FR30 that stores a 12 bit pc +- relative short offset into 11 bits. +- +- -- : BFD_RELOC_MCORE_PCREL_IMM8BY4 +- -- : BFD_RELOC_MCORE_PCREL_IMM11BY2 +- -- : BFD_RELOC_MCORE_PCREL_IMM4BY2 +- -- : BFD_RELOC_MCORE_PCREL_32 +- -- : BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2 +- -- : BFD_RELOC_MCORE_RVA +- Motorola Mcore relocations. +- +- -- : BFD_RELOC_MEP_8 +- -- : BFD_RELOC_MEP_16 +- -- : BFD_RELOC_MEP_32 +- -- : BFD_RELOC_MEP_PCREL8A2 +- -- : BFD_RELOC_MEP_PCREL12A2 +- -- : BFD_RELOC_MEP_PCREL17A2 +- -- : BFD_RELOC_MEP_PCREL24A2 +- -- : BFD_RELOC_MEP_PCABS24A2 +- -- : BFD_RELOC_MEP_LOW16 +- -- : BFD_RELOC_MEP_HI16U +- -- : BFD_RELOC_MEP_HI16S +- -- : BFD_RELOC_MEP_GPREL +- -- : BFD_RELOC_MEP_TPREL +- -- : BFD_RELOC_MEP_TPREL7 +- -- : BFD_RELOC_MEP_TPREL7A2 +- -- : BFD_RELOC_MEP_TPREL7A4 +- -- : BFD_RELOC_MEP_UIMM24 +- -- : BFD_RELOC_MEP_ADDR24A4 +- -- : BFD_RELOC_MEP_GNU_VTINHERIT +- -- : BFD_RELOC_MEP_GNU_VTENTRY +- Toshiba Media Processor Relocations. +- +- -- : BFD_RELOC_METAG_HIADDR16 +- -- : BFD_RELOC_METAG_LOADDR16 +- -- : BFD_RELOC_METAG_RELBRANCH +- -- : BFD_RELOC_METAG_GETSETOFF +- -- : BFD_RELOC_METAG_HIOG +- -- : BFD_RELOC_METAG_LOOG +- -- : BFD_RELOC_METAG_REL8 +- -- : BFD_RELOC_METAG_REL16 +- -- : BFD_RELOC_METAG_HI16_GOTOFF +- -- : BFD_RELOC_METAG_LO16_GOTOFF +- -- : BFD_RELOC_METAG_GETSET_GOTOFF +- -- : BFD_RELOC_METAG_GETSET_GOT +- -- : BFD_RELOC_METAG_HI16_GOTPC +- -- : BFD_RELOC_METAG_LO16_GOTPC +- -- : BFD_RELOC_METAG_HI16_PLT +- -- : BFD_RELOC_METAG_LO16_PLT +- -- : BFD_RELOC_METAG_RELBRANCH_PLT +- -- : BFD_RELOC_METAG_GOTOFF +- -- : BFD_RELOC_METAG_PLT +- -- : BFD_RELOC_METAG_COPY +- -- : BFD_RELOC_METAG_JMP_SLOT +- -- : BFD_RELOC_METAG_RELATIVE +- -- : BFD_RELOC_METAG_GLOB_DAT +- -- : BFD_RELOC_METAG_TLS_GD +- -- : BFD_RELOC_METAG_TLS_LDM +- -- : BFD_RELOC_METAG_TLS_LDO_HI16 +- -- : BFD_RELOC_METAG_TLS_LDO_LO16 +- -- : BFD_RELOC_METAG_TLS_LDO +- -- : BFD_RELOC_METAG_TLS_IE +- -- : BFD_RELOC_METAG_TLS_IENONPIC +- -- : BFD_RELOC_METAG_TLS_IENONPIC_HI16 +- -- : BFD_RELOC_METAG_TLS_IENONPIC_LO16 +- -- : BFD_RELOC_METAG_TLS_TPOFF +- -- : BFD_RELOC_METAG_TLS_DTPMOD +- -- : BFD_RELOC_METAG_TLS_DTPOFF +- -- : BFD_RELOC_METAG_TLS_LE +- -- : BFD_RELOC_METAG_TLS_LE_HI16 +- -- : BFD_RELOC_METAG_TLS_LE_LO16 +- Imagination Technologies Meta relocations. +- +- -- : BFD_RELOC_MMIX_GETA +- -- : BFD_RELOC_MMIX_GETA_1 +- -- : BFD_RELOC_MMIX_GETA_2 +- -- : BFD_RELOC_MMIX_GETA_3 +- These are relocations for the GETA instruction. +- +- -- : BFD_RELOC_MMIX_CBRANCH +- -- : BFD_RELOC_MMIX_CBRANCH_J +- -- : BFD_RELOC_MMIX_CBRANCH_1 +- -- : BFD_RELOC_MMIX_CBRANCH_2 +- -- : BFD_RELOC_MMIX_CBRANCH_3 +- These are relocations for a conditional branch instruction. +- +- -- : BFD_RELOC_MMIX_PUSHJ +- -- : BFD_RELOC_MMIX_PUSHJ_1 +- -- : BFD_RELOC_MMIX_PUSHJ_2 +- -- : BFD_RELOC_MMIX_PUSHJ_3 +- -- : BFD_RELOC_MMIX_PUSHJ_STUBBABLE +- These are relocations for the PUSHJ instruction. +- +- -- : BFD_RELOC_MMIX_JMP +- -- : BFD_RELOC_MMIX_JMP_1 +- -- : BFD_RELOC_MMIX_JMP_2 +- -- : BFD_RELOC_MMIX_JMP_3 +- These are relocations for the JMP instruction. +- +- -- : BFD_RELOC_MMIX_ADDR19 +- This is a relocation for a relative address as in a GETA +- instruction or a branch. +- +- -- : BFD_RELOC_MMIX_ADDR27 +- This is a relocation for a relative address as in a JMP +- instruction. +- +- -- : BFD_RELOC_MMIX_REG_OR_BYTE +- This is a relocation for an instruction field that may be a general +- register or a value 0..255. +- +- -- : BFD_RELOC_MMIX_REG +- This is a relocation for an instruction field that may be a general +- register. +- +- -- : BFD_RELOC_MMIX_BASE_PLUS_OFFSET +- This is a relocation for two instruction fields holding a register +- and an offset, the equivalent of the relocation. +- +- -- : BFD_RELOC_MMIX_LOCAL +- This relocation is an assertion that the expression is not +- allocated as a global register. It does not modify contents. +- +- -- : BFD_RELOC_AVR_7_PCREL +- This is a 16 bit reloc for the AVR that stores 8 bit pc relative +- short offset into 7 bits. +- +- -- : BFD_RELOC_AVR_13_PCREL +- This is a 16 bit reloc for the AVR that stores 13 bit pc relative +- short offset into 12 bits. +- +- -- : BFD_RELOC_AVR_16_PM +- This is a 16 bit reloc for the AVR that stores 17 bit value +- (usually program memory address) into 16 bits. +- +- -- : BFD_RELOC_AVR_LO8_LDI +- This is a 16 bit reloc for the AVR that stores 8 bit value (usually +- data memory address) into 8 bit immediate value of LDI insn. +- +- -- : BFD_RELOC_AVR_HI8_LDI +- This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 +- bit of data memory address) into 8 bit immediate value of LDI insn. +- +- -- : BFD_RELOC_AVR_HH8_LDI +- This is a 16 bit reloc for the AVR that stores 8 bit value (most +- high 8 bit of program memory address) into 8 bit immediate value +- of LDI insn. +- +- -- : BFD_RELOC_AVR_MS8_LDI +- This is a 16 bit reloc for the AVR that stores 8 bit value (most +- high 8 bit of 32 bit value) into 8 bit immediate value of LDI insn. +- +- -- : BFD_RELOC_AVR_LO8_LDI_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (usually data memory address) into 8 bit immediate value of SUBI +- insn. +- +- -- : BFD_RELOC_AVR_HI8_LDI_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (high 8 bit of data memory address) into 8 bit immediate value of +- SUBI insn. +- +- -- : BFD_RELOC_AVR_HH8_LDI_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (most high 8 bit of program memory address) into 8 bit immediate +- value of LDI or SUBI insn. +- +- -- : BFD_RELOC_AVR_MS8_LDI_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (msb of 32 bit value) into 8 bit immediate value of LDI insn. +- +- -- : BFD_RELOC_AVR_LO8_LDI_PM +- This is a 16 bit reloc for the AVR that stores 8 bit value (usually +- command address) into 8 bit immediate value of LDI insn. +- +- -- : BFD_RELOC_AVR_LO8_LDI_GS +- This is a 16 bit reloc for the AVR that stores 8 bit value +- (command address) into 8 bit immediate value of LDI insn. If the +- address is beyond the 128k boundary, the linker inserts a jump +- stub for this reloc in the lower 128k. +- +- -- : BFD_RELOC_AVR_HI8_LDI_PM +- This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 +- bit of command address) into 8 bit immediate value of LDI insn. +- +- -- : BFD_RELOC_AVR_HI8_LDI_GS +- This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 +- bit of command address) into 8 bit immediate value of LDI insn. +- If the address is beyond the 128k boundary, the linker inserts a +- jump stub for this reloc below 128k. +- +- -- : BFD_RELOC_AVR_HH8_LDI_PM +- This is a 16 bit reloc for the AVR that stores 8 bit value (most +- high 8 bit of command address) into 8 bit immediate value of LDI +- insn. +- +- -- : BFD_RELOC_AVR_LO8_LDI_PM_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (usually command address) into 8 bit immediate value of SUBI insn. +- +- -- : BFD_RELOC_AVR_HI8_LDI_PM_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (high 8 bit of 16 bit command address) into 8 bit immediate value +- of SUBI insn. +- +- -- : BFD_RELOC_AVR_HH8_LDI_PM_NEG +- This is a 16 bit reloc for the AVR that stores negated 8 bit value +- (high 6 bit of 22 bit command address) into 8 bit immediate value +- of SUBI insn. +- +- -- : BFD_RELOC_AVR_CALL +- This is a 32 bit reloc for the AVR that stores 23 bit value into +- 22 bits. +- +- -- : BFD_RELOC_AVR_LDI +- This is a 16 bit reloc for the AVR that stores all needed bits for +- absolute addressing with ldi with overflow check to linktime +- +- -- : BFD_RELOC_AVR_6 +- This is a 6 bit reloc for the AVR that stores offset for ldd/std +- instructions +- +- -- : BFD_RELOC_AVR_6_ADIW +- This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw +- instructions +- +- -- : BFD_RELOC_AVR_8_LO +- This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol +- in .byte lo8(symbol) +- +- -- : BFD_RELOC_AVR_8_HI +- This is a 8 bit reloc for the AVR that stores bits 8..15 of a +- symbol in .byte hi8(symbol) +- +- -- : BFD_RELOC_AVR_8_HLO +- This is a 8 bit reloc for the AVR that stores bits 16..23 of a +- symbol in .byte hlo8(symbol) +- +- -- : BFD_RELOC_RL78_NEG8 +- -- : BFD_RELOC_RL78_NEG16 +- -- : BFD_RELOC_RL78_NEG24 +- -- : BFD_RELOC_RL78_NEG32 +- -- : BFD_RELOC_RL78_16_OP +- -- : BFD_RELOC_RL78_24_OP +- -- : BFD_RELOC_RL78_32_OP +- -- : BFD_RELOC_RL78_8U +- -- : BFD_RELOC_RL78_16U +- -- : BFD_RELOC_RL78_24U +- -- : BFD_RELOC_RL78_DIR3U_PCREL +- -- : BFD_RELOC_RL78_DIFF +- -- : BFD_RELOC_RL78_GPRELB +- -- : BFD_RELOC_RL78_GPRELW +- -- : BFD_RELOC_RL78_GPRELL +- -- : BFD_RELOC_RL78_SYM +- -- : BFD_RELOC_RL78_OP_SUBTRACT +- -- : BFD_RELOC_RL78_OP_NEG +- -- : BFD_RELOC_RL78_OP_AND +- -- : BFD_RELOC_RL78_OP_SHRA +- -- : BFD_RELOC_RL78_ABS8 +- -- : BFD_RELOC_RL78_ABS16 +- -- : BFD_RELOC_RL78_ABS16_REV +- -- : BFD_RELOC_RL78_ABS32 +- -- : BFD_RELOC_RL78_ABS32_REV +- -- : BFD_RELOC_RL78_ABS16U +- -- : BFD_RELOC_RL78_ABS16UW +- -- : BFD_RELOC_RL78_ABS16UL +- -- : BFD_RELOC_RL78_RELAX +- -- : BFD_RELOC_RL78_HI16 +- -- : BFD_RELOC_RL78_HI8 +- -- : BFD_RELOC_RL78_LO16 +- -- : BFD_RELOC_RL78_CODE +- Renesas RL78 Relocations. +- +- -- : BFD_RELOC_RX_NEG8 +- -- : BFD_RELOC_RX_NEG16 +- -- : BFD_RELOC_RX_NEG24 +- -- : BFD_RELOC_RX_NEG32 +- -- : BFD_RELOC_RX_16_OP +- -- : BFD_RELOC_RX_24_OP +- -- : BFD_RELOC_RX_32_OP +- -- : BFD_RELOC_RX_8U +- -- : BFD_RELOC_RX_16U +- -- : BFD_RELOC_RX_24U +- -- : BFD_RELOC_RX_DIR3U_PCREL +- -- : BFD_RELOC_RX_DIFF +- -- : BFD_RELOC_RX_GPRELB +- -- : BFD_RELOC_RX_GPRELW +- -- : BFD_RELOC_RX_GPRELL +- -- : BFD_RELOC_RX_SYM +- -- : BFD_RELOC_RX_OP_SUBTRACT +- -- : BFD_RELOC_RX_OP_NEG +- -- : BFD_RELOC_RX_ABS8 +- -- : BFD_RELOC_RX_ABS16 +- -- : BFD_RELOC_RX_ABS16_REV +- -- : BFD_RELOC_RX_ABS32 +- -- : BFD_RELOC_RX_ABS32_REV +- -- : BFD_RELOC_RX_ABS16U +- -- : BFD_RELOC_RX_ABS16UW +- -- : BFD_RELOC_RX_ABS16UL +- -- : BFD_RELOC_RX_RELAX +- Renesas RX Relocations. +- +- -- : BFD_RELOC_390_12 +- Direct 12 bit. +- +- -- : BFD_RELOC_390_GOT12 +- 12 bit GOT offset. +- +- -- : BFD_RELOC_390_PLT32 +- 32 bit PC relative PLT address. +- +- -- : BFD_RELOC_390_COPY +- Copy symbol at runtime. +- +- -- : BFD_RELOC_390_GLOB_DAT +- Create GOT entry. +- +- -- : BFD_RELOC_390_JMP_SLOT +- Create PLT entry. +- +- -- : BFD_RELOC_390_RELATIVE +- Adjust by program base. +- +- -- : BFD_RELOC_390_GOTPC +- 32 bit PC relative offset to GOT. +- +- -- : BFD_RELOC_390_GOT16 +- 16 bit GOT offset. +- +- -- : BFD_RELOC_390_PC12DBL +- PC relative 12 bit shifted by 1. +- +- -- : BFD_RELOC_390_PLT12DBL +- 12 bit PC rel. PLT shifted by 1. +- +- -- : BFD_RELOC_390_PC16DBL +- PC relative 16 bit shifted by 1. +- +- -- : BFD_RELOC_390_PLT16DBL +- 16 bit PC rel. PLT shifted by 1. +- +- -- : BFD_RELOC_390_PC24DBL +- PC relative 24 bit shifted by 1. +- +- -- : BFD_RELOC_390_PLT24DBL +- 24 bit PC rel. PLT shifted by 1. +- +- -- : BFD_RELOC_390_PC32DBL +- PC relative 32 bit shifted by 1. +- +- -- : BFD_RELOC_390_PLT32DBL +- 32 bit PC rel. PLT shifted by 1. +- +- -- : BFD_RELOC_390_GOTPCDBL +- 32 bit PC rel. GOT shifted by 1. +- +- -- : BFD_RELOC_390_GOT64 +- 64 bit GOT offset. +- +- -- : BFD_RELOC_390_PLT64 +- 64 bit PC relative PLT address. +- +- -- : BFD_RELOC_390_GOTENT +- 32 bit rel. offset to GOT entry. +- +- -- : BFD_RELOC_390_GOTOFF64 +- 64 bit offset to GOT. +- +- -- : BFD_RELOC_390_GOTPLT12 +- 12-bit offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_390_GOTPLT16 +- 16-bit offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_390_GOTPLT32 +- 32-bit offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_390_GOTPLT64 +- 64-bit offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_390_GOTPLTENT +- 32-bit rel. offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_390_PLTOFF16 +- 16-bit rel. offset from the GOT to a PLT entry. +- +- -- : BFD_RELOC_390_PLTOFF32 +- 32-bit rel. offset from the GOT to a PLT entry. +- +- -- : BFD_RELOC_390_PLTOFF64 +- 64-bit rel. offset from the GOT to a PLT entry. +- +- -- : BFD_RELOC_390_TLS_LOAD +- -- : BFD_RELOC_390_TLS_GDCALL +- -- : BFD_RELOC_390_TLS_LDCALL +- -- : BFD_RELOC_390_TLS_GD32 +- -- : BFD_RELOC_390_TLS_GD64 +- -- : BFD_RELOC_390_TLS_GOTIE12 +- -- : BFD_RELOC_390_TLS_GOTIE32 +- -- : BFD_RELOC_390_TLS_GOTIE64 +- -- : BFD_RELOC_390_TLS_LDM32 +- -- : BFD_RELOC_390_TLS_LDM64 +- -- : BFD_RELOC_390_TLS_IE32 +- -- : BFD_RELOC_390_TLS_IE64 +- -- : BFD_RELOC_390_TLS_IEENT +- -- : BFD_RELOC_390_TLS_LE32 +- -- : BFD_RELOC_390_TLS_LE64 +- -- : BFD_RELOC_390_TLS_LDO32 +- -- : BFD_RELOC_390_TLS_LDO64 +- -- : BFD_RELOC_390_TLS_DTPMOD +- -- : BFD_RELOC_390_TLS_DTPOFF +- -- : BFD_RELOC_390_TLS_TPOFF +- s390 tls relocations. +- +- -- : BFD_RELOC_390_20 +- -- : BFD_RELOC_390_GOT20 +- -- : BFD_RELOC_390_GOTPLT20 +- -- : BFD_RELOC_390_TLS_GOTIE20 +- Long displacement extension. +- +- -- : BFD_RELOC_390_IRELATIVE +- STT_GNU_IFUNC relocation. +- +- -- : BFD_RELOC_SCORE_GPREL15 +- Score relocations Low 16 bit for load/store +- +- -- : BFD_RELOC_SCORE_DUMMY2 +- -- : BFD_RELOC_SCORE_JMP +- This is a 24-bit reloc with the right 1 bit assumed to be 0 +- +- -- : BFD_RELOC_SCORE_BRANCH +- This is a 19-bit reloc with the right 1 bit assumed to be 0 +- +- -- : BFD_RELOC_SCORE_IMM30 +- This is a 32-bit reloc for 48-bit instructions. +- +- -- : BFD_RELOC_SCORE_IMM32 +- This is a 32-bit reloc for 48-bit instructions. +- +- -- : BFD_RELOC_SCORE16_JMP +- This is a 11-bit reloc with the right 1 bit assumed to be 0 +- +- -- : BFD_RELOC_SCORE16_BRANCH +- This is a 8-bit reloc with the right 1 bit assumed to be 0 +- +- -- : BFD_RELOC_SCORE_BCMP +- This is a 9-bit reloc with the right 1 bit assumed to be 0 +- +- -- : BFD_RELOC_SCORE_GOT15 +- -- : BFD_RELOC_SCORE_GOT_LO16 +- -- : BFD_RELOC_SCORE_CALL15 +- -- : BFD_RELOC_SCORE_DUMMY_HI16 +- Undocumented Score relocs +- +- -- : BFD_RELOC_IP2K_FR9 +- Scenix IP2K - 9-bit register number / data address +- +- -- : BFD_RELOC_IP2K_BANK +- Scenix IP2K - 4-bit register/data bank number +- +- -- : BFD_RELOC_IP2K_ADDR16CJP +- Scenix IP2K - low 13 bits of instruction word address +- +- -- : BFD_RELOC_IP2K_PAGE3 +- Scenix IP2K - high 3 bits of instruction word address +- +- -- : BFD_RELOC_IP2K_LO8DATA +- -- : BFD_RELOC_IP2K_HI8DATA +- -- : BFD_RELOC_IP2K_EX8DATA +- Scenix IP2K - ext/low/high 8 bits of data address +- +- -- : BFD_RELOC_IP2K_LO8INSN +- -- : BFD_RELOC_IP2K_HI8INSN +- Scenix IP2K - low/high 8 bits of instruction word address +- +- -- : BFD_RELOC_IP2K_PC_SKIP +- Scenix IP2K - even/odd PC modifier to modify snb pcl.0 +- +- -- : BFD_RELOC_IP2K_TEXT +- Scenix IP2K - 16 bit word address in text section. +- +- -- : BFD_RELOC_IP2K_FR_OFFSET +- Scenix IP2K - 7-bit sp or dp offset +- +- -- : BFD_RELOC_VPE4KMATH_DATA +- -- : BFD_RELOC_VPE4KMATH_INSN +- Scenix VPE4K coprocessor - data/insn-space addressing +- +- -- : BFD_RELOC_VTABLE_INHERIT +- -- : BFD_RELOC_VTABLE_ENTRY +- These two relocations are used by the linker to determine which of +- the entries in a C++ virtual function table are actually used. +- When the -gc-sections option is given, the linker will zero out +- the entries that are not used, so that the code for those +- functions need not be included in the output. +- +- VTABLE_INHERIT is a zero-space relocation used to describe to the +- linker the inheritance tree of a C++ virtual function table. The +- relocation's symbol should be the parent class' vtable, and the +- relocation should be located at the child vtable. +- +- VTABLE_ENTRY is a zero-space relocation that describes the use of a +- virtual function table entry. The reloc's symbol should refer to +- the table of the class mentioned in the code. Off of that base, +- an offset describes the entry that is being used. For Rela hosts, +- this offset is stored in the reloc's addend. For Rel hosts, we +- are forced to put this offset in the reloc's section offset. +- +- -- : BFD_RELOC_IA64_IMM14 +- -- : BFD_RELOC_IA64_IMM22 +- -- : BFD_RELOC_IA64_IMM64 +- -- : BFD_RELOC_IA64_DIR32MSB +- -- : BFD_RELOC_IA64_DIR32LSB +- -- : BFD_RELOC_IA64_DIR64MSB +- -- : BFD_RELOC_IA64_DIR64LSB +- -- : BFD_RELOC_IA64_GPREL22 +- -- : BFD_RELOC_IA64_GPREL64I +- -- : BFD_RELOC_IA64_GPREL32MSB +- -- : BFD_RELOC_IA64_GPREL32LSB +- -- : BFD_RELOC_IA64_GPREL64MSB +- -- : BFD_RELOC_IA64_GPREL64LSB +- -- : BFD_RELOC_IA64_LTOFF22 +- -- : BFD_RELOC_IA64_LTOFF64I +- -- : BFD_RELOC_IA64_PLTOFF22 +- -- : BFD_RELOC_IA64_PLTOFF64I +- -- : BFD_RELOC_IA64_PLTOFF64MSB +- -- : BFD_RELOC_IA64_PLTOFF64LSB +- -- : BFD_RELOC_IA64_FPTR64I +- -- : BFD_RELOC_IA64_FPTR32MSB +- -- : BFD_RELOC_IA64_FPTR32LSB +- -- : BFD_RELOC_IA64_FPTR64MSB +- -- : BFD_RELOC_IA64_FPTR64LSB +- -- : BFD_RELOC_IA64_PCREL21B +- -- : BFD_RELOC_IA64_PCREL21BI +- -- : BFD_RELOC_IA64_PCREL21M +- -- : BFD_RELOC_IA64_PCREL21F +- -- : BFD_RELOC_IA64_PCREL22 +- -- : BFD_RELOC_IA64_PCREL60B +- -- : BFD_RELOC_IA64_PCREL64I +- -- : BFD_RELOC_IA64_PCREL32MSB +- -- : BFD_RELOC_IA64_PCREL32LSB +- -- : BFD_RELOC_IA64_PCREL64MSB +- -- : BFD_RELOC_IA64_PCREL64LSB +- -- : BFD_RELOC_IA64_LTOFF_FPTR22 +- -- : BFD_RELOC_IA64_LTOFF_FPTR64I +- -- : BFD_RELOC_IA64_LTOFF_FPTR32MSB +- -- : BFD_RELOC_IA64_LTOFF_FPTR32LSB +- -- : BFD_RELOC_IA64_LTOFF_FPTR64MSB +- -- : BFD_RELOC_IA64_LTOFF_FPTR64LSB +- -- : BFD_RELOC_IA64_SEGREL32MSB +- -- : BFD_RELOC_IA64_SEGREL32LSB +- -- : BFD_RELOC_IA64_SEGREL64MSB +- -- : BFD_RELOC_IA64_SEGREL64LSB +- -- : BFD_RELOC_IA64_SECREL32MSB +- -- : BFD_RELOC_IA64_SECREL32LSB +- -- : BFD_RELOC_IA64_SECREL64MSB +- -- : BFD_RELOC_IA64_SECREL64LSB +- -- : BFD_RELOC_IA64_REL32MSB +- -- : BFD_RELOC_IA64_REL32LSB +- -- : BFD_RELOC_IA64_REL64MSB +- -- : BFD_RELOC_IA64_REL64LSB +- -- : BFD_RELOC_IA64_LTV32MSB +- -- : BFD_RELOC_IA64_LTV32LSB +- -- : BFD_RELOC_IA64_LTV64MSB +- -- : BFD_RELOC_IA64_LTV64LSB +- -- : BFD_RELOC_IA64_IPLTMSB +- -- : BFD_RELOC_IA64_IPLTLSB +- -- : BFD_RELOC_IA64_COPY +- -- : BFD_RELOC_IA64_LTOFF22X +- -- : BFD_RELOC_IA64_LDXMOV +- -- : BFD_RELOC_IA64_TPREL14 +- -- : BFD_RELOC_IA64_TPREL22 +- -- : BFD_RELOC_IA64_TPREL64I +- -- : BFD_RELOC_IA64_TPREL64MSB +- -- : BFD_RELOC_IA64_TPREL64LSB +- -- : BFD_RELOC_IA64_LTOFF_TPREL22 +- -- : BFD_RELOC_IA64_DTPMOD64MSB +- -- : BFD_RELOC_IA64_DTPMOD64LSB +- -- : BFD_RELOC_IA64_LTOFF_DTPMOD22 +- -- : BFD_RELOC_IA64_DTPREL14 +- -- : BFD_RELOC_IA64_DTPREL22 +- -- : BFD_RELOC_IA64_DTPREL64I +- -- : BFD_RELOC_IA64_DTPREL32MSB +- -- : BFD_RELOC_IA64_DTPREL32LSB +- -- : BFD_RELOC_IA64_DTPREL64MSB +- -- : BFD_RELOC_IA64_DTPREL64LSB +- -- : BFD_RELOC_IA64_LTOFF_DTPREL22 +- Intel IA64 Relocations. +- +- -- : BFD_RELOC_M68HC11_HI8 +- Motorola 68HC11 reloc. This is the 8 bit high part of an absolute +- address. +- +- -- : BFD_RELOC_M68HC11_LO8 +- Motorola 68HC11 reloc. This is the 8 bit low part of an absolute +- address. +- +- -- : BFD_RELOC_M68HC11_3B +- Motorola 68HC11 reloc. This is the 3 bit of a value. +- +- -- : BFD_RELOC_M68HC11_RL_JUMP +- Motorola 68HC11 reloc. This reloc marks the beginning of a +- jump/call instruction. It is used for linker relaxation to +- correctly identify beginning of instruction and change some +- branches to use PC-relative addressing mode. +- +- -- : BFD_RELOC_M68HC11_RL_GROUP +- Motorola 68HC11 reloc. This reloc marks a group of several +- instructions that gcc generates and for which the linker +- relaxation pass can modify and/or remove some of them. +- +- -- : BFD_RELOC_M68HC11_LO16 +- Motorola 68HC11 reloc. This is the 16-bit lower part of an +- address. It is used for 'call' instruction to specify the symbol +- address without any special transformation (due to memory bank +- window). +- +- -- : BFD_RELOC_M68HC11_PAGE +- Motorola 68HC11 reloc. This is a 8-bit reloc that specifies the +- page number of an address. It is used by 'call' instruction to +- specify the page number of the symbol. +- +- -- : BFD_RELOC_M68HC11_24 +- Motorola 68HC11 reloc. This is a 24-bit reloc that represents the +- address with a 16-bit value and a 8-bit page number. The symbol +- address is transformed to follow the 16K memory bank of 68HC12 +- (seen as mapped in the window). +- +- -- : BFD_RELOC_M68HC12_5B +- Motorola 68HC12 reloc. This is the 5 bits of a value. +- +- -- : BFD_RELOC_XGATE_RL_JUMP +- Freescale XGATE reloc. This reloc marks the beginning of a +- bra/jal instruction. +- +- -- : BFD_RELOC_XGATE_RL_GROUP +- Freescale XGATE reloc. This reloc marks a group of several +- instructions that gcc generates and for which the linker +- relaxation pass can modify and/or remove some of them. +- +- -- : BFD_RELOC_XGATE_LO16 +- Freescale XGATE reloc. This is the 16-bit lower part of an +- address. It is used for the '16-bit' instructions. +- +- -- : BFD_RELOC_XGATE_GPAGE +- Freescale XGATE reloc. +- +- -- : BFD_RELOC_XGATE_24 +- Freescale XGATE reloc. +- +- -- : BFD_RELOC_XGATE_PCREL_9 +- Freescale XGATE reloc. This is a 9-bit pc-relative reloc. +- +- -- : BFD_RELOC_XGATE_PCREL_10 +- Freescale XGATE reloc. This is a 10-bit pc-relative reloc. +- +- -- : BFD_RELOC_XGATE_IMM8_LO +- Freescale XGATE reloc. This is the 16-bit lower part of an +- address. It is used for the '16-bit' instructions. +- +- -- : BFD_RELOC_XGATE_IMM8_HI +- Freescale XGATE reloc. This is the 16-bit higher part of an +- address. It is used for the '16-bit' instructions. +- +- -- : BFD_RELOC_XGATE_IMM3 +- Freescale XGATE reloc. This is a 3-bit pc-relative reloc. +- +- -- : BFD_RELOC_XGATE_IMM4 +- Freescale XGATE reloc. This is a 4-bit pc-relative reloc. +- +- -- : BFD_RELOC_XGATE_IMM5 +- Freescale XGATE reloc. This is a 5-bit pc-relative reloc. +- +- -- : BFD_RELOC_M68HC12_9B +- Motorola 68HC12 reloc. This is the 9 bits of a value. +- +- -- : BFD_RELOC_M68HC12_16B +- Motorola 68HC12 reloc. This is the 16 bits of a value. +- +- -- : BFD_RELOC_M68HC12_9_PCREL +- Motorola 68HC12/XGATE reloc. This is a PCREL9 branch. +- +- -- : BFD_RELOC_M68HC12_10_PCREL +- Motorola 68HC12/XGATE reloc. This is a PCREL10 branch. +- +- -- : BFD_RELOC_M68HC12_LO8XG +- Motorola 68HC12/XGATE reloc. This is the 8 bit low part of an +- absolute address and immediately precedes a matching HI8XG part. +- +- -- : BFD_RELOC_M68HC12_HI8XG +- Motorola 68HC12/XGATE reloc. This is the 8 bit high part of an +- absolute address and immediately follows a matching LO8XG part. +- +- -- : BFD_RELOC_16C_NUM08 +- -- : BFD_RELOC_16C_NUM08_C +- -- : BFD_RELOC_16C_NUM16 +- -- : BFD_RELOC_16C_NUM16_C +- -- : BFD_RELOC_16C_NUM32 +- -- : BFD_RELOC_16C_NUM32_C +- -- : BFD_RELOC_16C_DISP04 +- -- : BFD_RELOC_16C_DISP04_C +- -- : BFD_RELOC_16C_DISP08 +- -- : BFD_RELOC_16C_DISP08_C +- -- : BFD_RELOC_16C_DISP16 +- -- : BFD_RELOC_16C_DISP16_C +- -- : BFD_RELOC_16C_DISP24 +- -- : BFD_RELOC_16C_DISP24_C +- -- : BFD_RELOC_16C_DISP24a +- -- : BFD_RELOC_16C_DISP24a_C +- -- : BFD_RELOC_16C_REG04 +- -- : BFD_RELOC_16C_REG04_C +- -- : BFD_RELOC_16C_REG04a +- -- : BFD_RELOC_16C_REG04a_C +- -- : BFD_RELOC_16C_REG14 +- -- : BFD_RELOC_16C_REG14_C +- -- : BFD_RELOC_16C_REG16 +- -- : BFD_RELOC_16C_REG16_C +- -- : BFD_RELOC_16C_REG20 +- -- : BFD_RELOC_16C_REG20_C +- -- : BFD_RELOC_16C_ABS20 +- -- : BFD_RELOC_16C_ABS20_C +- -- : BFD_RELOC_16C_ABS24 +- -- : BFD_RELOC_16C_ABS24_C +- -- : BFD_RELOC_16C_IMM04 +- -- : BFD_RELOC_16C_IMM04_C +- -- : BFD_RELOC_16C_IMM16 +- -- : BFD_RELOC_16C_IMM16_C +- -- : BFD_RELOC_16C_IMM20 +- -- : BFD_RELOC_16C_IMM20_C +- -- : BFD_RELOC_16C_IMM24 +- -- : BFD_RELOC_16C_IMM24_C +- -- : BFD_RELOC_16C_IMM32 +- -- : BFD_RELOC_16C_IMM32_C +- NS CR16C Relocations. +- +- -- : BFD_RELOC_CR16_NUM8 +- -- : BFD_RELOC_CR16_NUM16 +- -- : BFD_RELOC_CR16_NUM32 +- -- : BFD_RELOC_CR16_NUM32a +- -- : BFD_RELOC_CR16_REGREL0 +- -- : BFD_RELOC_CR16_REGREL4 +- -- : BFD_RELOC_CR16_REGREL4a +- -- : BFD_RELOC_CR16_REGREL14 +- -- : BFD_RELOC_CR16_REGREL14a +- -- : BFD_RELOC_CR16_REGREL16 +- -- : BFD_RELOC_CR16_REGREL20 +- -- : BFD_RELOC_CR16_REGREL20a +- -- : BFD_RELOC_CR16_ABS20 +- -- : BFD_RELOC_CR16_ABS24 +- -- : BFD_RELOC_CR16_IMM4 +- -- : BFD_RELOC_CR16_IMM8 +- -- : BFD_RELOC_CR16_IMM16 +- -- : BFD_RELOC_CR16_IMM20 +- -- : BFD_RELOC_CR16_IMM24 +- -- : BFD_RELOC_CR16_IMM32 +- -- : BFD_RELOC_CR16_IMM32a +- -- : BFD_RELOC_CR16_DISP4 +- -- : BFD_RELOC_CR16_DISP8 +- -- : BFD_RELOC_CR16_DISP16 +- -- : BFD_RELOC_CR16_DISP20 +- -- : BFD_RELOC_CR16_DISP24 +- -- : BFD_RELOC_CR16_DISP24a +- -- : BFD_RELOC_CR16_SWITCH8 +- -- : BFD_RELOC_CR16_SWITCH16 +- -- : BFD_RELOC_CR16_SWITCH32 +- -- : BFD_RELOC_CR16_GOT_REGREL20 +- -- : BFD_RELOC_CR16_GOTC_REGREL20 +- -- : BFD_RELOC_CR16_GLOB_DAT +- NS CR16 Relocations. +- +- -- : BFD_RELOC_CRX_REL4 +- -- : BFD_RELOC_CRX_REL8 +- -- : BFD_RELOC_CRX_REL8_CMP +- -- : BFD_RELOC_CRX_REL16 +- -- : BFD_RELOC_CRX_REL24 +- -- : BFD_RELOC_CRX_REL32 +- -- : BFD_RELOC_CRX_REGREL12 +- -- : BFD_RELOC_CRX_REGREL22 +- -- : BFD_RELOC_CRX_REGREL28 +- -- : BFD_RELOC_CRX_REGREL32 +- -- : BFD_RELOC_CRX_ABS16 +- -- : BFD_RELOC_CRX_ABS32 +- -- : BFD_RELOC_CRX_NUM8 +- -- : BFD_RELOC_CRX_NUM16 +- -- : BFD_RELOC_CRX_NUM32 +- -- : BFD_RELOC_CRX_IMM16 +- -- : BFD_RELOC_CRX_IMM32 +- -- : BFD_RELOC_CRX_SWITCH8 +- -- : BFD_RELOC_CRX_SWITCH16 +- -- : BFD_RELOC_CRX_SWITCH32 +- NS CRX Relocations. +- +- -- : BFD_RELOC_CRIS_BDISP8 +- -- : BFD_RELOC_CRIS_UNSIGNED_5 +- -- : BFD_RELOC_CRIS_SIGNED_6 +- -- : BFD_RELOC_CRIS_UNSIGNED_6 +- -- : BFD_RELOC_CRIS_SIGNED_8 +- -- : BFD_RELOC_CRIS_UNSIGNED_8 +- -- : BFD_RELOC_CRIS_SIGNED_16 +- -- : BFD_RELOC_CRIS_UNSIGNED_16 +- -- : BFD_RELOC_CRIS_LAPCQ_OFFSET +- -- : BFD_RELOC_CRIS_UNSIGNED_4 +- These relocs are only used within the CRIS assembler. They are not +- (at present) written to any object files. +- +- -- : BFD_RELOC_CRIS_COPY +- -- : BFD_RELOC_CRIS_GLOB_DAT +- -- : BFD_RELOC_CRIS_JUMP_SLOT +- -- : BFD_RELOC_CRIS_RELATIVE +- Relocs used in ELF shared libraries for CRIS. +- +- -- : BFD_RELOC_CRIS_32_GOT +- 32-bit offset to symbol-entry within GOT. +- +- -- : BFD_RELOC_CRIS_16_GOT +- 16-bit offset to symbol-entry within GOT. +- +- -- : BFD_RELOC_CRIS_32_GOTPLT +- 32-bit offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_CRIS_16_GOTPLT +- 16-bit offset to symbol-entry within GOT, with PLT handling. +- +- -- : BFD_RELOC_CRIS_32_GOTREL +- 32-bit offset to symbol, relative to GOT. +- +- -- : BFD_RELOC_CRIS_32_PLT_GOTREL +- 32-bit offset to symbol with PLT entry, relative to GOT. +- +- -- : BFD_RELOC_CRIS_32_PLT_PCREL +- 32-bit offset to symbol with PLT entry, relative to this +- relocation. +- +- -- : BFD_RELOC_CRIS_32_GOT_GD +- -- : BFD_RELOC_CRIS_16_GOT_GD +- -- : BFD_RELOC_CRIS_32_GD +- -- : BFD_RELOC_CRIS_DTP +- -- : BFD_RELOC_CRIS_32_DTPREL +- -- : BFD_RELOC_CRIS_16_DTPREL +- -- : BFD_RELOC_CRIS_32_GOT_TPREL +- -- : BFD_RELOC_CRIS_16_GOT_TPREL +- -- : BFD_RELOC_CRIS_32_TPREL +- -- : BFD_RELOC_CRIS_16_TPREL +- -- : BFD_RELOC_CRIS_DTPMOD +- -- : BFD_RELOC_CRIS_32_IE +- Relocs used in TLS code for CRIS. +- +- -- : BFD_RELOC_860_COPY +- -- : BFD_RELOC_860_GLOB_DAT +- -- : BFD_RELOC_860_JUMP_SLOT +- -- : BFD_RELOC_860_RELATIVE +- -- : BFD_RELOC_860_PC26 +- -- : BFD_RELOC_860_PLT26 +- -- : BFD_RELOC_860_PC16 +- -- : BFD_RELOC_860_LOW0 +- -- : BFD_RELOC_860_SPLIT0 +- -- : BFD_RELOC_860_LOW1 +- -- : BFD_RELOC_860_SPLIT1 +- -- : BFD_RELOC_860_LOW2 +- -- : BFD_RELOC_860_SPLIT2 +- -- : BFD_RELOC_860_LOW3 +- -- : BFD_RELOC_860_LOGOT0 +- -- : BFD_RELOC_860_SPGOT0 +- -- : BFD_RELOC_860_LOGOT1 +- -- : BFD_RELOC_860_SPGOT1 +- -- : BFD_RELOC_860_LOGOTOFF0 +- -- : BFD_RELOC_860_SPGOTOFF0 +- -- : BFD_RELOC_860_LOGOTOFF1 +- -- : BFD_RELOC_860_SPGOTOFF1 +- -- : BFD_RELOC_860_LOGOTOFF2 +- -- : BFD_RELOC_860_LOGOTOFF3 +- -- : BFD_RELOC_860_LOPC +- -- : BFD_RELOC_860_HIGHADJ +- -- : BFD_RELOC_860_HAGOT +- -- : BFD_RELOC_860_HAGOTOFF +- -- : BFD_RELOC_860_HAPC +- -- : BFD_RELOC_860_HIGH +- -- : BFD_RELOC_860_HIGOT +- -- : BFD_RELOC_860_HIGOTOFF +- Intel i860 Relocations. +- +- -- : BFD_RELOC_OPENRISC_ABS_26 +- -- : BFD_RELOC_OPENRISC_REL_26 +- OpenRISC Relocations. +- +- -- : BFD_RELOC_H8_DIR16A8 +- -- : BFD_RELOC_H8_DIR16R8 +- -- : BFD_RELOC_H8_DIR24A8 +- -- : BFD_RELOC_H8_DIR24R8 +- -- : BFD_RELOC_H8_DIR32A16 +- -- : BFD_RELOC_H8_DISP32A16 +- H8 elf Relocations. +- +- -- : BFD_RELOC_XSTORMY16_REL_12 +- -- : BFD_RELOC_XSTORMY16_12 +- -- : BFD_RELOC_XSTORMY16_24 +- -- : BFD_RELOC_XSTORMY16_FPTR16 +- Sony Xstormy16 Relocations. +- +- -- : BFD_RELOC_RELC +- Self-describing complex relocations. +- +- -- : BFD_RELOC_XC16X_PAG +- -- : BFD_RELOC_XC16X_POF +- -- : BFD_RELOC_XC16X_SEG +- -- : BFD_RELOC_XC16X_SOF +- Infineon Relocations. +- +- -- : BFD_RELOC_VAX_GLOB_DAT +- -- : BFD_RELOC_VAX_JMP_SLOT +- -- : BFD_RELOC_VAX_RELATIVE +- Relocations used by VAX ELF. +- +- -- : BFD_RELOC_MT_PC16 +- Morpho MT - 16 bit immediate relocation. +- +- -- : BFD_RELOC_MT_HI16 +- Morpho MT - Hi 16 bits of an address. +- +- -- : BFD_RELOC_MT_LO16 +- Morpho MT - Low 16 bits of an address. +- +- -- : BFD_RELOC_MT_GNU_VTINHERIT +- Morpho MT - Used to tell the linker which vtable entries are used. +- +- -- : BFD_RELOC_MT_GNU_VTENTRY +- Morpho MT - Used to tell the linker which vtable entries are used. +- +- -- : BFD_RELOC_MT_PCINSN8 +- Morpho MT - 8 bit immediate relocation. +- +- -- : BFD_RELOC_MSP430_10_PCREL +- -- : BFD_RELOC_MSP430_16_PCREL +- -- : BFD_RELOC_MSP430_16 +- -- : BFD_RELOC_MSP430_16_PCREL_BYTE +- -- : BFD_RELOC_MSP430_16_BYTE +- -- : BFD_RELOC_MSP430_2X_PCREL +- -- : BFD_RELOC_MSP430_RL_PCREL +- -- : BFD_RELOC_MSP430_ABS8 +- -- : BFD_RELOC_MSP430X_PCR20_EXT_SRC +- -- : BFD_RELOC_MSP430X_PCR20_EXT_DST +- -- : BFD_RELOC_MSP430X_PCR20_EXT_ODST +- -- : BFD_RELOC_MSP430X_ABS20_EXT_SRC +- -- : BFD_RELOC_MSP430X_ABS20_EXT_DST +- -- : BFD_RELOC_MSP430X_ABS20_EXT_ODST +- -- : BFD_RELOC_MSP430X_ABS20_ADR_SRC +- -- : BFD_RELOC_MSP430X_ABS20_ADR_DST +- -- : BFD_RELOC_MSP430X_PCR16 +- -- : BFD_RELOC_MSP430X_PCR20_CALL +- -- : BFD_RELOC_MSP430X_ABS16 +- -- : BFD_RELOC_MSP430_ABS_HI16 +- -- : BFD_RELOC_MSP430_PREL31 +- -- : BFD_RELOC_MSP430_SYM_DIFF +- msp430 specific relocation codes +- +- -- : BFD_RELOC_NIOS2_S16 +- -- : BFD_RELOC_NIOS2_U16 +- -- : BFD_RELOC_NIOS2_CALL26 +- -- : BFD_RELOC_NIOS2_IMM5 +- -- : BFD_RELOC_NIOS2_CACHE_OPX +- -- : BFD_RELOC_NIOS2_IMM6 +- -- : BFD_RELOC_NIOS2_IMM8 +- -- : BFD_RELOC_NIOS2_HI16 +- -- : BFD_RELOC_NIOS2_LO16 +- -- : BFD_RELOC_NIOS2_HIADJ16 +- -- : BFD_RELOC_NIOS2_GPREL +- -- : BFD_RELOC_NIOS2_UJMP +- -- : BFD_RELOC_NIOS2_CJMP +- -- : BFD_RELOC_NIOS2_CALLR +- -- : BFD_RELOC_NIOS2_ALIGN +- -- : BFD_RELOC_NIOS2_GOT16 +- -- : BFD_RELOC_NIOS2_CALL16 +- -- : BFD_RELOC_NIOS2_GOTOFF_LO +- -- : BFD_RELOC_NIOS2_GOTOFF_HA +- -- : BFD_RELOC_NIOS2_PCREL_LO +- -- : BFD_RELOC_NIOS2_PCREL_HA +- -- : BFD_RELOC_NIOS2_TLS_GD16 +- -- : BFD_RELOC_NIOS2_TLS_LDM16 +- -- : BFD_RELOC_NIOS2_TLS_LDO16 +- -- : BFD_RELOC_NIOS2_TLS_IE16 +- -- : BFD_RELOC_NIOS2_TLS_LE16 +- -- : BFD_RELOC_NIOS2_TLS_DTPMOD +- -- : BFD_RELOC_NIOS2_TLS_DTPREL +- -- : BFD_RELOC_NIOS2_TLS_TPREL +- -- : BFD_RELOC_NIOS2_COPY +- -- : BFD_RELOC_NIOS2_GLOB_DAT +- -- : BFD_RELOC_NIOS2_JUMP_SLOT +- -- : BFD_RELOC_NIOS2_RELATIVE +- -- : BFD_RELOC_NIOS2_GOTOFF +- Relocations used by the Altera Nios II core. +- +- -- : BFD_RELOC_IQ2000_OFFSET_16 +- -- : BFD_RELOC_IQ2000_OFFSET_21 +- -- : BFD_RELOC_IQ2000_UHI16 +- IQ2000 Relocations. +- +- -- : BFD_RELOC_XTENSA_RTLD +- Special Xtensa relocation used only by PLT entries in ELF shared +- objects to indicate that the runtime linker should set the value +- to one of its own internal functions or data structures. +- +- -- : BFD_RELOC_XTENSA_GLOB_DAT +- -- : BFD_RELOC_XTENSA_JMP_SLOT +- -- : BFD_RELOC_XTENSA_RELATIVE +- Xtensa relocations for ELF shared objects. +- +- -- : BFD_RELOC_XTENSA_PLT +- Xtensa relocation used in ELF object files for symbols that may +- require PLT entries. Otherwise, this is just a generic 32-bit +- relocation. +- +- -- : BFD_RELOC_XTENSA_DIFF8 +- -- : BFD_RELOC_XTENSA_DIFF16 +- -- : BFD_RELOC_XTENSA_DIFF32 +- Xtensa relocations to mark the difference of two local symbols. +- These are only needed to support linker relaxation and can be +- ignored when not relaxing. The field is set to the value of the +- difference assuming no relaxation. The relocation encodes the +- position of the first symbol so the linker can determine whether +- to adjust the field value. +- +- -- : BFD_RELOC_XTENSA_SLOT0_OP +- -- : BFD_RELOC_XTENSA_SLOT1_OP +- -- : BFD_RELOC_XTENSA_SLOT2_OP +- -- : BFD_RELOC_XTENSA_SLOT3_OP +- -- : BFD_RELOC_XTENSA_SLOT4_OP +- -- : BFD_RELOC_XTENSA_SLOT5_OP +- -- : BFD_RELOC_XTENSA_SLOT6_OP +- -- : BFD_RELOC_XTENSA_SLOT7_OP +- -- : BFD_RELOC_XTENSA_SLOT8_OP +- -- : BFD_RELOC_XTENSA_SLOT9_OP +- -- : BFD_RELOC_XTENSA_SLOT10_OP +- -- : BFD_RELOC_XTENSA_SLOT11_OP +- -- : BFD_RELOC_XTENSA_SLOT12_OP +- -- : BFD_RELOC_XTENSA_SLOT13_OP +- -- : BFD_RELOC_XTENSA_SLOT14_OP +- Generic Xtensa relocations for instruction operands. Only the slot +- number is encoded in the relocation. The relocation applies to the +- last PC-relative immediate operand, or if there are no PC-relative +- immediates, to the last immediate operand. +- +- -- : BFD_RELOC_XTENSA_SLOT0_ALT +- -- : BFD_RELOC_XTENSA_SLOT1_ALT +- -- : BFD_RELOC_XTENSA_SLOT2_ALT +- -- : BFD_RELOC_XTENSA_SLOT3_ALT +- -- : BFD_RELOC_XTENSA_SLOT4_ALT +- -- : BFD_RELOC_XTENSA_SLOT5_ALT +- -- : BFD_RELOC_XTENSA_SLOT6_ALT +- -- : BFD_RELOC_XTENSA_SLOT7_ALT +- -- : BFD_RELOC_XTENSA_SLOT8_ALT +- -- : BFD_RELOC_XTENSA_SLOT9_ALT +- -- : BFD_RELOC_XTENSA_SLOT10_ALT +- -- : BFD_RELOC_XTENSA_SLOT11_ALT +- -- : BFD_RELOC_XTENSA_SLOT12_ALT +- -- : BFD_RELOC_XTENSA_SLOT13_ALT +- -- : BFD_RELOC_XTENSA_SLOT14_ALT +- Alternate Xtensa relocations. Only the slot is encoded in the +- relocation. The meaning of these relocations is opcode-specific. +- +- -- : BFD_RELOC_XTENSA_OP0 +- -- : BFD_RELOC_XTENSA_OP1 +- -- : BFD_RELOC_XTENSA_OP2 +- Xtensa relocations for backward compatibility. These have all been +- replaced by BFD_RELOC_XTENSA_SLOT0_OP. +- +- -- : BFD_RELOC_XTENSA_ASM_EXPAND +- Xtensa relocation to mark that the assembler expanded the +- instructions from an original target. The expansion size is +- encoded in the reloc size. +- +- -- : BFD_RELOC_XTENSA_ASM_SIMPLIFY +- Xtensa relocation to mark that the linker should simplify +- assembler-expanded instructions. This is commonly used internally +- by the linker after analysis of a BFD_RELOC_XTENSA_ASM_EXPAND. +- +- -- : BFD_RELOC_XTENSA_TLSDESC_FN +- -- : BFD_RELOC_XTENSA_TLSDESC_ARG +- -- : BFD_RELOC_XTENSA_TLS_DTPOFF +- -- : BFD_RELOC_XTENSA_TLS_TPOFF +- -- : BFD_RELOC_XTENSA_TLS_FUNC +- -- : BFD_RELOC_XTENSA_TLS_ARG +- -- : BFD_RELOC_XTENSA_TLS_CALL +- Xtensa TLS relocations. +- +- -- : BFD_RELOC_Z80_DISP8 +- 8 bit signed offset in (ix+d) or (iy+d). +- +- -- : BFD_RELOC_Z8K_DISP7 +- DJNZ offset. +- +- -- : BFD_RELOC_Z8K_CALLR +- CALR offset. +- +- -- : BFD_RELOC_Z8K_IMM4L +- 4 bit value. +- +- -- : BFD_RELOC_LM32_CALL +- -- : BFD_RELOC_LM32_BRANCH +- -- : BFD_RELOC_LM32_16_GOT +- -- : BFD_RELOC_LM32_GOTOFF_HI16 +- -- : BFD_RELOC_LM32_GOTOFF_LO16 +- -- : BFD_RELOC_LM32_COPY +- -- : BFD_RELOC_LM32_GLOB_DAT +- -- : BFD_RELOC_LM32_JMP_SLOT +- -- : BFD_RELOC_LM32_RELATIVE +- Lattice Mico32 relocations. +- +- -- : BFD_RELOC_MACH_O_SECTDIFF +- Difference between two section addreses. Must be followed by a +- BFD_RELOC_MACH_O_PAIR. +- +- -- : BFD_RELOC_MACH_O_LOCAL_SECTDIFF +- Like BFD_RELOC_MACH_O_SECTDIFF but with a local symbol. +- +- -- : BFD_RELOC_MACH_O_PAIR +- Pair of relocation. Contains the first symbol. +- +- -- : BFD_RELOC_MACH_O_X86_64_BRANCH32 +- -- : BFD_RELOC_MACH_O_X86_64_BRANCH8 +- PCREL relocations. They are marked as branch to create PLT entry +- if required. +- +- -- : BFD_RELOC_MACH_O_X86_64_GOT +- Used when referencing a GOT entry. +- +- -- : BFD_RELOC_MACH_O_X86_64_GOT_LOAD +- Used when loading a GOT entry with movq. It is specially marked +- so that the linker could optimize the movq to a leaq if possible. +- +- -- : BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32 +- Symbol will be substracted. Must be followed by a BFD_RELOC_64. +- +- -- : BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64 +- Symbol will be substracted. Must be followed by a BFD_RELOC_64. +- +- -- : BFD_RELOC_MACH_O_X86_64_PCREL32_1 +- Same as BFD_RELOC_32_PCREL but with an implicit -1 addend. +- +- -- : BFD_RELOC_MACH_O_X86_64_PCREL32_2 +- Same as BFD_RELOC_32_PCREL but with an implicit -2 addend. +- +- -- : BFD_RELOC_MACH_O_X86_64_PCREL32_4 +- Same as BFD_RELOC_32_PCREL but with an implicit -4 addend. +- +- -- : BFD_RELOC_MICROBLAZE_32_LO +- This is a 32 bit reloc for the microblaze that stores the low 16 +- bits of a value +- +- -- : BFD_RELOC_MICROBLAZE_32_LO_PCREL +- This is a 32 bit pc-relative reloc for the microblaze that stores +- the low 16 bits of a value +- +- -- : BFD_RELOC_MICROBLAZE_32_ROSDA +- This is a 32 bit reloc for the microblaze that stores a value +- relative to the read-only small data area anchor +- +- -- : BFD_RELOC_MICROBLAZE_32_RWSDA +- This is a 32 bit reloc for the microblaze that stores a value +- relative to the read-write small data area anchor +- +- -- : BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM +- This is a 32 bit reloc for the microblaze to handle expressions of +- the form "Symbol Op Symbol" +- +- -- : BFD_RELOC_MICROBLAZE_64_NONE +- This is a 64 bit reloc that stores the 32 bit pc relative value in +- two words (with an imm instruction). No relocation is done here - +- only used for relaxing +- +- -- : BFD_RELOC_MICROBLAZE_64_GOTPC +- This is a 64 bit reloc that stores the 32 bit pc relative value in +- two words (with an imm instruction). The relocation is +- PC-relative GOT offset +- +- -- : BFD_RELOC_MICROBLAZE_64_GOT +- This is a 64 bit reloc that stores the 32 bit pc relative value in +- two words (with an imm instruction). The relocation is GOT offset +- +- -- : BFD_RELOC_MICROBLAZE_64_PLT +- This is a 64 bit reloc that stores the 32 bit pc relative value in +- two words (with an imm instruction). The relocation is +- PC-relative offset into PLT +- +- -- : BFD_RELOC_MICROBLAZE_64_GOTOFF +- This is a 64 bit reloc that stores the 32 bit GOT relative value +- in two words (with an imm instruction). The relocation is +- relative offset from _GLOBAL_OFFSET_TABLE_ +- +- -- : BFD_RELOC_MICROBLAZE_32_GOTOFF +- This is a 32 bit reloc that stores the 32 bit GOT relative value +- in a word. The relocation is relative offset from +- +- -- : BFD_RELOC_MICROBLAZE_COPY +- This is used to tell the dynamic linker to copy the value out of +- the dynamic object into the runtime process image. +- +- -- : BFD_RELOC_MICROBLAZE_64_TLS +- Unused Reloc +- +- -- : BFD_RELOC_MICROBLAZE_64_TLSGD +- This is a 64 bit reloc that stores the 32 bit GOT relative value +- of the GOT TLS GD info entry in two words (with an imm +- instruction). The relocation is GOT offset. +- +- -- : BFD_RELOC_MICROBLAZE_64_TLSLD +- This is a 64 bit reloc that stores the 32 bit GOT relative value +- of the GOT TLS LD info entry in two words (with an imm +- instruction). The relocation is GOT offset. +- +- -- : BFD_RELOC_MICROBLAZE_32_TLSDTPMOD +- This is a 32 bit reloc that stores the Module ID to GOT(n). +- +- -- : BFD_RELOC_MICROBLAZE_32_TLSDTPREL +- This is a 32 bit reloc that stores TLS offset to GOT(n+1). +- +- -- : BFD_RELOC_MICROBLAZE_64_TLSDTPREL +- This is a 32 bit reloc for storing TLS offset to two words (uses +- imm instruction) +- +- -- : BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL +- This is a 64 bit reloc that stores 32-bit thread pointer relative +- offset to two words (uses imm instruction). +- +- -- : BFD_RELOC_MICROBLAZE_64_TLSTPREL +- This is a 64 bit reloc that stores 32-bit thread pointer relative +- offset to two words (uses imm instruction). +- +- -- : BFD_RELOC_AARCH64_RELOC_START +- AArch64 pseudo relocation code to mark the start of the AArch64 +- relocation enumerators. N.B. the order of the enumerators is +- important as several tables in the AArch64 bfd backend are indexed +- by these enumerators; make sure they are all synced. +- +- -- : BFD_RELOC_AARCH64_NONE +- AArch64 null relocation code. +- +- -- : BFD_RELOC_AARCH64_64 +- -- : BFD_RELOC_AARCH64_32 +- -- : BFD_RELOC_AARCH64_16 +- Basic absolute relocations of N bits. These are equivalent to +- BFD_RELOC_N and they were added to assist the indexing of the howto +- table. +- +- -- : BFD_RELOC_AARCH64_64_PCREL +- -- : BFD_RELOC_AARCH64_32_PCREL +- -- : BFD_RELOC_AARCH64_16_PCREL +- PC-relative relocations. These are equivalent to BFD_RELOC_N_PCREL +- and they were added to assist the indexing of the howto table. +- +- -- : BFD_RELOC_AARCH64_MOVW_G0 +- AArch64 MOV[NZK] instruction with most significant bits 0 to 15 of +- an unsigned address/value. +- +- -- : BFD_RELOC_AARCH64_MOVW_G0_NC +- AArch64 MOV[NZK] instruction with less significant bits 0 to 15 of +- an address/value. No overflow checking. +- +- -- : BFD_RELOC_AARCH64_MOVW_G1 +- AArch64 MOV[NZK] instruction with most significant bits 16 to 31 +- of an unsigned address/value. +- +- -- : BFD_RELOC_AARCH64_MOVW_G1_NC +- AArch64 MOV[NZK] instruction with less significant bits 16 to 31 +- of an address/value. No overflow checking. +- +- -- : BFD_RELOC_AARCH64_MOVW_G2 +- AArch64 MOV[NZK] instruction with most significant bits 32 to 47 +- of an unsigned address/value. +- +- -- : BFD_RELOC_AARCH64_MOVW_G2_NC +- AArch64 MOV[NZK] instruction with less significant bits 32 to 47 +- of an address/value. No overflow checking. +- +- -- : BFD_RELOC_AARCH64_MOVW_G3 +- AArch64 MOV[NZK] instruction with most signficant bits 48 to 64 of +- a signed or unsigned address/value. +- +- -- : BFD_RELOC_AARCH64_MOVW_G0_S +- AArch64 MOV[NZ] instruction with most significant bits 0 to 15 of +- a signed value. Changes instruction to MOVZ or MOVN depending on +- the value's sign. +- +- -- : BFD_RELOC_AARCH64_MOVW_G1_S +- AArch64 MOV[NZ] instruction with most significant bits 16 to 31 of +- a signed value. Changes instruction to MOVZ or MOVN depending on +- the value's sign. +- +- -- : BFD_RELOC_AARCH64_MOVW_G2_S +- AArch64 MOV[NZ] instruction with most significant bits 32 to 47 of +- a signed value. Changes instruction to MOVZ or MOVN depending on +- the value's sign. +- +- -- : BFD_RELOC_AARCH64_LD_LO19_PCREL +- AArch64 Load Literal instruction, holding a 19 bit pc-relative word +- offset. The lowest two bits must be zero and are not stored in the +- instruction, giving a 21 bit signed byte offset. +- +- -- : BFD_RELOC_AARCH64_ADR_LO21_PCREL +- AArch64 ADR instruction, holding a simple 21 bit pc-relative byte +- offset. +- +- -- : BFD_RELOC_AARCH64_ADR_HI21_PCREL +- AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page +- offset, giving a 4KB aligned page base address. +- +- -- : BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL +- AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page +- offset, giving a 4KB aligned page base address, but with no +- overflow checking. +- +- -- : BFD_RELOC_AARCH64_ADD_LO12 +- AArch64 ADD immediate instruction, holding bits 0 to 11 of the +- address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_LDST8_LO12 +- AArch64 8-bit load/store instruction, holding bits 0 to 11 of the +- address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_TSTBR14 +- AArch64 14 bit pc-relative test bit and branch. The lowest two +- bits must be zero and are not stored in the instruction, giving a +- 16 bit signed byte offset. +- +- -- : BFD_RELOC_AARCH64_BRANCH19 +- AArch64 19 bit pc-relative conditional branch and compare & branch. +- The lowest two bits must be zero and are not stored in the +- instruction, giving a 21 bit signed byte offset. +- +- -- : BFD_RELOC_AARCH64_JUMP26 +- AArch64 26 bit pc-relative unconditional branch. The lowest two +- bits must be zero and are not stored in the instruction, giving a +- 28 bit signed byte offset. +- +- -- : BFD_RELOC_AARCH64_CALL26 +- AArch64 26 bit pc-relative unconditional branch and link. The +- lowest two bits must be zero and are not stored in the instruction, +- giving a 28 bit signed byte offset. +- +- -- : BFD_RELOC_AARCH64_LDST16_LO12 +- AArch64 16-bit load/store instruction, holding bits 0 to 11 of the +- address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_LDST32_LO12 +- AArch64 32-bit load/store instruction, holding bits 0 to 11 of the +- address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_LDST64_LO12 +- AArch64 64-bit load/store instruction, holding bits 0 to 11 of the +- address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_LDST128_LO12 +- AArch64 128-bit load/store instruction, holding bits 0 to 11 of the +- address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_GOT_LD_PREL19 +- AArch64 Load Literal instruction, holding a 19 bit PC relative word +- offset of the global offset table entry for a symbol. The lowest +- two bits must be zero and are not stored in the instruction, +- giving a 21 bit signed byte offset. This relocation type requires +- signed overflow checking. +- +- -- : BFD_RELOC_AARCH64_ADR_GOT_PAGE +- Get to the page base of the global offset table entry for a symbol +- as part of an ADRP instruction using a 21 bit PC relative +- value.Used in conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC. +- +- -- : BFD_RELOC_AARCH64_LD64_GOT_LO12_NC +- Unsigned 12 bit byte offset for 64 bit load/store from the page of +- the GOT entry for this symbol. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in LP64 ABI only. +- +- -- : BFD_RELOC_AARCH64_LD32_GOT_LO12_NC +- Unsigned 12 bit byte offset for 32 bit load/store from the page of +- the GOT entry for this symbol. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in ILP32 ABI only. +- +- -- : BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 +- Get to the page base of the global offset table entry for a symbols +- tls_index structure as part of an adrp instruction using a 21 bit +- PC relative value. Used in conjunction with +- BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC. +- +- -- : BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC +- Unsigned 12 bit byte offset to global offset table entry for a +- symbols tls_index structure. Used in conjunction with +- BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21. +- +- -- : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 +- AArch64 TLS INITIAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC +- AArch64 TLS INITIAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 +- AArch64 TLS INITIAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC +- AArch64 TLS INITIAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC +- AArch64 TLS INITIAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 +- AArch64 TLS INITIAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC +- AArch64 TLS LOCAL EXEC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_OFF_G1 +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_LDR +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_ADD +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_CALL +- AArch64 TLS DESC relocation. +- +- -- : BFD_RELOC_AARCH64_COPY +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_GLOB_DAT +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_JUMP_SLOT +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_RELATIVE +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_TLS_DTPMOD +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_TLS_DTPREL +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_TLS_TPREL +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_TLSDESC +- AArch64 TLS relocation. +- +- -- : BFD_RELOC_AARCH64_IRELATIVE +- AArch64 support for STT_GNU_IFUNC. +- +- -- : BFD_RELOC_AARCH64_RELOC_END +- AArch64 pseudo relocation code to mark the end of the AArch64 +- relocation enumerators that have direct mapping to ELF reloc codes. +- There are a few more enumerators after this one; those are mainly +- used by the AArch64 assembler for the internal fixup or to select +- one of the above enumerators. +- +- -- : BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP +- AArch64 pseudo relocation code to be used internally by the AArch64 +- assembler and not (currently) written to any object files. +- +- -- : BFD_RELOC_AARCH64_LDST_LO12 +- AArch64 unspecified load/store instruction, holding bits 0 to 11 +- of the address. Used in conjunction with +- BFD_RELOC_AARCH64_ADR_HI21_PCREL. +- +- -- : BFD_RELOC_AARCH64_LD_GOT_LO12_NC +- AArch64 pseudo relocation code to be used internally by the AArch64 +- assembler and not (currently) written to any object files. +- +- -- : BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC +- AArch64 pseudo relocation code to be used internally by the AArch64 +- assembler and not (currently) written to any object files. +- +- -- : BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC +- AArch64 pseudo relocation code to be used internally by the AArch64 +- assembler and not (currently) written to any object files. +- +- -- : BFD_RELOC_TILEPRO_COPY +- -- : BFD_RELOC_TILEPRO_GLOB_DAT +- -- : BFD_RELOC_TILEPRO_JMP_SLOT +- -- : BFD_RELOC_TILEPRO_RELATIVE +- -- : BFD_RELOC_TILEPRO_BROFF_X1 +- -- : BFD_RELOC_TILEPRO_JOFFLONG_X1 +- -- : BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT +- -- : BFD_RELOC_TILEPRO_IMM8_X0 +- -- : BFD_RELOC_TILEPRO_IMM8_Y0 +- -- : BFD_RELOC_TILEPRO_IMM8_X1 +- -- : BFD_RELOC_TILEPRO_IMM8_Y1 +- -- : BFD_RELOC_TILEPRO_DEST_IMM8_X1 +- -- : BFD_RELOC_TILEPRO_MT_IMM15_X1 +- -- : BFD_RELOC_TILEPRO_MF_IMM15_X1 +- -- : BFD_RELOC_TILEPRO_IMM16_X0 +- -- : BFD_RELOC_TILEPRO_IMM16_X1 +- -- : BFD_RELOC_TILEPRO_IMM16_X0_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X1_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X0_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X1_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X0_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X1_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X0_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X1_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL +- -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT +- -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT +- -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA +- -- : BFD_RELOC_TILEPRO_MMSTART_X0 +- -- : BFD_RELOC_TILEPRO_MMEND_X0 +- -- : BFD_RELOC_TILEPRO_MMSTART_X1 +- -- : BFD_RELOC_TILEPRO_MMEND_X1 +- -- : BFD_RELOC_TILEPRO_SHAMT_X0 +- -- : BFD_RELOC_TILEPRO_SHAMT_X1 +- -- : BFD_RELOC_TILEPRO_SHAMT_Y0 +- -- : BFD_RELOC_TILEPRO_SHAMT_Y1 +- -- : BFD_RELOC_TILEPRO_TLS_GD_CALL +- -- : BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD +- -- : BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD +- -- : BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD +- -- : BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD +- -- : BFD_RELOC_TILEPRO_TLS_IE_LOAD +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA +- -- : BFD_RELOC_TILEPRO_TLS_DTPMOD32 +- -- : BFD_RELOC_TILEPRO_TLS_DTPOFF32 +- -- : BFD_RELOC_TILEPRO_TLS_TPOFF32 +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI +- -- : BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA +- -- : BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA +- Tilera TILEPro Relocations. +- +- -- : BFD_RELOC_TILEGX_HW0 +- -- : BFD_RELOC_TILEGX_HW1 +- -- : BFD_RELOC_TILEGX_HW2 +- -- : BFD_RELOC_TILEGX_HW3 +- -- : BFD_RELOC_TILEGX_HW0_LAST +- -- : BFD_RELOC_TILEGX_HW1_LAST +- -- : BFD_RELOC_TILEGX_HW2_LAST +- -- : BFD_RELOC_TILEGX_COPY +- -- : BFD_RELOC_TILEGX_GLOB_DAT +- -- : BFD_RELOC_TILEGX_JMP_SLOT +- -- : BFD_RELOC_TILEGX_RELATIVE +- -- : BFD_RELOC_TILEGX_BROFF_X1 +- -- : BFD_RELOC_TILEGX_JUMPOFF_X1 +- -- : BFD_RELOC_TILEGX_JUMPOFF_X1_PLT +- -- : BFD_RELOC_TILEGX_IMM8_X0 +- -- : BFD_RELOC_TILEGX_IMM8_Y0 +- -- : BFD_RELOC_TILEGX_IMM8_X1 +- -- : BFD_RELOC_TILEGX_IMM8_Y1 +- -- : BFD_RELOC_TILEGX_DEST_IMM8_X1 +- -- : BFD_RELOC_TILEGX_MT_IMM14_X1 +- -- : BFD_RELOC_TILEGX_MF_IMM14_X1 +- -- : BFD_RELOC_TILEGX_MMSTART_X0 +- -- : BFD_RELOC_TILEGX_MMEND_X0 +- -- : BFD_RELOC_TILEGX_SHAMT_X0 +- -- : BFD_RELOC_TILEGX_SHAMT_X1 +- -- : BFD_RELOC_TILEGX_SHAMT_Y0 +- -- : BFD_RELOC_TILEGX_SHAMT_Y1 +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0 +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0 +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1 +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1 +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW2 +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW2 +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW3 +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW3 +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE +- -- : BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE +- -- : BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE +- -- : BFD_RELOC_TILEGX_TLS_DTPMOD64 +- -- : BFD_RELOC_TILEGX_TLS_DTPOFF64 +- -- : BFD_RELOC_TILEGX_TLS_TPOFF64 +- -- : BFD_RELOC_TILEGX_TLS_DTPMOD32 +- -- : BFD_RELOC_TILEGX_TLS_DTPOFF32 +- -- : BFD_RELOC_TILEGX_TLS_TPOFF32 +- -- : BFD_RELOC_TILEGX_TLS_GD_CALL +- -- : BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD +- -- : BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD +- -- : BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD +- -- : BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD +- -- : BFD_RELOC_TILEGX_TLS_IE_LOAD +- -- : BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD +- -- : BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD +- -- : BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD +- -- : BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD +- Tilera TILE-Gx Relocations. +- +- -- : BFD_RELOC_EPIPHANY_SIMM8 +- Adapteva EPIPHANY - 8 bit signed pc-relative displacement +- +- -- : BFD_RELOC_EPIPHANY_SIMM24 +- Adapteva EPIPHANY - 24 bit signed pc-relative displacement +- +- -- : BFD_RELOC_EPIPHANY_HIGH +- Adapteva EPIPHANY - 16 most-significant bits of absolute address +- +- -- : BFD_RELOC_EPIPHANY_LOW +- Adapteva EPIPHANY - 16 least-significant bits of absolute address +- +- -- : BFD_RELOC_EPIPHANY_SIMM11 +- Adapteva EPIPHANY - 11 bit signed number - add/sub immediate +- +- -- : BFD_RELOC_EPIPHANY_IMM11 +- Adapteva EPIPHANY - 11 bit sign-magnitude number (ld/st +- displacement) +- +- -- : BFD_RELOC_EPIPHANY_IMM8 +- Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction. +- +- +- typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; +- +-2.10.2.2 `bfd_reloc_type_lookup' +-................................ +- +-*Synopsis* +- reloc_howto_type *bfd_reloc_type_lookup +- (bfd *abfd, bfd_reloc_code_real_type code); +- reloc_howto_type *bfd_reloc_name_lookup +- (bfd *abfd, const char *reloc_name); +- *Description* +-Return a pointer to a howto structure which, when invoked, will perform +-the relocation CODE on data from the architecture noted. +- +-2.10.2.3 `bfd_default_reloc_type_lookup' +-........................................ +- +-*Synopsis* +- reloc_howto_type *bfd_default_reloc_type_lookup +- (bfd *abfd, bfd_reloc_code_real_type code); +- *Description* +-Provides a default relocation lookup routine for any architecture. +- +-2.10.2.4 `bfd_get_reloc_code_name' +-.................................. +- +-*Synopsis* +- const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); +- *Description* +-Provides a printable name for the supplied relocation code. Useful +-mainly for printing error messages. +- +-2.10.2.5 `bfd_generic_relax_section' +-.................................... +- +-*Synopsis* +- bfd_boolean bfd_generic_relax_section +- (bfd *abfd, +- asection *section, +- struct bfd_link_info *, +- bfd_boolean *); +- *Description* +-Provides default handling for relaxing for back ends which don't do +-relaxing. +- +-2.10.2.6 `bfd_generic_gc_sections' +-.................................. +- +-*Synopsis* +- bfd_boolean bfd_generic_gc_sections +- (bfd *, struct bfd_link_info *); +- *Description* +-Provides default handling for relaxing for back ends which don't do +-section gc - i.e., does nothing. +- +-2.10.2.7 `bfd_generic_lookup_section_flags' +-........................................... +- +-*Synopsis* +- bfd_boolean bfd_generic_lookup_section_flags +- (struct bfd_link_info *, struct flag_info *, asection *); +- *Description* +-Provides default handling for section flags lookup - i.e., does nothing. +-Returns FALSE if the section should be omitted, otherwise TRUE. +- +-2.10.2.8 `bfd_generic_merge_sections' +-..................................... +- +-*Synopsis* +- bfd_boolean bfd_generic_merge_sections +- (bfd *, struct bfd_link_info *); +- *Description* +-Provides default handling for SEC_MERGE section merging for back ends +-which don't have SEC_MERGE support - i.e., does nothing. +- +-2.10.2.9 `bfd_generic_get_relocated_section_contents' +-..................................................... +- +-*Synopsis* +- bfd_byte *bfd_generic_get_relocated_section_contents +- (bfd *abfd, +- struct bfd_link_info *link_info, +- struct bfd_link_order *link_order, +- bfd_byte *data, +- bfd_boolean relocatable, +- asymbol **symbols); +- *Description* +-Provides default handling of relocation effort for back ends which +-can't be bothered to do it efficiently. +- +- +-File: bfd.info, Node: Core Files, Next: Targets, Prev: Relocations, Up: BFD front end +- +-2.11 Core files +-=============== +- +-2.11.1 Core file functions +--------------------------- +- +-*Description* +-These are functions pertaining to core files. +- +-2.11.1.1 `bfd_core_file_failing_command' +-........................................ +- +-*Synopsis* +- const char *bfd_core_file_failing_command (bfd *abfd); +- *Description* +-Return a read-only string explaining which program was running when it +-failed and produced the core file ABFD. +- +-2.11.1.2 `bfd_core_file_failing_signal' +-....................................... +- +-*Synopsis* +- int bfd_core_file_failing_signal (bfd *abfd); +- *Description* +-Returns the signal number which caused the core dump which generated +-the file the BFD ABFD is attached to. +- +-2.11.1.3 `bfd_core_file_pid' +-............................ +- +-*Synopsis* +- int bfd_core_file_pid (bfd *abfd); +- *Description* +-Returns the PID of the process the core dump the BFD ABFD is attached +-to was generated from. +- +-2.11.1.4 `core_file_matches_executable_p' +-......................................... +- +-*Synopsis* +- bfd_boolean core_file_matches_executable_p +- (bfd *core_bfd, bfd *exec_bfd); +- *Description* +-Return `TRUE' if the core file attached to CORE_BFD was generated by a +-run of the executable file attached to EXEC_BFD, `FALSE' otherwise. +- +-2.11.1.5 `generic_core_file_matches_executable_p' +-................................................. +- +-*Synopsis* +- bfd_boolean generic_core_file_matches_executable_p +- (bfd *core_bfd, bfd *exec_bfd); +- *Description* +-Return TRUE if the core file attached to CORE_BFD was generated by a +-run of the executable file attached to EXEC_BFD. The match is based on +-executable basenames only. +- +- Note: When not able to determine the core file failing command or +-the executable name, we still return TRUE even though we're not sure +-that core file and executable match. This is to avoid generating a +-false warning in situations where we really don't know whether they +-match or not. +- +- +-File: bfd.info, Node: Targets, Next: Architectures, Prev: Core Files, Up: BFD front end +- +-2.12 Targets +-============ +- +-*Description* +-Each port of BFD to a different machine requires the creation of a +-target back end. All the back end provides to the root part of BFD is a +-structure containing pointers to functions which perform certain low +-level operations on files. BFD translates the applications's requests +-through a pointer into calls to the back end routines. +- +- When a file is opened with `bfd_openr', its format and target are +-unknown. BFD uses various mechanisms to determine how to interpret the +-file. The operations performed are: +- +- * Create a BFD by calling the internal routine `_bfd_new_bfd', then +- call `bfd_find_target' with the target string supplied to +- `bfd_openr' and the new BFD pointer. +- +- * If a null target string was provided to `bfd_find_target', look up +- the environment variable `GNUTARGET' and use that as the target +- string. +- +- * If the target string is still `NULL', or the target string is +- `default', then use the first item in the target vector as the +- target type, and set `target_defaulted' in the BFD to cause +- `bfd_check_format' to loop through all the targets. *Note +- bfd_target::. *Note Formats::. +- +- * Otherwise, inspect the elements in the target vector one by one, +- until a match on target name is found. When found, use it. +- +- * Otherwise return the error `bfd_error_invalid_target' to +- `bfd_openr'. +- +- * `bfd_openr' attempts to open the file using `bfd_open_file', and +- returns the BFD. +- Once the BFD has been opened and the target selected, the file +-format may be determined. This is done by calling `bfd_check_format' on +-the BFD with a suggested format. If `target_defaulted' has been set, +-each possible target type is tried to see if it recognizes the +-specified format. `bfd_check_format' returns `TRUE' when the caller +-guesses right. +- +-* Menu: +- +-* bfd_target:: +- +- +-File: bfd.info, Node: bfd_target, Prev: Targets, Up: Targets +- +-2.12.1 bfd_target +------------------ +- +-*Description* +-This structure contains everything that BFD knows about a target. It +-includes things like its byte order, name, and which routines to call +-to do various operations. +- +- Every BFD points to a target structure with its `xvec' member. +- +- The macros below are used to dispatch to functions through the +-`bfd_target' vector. They are used in a number of macros further down +-in `bfd.h', and are also used when calling various routines by hand +-inside the BFD implementation. The ARGLIST argument must be +-parenthesized; it contains all the arguments to the called function. +- +- They make the documentation (more) unpleasant to read, so if someone +-wants to fix this and not break the above, please do. +- #define BFD_SEND(bfd, message, arglist) \ +- ((*((bfd)->xvec->message)) arglist) +- +- #ifdef DEBUG_BFD_SEND +- #undef BFD_SEND +- #define BFD_SEND(bfd, message, arglist) \ +- (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ +- ((*((bfd)->xvec->message)) arglist) : \ +- (bfd_assert (__FILE__,__LINE__), NULL)) +- #endif +- For operations which index on the BFD format: +- #define BFD_SEND_FMT(bfd, message, arglist) \ +- (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) +- +- #ifdef DEBUG_BFD_SEND +- #undef BFD_SEND_FMT +- #define BFD_SEND_FMT(bfd, message, arglist) \ +- (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ +- (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ +- (bfd_assert (__FILE__,__LINE__), NULL)) +- #endif +- This is the structure which defines the type of BFD this is. The +-`xvec' member of the struct `bfd' itself points here. Each module that +-implements access to a different target under BFD, defines one of these. +- +- FIXME, these names should be rationalised with the names of the +-entry points which call them. Too bad we can't have one macro to define +-them both! +- enum bfd_flavour +- { +- bfd_target_unknown_flavour, +- bfd_target_aout_flavour, +- bfd_target_coff_flavour, +- bfd_target_ecoff_flavour, +- bfd_target_xcoff_flavour, +- bfd_target_elf_flavour, +- bfd_target_ieee_flavour, +- bfd_target_nlm_flavour, +- bfd_target_oasys_flavour, +- bfd_target_tekhex_flavour, +- bfd_target_srec_flavour, +- bfd_target_verilog_flavour, +- bfd_target_ihex_flavour, +- bfd_target_som_flavour, +- bfd_target_os9k_flavour, +- bfd_target_versados_flavour, +- bfd_target_msdos_flavour, +- bfd_target_ovax_flavour, +- bfd_target_evax_flavour, +- bfd_target_mmo_flavour, +- bfd_target_mach_o_flavour, +- bfd_target_pef_flavour, +- bfd_target_pef_xlib_flavour, +- bfd_target_sym_flavour +- }; +- +- enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; +- +- /* Forward declaration. */ +- typedef struct bfd_link_info _bfd_link_info; +- +- /* Forward declaration. */ +- typedef struct flag_info flag_info; +- +- typedef struct bfd_target +- { +- /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ +- char *name; +- +- /* The "flavour" of a back end is a general indication about +- the contents of a file. */ +- enum bfd_flavour flavour; +- +- /* The order of bytes within the data area of a file. */ +- enum bfd_endian byteorder; +- +- /* The order of bytes within the header parts of a file. */ +- enum bfd_endian header_byteorder; +- +- /* A mask of all the flags which an executable may have set - +- from the set `BFD_NO_FLAGS', `HAS_RELOC', ...`D_PAGED'. */ +- flagword object_flags; +- +- /* A mask of all the flags which a section may have set - from +- the set `SEC_NO_FLAGS', `SEC_ALLOC', ...`SET_NEVER_LOAD'. */ +- flagword section_flags; +- +- /* The character normally found at the front of a symbol. +- (if any), perhaps `_'. */ +- char symbol_leading_char; +- +- /* The pad character for file names within an archive header. */ +- char ar_pad_char; +- +- /* The maximum number of characters in an archive header. */ +- unsigned char ar_max_namelen; +- +- /* How well this target matches, used to select between various +- possible targets when more than one target matches. */ +- unsigned char match_priority; +- +- /* Entries for byte swapping for data. These are different from the +- other entry points, since they don't take a BFD as the first argument. +- Certain other handlers could do the same. */ +- bfd_uint64_t (*bfd_getx64) (const void *); +- bfd_int64_t (*bfd_getx_signed_64) (const void *); +- void (*bfd_putx64) (bfd_uint64_t, void *); +- bfd_vma (*bfd_getx32) (const void *); +- bfd_signed_vma (*bfd_getx_signed_32) (const void *); +- void (*bfd_putx32) (bfd_vma, void *); +- bfd_vma (*bfd_getx16) (const void *); +- bfd_signed_vma (*bfd_getx_signed_16) (const void *); +- void (*bfd_putx16) (bfd_vma, void *); +- +- /* Byte swapping for the headers. */ +- bfd_uint64_t (*bfd_h_getx64) (const void *); +- bfd_int64_t (*bfd_h_getx_signed_64) (const void *); +- void (*bfd_h_putx64) (bfd_uint64_t, void *); +- bfd_vma (*bfd_h_getx32) (const void *); +- bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); +- void (*bfd_h_putx32) (bfd_vma, void *); +- bfd_vma (*bfd_h_getx16) (const void *); +- bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); +- void (*bfd_h_putx16) (bfd_vma, void *); +- +- /* Format dependent routines: these are vectors of entry points +- within the target vector structure, one for each format to check. */ +- +- /* Check the format of a file being read. Return a `bfd_target *' or zero. */ +- const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); +- +- /* Set the format of a file being written. */ +- bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); +- +- /* Write cached information into a file being written, at `bfd_close'. */ +- bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); +- The general target vector. These vectors are initialized using the +-BFD_JUMP_TABLE macros. +- +- /* Generic entry points. */ +- #define BFD_JUMP_TABLE_GENERIC(NAME) \ +- NAME##_close_and_cleanup, \ +- NAME##_bfd_free_cached_info, \ +- NAME##_new_section_hook, \ +- NAME##_get_section_contents, \ +- NAME##_get_section_contents_in_window +- +- /* Called when the BFD is being closed to do any necessary cleanup. */ +- bfd_boolean (*_close_and_cleanup) (bfd *); +- /* Ask the BFD to free all cached information. */ +- bfd_boolean (*_bfd_free_cached_info) (bfd *); +- /* Called when a new section is created. */ +- bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); +- /* Read the contents of a section. */ +- bfd_boolean (*_bfd_get_section_contents) +- (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); +- bfd_boolean (*_bfd_get_section_contents_in_window) +- (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); +- +- /* Entry points to copy private data. */ +- #define BFD_JUMP_TABLE_COPY(NAME) \ +- NAME##_bfd_copy_private_bfd_data, \ +- NAME##_bfd_merge_private_bfd_data, \ +- _bfd_generic_init_private_section_data, \ +- NAME##_bfd_copy_private_section_data, \ +- NAME##_bfd_copy_private_symbol_data, \ +- NAME##_bfd_copy_private_header_data, \ +- NAME##_bfd_set_private_flags, \ +- NAME##_bfd_print_private_bfd_data +- +- /* Called to copy BFD general private data from one object file +- to another. */ +- bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); +- /* Called to merge BFD general private data from one object file +- to a common output file when linking. */ +- bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); +- /* Called to initialize BFD private section data from one object file +- to another. */ +- #define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \ +- BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info)) +- bfd_boolean (*_bfd_init_private_section_data) +- (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *); +- /* Called to copy BFD private section data from one object file +- to another. */ +- bfd_boolean (*_bfd_copy_private_section_data) +- (bfd *, sec_ptr, bfd *, sec_ptr); +- /* Called to copy BFD private symbol data from one symbol +- to another. */ +- bfd_boolean (*_bfd_copy_private_symbol_data) +- (bfd *, asymbol *, bfd *, asymbol *); +- /* Called to copy BFD private header data from one object file +- to another. */ +- bfd_boolean (*_bfd_copy_private_header_data) +- (bfd *, bfd *); +- /* Called to set private backend flags. */ +- bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); +- +- /* Called to print private BFD data. */ +- bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); +- +- /* Core file entry points. */ +- #define BFD_JUMP_TABLE_CORE(NAME) \ +- NAME##_core_file_failing_command, \ +- NAME##_core_file_failing_signal, \ +- NAME##_core_file_matches_executable_p, \ +- NAME##_core_file_pid +- +- char * (*_core_file_failing_command) (bfd *); +- int (*_core_file_failing_signal) (bfd *); +- bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); +- int (*_core_file_pid) (bfd *); +- +- /* Archive entry points. */ +- #define BFD_JUMP_TABLE_ARCHIVE(NAME) \ +- NAME##_slurp_armap, \ +- NAME##_slurp_extended_name_table, \ +- NAME##_construct_extended_name_table, \ +- NAME##_truncate_arname, \ +- NAME##_write_armap, \ +- NAME##_read_ar_hdr, \ +- NAME##_write_ar_hdr, \ +- NAME##_openr_next_archived_file, \ +- NAME##_get_elt_at_index, \ +- NAME##_generic_stat_arch_elt, \ +- NAME##_update_armap_timestamp +- +- bfd_boolean (*_bfd_slurp_armap) (bfd *); +- bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); +- bfd_boolean (*_bfd_construct_extended_name_table) +- (bfd *, char **, bfd_size_type *, const char **); +- void (*_bfd_truncate_arname) (bfd *, const char *, char *); +- bfd_boolean (*write_armap) +- (bfd *, unsigned int, struct orl *, unsigned int, int); +- void * (*_bfd_read_ar_hdr_fn) (bfd *); +- bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *); +- bfd * (*openr_next_archived_file) (bfd *, bfd *); +- #define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) +- bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); +- int (*_bfd_stat_arch_elt) (bfd *, struct stat *); +- bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); +- +- /* Entry points used for symbols. */ +- #define BFD_JUMP_TABLE_SYMBOLS(NAME) \ +- NAME##_get_symtab_upper_bound, \ +- NAME##_canonicalize_symtab, \ +- NAME##_make_empty_symbol, \ +- NAME##_print_symbol, \ +- NAME##_get_symbol_info, \ +- NAME##_bfd_is_local_label_name, \ +- NAME##_bfd_is_target_special_symbol, \ +- NAME##_get_lineno, \ +- NAME##_find_nearest_line, \ +- _bfd_generic_find_nearest_line_discriminator, \ +- _bfd_generic_find_line, \ +- NAME##_find_inliner_info, \ +- NAME##_bfd_make_debug_symbol, \ +- NAME##_read_minisymbols, \ +- NAME##_minisymbol_to_symbol +- +- long (*_bfd_get_symtab_upper_bound) (bfd *); +- long (*_bfd_canonicalize_symtab) +- (bfd *, struct bfd_symbol **); +- struct bfd_symbol * +- (*_bfd_make_empty_symbol) (bfd *); +- void (*_bfd_print_symbol) +- (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); +- #define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) +- void (*_bfd_get_symbol_info) +- (bfd *, struct bfd_symbol *, symbol_info *); +- #define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) +- bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); +- bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); +- alent * (*_get_lineno) (bfd *, struct bfd_symbol *); +- bfd_boolean (*_bfd_find_nearest_line) +- (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, +- const char **, const char **, unsigned int *); +- bfd_boolean (*_bfd_find_nearest_line_discriminator) +- (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, +- const char **, const char **, unsigned int *, unsigned int *); +- bfd_boolean (*_bfd_find_line) +- (bfd *, struct bfd_symbol **, struct bfd_symbol *, +- const char **, unsigned int *); +- bfd_boolean (*_bfd_find_inliner_info) +- (bfd *, const char **, const char **, unsigned int *); +- /* Back-door to allow format-aware applications to create debug symbols +- while using BFD for everything else. Currently used by the assembler +- when creating COFF files. */ +- asymbol * (*_bfd_make_debug_symbol) +- (bfd *, void *, unsigned long size); +- #define bfd_read_minisymbols(b, d, m, s) \ +- BFD_SEND (b, _read_minisymbols, (b, d, m, s)) +- long (*_read_minisymbols) +- (bfd *, bfd_boolean, void **, unsigned int *); +- #define bfd_minisymbol_to_symbol(b, d, m, f) \ +- BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) +- asymbol * (*_minisymbol_to_symbol) +- (bfd *, bfd_boolean, const void *, asymbol *); +- +- /* Routines for relocs. */ +- #define BFD_JUMP_TABLE_RELOCS(NAME) \ +- NAME##_get_reloc_upper_bound, \ +- NAME##_canonicalize_reloc, \ +- NAME##_bfd_reloc_type_lookup, \ +- NAME##_bfd_reloc_name_lookup +- +- long (*_get_reloc_upper_bound) (bfd *, sec_ptr); +- long (*_bfd_canonicalize_reloc) +- (bfd *, sec_ptr, arelent **, struct bfd_symbol **); +- /* See documentation on reloc types. */ +- reloc_howto_type * +- (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); +- reloc_howto_type * +- (*reloc_name_lookup) (bfd *, const char *); +- +- +- /* Routines used when writing an object file. */ +- #define BFD_JUMP_TABLE_WRITE(NAME) \ +- NAME##_set_arch_mach, \ +- NAME##_set_section_contents +- +- bfd_boolean (*_bfd_set_arch_mach) +- (bfd *, enum bfd_architecture, unsigned long); +- bfd_boolean (*_bfd_set_section_contents) +- (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); +- +- /* Routines used by the linker. */ +- #define BFD_JUMP_TABLE_LINK(NAME) \ +- NAME##_sizeof_headers, \ +- NAME##_bfd_get_relocated_section_contents, \ +- NAME##_bfd_relax_section, \ +- NAME##_bfd_link_hash_table_create, \ +- NAME##_bfd_link_hash_table_free, \ +- NAME##_bfd_link_add_symbols, \ +- NAME##_bfd_link_just_syms, \ +- NAME##_bfd_copy_link_hash_symbol_type, \ +- NAME##_bfd_final_link, \ +- NAME##_bfd_link_split_section, \ +- NAME##_bfd_gc_sections, \ +- NAME##_bfd_lookup_section_flags, \ +- NAME##_bfd_merge_sections, \ +- NAME##_bfd_is_group_section, \ +- NAME##_bfd_discard_group, \ +- NAME##_section_already_linked, \ +- NAME##_bfd_define_common_symbol +- +- int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *); +- bfd_byte * (*_bfd_get_relocated_section_contents) +- (bfd *, struct bfd_link_info *, struct bfd_link_order *, +- bfd_byte *, bfd_boolean, struct bfd_symbol **); +- +- bfd_boolean (*_bfd_relax_section) +- (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); +- +- /* Create a hash table for the linker. Different backends store +- different information in this table. */ +- struct bfd_link_hash_table * +- (*_bfd_link_hash_table_create) (bfd *); +- +- /* Release the memory associated with the linker hash table. */ +- void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); +- +- /* Add symbols from this object file into the hash table. */ +- bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); +- +- /* Indicate that we are only retrieving symbol values from this section. */ +- void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); +- +- /* Copy the symbol type of a linker hash table entry. */ +- #define bfd_copy_link_hash_symbol_type(b, t, f) \ +- BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f)) +- void (*_bfd_copy_link_hash_symbol_type) +- (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); +- +- /* Do a link based on the link_order structures attached to each +- section of the BFD. */ +- bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); +- +- /* Should this section be split up into smaller pieces during linking. */ +- bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); +- +- /* Remove sections that are not referenced from the output. */ +- bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); +- +- /* Sets the bitmask of allowed and disallowed section flags. */ +- bfd_boolean (*_bfd_lookup_section_flags) (struct bfd_link_info *, +- struct flag_info *, +- asection *); +- +- /* Attempt to merge SEC_MERGE sections. */ +- bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); +- +- /* Is this section a member of a group? */ +- bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); +- +- /* Discard members of a group. */ +- bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); +- +- /* Check if SEC has been already linked during a reloceatable or +- final link. */ +- bfd_boolean (*_section_already_linked) (bfd *, asection *, +- struct bfd_link_info *); +- +- /* Define a common symbol. */ +- bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *, +- struct bfd_link_hash_entry *); +- +- /* Routines to handle dynamic symbols and relocs. */ +- #define BFD_JUMP_TABLE_DYNAMIC(NAME) \ +- NAME##_get_dynamic_symtab_upper_bound, \ +- NAME##_canonicalize_dynamic_symtab, \ +- NAME##_get_synthetic_symtab, \ +- NAME##_get_dynamic_reloc_upper_bound, \ +- NAME##_canonicalize_dynamic_reloc +- +- /* Get the amount of memory required to hold the dynamic symbols. */ +- long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); +- /* Read in the dynamic symbols. */ +- long (*_bfd_canonicalize_dynamic_symtab) +- (bfd *, struct bfd_symbol **); +- /* Create synthetized symbols. */ +- long (*_bfd_get_synthetic_symtab) +- (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, +- struct bfd_symbol **); +- /* Get the amount of memory required to hold the dynamic relocs. */ +- long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); +- /* Read in the dynamic relocs. */ +- long (*_bfd_canonicalize_dynamic_reloc) +- (bfd *, arelent **, struct bfd_symbol **); +- A pointer to an alternative bfd_target in case the current one is not +-satisfactory. This can happen when the target cpu supports both big +-and little endian code, and target chosen by the linker has the wrong +-endianness. The function open_output() in ld/ldlang.c uses this field +-to find an alternative output format that is suitable. +- /* Opposite endian version of this target. */ +- const struct bfd_target * alternative_target; +- +- /* Data for use by back-end routines, which isn't +- generic enough to belong in this structure. */ +- const void *backend_data; +- +- } bfd_target; +- +-2.12.1.1 `bfd_set_default_target' +-................................. +- +-*Synopsis* +- bfd_boolean bfd_set_default_target (const char *name); +- *Description* +-Set the default target vector to use when recognizing a BFD. This +-takes the name of the target, which may be a BFD target name or a +-configuration triplet. +- +-2.12.1.2 `bfd_find_target' +-.......................... +- +-*Synopsis* +- const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); +- *Description* +-Return a pointer to the transfer vector for the object target named +-TARGET_NAME. If TARGET_NAME is `NULL', choose the one in the +-environment variable `GNUTARGET'; if that is null or not defined, then +-choose the first entry in the target list. Passing in the string +-"default" or setting the environment variable to "default" will cause +-the first entry in the target list to be returned, and +-"target_defaulted" will be set in the BFD if ABFD isn't `NULL'. This +-causes `bfd_check_format' to loop over all the targets to find the one +-that matches the file being read. +- +-2.12.1.3 `bfd_get_target_info' +-.............................. +- +-*Synopsis* +- const bfd_target *bfd_get_target_info (const char *target_name, +- bfd *abfd, +- bfd_boolean *is_bigendian, +- int *underscoring, +- const char **def_target_arch); +- *Description* +-Return a pointer to the transfer vector for the object target named +-TARGET_NAME. If TARGET_NAME is `NULL', choose the one in the +-environment variable `GNUTARGET'; if that is null or not defined, then +-choose the first entry in the target list. Passing in the string +-"default" or setting the environment variable to "default" will cause +-the first entry in the target list to be returned, and +-"target_defaulted" will be set in the BFD if ABFD isn't `NULL'. This +-causes `bfd_check_format' to loop over all the targets to find the one +-that matches the file being read. If IS_BIGENDIAN is not `NULL', then +-set this value to target's endian mode. True for big-endian, FALSE for +-little-endian or for invalid target. If UNDERSCORING is not `NULL', +-then set this value to target's underscoring mode. Zero for +-none-underscoring, -1 for invalid target, else the value of target +-vector's symbol underscoring. If DEF_TARGET_ARCH is not `NULL', then +-set it to the architecture string specified by the target_name. +- +-2.12.1.4 `bfd_target_list' +-.......................... +- +-*Synopsis* +- const char ** bfd_target_list (void); +- *Description* +-Return a freshly malloced NULL-terminated vector of the names of all +-the valid BFD targets. Do not modify the names. +- +-2.12.1.5 `bfd_seach_for_target' +-............................... +- +-*Synopsis* +- const bfd_target *bfd_search_for_target +- (int (*search_func) (const bfd_target *, void *), +- void *); +- *Description* +-Return a pointer to the first transfer vector in the list of transfer +-vectors maintained by BFD that produces a non-zero result when passed +-to the function SEARCH_FUNC. The parameter DATA is passed, unexamined, +-to the search function. +- +- +-File: bfd.info, Node: Architectures, Next: Opening and Closing, Prev: Targets, Up: BFD front end +- +-2.13 Architectures +-================== +- +-BFD keeps one atom in a BFD describing the architecture of the data +-attached to the BFD: a pointer to a `bfd_arch_info_type'. +- +- Pointers to structures can be requested independently of a BFD so +-that an architecture's information can be interrogated without access +-to an open BFD. +- +- The architecture information is provided by each architecture +-package. The set of default architectures is selected by the macro +-`SELECT_ARCHITECTURES'. This is normally set up in the +-`config/TARGET.mt' file of your choice. If the name is not defined, +-then all the architectures supported are included. +- +- When BFD starts up, all the architectures are called with an +-initialize method. It is up to the architecture back end to insert as +-many items into the list of architectures as it wants to; generally +-this would be one for each machine and one for the default case (an +-item with a machine field of 0). +- +- BFD's idea of an architecture is implemented in `archures.c'. +- +-2.13.1 bfd_architecture +------------------------ +- +-*Description* +-This enum gives the object file's CPU architecture, in a global +-sense--i.e., what processor family does it belong to? Another field +-indicates which processor within the family is in use. The machine +-gives a number which distinguishes different versions of the +-architecture, containing, for example, 2 and 3 for Intel i960 KA and +-i960 KB, and 68020 and 68030 for Motorola 68020 and 68030. +- enum bfd_architecture +- { +- bfd_arch_unknown, /* File arch not known. */ +- bfd_arch_obscure, /* Arch known, not one of these. */ +- bfd_arch_m68k, /* Motorola 68xxx */ +- #define bfd_mach_m68000 1 +- #define bfd_mach_m68008 2 +- #define bfd_mach_m68010 3 +- #define bfd_mach_m68020 4 +- #define bfd_mach_m68030 5 +- #define bfd_mach_m68040 6 +- #define bfd_mach_m68060 7 +- #define bfd_mach_cpu32 8 +- #define bfd_mach_fido 9 +- #define bfd_mach_mcf_isa_a_nodiv 10 +- #define bfd_mach_mcf_isa_a 11 +- #define bfd_mach_mcf_isa_a_mac 12 +- #define bfd_mach_mcf_isa_a_emac 13 +- #define bfd_mach_mcf_isa_aplus 14 +- #define bfd_mach_mcf_isa_aplus_mac 15 +- #define bfd_mach_mcf_isa_aplus_emac 16 +- #define bfd_mach_mcf_isa_b_nousp 17 +- #define bfd_mach_mcf_isa_b_nousp_mac 18 +- #define bfd_mach_mcf_isa_b_nousp_emac 19 +- #define bfd_mach_mcf_isa_b 20 +- #define bfd_mach_mcf_isa_b_mac 21 +- #define bfd_mach_mcf_isa_b_emac 22 +- #define bfd_mach_mcf_isa_b_float 23 +- #define bfd_mach_mcf_isa_b_float_mac 24 +- #define bfd_mach_mcf_isa_b_float_emac 25 +- #define bfd_mach_mcf_isa_c 26 +- #define bfd_mach_mcf_isa_c_mac 27 +- #define bfd_mach_mcf_isa_c_emac 28 +- #define bfd_mach_mcf_isa_c_nodiv 29 +- #define bfd_mach_mcf_isa_c_nodiv_mac 30 +- #define bfd_mach_mcf_isa_c_nodiv_emac 31 +- bfd_arch_vax, /* DEC Vax */ +- bfd_arch_i960, /* Intel 960 */ +- /* The order of the following is important. +- lower number indicates a machine type that +- only accepts a subset of the instructions +- available to machines with higher numbers. +- The exception is the "ca", which is +- incompatible with all other machines except +- "core". */ +- +- #define bfd_mach_i960_core 1 +- #define bfd_mach_i960_ka_sa 2 +- #define bfd_mach_i960_kb_sb 3 +- #define bfd_mach_i960_mc 4 +- #define bfd_mach_i960_xa 5 +- #define bfd_mach_i960_ca 6 +- #define bfd_mach_i960_jx 7 +- #define bfd_mach_i960_hx 8 +- +- bfd_arch_or32, /* OpenRISC 32 */ +- +- bfd_arch_sparc, /* SPARC */ +- #define bfd_mach_sparc 1 +- /* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ +- #define bfd_mach_sparc_sparclet 2 +- #define bfd_mach_sparc_sparclite 3 +- #define bfd_mach_sparc_v8plus 4 +- #define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ +- #define bfd_mach_sparc_sparclite_le 6 +- #define bfd_mach_sparc_v9 7 +- #define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ +- #define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ +- #define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ +- /* Nonzero if MACH has the v9 instruction set. */ +- #define bfd_mach_sparc_v9_p(mach) \ +- ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ +- && (mach) != bfd_mach_sparc_sparclite_le) +- /* Nonzero if MACH is a 64 bit sparc architecture. */ +- #define bfd_mach_sparc_64bit_p(mach) \ +- ((mach) >= bfd_mach_sparc_v9 && (mach) != bfd_mach_sparc_v8plusb) +- bfd_arch_spu, /* PowerPC SPU */ +- #define bfd_mach_spu 256 +- bfd_arch_mips, /* MIPS Rxxxx */ +- #define bfd_mach_mips3000 3000 +- #define bfd_mach_mips3900 3900 +- #define bfd_mach_mips4000 4000 +- #define bfd_mach_mips4010 4010 +- #define bfd_mach_mips4100 4100 +- #define bfd_mach_mips4111 4111 +- #define bfd_mach_mips4120 4120 +- #define bfd_mach_mips4300 4300 +- #define bfd_mach_mips4400 4400 +- #define bfd_mach_mips4600 4600 +- #define bfd_mach_mips4650 4650 +- #define bfd_mach_mips5000 5000 +- #define bfd_mach_mips5400 5400 +- #define bfd_mach_mips5500 5500 +- #define bfd_mach_mips5900 5900 +- #define bfd_mach_mips6000 6000 +- #define bfd_mach_mips7000 7000 +- #define bfd_mach_mips8000 8000 +- #define bfd_mach_mips9000 9000 +- #define bfd_mach_mips10000 10000 +- #define bfd_mach_mips12000 12000 +- #define bfd_mach_mips14000 14000 +- #define bfd_mach_mips16000 16000 +- #define bfd_mach_mips16 16 +- #define bfd_mach_mips5 5 +- #define bfd_mach_mips_loongson_2e 3001 +- #define bfd_mach_mips_loongson_2f 3002 +- #define bfd_mach_mips_loongson_3a 3003 +- #define bfd_mach_mips_sb1 12310201 /* octal 'SB', 01 */ +- #define bfd_mach_mips_octeon 6501 +- #define bfd_mach_mips_octeonp 6601 +- #define bfd_mach_mips_octeon2 6502 +- #define bfd_mach_mips_xlr 887682 /* decimal 'XLR' */ +- #define bfd_mach_mipsisa32 32 +- #define bfd_mach_mipsisa32r2 33 +- #define bfd_mach_mipsisa64 64 +- #define bfd_mach_mipsisa64r2 65 +- #define bfd_mach_mips_micromips 96 +- bfd_arch_i386, /* Intel 386 */ +- #define bfd_mach_i386_intel_syntax (1 << 0) +- #define bfd_mach_i386_i8086 (1 << 1) +- #define bfd_mach_i386_i386 (1 << 2) +- #define bfd_mach_x86_64 (1 << 3) +- #define bfd_mach_x64_32 (1 << 4) +- #define bfd_mach_i386_i386_intel_syntax (bfd_mach_i386_i386 | bfd_mach_i386_intel_syntax) +- #define bfd_mach_x86_64_intel_syntax (bfd_mach_x86_64 | bfd_mach_i386_intel_syntax) +- #define bfd_mach_x64_32_intel_syntax (bfd_mach_x64_32 | bfd_mach_i386_intel_syntax) +- bfd_arch_l1om, /* Intel L1OM */ +- #define bfd_mach_l1om (1 << 5) +- #define bfd_mach_l1om_intel_syntax (bfd_mach_l1om | bfd_mach_i386_intel_syntax) +- bfd_arch_k1om, /* Intel K1OM */ +- #define bfd_mach_k1om (1 << 6) +- #define bfd_mach_k1om_intel_syntax (bfd_mach_k1om | bfd_mach_i386_intel_syntax) +- #define bfd_mach_i386_nacl (1 << 7) +- #define bfd_mach_i386_i386_nacl (bfd_mach_i386_i386 | bfd_mach_i386_nacl) +- #define bfd_mach_x86_64_nacl (bfd_mach_x86_64 | bfd_mach_i386_nacl) +- #define bfd_mach_x64_32_nacl (bfd_mach_x64_32 | bfd_mach_i386_nacl) +- bfd_arch_we32k, /* AT&T WE32xxx */ +- bfd_arch_tahoe, /* CCI/Harris Tahoe */ +- bfd_arch_i860, /* Intel 860 */ +- bfd_arch_i370, /* IBM 360/370 Mainframes */ +- bfd_arch_romp, /* IBM ROMP PC/RT */ +- bfd_arch_convex, /* Convex */ +- bfd_arch_m88k, /* Motorola 88xxx */ +- bfd_arch_m98k, /* Motorola 98xxx */ +- bfd_arch_pyramid, /* Pyramid Technology */ +- bfd_arch_h8300, /* Renesas H8/300 (formerly Hitachi H8/300) */ +- #define bfd_mach_h8300 1 +- #define bfd_mach_h8300h 2 +- #define bfd_mach_h8300s 3 +- #define bfd_mach_h8300hn 4 +- #define bfd_mach_h8300sn 5 +- #define bfd_mach_h8300sx 6 +- #define bfd_mach_h8300sxn 7 +- bfd_arch_pdp11, /* DEC PDP-11 */ +- bfd_arch_plugin, +- bfd_arch_powerpc, /* PowerPC */ +- #define bfd_mach_ppc 32 +- #define bfd_mach_ppc64 64 +- #define bfd_mach_ppc_403 403 +- #define bfd_mach_ppc_403gc 4030 +- #define bfd_mach_ppc_405 405 +- #define bfd_mach_ppc_505 505 +- #define bfd_mach_ppc_601 601 +- #define bfd_mach_ppc_602 602 +- #define bfd_mach_ppc_603 603 +- #define bfd_mach_ppc_ec603e 6031 +- #define bfd_mach_ppc_604 604 +- #define bfd_mach_ppc_620 620 +- #define bfd_mach_ppc_630 630 +- #define bfd_mach_ppc_750 750 +- #define bfd_mach_ppc_860 860 +- #define bfd_mach_ppc_a35 35 +- #define bfd_mach_ppc_rs64ii 642 +- #define bfd_mach_ppc_rs64iii 643 +- #define bfd_mach_ppc_7400 7400 +- #define bfd_mach_ppc_e500 500 +- #define bfd_mach_ppc_e500mc 5001 +- #define bfd_mach_ppc_e500mc64 5005 +- #define bfd_mach_ppc_e5500 5006 +- #define bfd_mach_ppc_e6500 5007 +- #define bfd_mach_ppc_titan 83 +- #define bfd_mach_ppc_vle 84 +- bfd_arch_rs6000, /* IBM RS/6000 */ +- #define bfd_mach_rs6k 6000 +- #define bfd_mach_rs6k_rs1 6001 +- #define bfd_mach_rs6k_rsc 6003 +- #define bfd_mach_rs6k_rs2 6002 +- bfd_arch_hppa, /* HP PA RISC */ +- #define bfd_mach_hppa10 10 +- #define bfd_mach_hppa11 11 +- #define bfd_mach_hppa20 20 +- #define bfd_mach_hppa20w 25 +- bfd_arch_d10v, /* Mitsubishi D10V */ +- #define bfd_mach_d10v 1 +- #define bfd_mach_d10v_ts2 2 +- #define bfd_mach_d10v_ts3 3 +- bfd_arch_d30v, /* Mitsubishi D30V */ +- bfd_arch_dlx, /* DLX */ +- bfd_arch_m68hc11, /* Motorola 68HC11 */ +- bfd_arch_m68hc12, /* Motorola 68HC12 */ +- #define bfd_mach_m6812_default 0 +- #define bfd_mach_m6812 1 +- #define bfd_mach_m6812s 2 +- bfd_arch_m9s12x, /* Freescale S12X */ +- bfd_arch_m9s12xg, /* Freescale XGATE */ +- bfd_arch_z8k, /* Zilog Z8000 */ +- #define bfd_mach_z8001 1 +- #define bfd_mach_z8002 2 +- bfd_arch_h8500, /* Renesas H8/500 (formerly Hitachi H8/500) */ +- bfd_arch_sh, /* Renesas / SuperH SH (formerly Hitachi SH) */ +- #define bfd_mach_sh 1 +- #define bfd_mach_sh2 0x20 +- #define bfd_mach_sh_dsp 0x2d +- #define bfd_mach_sh2a 0x2a +- #define bfd_mach_sh2a_nofpu 0x2b +- #define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 +- #define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 +- #define bfd_mach_sh2a_or_sh4 0x2a3 +- #define bfd_mach_sh2a_or_sh3e 0x2a4 +- #define bfd_mach_sh2e 0x2e +- #define bfd_mach_sh3 0x30 +- #define bfd_mach_sh3_nommu 0x31 +- #define bfd_mach_sh3_dsp 0x3d +- #define bfd_mach_sh3e 0x3e +- #define bfd_mach_sh4 0x40 +- #define bfd_mach_sh4_nofpu 0x41 +- #define bfd_mach_sh4_nommu_nofpu 0x42 +- #define bfd_mach_sh4a 0x4a +- #define bfd_mach_sh4a_nofpu 0x4b +- #define bfd_mach_sh4al_dsp 0x4d +- #define bfd_mach_sh5 0x50 +- bfd_arch_alpha, /* Dec Alpha */ +- #define bfd_mach_alpha_ev4 0x10 +- #define bfd_mach_alpha_ev5 0x20 +- #define bfd_mach_alpha_ev6 0x30 +- bfd_arch_arm, /* Advanced Risc Machines ARM. */ +- #define bfd_mach_arm_unknown 0 +- #define bfd_mach_arm_2 1 +- #define bfd_mach_arm_2a 2 +- #define bfd_mach_arm_3 3 +- #define bfd_mach_arm_3M 4 +- #define bfd_mach_arm_4 5 +- #define bfd_mach_arm_4T 6 +- #define bfd_mach_arm_5 7 +- #define bfd_mach_arm_5T 8 +- #define bfd_mach_arm_5TE 9 +- #define bfd_mach_arm_XScale 10 +- #define bfd_mach_arm_ep9312 11 +- #define bfd_mach_arm_iWMMXt 12 +- #define bfd_mach_arm_iWMMXt2 13 +- bfd_arch_ns32k, /* National Semiconductors ns32000 */ +- bfd_arch_w65, /* WDC 65816 */ +- bfd_arch_tic30, /* Texas Instruments TMS320C30 */ +- bfd_arch_tic4x, /* Texas Instruments TMS320C3X/4X */ +- #define bfd_mach_tic3x 30 +- #define bfd_mach_tic4x 40 +- bfd_arch_tic54x, /* Texas Instruments TMS320C54X */ +- bfd_arch_tic6x, /* Texas Instruments TMS320C6X */ +- bfd_arch_tic80, /* TI TMS320c80 (MVP) */ +- bfd_arch_v850, /* NEC V850 */ +- bfd_arch_v850_rh850,/* NEC V850 (using RH850 ABI) */ +- #define bfd_mach_v850 1 +- #define bfd_mach_v850e 'E' +- #define bfd_mach_v850e1 '1' +- #define bfd_mach_v850e2 0x4532 +- #define bfd_mach_v850e2v3 0x45325633 +- #define bfd_mach_v850e3v5 0x45335635 /* ('E'|'3'|'V'|'5') */ +- bfd_arch_arc, /* ARC Cores */ +- #define bfd_mach_arc_5 5 +- #define bfd_mach_arc_6 6 +- #define bfd_mach_arc_7 7 +- #define bfd_mach_arc_8 8 +- bfd_arch_m32c, /* Renesas M16C/M32C. */ +- #define bfd_mach_m16c 0x75 +- #define bfd_mach_m32c 0x78 +- bfd_arch_m32r, /* Renesas M32R (formerly Mitsubishi M32R/D) */ +- #define bfd_mach_m32r 1 /* For backwards compatibility. */ +- #define bfd_mach_m32rx 'x' +- #define bfd_mach_m32r2 '2' +- bfd_arch_mn10200, /* Matsushita MN10200 */ +- bfd_arch_mn10300, /* Matsushita MN10300 */ +- #define bfd_mach_mn10300 300 +- #define bfd_mach_am33 330 +- #define bfd_mach_am33_2 332 +- bfd_arch_fr30, +- #define bfd_mach_fr30 0x46523330 +- bfd_arch_frv, +- #define bfd_mach_frv 1 +- #define bfd_mach_frvsimple 2 +- #define bfd_mach_fr300 300 +- #define bfd_mach_fr400 400 +- #define bfd_mach_fr450 450 +- #define bfd_mach_frvtomcat 499 /* fr500 prototype */ +- #define bfd_mach_fr500 500 +- #define bfd_mach_fr550 550 +- bfd_arch_moxie, /* The moxie processor */ +- #define bfd_mach_moxie 1 +- bfd_arch_mcore, +- bfd_arch_mep, +- #define bfd_mach_mep 1 +- #define bfd_mach_mep_h1 0x6831 +- #define bfd_mach_mep_c5 0x6335 +- bfd_arch_metag, +- #define bfd_mach_metag 1 +- bfd_arch_ia64, /* HP/Intel ia64 */ +- #define bfd_mach_ia64_elf64 64 +- #define bfd_mach_ia64_elf32 32 +- bfd_arch_ip2k, /* Ubicom IP2K microcontrollers. */ +- #define bfd_mach_ip2022 1 +- #define bfd_mach_ip2022ext 2 +- bfd_arch_iq2000, /* Vitesse IQ2000. */ +- #define bfd_mach_iq2000 1 +- #define bfd_mach_iq10 2 +- bfd_arch_epiphany, /* Adapteva EPIPHANY */ +- #define bfd_mach_epiphany16 1 +- #define bfd_mach_epiphany32 2 +- bfd_arch_mt, +- #define bfd_mach_ms1 1 +- #define bfd_mach_mrisc2 2 +- #define bfd_mach_ms2 3 +- bfd_arch_pj, +- bfd_arch_avr, /* Atmel AVR microcontrollers. */ +- #define bfd_mach_avr1 1 +- #define bfd_mach_avr2 2 +- #define bfd_mach_avr25 25 +- #define bfd_mach_avr3 3 +- #define bfd_mach_avr31 31 +- #define bfd_mach_avr35 35 +- #define bfd_mach_avr4 4 +- #define bfd_mach_avr5 5 +- #define bfd_mach_avr51 51 +- #define bfd_mach_avr6 6 +- #define bfd_mach_avrxmega1 101 +- #define bfd_mach_avrxmega2 102 +- #define bfd_mach_avrxmega3 103 +- #define bfd_mach_avrxmega4 104 +- #define bfd_mach_avrxmega5 105 +- #define bfd_mach_avrxmega6 106 +- #define bfd_mach_avrxmega7 107 +- bfd_arch_bfin, /* ADI Blackfin */ +- #define bfd_mach_bfin 1 +- bfd_arch_cr16, /* National Semiconductor CompactRISC (ie CR16). */ +- #define bfd_mach_cr16 1 +- bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ +- #define bfd_mach_cr16c 1 +- bfd_arch_crx, /* National Semiconductor CRX. */ +- #define bfd_mach_crx 1 +- bfd_arch_cris, /* Axis CRIS */ +- #define bfd_mach_cris_v0_v10 255 +- #define bfd_mach_cris_v32 32 +- #define bfd_mach_cris_v10_v32 1032 +- bfd_arch_rl78, +- #define bfd_mach_rl78 0x75 +- bfd_arch_rx, /* Renesas RX. */ +- #define bfd_mach_rx 0x75 +- bfd_arch_s390, /* IBM s390 */ +- #define bfd_mach_s390_31 31 +- #define bfd_mach_s390_64 64 +- bfd_arch_score, /* Sunplus score */ +- #define bfd_mach_score3 3 +- #define bfd_mach_score7 7 +- bfd_arch_openrisc, /* OpenRISC */ +- bfd_arch_mmix, /* Donald Knuth's educational processor. */ +- bfd_arch_xstormy16, +- #define bfd_mach_xstormy16 1 +- bfd_arch_msp430, /* Texas Instruments MSP430 architecture. */ +- #define bfd_mach_msp11 11 +- #define bfd_mach_msp110 110 +- #define bfd_mach_msp12 12 +- #define bfd_mach_msp13 13 +- #define bfd_mach_msp14 14 +- #define bfd_mach_msp15 15 +- #define bfd_mach_msp16 16 +- #define bfd_mach_msp20 20 +- #define bfd_mach_msp21 21 +- #define bfd_mach_msp22 22 +- #define bfd_mach_msp23 23 +- #define bfd_mach_msp24 24 +- #define bfd_mach_msp26 26 +- #define bfd_mach_msp31 31 +- #define bfd_mach_msp32 32 +- #define bfd_mach_msp33 33 +- #define bfd_mach_msp41 41 +- #define bfd_mach_msp42 42 +- #define bfd_mach_msp43 43 +- #define bfd_mach_msp44 44 +- #define bfd_mach_msp430x 45 +- #define bfd_mach_msp46 46 +- #define bfd_mach_msp47 47 +- #define bfd_mach_msp54 54 +- bfd_arch_xc16x, /* Infineon's XC16X Series. */ +- #define bfd_mach_xc16x 1 +- #define bfd_mach_xc16xl 2 +- #define bfd_mach_xc16xs 3 +- bfd_arch_xgate, /* Freescale XGATE */ +- #define bfd_mach_xgate 1 +- bfd_arch_xtensa, /* Tensilica's Xtensa cores. */ +- #define bfd_mach_xtensa 1 +- bfd_arch_z80, +- #define bfd_mach_z80strict 1 /* No undocumented opcodes. */ +- #define bfd_mach_z80 3 /* With ixl, ixh, iyl, and iyh. */ +- #define bfd_mach_z80full 7 /* All undocumented instructions. */ +- #define bfd_mach_r800 11 /* R800: successor with multiplication. */ +- bfd_arch_lm32, /* Lattice Mico32 */ +- #define bfd_mach_lm32 1 +- bfd_arch_microblaze,/* Xilinx MicroBlaze. */ +- bfd_arch_tilepro, /* Tilera TILEPro */ +- bfd_arch_tilegx, /* Tilera TILE-Gx */ +- #define bfd_mach_tilepro 1 +- #define bfd_mach_tilegx 1 +- #define bfd_mach_tilegx32 2 +- bfd_arch_aarch64, /* AArch64 */ +- #define bfd_mach_aarch64 0 +- #define bfd_mach_aarch64_ilp32 32 +- bfd_arch_nios2, +- #define bfd_mach_nios2 0 +- bfd_arch_last +- }; +- +-2.13.2 bfd_arch_info +--------------------- +- +-*Description* +-This structure contains information on architectures for use within BFD. +- +- typedef struct bfd_arch_info +- { +- int bits_per_word; +- int bits_per_address; +- int bits_per_byte; +- enum bfd_architecture arch; +- unsigned long mach; +- const char *arch_name; +- const char *printable_name; +- unsigned int section_align_power; +- /* TRUE if this is the default machine for the architecture. +- The default arch should be the first entry for an arch so that +- all the entries for that arch can be accessed via `next'. */ +- bfd_boolean the_default; +- const struct bfd_arch_info * (*compatible) +- (const struct bfd_arch_info *a, const struct bfd_arch_info *b); +- +- bfd_boolean (*scan) (const struct bfd_arch_info *, const char *); +- +- /* Allocate via bfd_malloc and return a fill buffer of size COUNT. If +- IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is +- TRUE, the buffer contains code. */ +- void *(*fill) (bfd_size_type count, bfd_boolean is_bigendian, +- bfd_boolean code); +- +- const struct bfd_arch_info *next; +- } +- bfd_arch_info_type; +- +-2.13.2.1 `bfd_printable_name' +-............................. +- +-*Synopsis* +- const char *bfd_printable_name (bfd *abfd); +- *Description* +-Return a printable string representing the architecture and machine +-from the pointer to the architecture info structure. +- +-2.13.2.2 `bfd_scan_arch' +-........................ +- +-*Synopsis* +- const bfd_arch_info_type *bfd_scan_arch (const char *string); +- *Description* +-Figure out if BFD supports any cpu which could be described with the +-name STRING. Return a pointer to an `arch_info' structure if a machine +-is found, otherwise NULL. +- +-2.13.2.3 `bfd_arch_list' +-........................ +- +-*Synopsis* +- const char **bfd_arch_list (void); +- *Description* +-Return a freshly malloced NULL-terminated vector of the names of all +-the valid BFD architectures. Do not modify the names. +- +-2.13.2.4 `bfd_arch_get_compatible' +-.................................. +- +-*Synopsis* +- const bfd_arch_info_type *bfd_arch_get_compatible +- (const bfd *abfd, const bfd *bbfd, bfd_boolean accept_unknowns); +- *Description* +-Determine whether two BFDs' architectures and machine types are +-compatible. Calculates the lowest common denominator between the two +-architectures and machine types implied by the BFDs and returns a +-pointer to an `arch_info' structure describing the compatible machine. +- +-2.13.2.5 `bfd_default_arch_struct' +-.................................. +- +-*Description* +-The `bfd_default_arch_struct' is an item of `bfd_arch_info_type' which +-has been initialized to a fairly generic state. A BFD starts life by +-pointing to this structure, until the correct back end has determined +-the real architecture of the file. +- extern const bfd_arch_info_type bfd_default_arch_struct; +- +-2.13.2.6 `bfd_set_arch_info' +-............................ +- +-*Synopsis* +- void bfd_set_arch_info (bfd *abfd, const bfd_arch_info_type *arg); +- *Description* +-Set the architecture info of ABFD to ARG. +- +-2.13.2.7 `bfd_default_set_arch_mach' +-.................................... +- +-*Synopsis* +- bfd_boolean bfd_default_set_arch_mach +- (bfd *abfd, enum bfd_architecture arch, unsigned long mach); +- *Description* +-Set the architecture and machine type in BFD ABFD to ARCH and MACH. +-Find the correct pointer to a structure and insert it into the +-`arch_info' pointer. +- +-2.13.2.8 `bfd_get_arch' +-....................... +- +-*Synopsis* +- enum bfd_architecture bfd_get_arch (bfd *abfd); +- *Description* +-Return the enumerated type which describes the BFD ABFD's architecture. +- +-2.13.2.9 `bfd_get_mach' +-....................... +- +-*Synopsis* +- unsigned long bfd_get_mach (bfd *abfd); +- *Description* +-Return the long type which describes the BFD ABFD's machine. +- +-2.13.2.10 `bfd_arch_bits_per_byte' +-.................................. +- +-*Synopsis* +- unsigned int bfd_arch_bits_per_byte (bfd *abfd); +- *Description* +-Return the number of bits in one of the BFD ABFD's architecture's bytes. +- +-2.13.2.11 `bfd_arch_bits_per_address' +-..................................... +- +-*Synopsis* +- unsigned int bfd_arch_bits_per_address (bfd *abfd); +- *Description* +-Return the number of bits in one of the BFD ABFD's architecture's +-addresses. +- +-2.13.2.12 `bfd_default_compatible' +-.................................. +- +-*Synopsis* +- const bfd_arch_info_type *bfd_default_compatible +- (const bfd_arch_info_type *a, const bfd_arch_info_type *b); +- *Description* +-The default function for testing for compatibility. +- +-2.13.2.13 `bfd_default_scan' +-............................ +- +-*Synopsis* +- bfd_boolean bfd_default_scan +- (const struct bfd_arch_info *info, const char *string); +- *Description* +-The default function for working out whether this is an architecture +-hit and a machine hit. +- +-2.13.2.14 `bfd_get_arch_info' +-............................. +- +-*Synopsis* +- const bfd_arch_info_type *bfd_get_arch_info (bfd *abfd); +- *Description* +-Return the architecture info struct in ABFD. +- +-2.13.2.15 `bfd_lookup_arch' +-........................... +- +-*Synopsis* +- const bfd_arch_info_type *bfd_lookup_arch +- (enum bfd_architecture arch, unsigned long machine); +- *Description* +-Look for the architecture info structure which matches the arguments +-ARCH and MACHINE. A machine of 0 matches the machine/architecture +-structure which marks itself as the default. +- +-2.13.2.16 `bfd_printable_arch_mach' +-................................... +- +-*Synopsis* +- const char *bfd_printable_arch_mach +- (enum bfd_architecture arch, unsigned long machine); +- *Description* +-Return a printable string representing the architecture and machine +-type. +- +- This routine is depreciated. +- +-2.13.2.17 `bfd_octets_per_byte' +-............................... +- +-*Synopsis* +- unsigned int bfd_octets_per_byte (bfd *abfd); +- *Description* +-Return the number of octets (8-bit quantities) per target byte (minimum +-addressable unit). In most cases, this will be one, but some DSP +-targets have 16, 32, or even 48 bits per byte. +- +-2.13.2.18 `bfd_arch_mach_octets_per_byte' +-......................................... +- +-*Synopsis* +- unsigned int bfd_arch_mach_octets_per_byte +- (enum bfd_architecture arch, unsigned long machine); +- *Description* +-See bfd_octets_per_byte. +- +- This routine is provided for those cases where a bfd * is not +-available +- +-2.13.2.19 `bfd_arch_default_fill' +-................................. +- +-*Synopsis* +- void *bfd_arch_default_fill (bfd_size_type count, +- bfd_boolean is_bigendian, +- bfd_boolean code); +- *Description* +-Allocate via bfd_malloc and return a fill buffer of size COUNT. If +-IS_BIGENDIAN is TRUE, the order of bytes is big endian. If CODE is +-TRUE, the buffer contains code. +- +- +-File: bfd.info, Node: Opening and Closing, Next: Internal, Prev: Architectures, Up: BFD front end +- +- /* Set to N to open the next N BFDs using an alternate id space. */ +- extern unsigned int bfd_use_reserved_id; +- +-2.14 Opening and closing BFDs +-============================= +- +-2.14.1 Functions for opening and closing +----------------------------------------- +- +-2.14.1.1 `bfd_fopen' +-.................... +- +-*Synopsis* +- bfd *bfd_fopen (const char *filename, const char *target, +- const char *mode, int fd); +- *Description* +-Open the file FILENAME with the target TARGET. Return a pointer to the +-created BFD. If FD is not -1, then `fdopen' is used to open the file; +-otherwise, `fopen' is used. MODE is passed directly to `fopen' or +-`fdopen'. +- +- Calls `bfd_find_target', so TARGET is interpreted as by that +-function. +- +- The new BFD is marked as cacheable iff FD is -1. +- +- If `NULL' is returned then an error has occured. Possible errors +-are `bfd_error_no_memory', `bfd_error_invalid_target' or `system_call' +-error. +- +- On error, FD is always closed. +- +-2.14.1.2 `bfd_openr' +-.................... +- +-*Synopsis* +- bfd *bfd_openr (const char *filename, const char *target); +- *Description* +-Open the file FILENAME (using `fopen') with the target TARGET. Return +-a pointer to the created BFD. +- +- Calls `bfd_find_target', so TARGET is interpreted as by that +-function. +- +- If `NULL' is returned then an error has occured. Possible errors +-are `bfd_error_no_memory', `bfd_error_invalid_target' or `system_call' +-error. +- +-2.14.1.3 `bfd_fdopenr' +-...................... +- +-*Synopsis* +- bfd *bfd_fdopenr (const char *filename, const char *target, int fd); +- *Description* +-`bfd_fdopenr' is to `bfd_fopenr' much like `fdopen' is to `fopen'. It +-opens a BFD on a file already described by the FD supplied. +- +- When the file is later `bfd_close'd, the file descriptor will be +-closed. If the caller desires that this file descriptor be cached by +-BFD (opened as needed, closed as needed to free descriptors for other +-opens), with the supplied FD used as an initial file descriptor (but +-subject to closure at any time), call bfd_set_cacheable(bfd, 1) on the +-returned BFD. The default is to assume no caching; the file descriptor +-will remain open until `bfd_close', and will not be affected by BFD +-operations on other files. +- +- Possible errors are `bfd_error_no_memory', +-`bfd_error_invalid_target' and `bfd_error_system_call'. +- +- On error, FD is closed. +- +-2.14.1.4 `bfd_openstreamr' +-.......................... +- +-*Synopsis* +- bfd *bfd_openstreamr (const char *, const char *, void *); +- *Description* +-Open a BFD for read access on an existing stdio stream. When the BFD +-is passed to `bfd_close', the stream will be closed. +- +-2.14.1.5 `bfd_openr_iovec' +-.......................... +- +-*Synopsis* +- bfd *bfd_openr_iovec (const char *filename, const char *target, +- void *(*open_func) (struct bfd *nbfd, +- void *open_closure), +- void *open_closure, +- file_ptr (*pread_func) (struct bfd *nbfd, +- void *stream, +- void *buf, +- file_ptr nbytes, +- file_ptr offset), +- int (*close_func) (struct bfd *nbfd, +- void *stream), +- int (*stat_func) (struct bfd *abfd, +- void *stream, +- struct stat *sb)); +- *Description* +-Create and return a BFD backed by a read-only STREAM. The STREAM is +-created using OPEN_FUNC, accessed using PREAD_FUNC and destroyed using +-CLOSE_FUNC. +- +- Calls `bfd_find_target', so TARGET is interpreted as by that +-function. +- +- Calls OPEN_FUNC (which can call `bfd_zalloc' and `bfd_get_filename') +-to obtain the read-only stream backing the BFD. OPEN_FUNC either +-succeeds returning the non-`NULL' STREAM, or fails returning `NULL' +-(setting `bfd_error'). +- +- Calls PREAD_FUNC to request NBYTES of data from STREAM starting at +-OFFSET (e.g., via a call to `bfd_read'). PREAD_FUNC either succeeds +-returning the number of bytes read (which can be less than NBYTES when +-end-of-file), or fails returning -1 (setting `bfd_error'). +- +- Calls CLOSE_FUNC when the BFD is later closed using `bfd_close'. +-CLOSE_FUNC either succeeds returning 0, or fails returning -1 (setting +-`bfd_error'). +- +- Calls STAT_FUNC to fill in a stat structure for bfd_stat, +-bfd_get_size, and bfd_get_mtime calls. STAT_FUNC returns 0 on success, +-or returns -1 on failure (setting `bfd_error'). +- +- If `bfd_openr_iovec' returns `NULL' then an error has occurred. +-Possible errors are `bfd_error_no_memory', `bfd_error_invalid_target' +-and `bfd_error_system_call'. +- +-2.14.1.6 `bfd_openw' +-.................... +- +-*Synopsis* +- bfd *bfd_openw (const char *filename, const char *target); +- *Description* +-Create a BFD, associated with file FILENAME, using the file format +-TARGET, and return a pointer to it. +- +- Possible errors are `bfd_error_system_call', `bfd_error_no_memory', +-`bfd_error_invalid_target'. +- +-2.14.1.7 `bfd_close' +-.................... +- +-*Synopsis* +- bfd_boolean bfd_close (bfd *abfd); +- *Description* +-Close a BFD. If the BFD was open for writing, then pending operations +-are completed and the file written out and closed. If the created file +-is executable, then `chmod' is called to mark it as such. +- +- All memory attached to the BFD is released. +- +- The file descriptor associated with the BFD is closed (even if it +-was passed in to BFD by `bfd_fdopenr'). +- +- *Returns* +-`TRUE' is returned if all is ok, otherwise `FALSE'. +- +-2.14.1.8 `bfd_close_all_done' +-............................. +- +-*Synopsis* +- bfd_boolean bfd_close_all_done (bfd *); +- *Description* +-Close a BFD. Differs from `bfd_close' since it does not complete any +-pending operations. This routine would be used if the application had +-just used BFD for swapping and didn't want to use any of the writing +-code. +- +- If the created file is executable, then `chmod' is called to mark it +-as such. +- +- All memory attached to the BFD is released. +- +- *Returns* +-`TRUE' is returned if all is ok, otherwise `FALSE'. +- +-2.14.1.9 `bfd_create' +-..................... +- +-*Synopsis* +- bfd *bfd_create (const char *filename, bfd *templ); +- *Description* +-Create a new BFD in the manner of `bfd_openw', but without opening a +-file. The new BFD takes the target from the target used by TEMPL. The +-format is always set to `bfd_object'. +- +-2.14.1.10 `bfd_make_writable' +-............................. +- +-*Synopsis* +- bfd_boolean bfd_make_writable (bfd *abfd); +- *Description* +-Takes a BFD as created by `bfd_create' and converts it into one like as +-returned by `bfd_openw'. It does this by converting the BFD to +-BFD_IN_MEMORY. It's assumed that you will call `bfd_make_readable' on +-this bfd later. +- +- *Returns* +-`TRUE' is returned if all is ok, otherwise `FALSE'. +- +-2.14.1.11 `bfd_make_readable' +-............................. +- +-*Synopsis* +- bfd_boolean bfd_make_readable (bfd *abfd); +- *Description* +-Takes a BFD as created by `bfd_create' and `bfd_make_writable' and +-converts it into one like as returned by `bfd_openr'. It does this by +-writing the contents out to the memory buffer, then reversing the +-direction. +- +- *Returns* +-`TRUE' is returned if all is ok, otherwise `FALSE'. +- +-2.14.1.12 `bfd_alloc' +-..................... +- +-*Synopsis* +- void *bfd_alloc (bfd *abfd, bfd_size_type wanted); +- *Description* +-Allocate a block of WANTED bytes of memory attached to `abfd' and +-return a pointer to it. +- +-2.14.1.13 `bfd_alloc2' +-...................... +- +-*Synopsis* +- void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size); +- *Description* +-Allocate a block of NMEMB elements of SIZE bytes each of memory +-attached to `abfd' and return a pointer to it. +- +-2.14.1.14 `bfd_zalloc' +-...................... +- +-*Synopsis* +- void *bfd_zalloc (bfd *abfd, bfd_size_type wanted); +- *Description* +-Allocate a block of WANTED bytes of zeroed memory attached to `abfd' +-and return a pointer to it. +- +-2.14.1.15 `bfd_zalloc2' +-....................... +- +-*Synopsis* +- void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size); +- *Description* +-Allocate a block of NMEMB elements of SIZE bytes each of zeroed memory +-attached to `abfd' and return a pointer to it. +- +-2.14.1.16 `bfd_calc_gnu_debuglink_crc32' +-........................................ +- +-*Synopsis* +- unsigned long bfd_calc_gnu_debuglink_crc32 +- (unsigned long crc, const unsigned char *buf, bfd_size_type len); +- *Description* +-Computes a CRC value as used in the .gnu_debuglink section. Advances +-the previously computed CRC value by computing and adding in the crc32 +-for LEN bytes of BUF. +- +- *Returns* +-Return the updated CRC32 value. +- +-2.14.1.17 `bfd_get_debug_link_info' +-................................... +- +-*Synopsis* +- char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out); +- *Description* +-fetch the filename and CRC32 value for any separate debuginfo +-associated with ABFD. Return NULL if no such info found, otherwise +-return filename and update CRC32_OUT. The returned filename is +-allocated with `malloc'; freeing it is the responsibility of the caller. +- +-2.14.1.18 `bfd_get_alt_debug_link_info' +-....................................... +- +-*Synopsis* +- char *bfd_get_alt_debug_link_info (bfd *abfd, unsigned long *crc32_out); +- *Description* +-Fetch the filename and BuildID value for any alternate debuginfo +-associated with ABFD. Return NULL if no such info found, otherwise +-return filename and update BUILDID_OUT. The returned filename is +-allocated with `malloc'; freeing it is the responsibility of the caller. +- +-2.14.1.19 `separate_debug_file_exists' +-...................................... +- +-*Synopsis* +- bfd_boolean separate_debug_file_exists +- (char *name, unsigned long crc32); +- *Description* +-Checks to see if NAME is a file and if its contents match CRC32. +- +-2.14.1.20 `separate_alt_debug_file_exists' +-.......................................... +- +-*Synopsis* +- bfd_boolean separate_alt_debug_file_exists +- (char *name, unsigned long crc32); +- *Description* +-Checks to see if NAME is a file and if its BuildID matches BUILDID. +- +-2.14.1.21 `find_separate_debug_file' +-.................................... +- +-*Synopsis* +- char *find_separate_debug_file (bfd *abfd); +- *Description* +-Searches ABFD for a section called SECTION_NAME which is expected to +-contain a reference to a file containing separate debugging +-information. The function scans various locations in the filesystem, +-including the file tree rooted at DEBUG_FILE_DIRECTORY, and returns the +-first matching filename that it finds. If CHECK_CRC is TRUE then the +-contents of the file must also match the CRC value contained in +-SECTION_NAME. Returns NULL if no valid file could be found. +- +-2.14.1.22 `bfd_follow_gnu_debuglink' +-.................................... +- +-*Synopsis* +- char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); +- *Description* +-Takes a BFD and searches it for a .gnu_debuglink section. If this +-section is found, it examines the section for the name and checksum of +-a '.debug' file containing auxiliary debugging information. It then +-searches the filesystem for this .debug file in some standard +-locations, including the directory tree rooted at DIR, and if found +-returns the full filename. +- +- If DIR is NULL, it will search a default path configured into libbfd +-at build time. [XXX this feature is not currently implemented]. +- +- *Returns* +-`NULL' on any errors or failure to locate the .debug file, otherwise a +-pointer to a heap-allocated string containing the filename. The caller +-is responsible for freeing this string. +- +-2.14.1.23 `bfd_follow_gnu_debugaltlink' +-....................................... +- +-*Synopsis* +- char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir); +- *Description* +-Takes a BFD and searches it for a .gnu_debugaltlink section. If this +-section is found, it examines the section for the name of a file +-containing auxiliary debugging information. It then searches the +-filesystem for this file in a set of standard locations, including the +-directory tree rooted at DIR, and if found returns the full filename. +- +- If DIR is NULL, it will search a default path configured into libbfd +-at build time. [FIXME: This feature is not currently implemented]. +- +- *Returns* +-`NULL' on any errors or failure to locate the debug file, otherwise a +-pointer to a heap-allocated string containing the filename. The caller +-is responsible for freeing this string. +- +-2.14.1.24 `bfd_create_gnu_debuglink_section' +-............................................ +- +-*Synopsis* +- struct bfd_section *bfd_create_gnu_debuglink_section +- (bfd *abfd, const char *filename); +- *Description* +-Takes a BFD and adds a .gnu_debuglink section to it. The section is +-sized to be big enough to contain a link to the specified FILENAME. +- +- *Returns* +-A pointer to the new section is returned if all is ok. Otherwise +-`NULL' is returned and bfd_error is set. +- +-2.14.1.25 `bfd_fill_in_gnu_debuglink_section' +-............................................. +- +-*Synopsis* +- bfd_boolean bfd_fill_in_gnu_debuglink_section +- (bfd *abfd, struct bfd_section *sect, const char *filename); +- *Description* +-Takes a BFD and containing a .gnu_debuglink section SECT and fills in +-the contents of the section to contain a link to the specified +-FILENAME. The filename should be relative to the current directory. +- +- *Returns* +-`TRUE' is returned if all is ok. Otherwise `FALSE' is returned and +-bfd_error is set. +- +- +-File: bfd.info, Node: Internal, Next: File Caching, Prev: Opening and Closing, Up: BFD front end +- +-2.15 Implementation details +-=========================== +- +-2.15.1 Internal functions +-------------------------- +- +-*Description* +-These routines are used within BFD. They are not intended for export, +-but are documented here for completeness. +- +-2.15.1.1 `bfd_write_bigendian_4byte_int' +-........................................ +- +-*Synopsis* +- bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); +- *Description* +-Write a 4 byte integer I to the output BFD ABFD, in big endian order +-regardless of what else is going on. This is useful in archives. +- +-2.15.1.2 `bfd_put_size' +-....................... +- +-2.15.1.3 `bfd_get_size' +-....................... +- +-*Description* +-These macros as used for reading and writing raw data in sections; each +-access (except for bytes) is vectored through the target format of the +-BFD and mangled accordingly. The mangling performs any necessary endian +-translations and removes alignment restrictions. Note that types +-accepted and returned by these macros are identical so they can be +-swapped around in macros--for example, `libaout.h' defines `GET_WORD' +-to either `bfd_get_32' or `bfd_get_64'. +- +- In the put routines, VAL must be a `bfd_vma'. If we are on a system +-without prototypes, the caller is responsible for making sure that is +-true, with a cast if necessary. We don't cast them in the macro +-definitions because that would prevent `lint' or `gcc -Wall' from +-detecting sins such as passing a pointer. To detect calling these with +-less than a `bfd_vma', use `gcc -Wconversion' on a host with 64 bit +-`bfd_vma''s. +- +- /* Byte swapping macros for user section data. */ +- +- #define bfd_put_8(abfd, val, ptr) \ +- ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) +- #define bfd_put_signed_8 \ +- bfd_put_8 +- #define bfd_get_8(abfd, ptr) \ +- (*(const unsigned char *) (ptr) & 0xff) +- #define bfd_get_signed_8(abfd, ptr) \ +- (((*(const unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) +- +- #define bfd_put_16(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) +- #define bfd_put_signed_16 \ +- bfd_put_16 +- #define bfd_get_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx16, (ptr)) +- #define bfd_get_signed_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) +- +- #define bfd_put_32(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) +- #define bfd_put_signed_32 \ +- bfd_put_32 +- #define bfd_get_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx32, (ptr)) +- #define bfd_get_signed_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) +- +- #define bfd_put_64(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) +- #define bfd_put_signed_64 \ +- bfd_put_64 +- #define bfd_get_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx64, (ptr)) +- #define bfd_get_signed_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) +- +- #define bfd_get(bits, abfd, ptr) \ +- ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ +- : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ +- : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ +- : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ +- : (abort (), (bfd_vma) - 1)) +- +- #define bfd_put(bits, abfd, val, ptr) \ +- ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ +- : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ +- : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ +- : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ +- : (abort (), (void) 0)) +- +-2.15.1.4 `bfd_h_put_size' +-......................... +- +-*Description* +-These macros have the same function as their `bfd_get_x' brethren, +-except that they are used for removing information for the header +-records of object files. Believe it or not, some object files keep +-their header records in big endian order and their data in little +-endian order. +- +- /* Byte swapping macros for file header data. */ +- +- #define bfd_h_put_8(abfd, val, ptr) \ +- bfd_put_8 (abfd, val, ptr) +- #define bfd_h_put_signed_8(abfd, val, ptr) \ +- bfd_put_8 (abfd, val, ptr) +- #define bfd_h_get_8(abfd, ptr) \ +- bfd_get_8 (abfd, ptr) +- #define bfd_h_get_signed_8(abfd, ptr) \ +- bfd_get_signed_8 (abfd, ptr) +- +- #define bfd_h_put_16(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) +- #define bfd_h_put_signed_16 \ +- bfd_h_put_16 +- #define bfd_h_get_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx16, (ptr)) +- #define bfd_h_get_signed_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) +- +- #define bfd_h_put_32(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) +- #define bfd_h_put_signed_32 \ +- bfd_h_put_32 +- #define bfd_h_get_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx32, (ptr)) +- #define bfd_h_get_signed_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) +- +- #define bfd_h_put_64(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) +- #define bfd_h_put_signed_64 \ +- bfd_h_put_64 +- #define bfd_h_get_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx64, (ptr)) +- #define bfd_h_get_signed_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) +- +- /* Aliases for the above, which should eventually go away. */ +- +- #define H_PUT_64 bfd_h_put_64 +- #define H_PUT_32 bfd_h_put_32 +- #define H_PUT_16 bfd_h_put_16 +- #define H_PUT_8 bfd_h_put_8 +- #define H_PUT_S64 bfd_h_put_signed_64 +- #define H_PUT_S32 bfd_h_put_signed_32 +- #define H_PUT_S16 bfd_h_put_signed_16 +- #define H_PUT_S8 bfd_h_put_signed_8 +- #define H_GET_64 bfd_h_get_64 +- #define H_GET_32 bfd_h_get_32 +- #define H_GET_16 bfd_h_get_16 +- #define H_GET_8 bfd_h_get_8 +- #define H_GET_S64 bfd_h_get_signed_64 +- #define H_GET_S32 bfd_h_get_signed_32 +- #define H_GET_S16 bfd_h_get_signed_16 +- #define H_GET_S8 bfd_h_get_signed_8 +- +-2.15.1.5 `bfd_log2' +-................... +- +-*Synopsis* +- unsigned int bfd_log2 (bfd_vma x); +- *Description* +-Return the log base 2 of the value supplied, rounded up. E.g., an X of +-1025 returns 11. A X of 0 returns 0. +- +- +-File: bfd.info, Node: File Caching, Next: Linker Functions, Prev: Internal, Up: BFD front end +- +-2.16 File caching +-================= +- +-The file caching mechanism is embedded within BFD and allows the +-application to open as many BFDs as it wants without regard to the +-underlying operating system's file descriptor limit (often as low as 20 +-open files). The module in `cache.c' maintains a least recently used +-list of `bfd_cache_max_open' files, and exports the name +-`bfd_cache_lookup', which runs around and makes sure that the required +-BFD is open. If not, then it chooses a file to close, closes it and +-opens the one wanted, returning its file handle. +- +-2.16.1 Caching functions +------------------------- +- +-2.16.1.1 `bfd_cache_init' +-......................... +- +-*Synopsis* +- bfd_boolean bfd_cache_init (bfd *abfd); +- *Description* +-Add a newly opened BFD to the cache. +- +-2.16.1.2 `bfd_cache_close' +-.......................... +- +-*Synopsis* +- bfd_boolean bfd_cache_close (bfd *abfd); +- *Description* +-Remove the BFD ABFD from the cache. If the attached file is open, then +-close it too. +- +- *Returns* +-`FALSE' is returned if closing the file fails, `TRUE' is returned if +-all is well. +- +-2.16.1.3 `bfd_cache_close_all' +-.............................. +- +-*Synopsis* +- bfd_boolean bfd_cache_close_all (void); +- *Description* +-Remove all BFDs from the cache. If the attached file is open, then +-close it too. +- +- *Returns* +-`FALSE' is returned if closing one of the file fails, `TRUE' is +-returned if all is well. +- +-2.16.1.4 `bfd_open_file' +-........................ +- +-*Synopsis* +- FILE* bfd_open_file (bfd *abfd); +- *Description* +-Call the OS to open a file for ABFD. Return the `FILE *' (possibly +-`NULL') that results from this operation. Set up the BFD so that +-future accesses know the file is open. If the `FILE *' returned is +-`NULL', then it won't have been put in the cache, so it won't have to +-be removed from it. +- +- +-File: bfd.info, Node: Linker Functions, Next: Hash Tables, Prev: File Caching, Up: BFD front end +- +-2.17 Linker Functions +-===================== +- +-The linker uses three special entry points in the BFD target vector. +-It is not necessary to write special routines for these entry points +-when creating a new BFD back end, since generic versions are provided. +-However, writing them can speed up linking and make it use +-significantly less runtime memory. +- +- The first routine creates a hash table used by the other routines. +-The second routine adds the symbols from an object file to the hash +-table. The third routine takes all the object files and links them +-together to create the output file. These routines are designed so +-that the linker proper does not need to know anything about the symbols +-in the object files that it is linking. The linker merely arranges the +-sections as directed by the linker script and lets BFD handle the +-details of symbols and relocs. +- +- The second routine and third routines are passed a pointer to a +-`struct bfd_link_info' structure (defined in `bfdlink.h') which holds +-information relevant to the link, including the linker hash table +-(which was created by the first routine) and a set of callback +-functions to the linker proper. +- +- The generic linker routines are in `linker.c', and use the header +-file `genlink.h'. As of this writing, the only back ends which have +-implemented versions of these routines are a.out (in `aoutx.h') and +-ECOFF (in `ecoff.c'). The a.out routines are used as examples +-throughout this section. +- +-* Menu: +- +-* Creating a Linker Hash Table:: +-* Adding Symbols to the Hash Table:: +-* Performing the Final Link:: +- +- +-File: bfd.info, Node: Creating a Linker Hash Table, Next: Adding Symbols to the Hash Table, Prev: Linker Functions, Up: Linker Functions +- +-2.17.1 Creating a linker hash table +------------------------------------ +- +-The linker routines must create a hash table, which must be derived +-from `struct bfd_link_hash_table' described in `bfdlink.c'. *Note Hash +-Tables::, for information on how to create a derived hash table. This +-entry point is called using the target vector of the linker output file. +- +- The `_bfd_link_hash_table_create' entry point must allocate and +-initialize an instance of the desired hash table. If the back end does +-not require any additional information to be stored with the entries in +-the hash table, the entry point may simply create a `struct +-bfd_link_hash_table'. Most likely, however, some additional +-information will be needed. +- +- For example, with each entry in the hash table the a.out linker +-keeps the index the symbol has in the final output file (this index +-number is used so that when doing a relocatable link the symbol index +-used in the output file can be quickly filled in when copying over a +-reloc). The a.out linker code defines the required structures and +-functions for a hash table derived from `struct bfd_link_hash_table'. +-The a.out linker hash table is created by the function +-`NAME(aout,link_hash_table_create)'; it simply allocates space for the +-hash table, initializes it, and returns a pointer to it. +- +- When writing the linker routines for a new back end, you will +-generally not know exactly which fields will be required until you have +-finished. You should simply create a new hash table which defines no +-additional fields, and then simply add fields as they become necessary. +- +- +-File: bfd.info, Node: Adding Symbols to the Hash Table, Next: Performing the Final Link, Prev: Creating a Linker Hash Table, Up: Linker Functions +- +-2.17.2 Adding symbols to the hash table +---------------------------------------- +- +-The linker proper will call the `_bfd_link_add_symbols' entry point for +-each object file or archive which is to be linked (typically these are +-the files named on the command line, but some may also come from the +-linker script). The entry point is responsible for examining the file. +-For an object file, BFD must add any relevant symbol information to +-the hash table. For an archive, BFD must determine which elements of +-the archive should be used and adding them to the link. +- +- The a.out version of this entry point is +-`NAME(aout,link_add_symbols)'. +- +-* Menu: +- +-* Differing file formats:: +-* Adding symbols from an object file:: +-* Adding symbols from an archive:: +- +- +-File: bfd.info, Node: Differing file formats, Next: Adding symbols from an object file, Prev: Adding Symbols to the Hash Table, Up: Adding Symbols to the Hash Table +- +-2.17.2.1 Differing file formats +-............................... +- +-Normally all the files involved in a link will be of the same format, +-but it is also possible to link together different format object files, +-and the back end must support that. The `_bfd_link_add_symbols' entry +-point is called via the target vector of the file to be added. This +-has an important consequence: the function may not assume that the hash +-table is the type created by the corresponding +-`_bfd_link_hash_table_create' vector. All the `_bfd_link_add_symbols' +-function can assume about the hash table is that it is derived from +-`struct bfd_link_hash_table'. +- +- Sometimes the `_bfd_link_add_symbols' function must store some +-information in the hash table entry to be used by the `_bfd_final_link' +-function. In such a case the output bfd xvec must be checked to make +-sure that the hash table was created by an object file of the same +-format. +- +- The `_bfd_final_link' routine must be prepared to handle a hash +-entry without any extra information added by the +-`_bfd_link_add_symbols' function. A hash entry without extra +-information will also occur when the linker script directs the linker +-to create a symbol. Note that, regardless of how a hash table entry is +-added, all the fields will be initialized to some sort of null value by +-the hash table entry initialization function. +- +- See `ecoff_link_add_externals' for an example of how to check the +-output bfd before saving information (in this case, the ECOFF external +-symbol debugging information) in a hash table entry. +- +- +-File: bfd.info, Node: Adding symbols from an object file, Next: Adding symbols from an archive, Prev: Differing file formats, Up: Adding Symbols to the Hash Table +- +-2.17.2.2 Adding symbols from an object file +-........................................... +- +-When the `_bfd_link_add_symbols' routine is passed an object file, it +-must add all externally visible symbols in that object file to the hash +-table. The actual work of adding the symbol to the hash table is +-normally handled by the function `_bfd_generic_link_add_one_symbol'. +-The `_bfd_link_add_symbols' routine is responsible for reading all the +-symbols from the object file and passing the correct information to +-`_bfd_generic_link_add_one_symbol'. +- +- The `_bfd_link_add_symbols' routine should not use +-`bfd_canonicalize_symtab' to read the symbols. The point of providing +-this routine is to avoid the overhead of converting the symbols into +-generic `asymbol' structures. +- +- `_bfd_generic_link_add_one_symbol' handles the details of combining +-common symbols, warning about multiple definitions, and so forth. It +-takes arguments which describe the symbol to add, notably symbol flags, +-a section, and an offset. The symbol flags include such things as +-`BSF_WEAK' or `BSF_INDIRECT'. The section is a section in the object +-file, or something like `bfd_und_section_ptr' for an undefined symbol +-or `bfd_com_section_ptr' for a common symbol. +- +- If the `_bfd_final_link' routine is also going to need to read the +-symbol information, the `_bfd_link_add_symbols' routine should save it +-somewhere attached to the object file BFD. However, the information +-should only be saved if the `keep_memory' field of the `info' argument +-is TRUE, so that the `-no-keep-memory' linker switch is effective. +- +- The a.out function which adds symbols from an object file is +-`aout_link_add_object_symbols', and most of the interesting work is in +-`aout_link_add_symbols'. The latter saves pointers to the hash tables +-entries created by `_bfd_generic_link_add_one_symbol' indexed by symbol +-number, so that the `_bfd_final_link' routine does not have to call the +-hash table lookup routine to locate the entry. +- +- +-File: bfd.info, Node: Adding symbols from an archive, Prev: Adding symbols from an object file, Up: Adding Symbols to the Hash Table +- +-2.17.2.3 Adding symbols from an archive +-....................................... +- +-When the `_bfd_link_add_symbols' routine is passed an archive, it must +-look through the symbols defined by the archive and decide which +-elements of the archive should be included in the link. For each such +-element it must call the `add_archive_element' linker callback, and it +-must add the symbols from the object file to the linker hash table. +-(The callback may in fact indicate that a replacement BFD should be +-used, in which case the symbols from that BFD should be added to the +-linker hash table instead.) +- +- In most cases the work of looking through the symbols in the archive +-should be done by the `_bfd_generic_link_add_archive_symbols' function. +-This function builds a hash table from the archive symbol table and +-looks through the list of undefined symbols to see which elements +-should be included. `_bfd_generic_link_add_archive_symbols' is passed +-a function to call to make the final decision about adding an archive +-element to the link and to do the actual work of adding the symbols to +-the linker hash table. +- +- The function passed to `_bfd_generic_link_add_archive_symbols' must +-read the symbols of the archive element and decide whether the archive +-element should be included in the link. If the element is to be +-included, the `add_archive_element' linker callback routine must be +-called with the element as an argument, and the element's symbols must +-be added to the linker hash table just as though the element had itself +-been passed to the `_bfd_link_add_symbols' function. The +-`add_archive_element' callback has the option to indicate that it would +-like to replace the element archive with a substitute BFD, in which +-case it is the symbols of that substitute BFD that must be added to the +-linker hash table instead. +- +- When the a.out `_bfd_link_add_symbols' function receives an archive, +-it calls `_bfd_generic_link_add_archive_symbols' passing +-`aout_link_check_archive_element' as the function argument. +-`aout_link_check_archive_element' calls `aout_link_check_ar_symbols'. +-If the latter decides to add the element (an element is only added if +-it provides a real, non-common, definition for a previously undefined +-or common symbol) it calls the `add_archive_element' callback and then +-`aout_link_check_archive_element' calls `aout_link_add_symbols' to +-actually add the symbols to the linker hash table - possibly those of a +-substitute BFD, if the `add_archive_element' callback avails itself of +-that option. +- +- The ECOFF back end is unusual in that it does not normally call +-`_bfd_generic_link_add_archive_symbols', because ECOFF archives already +-contain a hash table of symbols. The ECOFF back end searches the +-archive itself to avoid the overhead of creating a new hash table. +- +- +-File: bfd.info, Node: Performing the Final Link, Prev: Adding Symbols to the Hash Table, Up: Linker Functions +- +-2.17.3 Performing the final link +--------------------------------- +- +-When all the input files have been processed, the linker calls the +-`_bfd_final_link' entry point of the output BFD. This routine is +-responsible for producing the final output file, which has several +-aspects. It must relocate the contents of the input sections and copy +-the data into the output sections. It must build an output symbol +-table including any local symbols from the input files and the global +-symbols from the hash table. When producing relocatable output, it must +-modify the input relocs and write them into the output file. There may +-also be object format dependent work to be done. +- +- The linker will also call the `write_object_contents' entry point +-when the BFD is closed. The two entry points must work together in +-order to produce the correct output file. +- +- The details of how this works are inevitably dependent upon the +-specific object file format. The a.out `_bfd_final_link' routine is +-`NAME(aout,final_link)'. +- +-* Menu: +- +-* Information provided by the linker:: +-* Relocating the section contents:: +-* Writing the symbol table:: +- +- +-File: bfd.info, Node: Information provided by the linker, Next: Relocating the section contents, Prev: Performing the Final Link, Up: Performing the Final Link +- +-2.17.3.1 Information provided by the linker +-........................................... +- +-Before the linker calls the `_bfd_final_link' entry point, it sets up +-some data structures for the function to use. +- +- The `input_bfds' field of the `bfd_link_info' structure will point +-to a list of all the input files included in the link. These files are +-linked through the `link_next' field of the `bfd' structure. +- +- Each section in the output file will have a list of `link_order' +-structures attached to the `map_head.link_order' field (the +-`link_order' structure is defined in `bfdlink.h'). These structures +-describe how to create the contents of the output section in terms of +-the contents of various input sections, fill constants, and, +-eventually, other types of information. They also describe relocs that +-must be created by the BFD backend, but do not correspond to any input +-file; this is used to support -Ur, which builds constructors while +-generating a relocatable object file. +- +- +-File: bfd.info, Node: Relocating the section contents, Next: Writing the symbol table, Prev: Information provided by the linker, Up: Performing the Final Link +- +-2.17.3.2 Relocating the section contents +-........................................ +- +-The `_bfd_final_link' function should look through the `link_order' +-structures attached to each section of the output file. Each +-`link_order' structure should either be handled specially, or it should +-be passed to the function `_bfd_default_link_order' which will do the +-right thing (`_bfd_default_link_order' is defined in `linker.c'). +- +- For efficiency, a `link_order' of type `bfd_indirect_link_order' +-whose associated section belongs to a BFD of the same format as the +-output BFD must be handled specially. This type of `link_order' +-describes part of an output section in terms of a section belonging to +-one of the input files. The `_bfd_final_link' function should read the +-contents of the section and any associated relocs, apply the relocs to +-the section contents, and write out the modified section contents. If +-performing a relocatable link, the relocs themselves must also be +-modified and written out. +- +- The functions `_bfd_relocate_contents' and +-`_bfd_final_link_relocate' provide some general support for performing +-the actual relocations, notably overflow checking. Their arguments +-include information about the symbol the relocation is against and a +-`reloc_howto_type' argument which describes the relocation to perform. +-These functions are defined in `reloc.c'. +- +- The a.out function which handles reading, relocating, and writing +-section contents is `aout_link_input_section'. The actual relocation +-is done in `aout_link_input_section_std' and +-`aout_link_input_section_ext'. +- +- +-File: bfd.info, Node: Writing the symbol table, Prev: Relocating the section contents, Up: Performing the Final Link +- +-2.17.3.3 Writing the symbol table +-................................. +- +-The `_bfd_final_link' function must gather all the symbols in the input +-files and write them out. It must also write out all the symbols in +-the global hash table. This must be controlled by the `strip' and +-`discard' fields of the `bfd_link_info' structure. +- +- The local symbols of the input files will not have been entered into +-the linker hash table. The `_bfd_final_link' routine must consider +-each input file and include the symbols in the output file. It may be +-convenient to do this when looking through the `link_order' structures, +-or it may be done by stepping through the `input_bfds' list. +- +- The `_bfd_final_link' routine must also traverse the global hash +-table to gather all the externally visible symbols. It is possible +-that most of the externally visible symbols may be written out when +-considering the symbols of each input file, but it is still necessary +-to traverse the hash table since the linker script may have defined +-some symbols that are not in any of the input files. +- +- The `strip' field of the `bfd_link_info' structure controls which +-symbols are written out. The possible values are listed in +-`bfdlink.h'. If the value is `strip_some', then the `keep_hash' field +-of the `bfd_link_info' structure is a hash table of symbols to keep; +-each symbol should be looked up in this hash table, and only symbols +-which are present should be included in the output file. +- +- If the `strip' field of the `bfd_link_info' structure permits local +-symbols to be written out, the `discard' field is used to further +-controls which local symbols are included in the output file. If the +-value is `discard_l', then all local symbols which begin with a certain +-prefix are discarded; this is controlled by the +-`bfd_is_local_label_name' entry point. +- +- The a.out backend handles symbols by calling +-`aout_link_write_symbols' on each input BFD and then traversing the +-global hash table with the function `aout_link_write_other_symbol'. It +-builds a string table while writing out the symbols, which is written +-to the output file at the end of `NAME(aout,final_link)'. +- +-2.17.3.4 `bfd_link_split_section' +-................................. +- +-*Synopsis* +- bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); +- *Description* +-Return nonzero if SEC should be split during a reloceatable or final +-link. +- #define bfd_link_split_section(abfd, sec) \ +- BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) +- +-2.17.3.5 `bfd_section_already_linked' +-..................................... +- +-*Synopsis* +- bfd_boolean bfd_section_already_linked (bfd *abfd, +- asection *sec, +- struct bfd_link_info *info); +- *Description* +-Check if DATA has been already linked during a reloceatable or final +-link. Return TRUE if it has. +- #define bfd_section_already_linked(abfd, sec, info) \ +- BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) +- +-2.17.3.6 `bfd_generic_define_common_symbol' +-........................................... +- +-*Synopsis* +- bfd_boolean bfd_generic_define_common_symbol +- (bfd *output_bfd, struct bfd_link_info *info, +- struct bfd_link_hash_entry *h); +- *Description* +-Convert common symbol H into a defined symbol. Return TRUE on success +-and FALSE on failure. +- #define bfd_define_common_symbol(output_bfd, info, h) \ +- BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h)) +- +-2.17.3.7 `bfd_find_version_for_sym' +-................................... +- +-*Synopsis* +- struct bfd_elf_version_tree * bfd_find_version_for_sym +- (struct bfd_elf_version_tree *verdefs, +- const char *sym_name, bfd_boolean *hide); +- *Description* +-Search an elf version script tree for symbol versioning info and export +-/ don't-export status for a given symbol. Return non-NULL on success +-and NULL on failure; also sets the output `hide' boolean parameter. +- +-2.17.3.8 `bfd_hide_sym_by_version' +-.................................. +- +-*Synopsis* +- bfd_boolean bfd_hide_sym_by_version +- (struct bfd_elf_version_tree *verdefs, const char *sym_name); +- *Description* +-Search an elf version script tree for symbol versioning info for a +-given symbol. Return TRUE if the symbol is hidden. +- +- +-File: bfd.info, Node: Hash Tables, Prev: Linker Functions, Up: BFD front end +- +-2.18 Hash Tables +-================ +- +-BFD provides a simple set of hash table functions. Routines are +-provided to initialize a hash table, to free a hash table, to look up a +-string in a hash table and optionally create an entry for it, and to +-traverse a hash table. There is currently no routine to delete an +-string from a hash table. +- +- The basic hash table does not permit any data to be stored with a +-string. However, a hash table is designed to present a base class from +-which other types of hash tables may be derived. These derived types +-may store additional information with the string. Hash tables were +-implemented in this way, rather than simply providing a data pointer in +-a hash table entry, because they were designed for use by the linker +-back ends. The linker may create thousands of hash table entries, and +-the overhead of allocating private data and storing and following +-pointers becomes noticeable. +- +- The basic hash table code is in `hash.c'. +- +-* Menu: +- +-* Creating and Freeing a Hash Table:: +-* Looking Up or Entering a String:: +-* Traversing a Hash Table:: +-* Deriving a New Hash Table Type:: +- +- +-File: bfd.info, Node: Creating and Freeing a Hash Table, Next: Looking Up or Entering a String, Prev: Hash Tables, Up: Hash Tables +- +-2.18.1 Creating and freeing a hash table +----------------------------------------- +- +-To create a hash table, create an instance of a `struct bfd_hash_table' +-(defined in `bfd.h') and call `bfd_hash_table_init' (if you know +-approximately how many entries you will need, the function +-`bfd_hash_table_init_n', which takes a SIZE argument, may be used). +-`bfd_hash_table_init' returns `FALSE' if some sort of error occurs. +- +- The function `bfd_hash_table_init' take as an argument a function to +-use to create new entries. For a basic hash table, use the function +-`bfd_hash_newfunc'. *Note Deriving a New Hash Table Type::, for why +-you would want to use a different value for this argument. +- +- `bfd_hash_table_init' will create an objalloc which will be used to +-allocate new entries. You may allocate memory on this objalloc using +-`bfd_hash_allocate'. +- +- Use `bfd_hash_table_free' to free up all the memory that has been +-allocated for a hash table. This will not free up the `struct +-bfd_hash_table' itself, which you must provide. +- +- Use `bfd_hash_set_default_size' to set the default size of hash +-table to use. +- +- +-File: bfd.info, Node: Looking Up or Entering a String, Next: Traversing a Hash Table, Prev: Creating and Freeing a Hash Table, Up: Hash Tables +- +-2.18.2 Looking up or entering a string +--------------------------------------- +- +-The function `bfd_hash_lookup' is used both to look up a string in the +-hash table and to create a new entry. +- +- If the CREATE argument is `FALSE', `bfd_hash_lookup' will look up a +-string. If the string is found, it will returns a pointer to a `struct +-bfd_hash_entry'. If the string is not found in the table +-`bfd_hash_lookup' will return `NULL'. You should not modify any of the +-fields in the returns `struct bfd_hash_entry'. +- +- If the CREATE argument is `TRUE', the string will be entered into +-the hash table if it is not already there. Either way a pointer to a +-`struct bfd_hash_entry' will be returned, either to the existing +-structure or to a newly created one. In this case, a `NULL' return +-means that an error occurred. +- +- If the CREATE argument is `TRUE', and a new entry is created, the +-COPY argument is used to decide whether to copy the string onto the +-hash table objalloc or not. If COPY is passed as `FALSE', you must be +-careful not to deallocate or modify the string as long as the hash table +-exists. +- +- +-File: bfd.info, Node: Traversing a Hash Table, Next: Deriving a New Hash Table Type, Prev: Looking Up or Entering a String, Up: Hash Tables +- +-2.18.3 Traversing a hash table +------------------------------- +- +-The function `bfd_hash_traverse' may be used to traverse a hash table, +-calling a function on each element. The traversal is done in a random +-order. +- +- `bfd_hash_traverse' takes as arguments a function and a generic +-`void *' pointer. The function is called with a hash table entry (a +-`struct bfd_hash_entry *') and the generic pointer passed to +-`bfd_hash_traverse'. The function must return a `boolean' value, which +-indicates whether to continue traversing the hash table. If the +-function returns `FALSE', `bfd_hash_traverse' will stop the traversal +-and return immediately. +- +- +-File: bfd.info, Node: Deriving a New Hash Table Type, Prev: Traversing a Hash Table, Up: Hash Tables +- +-2.18.4 Deriving a new hash table type +-------------------------------------- +- +-Many uses of hash tables want to store additional information which +-each entry in the hash table. Some also find it convenient to store +-additional information with the hash table itself. This may be done +-using a derived hash table. +- +- Since C is not an object oriented language, creating a derived hash +-table requires sticking together some boilerplate routines with a few +-differences specific to the type of hash table you want to create. +- +- An example of a derived hash table is the linker hash table. The +-structures for this are defined in `bfdlink.h'. The functions are in +-`linker.c'. +- +- You may also derive a hash table from an already derived hash table. +-For example, the a.out linker backend code uses a hash table derived +-from the linker hash table. +- +-* Menu: +- +-* Define the Derived Structures:: +-* Write the Derived Creation Routine:: +-* Write Other Derived Routines:: +- +- +-File: bfd.info, Node: Define the Derived Structures, Next: Write the Derived Creation Routine, Prev: Deriving a New Hash Table Type, Up: Deriving a New Hash Table Type +- +-2.18.4.1 Define the derived structures +-...................................... +- +-You must define a structure for an entry in the hash table, and a +-structure for the hash table itself. +- +- The first field in the structure for an entry in the hash table must +-be of the type used for an entry in the hash table you are deriving +-from. If you are deriving from a basic hash table this is `struct +-bfd_hash_entry', which is defined in `bfd.h'. The first field in the +-structure for the hash table itself must be of the type of the hash +-table you are deriving from itself. If you are deriving from a basic +-hash table, this is `struct bfd_hash_table'. +- +- For example, the linker hash table defines `struct +-bfd_link_hash_entry' (in `bfdlink.h'). The first field, `root', is of +-type `struct bfd_hash_entry'. Similarly, the first field in `struct +-bfd_link_hash_table', `table', is of type `struct bfd_hash_table'. +- +- +-File: bfd.info, Node: Write the Derived Creation Routine, Next: Write Other Derived Routines, Prev: Define the Derived Structures, Up: Deriving a New Hash Table Type +- +-2.18.4.2 Write the derived creation routine +-........................................... +- +-You must write a routine which will create and initialize an entry in +-the hash table. This routine is passed as the function argument to +-`bfd_hash_table_init'. +- +- In order to permit other hash tables to be derived from the hash +-table you are creating, this routine must be written in a standard way. +- +- The first argument to the creation routine is a pointer to a hash +-table entry. This may be `NULL', in which case the routine should +-allocate the right amount of space. Otherwise the space has already +-been allocated by a hash table type derived from this one. +- +- After allocating space, the creation routine must call the creation +-routine of the hash table type it is derived from, passing in a pointer +-to the space it just allocated. This will initialize any fields used +-by the base hash table. +- +- Finally the creation routine must initialize any local fields for +-the new hash table type. +- +- Here is a boilerplate example of a creation routine. FUNCTION_NAME +-is the name of the routine. ENTRY_TYPE is the type of an entry in the +-hash table you are creating. BASE_NEWFUNC is the name of the creation +-routine of the hash table type your hash table is derived from. +- +- struct bfd_hash_entry * +- FUNCTION_NAME (struct bfd_hash_entry *entry, +- struct bfd_hash_table *table, +- const char *string) +- { +- struct ENTRY_TYPE *ret = (ENTRY_TYPE *) entry; +- +- /* Allocate the structure if it has not already been allocated by a +- derived class. */ +- if (ret == NULL) +- { +- ret = bfd_hash_allocate (table, sizeof (* ret)); +- if (ret == NULL) +- return NULL; +- } +- +- /* Call the allocation method of the base class. */ +- ret = ((ENTRY_TYPE *) +- BASE_NEWFUNC ((struct bfd_hash_entry *) ret, table, string)); +- +- /* Initialize the local fields here. */ +- +- return (struct bfd_hash_entry *) ret; +- } +- *Description* +-The creation routine for the linker hash table, which is in `linker.c', +-looks just like this example. FUNCTION_NAME is +-`_bfd_link_hash_newfunc'. ENTRY_TYPE is `struct bfd_link_hash_entry'. +-BASE_NEWFUNC is `bfd_hash_newfunc', the creation routine for a basic +-hash table. +- +- `_bfd_link_hash_newfunc' also initializes the local fields in a +-linker hash table entry: `type', `written' and `next'. +- +- +-File: bfd.info, Node: Write Other Derived Routines, Prev: Write the Derived Creation Routine, Up: Deriving a New Hash Table Type +- +-2.18.4.3 Write other derived routines +-..................................... +- +-You will want to write other routines for your new hash table, as well. +- +- You will want an initialization routine which calls the +-initialization routine of the hash table you are deriving from and +-initializes any other local fields. For the linker hash table, this is +-`_bfd_link_hash_table_init' in `linker.c'. +- +- You will want a lookup routine which calls the lookup routine of the +-hash table you are deriving from and casts the result. The linker hash +-table uses `bfd_link_hash_lookup' in `linker.c' (this actually takes an +-additional argument which it uses to decide how to return the looked up +-value). +- +- You may want a traversal routine. This should just call the +-traversal routine of the hash table you are deriving from with +-appropriate casts. The linker hash table uses `bfd_link_hash_traverse' +-in `linker.c'. +- +- These routines may simply be defined as macros. For example, the +-a.out backend linker hash table, which is derived from the linker hash +-table, uses macros for the lookup and traversal routines. These are +-`aout_link_hash_lookup' and `aout_link_hash_traverse' in aoutx.h. +- +- +-File: bfd.info, Node: BFD back ends, Next: GNU Free Documentation License, Prev: BFD front end, Up: Top +- +-3 BFD back ends +-*************** +- +-* Menu: +- +-* What to Put Where:: +-* aout :: a.out backends +-* coff :: coff backends +-* elf :: elf backends +-* mmo :: mmo backend +- +- +-File: bfd.info, Node: What to Put Where, Next: aout, Prev: BFD back ends, Up: BFD back ends +- +-3.1 What to Put Where +-===================== +- +-All of BFD lives in one directory. +- +- +-File: bfd.info, Node: aout, Next: coff, Prev: What to Put Where, Up: BFD back ends +- +-3.2 a.out backends +-================== +- +-*Description* +-BFD supports a number of different flavours of a.out format, though the +-major differences are only the sizes of the structures on disk, and the +-shape of the relocation information. +- +- The support is split into a basic support file `aoutx.h' and other +-files which derive functions from the base. One derivation file is +-`aoutf1.h' (for a.out flavour 1), and adds to the basic a.out functions +-support for sun3, sun4, 386 and 29k a.out files, to create a target +-jump vector for a specific target. +- +- This information is further split out into more specific files for +-each machine, including `sunos.c' for sun3 and sun4, `newsos3.c' for +-the Sony NEWS, and `demo64.c' for a demonstration of a 64 bit a.out +-format. +- +- The base file `aoutx.h' defines general mechanisms for reading and +-writing records to and from disk and various other methods which BFD +-requires. It is included by `aout32.c' and `aout64.c' to form the names +-`aout_32_swap_exec_header_in', `aout_64_swap_exec_header_in', etc. +- +- As an example, this is what goes on to make the back end for a sun4, +-from `aout32.c': +- +- #define ARCH_SIZE 32 +- #include "aoutx.h" +- +- Which exports names: +- +- ... +- aout_32_canonicalize_reloc +- aout_32_find_nearest_line +- aout_32_get_lineno +- aout_32_get_reloc_upper_bound +- ... +- +- from `sunos.c': +- +- #define TARGET_NAME "a.out-sunos-big" +- #define VECNAME sunos_big_vec +- #include "aoutf1.h" +- +- requires all the names from `aout32.c', and produces the jump vector +- +- sunos_big_vec +- +- The file `host-aout.c' is a special case. It is for a large set of +-hosts that use "more or less standard" a.out files, and for which +-cross-debugging is not interesting. It uses the standard 32-bit a.out +-support routines, but determines the file offsets and addresses of the +-text, data, and BSS sections, the machine architecture and machine +-type, and the entry point address, in a host-dependent manner. Once +-these values have been determined, generic code is used to handle the +-object file. +- +- When porting it to run on a new system, you must supply: +- +- HOST_PAGE_SIZE +- HOST_SEGMENT_SIZE +- HOST_MACHINE_ARCH (optional) +- HOST_MACHINE_MACHINE (optional) +- HOST_TEXT_START_ADDR +- HOST_STACK_END_ADDR +- +- in the file `../include/sys/h-XXX.h' (for your host). These values, +-plus the structures and macros defined in `a.out.h' on your host +-system, will produce a BFD target that will access ordinary a.out files +-on your host. To configure a new machine to use `host-aout.c', specify: +- +- TDEFAULTS = -DDEFAULT_VECTOR=host_aout_big_vec +- TDEPFILES= host-aout.o trad-core.o +- +- in the `config/XXX.mt' file, and modify `configure.in' to use the +-`XXX.mt' file (by setting "`bfd_target=XXX'") when your configuration +-is selected. +- +-3.2.1 Relocations +------------------ +- +-*Description* +-The file `aoutx.h' provides for both the _standard_ and _extended_ +-forms of a.out relocation records. +- +- The standard records contain only an address, a symbol index, and a +-type field. The extended records (used on 29ks and sparcs) also have a +-full integer for an addend. +- +-3.2.2 Internal entry points +---------------------------- +- +-*Description* +-`aoutx.h' exports several routines for accessing the contents of an +-a.out file, which are gathered and exported in turn by various format +-specific files (eg sunos.c). +- +-3.2.2.1 `aout_SIZE_swap_exec_header_in' +-....................................... +- +-*Synopsis* +- void aout_SIZE_swap_exec_header_in, +- (bfd *abfd, +- struct external_exec *bytes, +- struct internal_exec *execp); +- *Description* +-Swap the information in an executable header RAW_BYTES taken from a raw +-byte stream memory image into the internal exec header structure EXECP. +- +-3.2.2.2 `aout_SIZE_swap_exec_header_out' +-........................................ +- +-*Synopsis* +- void aout_SIZE_swap_exec_header_out +- (bfd *abfd, +- struct internal_exec *execp, +- struct external_exec *raw_bytes); +- *Description* +-Swap the information in an internal exec header structure EXECP into +-the buffer RAW_BYTES ready for writing to disk. +- +-3.2.2.3 `aout_SIZE_some_aout_object_p' +-...................................... +- +-*Synopsis* +- const bfd_target *aout_SIZE_some_aout_object_p +- (bfd *abfd, +- struct internal_exec *execp, +- const bfd_target *(*callback_to_real_object_p) (bfd *)); +- *Description* +-Some a.out variant thinks that the file open in ABFD checking is an +-a.out file. Do some more checking, and set up for access if it really +-is. Call back to the calling environment's "finish up" function just +-before returning, to handle any last-minute setup. +- +-3.2.2.4 `aout_SIZE_mkobject' +-............................ +- +-*Synopsis* +- bfd_boolean aout_SIZE_mkobject, (bfd *abfd); +- *Description* +-Initialize BFD ABFD for use with a.out files. +- +-3.2.2.5 `aout_SIZE_machine_type' +-................................ +- +-*Synopsis* +- enum machine_type aout_SIZE_machine_type +- (enum bfd_architecture arch, +- unsigned long machine, +- bfd_boolean *unknown); +- *Description* +-Keep track of machine architecture and machine type for a.out's. Return +-the `machine_type' for a particular architecture and machine, or +-`M_UNKNOWN' if that exact architecture and machine can't be represented +-in a.out format. +- +- If the architecture is understood, machine type 0 (default) is +-always understood. +- +-3.2.2.6 `aout_SIZE_set_arch_mach' +-................................. +- +-*Synopsis* +- bfd_boolean aout_SIZE_set_arch_mach, +- (bfd *, +- enum bfd_architecture arch, +- unsigned long machine); +- *Description* +-Set the architecture and the machine of the BFD ABFD to the values ARCH +-and MACHINE. Verify that ABFD's format can support the architecture +-required. +- +-3.2.2.7 `aout_SIZE_new_section_hook' +-.................................... +- +-*Synopsis* +- bfd_boolean aout_SIZE_new_section_hook, +- (bfd *abfd, +- asection *newsect); +- *Description* +-Called by the BFD in response to a `bfd_make_section' request. +- +- +-File: bfd.info, Node: coff, Next: elf, Prev: aout, Up: BFD back ends +- +-3.3 coff backends +-================= +- +-BFD supports a number of different flavours of coff format. The major +-differences between formats are the sizes and alignments of fields in +-structures on disk, and the occasional extra field. +- +- Coff in all its varieties is implemented with a few common files and +-a number of implementation specific files. For example, The 88k bcs +-coff format is implemented in the file `coff-m88k.c'. This file +-`#include's `coff/m88k.h' which defines the external structure of the +-coff format for the 88k, and `coff/internal.h' which defines the +-internal structure. `coff-m88k.c' also defines the relocations used by +-the 88k format *Note Relocations::. +- +- The Intel i960 processor version of coff is implemented in +-`coff-i960.c'. This file has the same structure as `coff-m88k.c', +-except that it includes `coff/i960.h' rather than `coff-m88k.h'. +- +-3.3.1 Porting to a new version of coff +--------------------------------------- +- +-The recommended method is to select from the existing implementations +-the version of coff which is most like the one you want to use. For +-example, we'll say that i386 coff is the one you select, and that your +-coff flavour is called foo. Copy `i386coff.c' to `foocoff.c', copy +-`../include/coff/i386.h' to `../include/coff/foo.h', and add the lines +-to `targets.c' and `Makefile.in' so that your new back end is used. +-Alter the shapes of the structures in `../include/coff/foo.h' so that +-they match what you need. You will probably also have to add `#ifdef's +-to the code in `coff/internal.h' and `coffcode.h' if your version of +-coff is too wild. +- +- You can verify that your new BFD backend works quite simply by +-building `objdump' from the `binutils' directory, and making sure that +-its version of what's going on and your host system's idea (assuming it +-has the pretty standard coff dump utility, usually called `att-dump' or +-just `dump') are the same. Then clean up your code, and send what +-you've done to Cygnus. Then your stuff will be in the next release, and +-you won't have to keep integrating it. +- +-3.3.2 How the coff backend works +--------------------------------- +- +-3.3.2.1 File layout +-................... +- +-The Coff backend is split into generic routines that are applicable to +-any Coff target and routines that are specific to a particular target. +-The target-specific routines are further split into ones which are +-basically the same for all Coff targets except that they use the +-external symbol format or use different values for certain constants. +- +- The generic routines are in `coffgen.c'. These routines work for +-any Coff target. They use some hooks into the target specific code; +-the hooks are in a `bfd_coff_backend_data' structure, one of which +-exists for each target. +- +- The essentially similar target-specific routines are in +-`coffcode.h'. This header file includes executable C code. The +-various Coff targets first include the appropriate Coff header file, +-make any special defines that are needed, and then include `coffcode.h'. +- +- Some of the Coff targets then also have additional routines in the +-target source file itself. +- +- For example, `coff-i960.c' includes `coff/internal.h' and +-`coff/i960.h'. It then defines a few constants, such as `I960', and +-includes `coffcode.h'. Since the i960 has complex relocation types, +-`coff-i960.c' also includes some code to manipulate the i960 relocs. +-This code is not in `coffcode.h' because it would not be used by any +-other target. +- +-3.3.2.2 Coff long section names +-............................... +- +-In the standard Coff object format, section names are limited to the +-eight bytes available in the `s_name' field of the `SCNHDR' section +-header structure. The format requires the field to be NUL-padded, but +-not necessarily NUL-terminated, so the longest section names permitted +-are a full eight characters. +- +- The Microsoft PE variants of the Coff object file format add an +-extension to support the use of long section names. This extension is +-defined in section 4 of the Microsoft PE/COFF specification (rev 8.1). +-If a section name is too long to fit into the section header's `s_name' +-field, it is instead placed into the string table, and the `s_name' +-field is filled with a slash ("/") followed by the ASCII decimal +-representation of the offset of the full name relative to the string +-table base. +- +- Note that this implies that the extension can only be used in object +-files, as executables do not contain a string table. The standard +-specifies that long section names from objects emitted into executable +-images are to be truncated. +- +- However, as a GNU extension, BFD can generate executable images that +-contain a string table and long section names. This would appear to be +-technically valid, as the standard only says that Coff debugging +-information is deprecated, not forbidden, and in practice it works, +-although some tools that parse PE files expecting the MS standard +-format may become confused; `PEview' is one known example. +- +- The functionality is supported in BFD by code implemented under the +-control of the macro `COFF_LONG_SECTION_NAMES'. If not defined, the +-format does not support long section names in any way. If defined, it +-is used to initialise a flag, `_bfd_coff_long_section_names', and a +-hook function pointer, `_bfd_coff_set_long_section_names', in the Coff +-backend data structure. The flag controls the generation of long +-section names in output BFDs at runtime; if it is false, as it will be +-by default when generating an executable image, long section names are +-truncated; if true, the long section names extension is employed. The +-hook points to a function that allows the value of the flag to be +-altered at runtime, on formats that support long section names at all; +-on other formats it points to a stub that returns an error indication. +- +- With input BFDs, the flag is set according to whether any long +-section names are detected while reading the section headers. For a +-completely new BFD, the flag is set to the default for the target +-format. This information can be used by a client of the BFD library +-when deciding what output format to generate, and means that a BFD that +-is opened for read and subsequently converted to a writeable BFD and +-modified in-place will retain whatever format it had on input. +- +- If `COFF_LONG_SECTION_NAMES' is simply defined (blank), or is +-defined to the value "1", then long section names are enabled by +-default; if it is defined to the value zero, they are disabled by +-default (but still accepted in input BFDs). The header `coffcode.h' +-defines a macro, `COFF_DEFAULT_LONG_SECTION_NAMES', which is used in +-the backends to initialise the backend data structure fields +-appropriately; see the comments for further detail. +- +-3.3.2.3 Bit twiddling +-..................... +- +-Each flavour of coff supported in BFD has its own header file +-describing the external layout of the structures. There is also an +-internal description of the coff layout, in `coff/internal.h'. A major +-function of the coff backend is swapping the bytes and twiddling the +-bits to translate the external form of the structures into the normal +-internal form. This is all performed in the `bfd_swap'_thing_direction +-routines. Some elements are different sizes between different versions +-of coff; it is the duty of the coff version specific include file to +-override the definitions of various packing routines in `coffcode.h'. +-E.g., the size of line number entry in coff is sometimes 16 bits, and +-sometimes 32 bits. `#define'ing `PUT_LNSZ_LNNO' and `GET_LNSZ_LNNO' +-will select the correct one. No doubt, some day someone will find a +-version of coff which has a varying field size not catered to at the +-moment. To port BFD, that person will have to add more `#defines'. +-Three of the bit twiddling routines are exported to `gdb'; +-`coff_swap_aux_in', `coff_swap_sym_in' and `coff_swap_lineno_in'. `GDB' +-reads the symbol table on its own, but uses BFD to fix things up. More +-of the bit twiddlers are exported for `gas'; `coff_swap_aux_out', +-`coff_swap_sym_out', `coff_swap_lineno_out', `coff_swap_reloc_out', +-`coff_swap_filehdr_out', `coff_swap_aouthdr_out', +-`coff_swap_scnhdr_out'. `Gas' currently keeps track of all the symbol +-table and reloc drudgery itself, thereby saving the internal BFD +-overhead, but uses BFD to swap things on the way out, making cross +-ports much safer. Doing so also allows BFD (and thus the linker) to +-use the same header files as `gas', which makes one avenue to disaster +-disappear. +- +-3.3.2.4 Symbol reading +-...................... +- +-The simple canonical form for symbols used by BFD is not rich enough to +-keep all the information available in a coff symbol table. The back end +-gets around this problem by keeping the original symbol table around, +-"behind the scenes". +- +- When a symbol table is requested (through a call to +-`bfd_canonicalize_symtab'), a request gets through to +-`coff_get_normalized_symtab'. This reads the symbol table from the coff +-file and swaps all the structures inside into the internal form. It +-also fixes up all the pointers in the table (represented in the file by +-offsets from the first symbol in the table) into physical pointers to +-elements in the new internal table. This involves some work since the +-meanings of fields change depending upon context: a field that is a +-pointer to another structure in the symbol table at one moment may be +-the size in bytes of a structure at the next. Another pass is made +-over the table. All symbols which mark file names (`C_FILE' symbols) +-are modified so that the internal string points to the value in the +-auxent (the real filename) rather than the normal text associated with +-the symbol (`".file"'). +- +- At this time the symbol names are moved around. Coff stores all +-symbols less than nine characters long physically within the symbol +-table; longer strings are kept at the end of the file in the string +-table. This pass moves all strings into memory and replaces them with +-pointers to the strings. +- +- The symbol table is massaged once again, this time to create the +-canonical table used by the BFD application. Each symbol is inspected +-in turn, and a decision made (using the `sclass' field) about the +-various flags to set in the `asymbol'. *Note Symbols::. The generated +-canonical table shares strings with the hidden internal symbol table. +- +- Any linenumbers are read from the coff file too, and attached to the +-symbols which own the functions the linenumbers belong to. +- +-3.3.2.5 Symbol writing +-...................... +- +-Writing a symbol to a coff file which didn't come from a coff file will +-lose any debugging information. The `asymbol' structure remembers the +-BFD from which the symbol was taken, and on output the back end makes +-sure that the same destination target as source target is present. +- +- When the symbols have come from a coff file then all the debugging +-information is preserved. +- +- Symbol tables are provided for writing to the back end in a vector +-of pointers to pointers. This allows applications like the linker to +-accumulate and output large symbol tables without having to do too much +-byte copying. +- +- This function runs through the provided symbol table and patches +-each symbol marked as a file place holder (`C_FILE') to point to the +-next file place holder in the list. It also marks each `offset' field +-in the list with the offset from the first symbol of the current symbol. +- +- Another function of this procedure is to turn the canonical value +-form of BFD into the form used by coff. Internally, BFD expects symbol +-values to be offsets from a section base; so a symbol physically at +-0x120, but in a section starting at 0x100, would have the value 0x20. +-Coff expects symbols to contain their final value, so symbols have +-their values changed at this point to reflect their sum with their +-owning section. This transformation uses the `output_section' field of +-the `asymbol''s `asection' *Note Sections::. +- +- * `coff_mangle_symbols' +- This routine runs though the provided symbol table and uses the +-offsets generated by the previous pass and the pointers generated when +-the symbol table was read in to create the structured hierarchy +-required by coff. It changes each pointer to a symbol into the index +-into the symbol table of the asymbol. +- +- * `coff_write_symbols' +- This routine runs through the symbol table and patches up the +-symbols from their internal form into the coff way, calls the bit +-twiddlers, and writes out the table to the file. +- +-3.3.2.6 `coff_symbol_type' +-.......................... +- +-*Description* +-The hidden information for an `asymbol' is described in a +-`combined_entry_type': +- +- +- typedef struct coff_ptr_struct +- { +- /* Remembers the offset from the first symbol in the file for +- this symbol. Generated by coff_renumber_symbols. */ +- unsigned int offset; +- +- /* Should the value of this symbol be renumbered. Used for +- XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */ +- unsigned int fix_value : 1; +- +- /* Should the tag field of this symbol be renumbered. +- Created by coff_pointerize_aux. */ +- unsigned int fix_tag : 1; +- +- /* Should the endidx field of this symbol be renumbered. +- Created by coff_pointerize_aux. */ +- unsigned int fix_end : 1; +- +- /* Should the x_csect.x_scnlen field be renumbered. +- Created by coff_pointerize_aux. */ +- unsigned int fix_scnlen : 1; +- +- /* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the +- index into the line number entries. Set by coff_slurp_symbol_table. */ +- unsigned int fix_line : 1; +- +- /* The container for the symbol structure as read and translated +- from the file. */ +- union +- { +- union internal_auxent auxent; +- struct internal_syment syment; +- } u; +- } combined_entry_type; +- +- +- /* Each canonical asymbol really looks like this: */ +- +- typedef struct coff_symbol_struct +- { +- /* The actual symbol which the rest of BFD works with */ +- asymbol symbol; +- +- /* A pointer to the hidden information for this symbol */ +- combined_entry_type *native; +- +- /* A pointer to the linenumber information for this symbol */ +- struct lineno_cache_entry *lineno; +- +- /* Have the line numbers been relocated yet ? */ +- bfd_boolean done_lineno; +- } coff_symbol_type; +- +-3.3.2.7 `bfd_coff_backend_data' +-............................... +- +- /* COFF symbol classifications. */ +- +- enum coff_symbol_classification +- { +- /* Global symbol. */ +- COFF_SYMBOL_GLOBAL, +- /* Common symbol. */ +- COFF_SYMBOL_COMMON, +- /* Undefined symbol. */ +- COFF_SYMBOL_UNDEFINED, +- /* Local symbol. */ +- COFF_SYMBOL_LOCAL, +- /* PE section symbol. */ +- COFF_SYMBOL_PE_SECTION +- }; +-Special entry points for gdb to swap in coff symbol table parts: +- typedef struct +- { +- void (*_bfd_coff_swap_aux_in) +- (bfd *, void *, int, int, int, int, void *); +- +- void (*_bfd_coff_swap_sym_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_lineno_in) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_aux_out) +- (bfd *, void *, int, int, int, int, void *); +- +- unsigned int (*_bfd_coff_swap_sym_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_lineno_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_reloc_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_filehdr_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_aouthdr_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_scnhdr_out) +- (bfd *, void *, void *); +- +- unsigned int _bfd_filhsz; +- unsigned int _bfd_aoutsz; +- unsigned int _bfd_scnhsz; +- unsigned int _bfd_symesz; +- unsigned int _bfd_auxesz; +- unsigned int _bfd_relsz; +- unsigned int _bfd_linesz; +- unsigned int _bfd_filnmlen; +- bfd_boolean _bfd_coff_long_filenames; +- +- bfd_boolean _bfd_coff_long_section_names; +- bfd_boolean (*_bfd_coff_set_long_section_names) +- (bfd *, int); +- +- unsigned int _bfd_coff_default_section_alignment_power; +- bfd_boolean _bfd_coff_force_symnames_in_strings; +- unsigned int _bfd_coff_debug_string_prefix_length; +- +- void (*_bfd_coff_swap_filehdr_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_aouthdr_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_scnhdr_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_reloc_in) +- (bfd *abfd, void *, void *); +- +- bfd_boolean (*_bfd_coff_bad_format_hook) +- (bfd *, void *); +- +- bfd_boolean (*_bfd_coff_set_arch_mach_hook) +- (bfd *, void *); +- +- void * (*_bfd_coff_mkobject_hook) +- (bfd *, void *, void *); +- +- bfd_boolean (*_bfd_styp_to_sec_flags_hook) +- (bfd *, void *, const char *, asection *, flagword *); +- +- void (*_bfd_set_alignment_hook) +- (bfd *, asection *, void *); +- +- bfd_boolean (*_bfd_coff_slurp_symbol_table) +- (bfd *); +- +- bfd_boolean (*_bfd_coff_symname_in_debug) +- (bfd *, struct internal_syment *); +- +- bfd_boolean (*_bfd_coff_pointerize_aux_hook) +- (bfd *, combined_entry_type *, combined_entry_type *, +- unsigned int, combined_entry_type *); +- +- bfd_boolean (*_bfd_coff_print_aux) +- (bfd *, FILE *, combined_entry_type *, combined_entry_type *, +- combined_entry_type *, unsigned int); +- +- void (*_bfd_coff_reloc16_extra_cases) +- (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, +- bfd_byte *, unsigned int *, unsigned int *); +- +- int (*_bfd_coff_reloc16_estimate) +- (bfd *, asection *, arelent *, unsigned int, +- struct bfd_link_info *); +- +- enum coff_symbol_classification (*_bfd_coff_classify_symbol) +- (bfd *, struct internal_syment *); +- +- bfd_boolean (*_bfd_coff_compute_section_file_positions) +- (bfd *); +- +- bfd_boolean (*_bfd_coff_start_final_link) +- (bfd *, struct bfd_link_info *); +- +- bfd_boolean (*_bfd_coff_relocate_section) +- (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, +- struct internal_reloc *, struct internal_syment *, asection **); +- +- reloc_howto_type *(*_bfd_coff_rtype_to_howto) +- (bfd *, asection *, struct internal_reloc *, +- struct coff_link_hash_entry *, struct internal_syment *, +- bfd_vma *); +- +- bfd_boolean (*_bfd_coff_adjust_symndx) +- (bfd *, struct bfd_link_info *, bfd *, asection *, +- struct internal_reloc *, bfd_boolean *); +- +- bfd_boolean (*_bfd_coff_link_add_one_symbol) +- (struct bfd_link_info *, bfd *, const char *, flagword, +- asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, +- struct bfd_link_hash_entry **); +- +- bfd_boolean (*_bfd_coff_link_output_has_begun) +- (bfd *, struct coff_final_link_info *); +- +- bfd_boolean (*_bfd_coff_final_link_postscript) +- (bfd *, struct coff_final_link_info *); +- +- bfd_boolean (*_bfd_coff_print_pdata) +- (bfd *, void *); +- +- } bfd_coff_backend_data; +- +- #define coff_backend_info(abfd) \ +- ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) +- +- #define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ +- ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) +- +- #define bfd_coff_swap_sym_in(a,e,i) \ +- ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i)) +- +- #define bfd_coff_swap_lineno_in(a,e,i) \ +- ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) +- +- #define bfd_coff_swap_reloc_out(abfd, i, o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) +- +- #define bfd_coff_swap_lineno_out(abfd, i, o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) +- +- #define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \ +- ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o)) +- +- #define bfd_coff_swap_sym_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o)) +- +- #define bfd_coff_swap_scnhdr_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) +- +- #define bfd_coff_swap_filehdr_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) +- +- #define bfd_coff_swap_aouthdr_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) +- +- #define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) +- #define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) +- #define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) +- #define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) +- #define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) +- #define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) +- #define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) +- #define bfd_coff_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen) +- #define bfd_coff_long_filenames(abfd) \ +- (coff_backend_info (abfd)->_bfd_coff_long_filenames) +- #define bfd_coff_long_section_names(abfd) \ +- (coff_backend_info (abfd)->_bfd_coff_long_section_names) +- #define bfd_coff_set_long_section_names(abfd, enable) \ +- ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) +- #define bfd_coff_default_section_alignment_power(abfd) \ +- (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) +- #define bfd_coff_swap_filehdr_in(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) +- +- #define bfd_coff_swap_aouthdr_in(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) +- +- #define bfd_coff_swap_scnhdr_in(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) +- +- #define bfd_coff_swap_reloc_in(abfd, i, o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) +- +- #define bfd_coff_bad_format_hook(abfd, filehdr) \ +- ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) +- +- #define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ +- ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) +- #define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ +- ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\ +- (abfd, filehdr, aouthdr)) +- +- #define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\ +- ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\ +- (abfd, scnhdr, name, section, flags_ptr)) +- +- #define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ +- ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) +- +- #define bfd_coff_slurp_symbol_table(abfd)\ +- ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) +- +- #define bfd_coff_symname_in_debug(abfd, sym)\ +- ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) +- +- #define bfd_coff_force_symnames_in_strings(abfd)\ +- (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings) +- +- #define bfd_coff_debug_string_prefix_length(abfd)\ +- (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length) +- +- #define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\ +- ((coff_backend_info (abfd)->_bfd_coff_print_aux)\ +- (abfd, file, base, symbol, aux, indaux)) +- +- #define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\ +- reloc, data, src_ptr, dst_ptr)\ +- ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\ +- (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)) +- +- #define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ +- ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ +- (abfd, section, reloc, shrink, link_info)) +- +- #define bfd_coff_classify_symbol(abfd, sym)\ +- ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\ +- (abfd, sym)) +- +- #define bfd_coff_compute_section_file_positions(abfd)\ +- ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ +- (abfd)) +- +- #define bfd_coff_start_final_link(obfd, info)\ +- ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\ +- (obfd, info)) +- #define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ +- ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ +- (obfd, info, ibfd, o, con, rel, isyms, secs)) +- #define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\ +- ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\ +- (abfd, sec, rel, h, sym, addendp)) +- #define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ +- ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ +- (obfd, info, ibfd, sec, rel, adjustedp)) +- #define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\ +- value, string, cp, coll, hashp)\ +- ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ +- (info, abfd, name, flags, section, value, string, cp, coll, hashp)) +- +- #define bfd_coff_link_output_has_begun(a,p) \ +- ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p)) +- #define bfd_coff_final_link_postscript(a,p) \ +- ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a, p)) +- +- #define bfd_coff_have_print_pdata(a) \ +- (coff_backend_info (a)->_bfd_coff_print_pdata) +- #define bfd_coff_print_pdata(a,p) \ +- ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p)) +- +- /* Macro: Returns true if the bfd is a PE executable as opposed to a +- PE object file. */ +- #define bfd_pei_p(abfd) \ +- (CONST_STRNEQ ((abfd)->xvec->name, "pei-")) +- +-3.3.2.8 Writing relocations +-........................... +- +-To write relocations, the back end steps though the canonical +-relocation table and create an `internal_reloc'. The symbol index to +-use is removed from the `offset' field in the symbol table supplied. +-The address comes directly from the sum of the section base address and +-the relocation offset; the type is dug directly from the howto field. +-Then the `internal_reloc' is swapped into the shape of an +-`external_reloc' and written out to disk. +- +-3.3.2.9 Reading linenumbers +-........................... +- +-Creating the linenumber table is done by reading in the entire coff +-linenumber table, and creating another table for internal use. +- +- A coff linenumber table is structured so that each function is +-marked as having a line number of 0. Each line within the function is +-an offset from the first line in the function. The base of the line +-number information for the table is stored in the symbol associated +-with the function. +- +- Note: The PE format uses line number 0 for a flag indicating a new +-source file. +- +- The information is copied from the external to the internal table, +-and each symbol which marks a function is marked by pointing its... +- +- How does this work ? +- +-3.3.2.10 Reading relocations +-............................ +- +-Coff relocations are easily transformed into the internal BFD form +-(`arelent'). +- +- Reading a coff relocation table is done in the following stages: +- +- * Read the entire coff relocation table into memory. +- +- * Process each relocation in turn; first swap it from the external +- to the internal form. +- +- * Turn the symbol referenced in the relocation's symbol index into a +- pointer into the canonical symbol table. This table is the same +- as the one returned by a call to `bfd_canonicalize_symtab'. The +- back end will call that routine and save the result if a +- canonicalization hasn't been done. +- +- * The reloc index is turned into a pointer to a howto structure, in +- a back end specific way. For instance, the 386 and 960 use the +- `r_type' to directly produce an index into a howto table vector; +- the 88k subtracts a number from the `r_type' field and creates an +- addend field. +- +- +-File: bfd.info, Node: elf, Next: mmo, Prev: coff, Up: BFD back ends +- +-3.4 ELF backends +-================ +- +-BFD support for ELF formats is being worked on. Currently, the best +-supported back ends are for sparc and i386 (running svr4 or Solaris 2). +- +- Documentation of the internals of the support code still needs to be +-written. The code is changing quickly enough that we haven't bothered +-yet. +- +- +-File: bfd.info, Node: mmo, Prev: elf, Up: BFD back ends +- +-3.5 mmo backend +-=============== +- +-The mmo object format is used exclusively together with Professor +-Donald E. Knuth's educational 64-bit processor MMIX. The simulator +-`mmix' which is available at +-`http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz' +-understands this format. That package also includes a combined +-assembler and linker called `mmixal'. The mmo format has no advantages +-feature-wise compared to e.g. ELF. It is a simple non-relocatable +-object format with no support for archives or debugging information, +-except for symbol value information and line numbers (which is not yet +-implemented in BFD). See +-`http://www-cs-faculty.stanford.edu/~knuth/mmix.html' for more +-information about MMIX. The ELF format is used for intermediate object +-files in the BFD implementation. +- +-* Menu: +- +-* File layout:: +-* Symbol-table:: +-* mmo section mapping:: +- +- +-File: bfd.info, Node: File layout, Next: Symbol-table, Prev: mmo, Up: mmo +- +-3.5.1 File layout +------------------ +- +-The mmo file contents is not partitioned into named sections as with +-e.g. ELF. Memory areas is formed by specifying the location of the +-data that follows. Only the memory area `0x0000...00' to `0x01ff...ff' +-is executable, so it is used for code (and constants) and the area +-`0x2000...00' to `0x20ff...ff' is used for writable data. *Note mmo +-section mapping::. +- +- There is provision for specifying "special data" of 65536 different +-types. We use type 80 (decimal), arbitrarily chosen the same as the +-ELF `e_machine' number for MMIX, filling it with section information +-normally found in ELF objects. *Note mmo section mapping::. +- +- Contents is entered as 32-bit words, xor:ed over previous contents, +-always zero-initialized. A word that starts with the byte `0x98' forms +-a command called a `lopcode', where the next byte distinguished between +-the thirteen lopcodes. The two remaining bytes, called the `Y' and `Z' +-fields, or the `YZ' field (a 16-bit big-endian number), are used for +-various purposes different for each lopcode. As documented in +-`http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz', the +-lopcodes are: +- +-`lop_quote' +- 0x98000001. The next word is contents, regardless of whether it +- starts with 0x98 or not. +- +-`lop_loc' +- 0x9801YYZZ, where `Z' is 1 or 2. This is a location directive, +- setting the location for the next data to the next 32-bit word +- (for Z = 1) or 64-bit word (for Z = 2), plus Y * 2^56. Normally +- `Y' is 0 for the text segment and 2 for the data segment. +- +-`lop_skip' +- 0x9802YYZZ. Increase the current location by `YZ' bytes. +- +-`lop_fixo' +- 0x9803YYZZ, where `Z' is 1 or 2. Store the current location as 64 +- bits into the location pointed to by the next 32-bit (Z = 1) or +- 64-bit (Z = 2) word, plus Y * 2^56. +- +-`lop_fixr' +- 0x9804YYZZ. `YZ' is stored into the current location plus 2 - 4 * +- YZ. +- +-`lop_fixrx' +- 0x980500ZZ. `Z' is 16 or 24. A value `L' derived from the +- following 32-bit word are used in a manner similar to `YZ' in +- lop_fixr: it is xor:ed into the current location minus 4 * L. The +- first byte of the word is 0 or 1. If it is 1, then L = (LOWEST 24 +- BITS OF WORD) - 2^Z, if 0, then L = (LOWEST 24 BITS OF WORD). +- +-`lop_file' +- 0x9806YYZZ. `Y' is the file number, `Z' is count of 32-bit words. +- Set the file number to `Y' and the line counter to 0. The next Z +- * 4 bytes contain the file name, padded with zeros if the count is +- not a multiple of four. The same `Y' may occur multiple times, +- but `Z' must be 0 for all but the first occurrence. +- +-`lop_line' +- 0x9807YYZZ. `YZ' is the line number. Together with lop_file, it +- forms the source location for the next 32-bit word. Note that for +- each non-lopcode 32-bit word, line numbers are assumed incremented +- by one. +- +-`lop_spec' +- 0x9808YYZZ. `YZ' is the type number. Data until the next lopcode +- other than lop_quote forms special data of type `YZ'. *Note mmo +- section mapping::. +- +- Other types than 80, (or type 80 with a content that does not +- parse) is stored in sections named `.MMIX.spec_data.N' where N is +- the `YZ'-type. The flags for such a sections say not to allocate +- or load the data. The vma is 0. Contents of multiple occurrences +- of special data N is concatenated to the data of the previous +- lop_spec Ns. The location in data or code at which the lop_spec +- occurred is lost. +- +-`lop_pre' +- 0x980901ZZ. The first lopcode in a file. The `Z' field forms the +- length of header information in 32-bit words, where the first word +- tells the time in seconds since `00:00:00 GMT Jan 1 1970'. +- +-`lop_post' +- 0x980a00ZZ. Z > 32. This lopcode follows after all +- content-generating lopcodes in a program. The `Z' field denotes +- the value of `rG' at the beginning of the program. The following +- 256 - Z big-endian 64-bit words are loaded into global registers +- `$G' ... `$255'. +- +-`lop_stab' +- 0x980b0000. The next-to-last lopcode in a program. Must follow +- immediately after the lop_post lopcode and its data. After this +- lopcode follows all symbols in a compressed format (*note +- Symbol-table::). +- +-`lop_end' +- 0x980cYYZZ. The last lopcode in a program. It must follow the +- lop_stab lopcode and its data. The `YZ' field contains the number +- of 32-bit words of symbol table information after the preceding +- lop_stab lopcode. +- +- Note that the lopcode "fixups"; `lop_fixr', `lop_fixrx' and +-`lop_fixo' are not generated by BFD, but are handled. They are +-generated by `mmixal'. +- +- This trivial one-label, one-instruction file: +- +- :Main TRAP 1,2,3 +- +- can be represented this way in mmo: +- +- 0x98090101 - lop_pre, one 32-bit word with timestamp. +- +- 0x98010002 - lop_loc, text segment, using a 64-bit address. +- Note that mmixal does not emit this for the file above. +- 0x00000000 - Address, high 32 bits. +- 0x00000000 - Address, low 32 bits. +- 0x98060002 - lop_file, 2 32-bit words for file-name. +- 0x74657374 - "test" +- 0x2e730000 - ".s\0\0" +- 0x98070001 - lop_line, line 1. +- 0x00010203 - TRAP 1,2,3 +- 0x980a00ff - lop_post, setting $255 to 0. +- 0x00000000 +- 0x00000000 +- 0x980b0000 - lop_stab for ":Main" = 0, serial 1. +- 0x203a4040 *Note Symbol-table::. +- 0x10404020 +- 0x4d206120 +- 0x69016e00 +- 0x81000000 +- 0x980c0005 - lop_end; symbol table contained five 32-bit words. +- +- +-File: bfd.info, Node: Symbol-table, Next: mmo section mapping, Prev: File layout, Up: mmo +- +-3.5.2 Symbol table format +-------------------------- +- +-From mmixal.w (or really, the generated mmixal.tex) in +-`http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz'): +-"Symbols are stored and retrieved by means of a `ternary search trie', +-following ideas of Bentley and Sedgewick. (See ACM-SIAM Symp. on +-Discrete Algorithms `8' (1997), 360-369; R.Sedgewick, `Algorithms in C' +-(Reading, Mass. Addison-Wesley, 1998), `15.4'.) Each trie node stores +-a character, and there are branches to subtries for the cases where a +-given character is less than, equal to, or greater than the character +-in the trie. There also is a pointer to a symbol table entry if a +-symbol ends at the current node." +- +- So it's a tree encoded as a stream of bytes. The stream of bytes +-acts on a single virtual global symbol, adding and removing characters +-and signalling complete symbol points. Here, we read the stream and +-create symbols at the completion points. +- +- First, there's a control byte `m'. If any of the listed bits in `m' +-is nonzero, we execute what stands at the right, in the listed order: +- +- (MMO3_LEFT) +- 0x40 - Traverse left trie. +- (Read a new command byte and recurse.) +- +- (MMO3_SYMBITS) +- 0x2f - Read the next byte as a character and store it in the +- current character position; increment character position. +- Test the bits of `m': +- +- (MMO3_WCHAR) +- 0x80 - The character is 16-bit (so read another byte, +- merge into current character. +- +- (MMO3_TYPEBITS) +- 0xf - We have a complete symbol; parse the type, value +- and serial number and do what should be done +- with a symbol. The type and length information +- is in j = (m & 0xf). +- +- (MMO3_REGQUAL_BITS) +- j == 0xf: A register variable. The following +- byte tells which register. +- j <= 8: An absolute symbol. Read j bytes as the +- big-endian number the symbol equals. +- A j = 2 with two zero bytes denotes an +- unknown symbol. +- j > 8: As with j <= 8, but add (0x20 << 56) +- to the value in the following j - 8 +- bytes. +- +- Then comes the serial number, as a variant of +- uleb128, but better named ubeb128: +- Read bytes and shift the previous value left 7 +- (multiply by 128). Add in the new byte, repeat +- until a byte has bit 7 set. The serial number +- is the computed value minus 128. +- +- (MMO3_MIDDLE) +- 0x20 - Traverse middle trie. (Read a new command byte +- and recurse.) Decrement character position. +- +- (MMO3_RIGHT) +- 0x10 - Traverse right trie. (Read a new command byte and +- recurse.) +- +- Let's look again at the `lop_stab' for the trivial file (*note File +-layout::). +- +- 0x980b0000 - lop_stab for ":Main" = 0, serial 1. +- 0x203a4040 +- 0x10404020 +- 0x4d206120 +- 0x69016e00 +- 0x81000000 +- +- This forms the trivial trie (note that the path between ":" and "M" +-is redundant): +- +- 203a ":" +- 40 / +- 40 / +- 10 \ +- 40 / +- 40 / +- 204d "M" +- 2061 "a" +- 2069 "i" +- 016e "n" is the last character in a full symbol, and +- with a value represented in one byte. +- 00 The value is 0. +- 81 The serial number is 1. +- +- +-File: bfd.info, Node: mmo section mapping, Prev: Symbol-table, Up: mmo +- +-3.5.3 mmo section mapping +-------------------------- +- +-The implementation in BFD uses special data type 80 (decimal) to +-encapsulate and describe named sections, containing e.g. debug +-information. If needed, any datum in the encapsulation will be quoted +-using lop_quote. First comes a 32-bit word holding the number of +-32-bit words containing the zero-terminated zero-padded segment name. +-After the name there's a 32-bit word holding flags describing the +-section type. Then comes a 64-bit big-endian word with the section +-length (in bytes), then another with the section start address. +-Depending on the type of section, the contents might follow, +-zero-padded to 32-bit boundary. For a loadable section (such as data +-or code), the contents might follow at some later point, not +-necessarily immediately, as a lop_loc with the same start address as in +-the section description, followed by the contents. This in effect +-forms a descriptor that must be emitted before the actual contents. +-Sections described this way must not overlap. +- +- For areas that don't have such descriptors, synthetic sections are +-formed by BFD. Consecutive contents in the two memory areas +-`0x0000...00' to `0x01ff...ff' and `0x2000...00' to `0x20ff...ff' are +-entered in sections named `.text' and `.data' respectively. If an area +-is not otherwise described, but would together with a neighboring lower +-area be less than `0x40000000' bytes long, it is joined with the lower +-area and the gap is zero-filled. For other cases, a new section is +-formed, named `.MMIX.sec.N'. Here, N is a number, a running count +-through the mmo file, starting at 0. +- +- A loadable section specified as: +- +- .section secname,"ax" +- TETRA 1,2,3,4,-1,-2009 +- BYTE 80 +- +- and linked to address `0x4', is represented by the sequence: +- +- 0x98080050 - lop_spec 80 +- 0x00000002 - two 32-bit words for the section name +- 0x7365636e - "secn" +- 0x616d6500 - "ame\0" +- 0x00000033 - flags CODE, READONLY, LOAD, ALLOC +- 0x00000000 - high 32 bits of section length +- 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits +- 0x00000000 - high 32 bits of section address +- 0x00000004 - section address is 4 +- 0x98010002 - 64 bits with address of following data +- 0x00000000 - high 32 bits of address +- 0x00000004 - low 32 bits: data starts at address 4 +- 0x00000001 - 1 +- 0x00000002 - 2 +- 0x00000003 - 3 +- 0x00000004 - 4 +- 0xffffffff - -1 +- 0xfffff827 - -2009 +- 0x50000000 - 80 as a byte, padded with zeros. +- +- Note that the lop_spec wrapping does not include the section +-contents. Compare this to a non-loaded section specified as: +- +- .section thirdsec +- TETRA 200001,100002 +- BYTE 38,40 +- +- This, when linked to address `0x200000000000001c', is represented by: +- +- 0x98080050 - lop_spec 80 +- 0x00000002 - two 32-bit words for the section name +- 0x7365636e - "thir" +- 0x616d6500 - "dsec" +- 0x00000010 - flag READONLY +- 0x00000000 - high 32 bits of section length +- 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits +- 0x20000000 - high 32 bits of address +- 0x0000001c - low 32 bits of address 0x200000000000001c +- 0x00030d41 - 200001 +- 0x000186a2 - 100002 +- 0x26280000 - 38, 40 as bytes, padded with zeros +- +- For the latter example, the section contents must not be loaded in +-memory, and is therefore specified as part of the special data. The +-address is usually unimportant but might provide information for e.g. +-the DWARF 2 debugging format. +- +- +-File: bfd.info, Node: GNU Free Documentation License, Next: BFD Index, Prev: BFD back ends, Up: Top +- +- Version 1.3, 3 November 2008 +- +- Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +- `http://fsf.org/' +- +- Everyone is permitted to copy and distribute verbatim copies +- of this license document, but changing it is not allowed. +- +- 0. PREAMBLE +- +- The purpose of this License is to make a manual, textbook, or other +- functional and useful document "free" in the sense of freedom: to +- assure everyone the effective freedom to copy and redistribute it, +- with or without modifying it, either commercially or +- noncommercially. Secondarily, this License preserves for the +- author and publisher a way to get credit for their work, while not +- being considered responsible for modifications made by others. +- +- This License is a kind of "copyleft", which means that derivative +- works of the document must themselves be free in the same sense. +- It complements the GNU General Public License, which is a copyleft +- license designed for free software. +- +- We have designed this License in order to use it for manuals for +- free software, because free software needs free documentation: a +- free program should come with manuals providing the same freedoms +- that the software does. But this License is not limited to +- software manuals; it can be used for any textual work, regardless +- of subject matter or whether it is published as a printed book. +- We recommend this License principally for works whose purpose is +- instruction or reference. +- +- 1. APPLICABILITY AND DEFINITIONS +- +- This License applies to any manual or other work, in any medium, +- that contains a notice placed by the copyright holder saying it +- can be distributed under the terms of this License. Such a notice +- grants a world-wide, royalty-free license, unlimited in duration, +- to use that work under the conditions stated herein. The +- "Document", below, refers to any such manual or work. Any member +- of the public is a licensee, and is addressed as "you". You +- accept the license if you copy, modify or distribute the work in a +- way requiring permission under copyright law. +- +- A "Modified Version" of the Document means any work containing the +- Document or a portion of it, either copied verbatim, or with +- modifications and/or translated into another language. +- +- A "Secondary Section" is a named appendix or a front-matter section +- of the Document that deals exclusively with the relationship of the +- publishers or authors of the Document to the Document's overall +- subject (or to related matters) and contains nothing that could +- fall directly within that overall subject. (Thus, if the Document +- is in part a textbook of mathematics, a Secondary Section may not +- explain any mathematics.) The relationship could be a matter of +- historical connection with the subject or with related matters, or +- of legal, commercial, philosophical, ethical or political position +- regarding them. +- +- The "Invariant Sections" are certain Secondary Sections whose +- titles are designated, as being those of Invariant Sections, in +- the notice that says that the Document is released under this +- License. If a section does not fit the above definition of +- Secondary then it is not allowed to be designated as Invariant. +- The Document may contain zero Invariant Sections. If the Document +- does not identify any Invariant Sections then there are none. +- +- The "Cover Texts" are certain short passages of text that are +- listed, as Front-Cover Texts or Back-Cover Texts, in the notice +- that says that the Document is released under this License. A +- Front-Cover Text may be at most 5 words, and a Back-Cover Text may +- be at most 25 words. +- +- A "Transparent" copy of the Document means a machine-readable copy, +- represented in a format whose specification is available to the +- general public, that is suitable for revising the document +- straightforwardly with generic text editors or (for images +- composed of pixels) generic paint programs or (for drawings) some +- widely available drawing editor, and that is suitable for input to +- text formatters or for automatic translation to a variety of +- formats suitable for input to text formatters. A copy made in an +- otherwise Transparent file format whose markup, or absence of +- markup, has been arranged to thwart or discourage subsequent +- modification by readers is not Transparent. An image format is +- not Transparent if used for any substantial amount of text. A +- copy that is not "Transparent" is called "Opaque". +- +- Examples of suitable formats for Transparent copies include plain +- ASCII without markup, Texinfo input format, LaTeX input format, +- SGML or XML using a publicly available DTD, and +- standard-conforming simple HTML, PostScript or PDF designed for +- human modification. Examples of transparent image formats include +- PNG, XCF and JPG. Opaque formats include proprietary formats that +- can be read and edited only by proprietary word processors, SGML or +- XML for which the DTD and/or processing tools are not generally +- available, and the machine-generated HTML, PostScript or PDF +- produced by some word processors for output purposes only. +- +- The "Title Page" means, for a printed book, the title page itself, +- plus such following pages as are needed to hold, legibly, the +- material this License requires to appear in the title page. For +- works in formats which do not have any title page as such, "Title +- Page" means the text near the most prominent appearance of the +- work's title, preceding the beginning of the body of the text. +- +- The "publisher" means any person or entity that distributes copies +- of the Document to the public. +- +- A section "Entitled XYZ" means a named subunit of the Document +- whose title either is precisely XYZ or contains XYZ in parentheses +- following text that translates XYZ in another language. (Here XYZ +- stands for a specific section name mentioned below, such as +- "Acknowledgements", "Dedications", "Endorsements", or "History".) +- To "Preserve the Title" of such a section when you modify the +- Document means that it remains a section "Entitled XYZ" according +- to this definition. +- +- The Document may include Warranty Disclaimers next to the notice +- which states that this License applies to the Document. These +- Warranty Disclaimers are considered to be included by reference in +- this License, but only as regards disclaiming warranties: any other +- implication that these Warranty Disclaimers may have is void and +- has no effect on the meaning of this License. +- +- 2. VERBATIM COPYING +- +- You may copy and distribute the Document in any medium, either +- commercially or noncommercially, provided that this License, the +- copyright notices, and the license notice saying this License +- applies to the Document are reproduced in all copies, and that you +- add no other conditions whatsoever to those of this License. You +- may not use technical measures to obstruct or control the reading +- or further copying of the copies you make or distribute. However, +- you may accept compensation in exchange for copies. If you +- distribute a large enough number of copies you must also follow +- the conditions in section 3. +- +- You may also lend copies, under the same conditions stated above, +- and you may publicly display copies. +- +- 3. COPYING IN QUANTITY +- +- If you publish printed copies (or copies in media that commonly +- have printed covers) of the Document, numbering more than 100, and +- the Document's license notice requires Cover Texts, you must +- enclose the copies in covers that carry, clearly and legibly, all +- these Cover Texts: Front-Cover Texts on the front cover, and +- Back-Cover Texts on the back cover. Both covers must also clearly +- and legibly identify you as the publisher of these copies. The +- front cover must present the full title with all words of the +- title equally prominent and visible. You may add other material +- on the covers in addition. Copying with changes limited to the +- covers, as long as they preserve the title of the Document and +- satisfy these conditions, can be treated as verbatim copying in +- other respects. +- +- If the required texts for either cover are too voluminous to fit +- legibly, you should put the first ones listed (as many as fit +- reasonably) on the actual cover, and continue the rest onto +- adjacent pages. +- +- If you publish or distribute Opaque copies of the Document +- numbering more than 100, you must either include a +- machine-readable Transparent copy along with each Opaque copy, or +- state in or with each Opaque copy a computer-network location from +- which the general network-using public has access to download +- using public-standard network protocols a complete Transparent +- copy of the Document, free of added material. If you use the +- latter option, you must take reasonably prudent steps, when you +- begin distribution of Opaque copies in quantity, to ensure that +- this Transparent copy will remain thus accessible at the stated +- location until at least one year after the last time you +- distribute an Opaque copy (directly or through your agents or +- retailers) of that edition to the public. +- +- It is requested, but not required, that you contact the authors of +- the Document well before redistributing any large number of +- copies, to give them a chance to provide you with an updated +- version of the Document. +- +- 4. MODIFICATIONS +- +- You may copy and distribute a Modified Version of the Document +- under the conditions of sections 2 and 3 above, provided that you +- release the Modified Version under precisely this License, with +- the Modified Version filling the role of the Document, thus +- licensing distribution and modification of the Modified Version to +- whoever possesses a copy of it. In addition, you must do these +- things in the Modified Version: +- +- A. Use in the Title Page (and on the covers, if any) a title +- distinct from that of the Document, and from those of +- previous versions (which should, if there were any, be listed +- in the History section of the Document). You may use the +- same title as a previous version if the original publisher of +- that version gives permission. +- +- B. List on the Title Page, as authors, one or more persons or +- entities responsible for authorship of the modifications in +- the Modified Version, together with at least five of the +- principal authors of the Document (all of its principal +- authors, if it has fewer than five), unless they release you +- from this requirement. +- +- C. State on the Title page the name of the publisher of the +- Modified Version, as the publisher. +- +- D. Preserve all the copyright notices of the Document. +- +- E. Add an appropriate copyright notice for your modifications +- adjacent to the other copyright notices. +- +- F. Include, immediately after the copyright notices, a license +- notice giving the public permission to use the Modified +- Version under the terms of this License, in the form shown in +- the Addendum below. +- +- G. Preserve in that license notice the full lists of Invariant +- Sections and required Cover Texts given in the Document's +- license notice. +- +- H. Include an unaltered copy of this License. +- +- I. Preserve the section Entitled "History", Preserve its Title, +- and add to it an item stating at least the title, year, new +- authors, and publisher of the Modified Version as given on +- the Title Page. If there is no section Entitled "History" in +- the Document, create one stating the title, year, authors, +- and publisher of the Document as given on its Title Page, +- then add an item describing the Modified Version as stated in +- the previous sentence. +- +- J. Preserve the network location, if any, given in the Document +- for public access to a Transparent copy of the Document, and +- likewise the network locations given in the Document for +- previous versions it was based on. These may be placed in +- the "History" section. You may omit a network location for a +- work that was published at least four years before the +- Document itself, or if the original publisher of the version +- it refers to gives permission. +- +- K. For any section Entitled "Acknowledgements" or "Dedications", +- Preserve the Title of the section, and preserve in the +- section all the substance and tone of each of the contributor +- acknowledgements and/or dedications given therein. +- +- L. Preserve all the Invariant Sections of the Document, +- unaltered in their text and in their titles. Section numbers +- or the equivalent are not considered part of the section +- titles. +- +- M. Delete any section Entitled "Endorsements". Such a section +- may not be included in the Modified Version. +- +- N. Do not retitle any existing section to be Entitled +- "Endorsements" or to conflict in title with any Invariant +- Section. +- +- O. Preserve any Warranty Disclaimers. +- +- If the Modified Version includes new front-matter sections or +- appendices that qualify as Secondary Sections and contain no +- material copied from the Document, you may at your option +- designate some or all of these sections as invariant. To do this, +- add their titles to the list of Invariant Sections in the Modified +- Version's license notice. These titles must be distinct from any +- other section titles. +- +- You may add a section Entitled "Endorsements", provided it contains +- nothing but endorsements of your Modified Version by various +- parties--for example, statements of peer review or that the text +- has been approved by an organization as the authoritative +- definition of a standard. +- +- You may add a passage of up to five words as a Front-Cover Text, +- and a passage of up to 25 words as a Back-Cover Text, to the end +- of the list of Cover Texts in the Modified Version. Only one +- passage of Front-Cover Text and one of Back-Cover Text may be +- added by (or through arrangements made by) any one entity. If the +- Document already includes a cover text for the same cover, +- previously added by you or by arrangement made by the same entity +- you are acting on behalf of, you may not add another; but you may +- replace the old one, on explicit permission from the previous +- publisher that added the old one. +- +- The author(s) and publisher(s) of the Document do not by this +- License give permission to use their names for publicity for or to +- assert or imply endorsement of any Modified Version. +- +- 5. COMBINING DOCUMENTS +- +- You may combine the Document with other documents released under +- this License, under the terms defined in section 4 above for +- modified versions, provided that you include in the combination +- all of the Invariant Sections of all of the original documents, +- unmodified, and list them all as Invariant Sections of your +- combined work in its license notice, and that you preserve all +- their Warranty Disclaimers. +- +- The combined work need only contain one copy of this License, and +- multiple identical Invariant Sections may be replaced with a single +- copy. If there are multiple Invariant Sections with the same name +- but different contents, make the title of each such section unique +- by adding at the end of it, in parentheses, the name of the +- original author or publisher of that section if known, or else a +- unique number. Make the same adjustment to the section titles in +- the list of Invariant Sections in the license notice of the +- combined work. +- +- In the combination, you must combine any sections Entitled +- "History" in the various original documents, forming one section +- Entitled "History"; likewise combine any sections Entitled +- "Acknowledgements", and any sections Entitled "Dedications". You +- must delete all sections Entitled "Endorsements." +- +- 6. COLLECTIONS OF DOCUMENTS +- +- You may make a collection consisting of the Document and other +- documents released under this License, and replace the individual +- copies of this License in the various documents with a single copy +- that is included in the collection, provided that you follow the +- rules of this License for verbatim copying of each of the +- documents in all other respects. +- +- You may extract a single document from such a collection, and +- distribute it individually under this License, provided you insert +- a copy of this License into the extracted document, and follow +- this License in all other respects regarding verbatim copying of +- that document. +- +- 7. AGGREGATION WITH INDEPENDENT WORKS +- +- A compilation of the Document or its derivatives with other +- separate and independent documents or works, in or on a volume of +- a storage or distribution medium, is called an "aggregate" if the +- copyright resulting from the compilation is not used to limit the +- legal rights of the compilation's users beyond what the individual +- works permit. When the Document is included in an aggregate, this +- License does not apply to the other works in the aggregate which +- are not themselves derivative works of the Document. +- +- If the Cover Text requirement of section 3 is applicable to these +- copies of the Document, then if the Document is less than one half +- of the entire aggregate, the Document's Cover Texts may be placed +- on covers that bracket the Document within the aggregate, or the +- electronic equivalent of covers if the Document is in electronic +- form. Otherwise they must appear on printed covers that bracket +- the whole aggregate. +- +- 8. TRANSLATION +- +- Translation is considered a kind of modification, so you may +- distribute translations of the Document under the terms of section +- 4. Replacing Invariant Sections with translations requires special +- permission from their copyright holders, but you may include +- translations of some or all Invariant Sections in addition to the +- original versions of these Invariant Sections. You may include a +- translation of this License, and all the license notices in the +- Document, and any Warranty Disclaimers, provided that you also +- include the original English version of this License and the +- original versions of those notices and disclaimers. In case of a +- disagreement between the translation and the original version of +- this License or a notice or disclaimer, the original version will +- prevail. +- +- If a section in the Document is Entitled "Acknowledgements", +- "Dedications", or "History", the requirement (section 4) to +- Preserve its Title (section 1) will typically require changing the +- actual title. +- +- 9. TERMINATION +- +- You may not copy, modify, sublicense, or distribute the Document +- except as expressly provided under this License. Any attempt +- otherwise to copy, modify, sublicense, or distribute it is void, +- and will automatically terminate your rights under this License. +- +- However, if you cease all violation of this License, then your +- license from a particular copyright holder is reinstated (a) +- provisionally, unless and until the copyright holder explicitly +- and finally terminates your license, and (b) permanently, if the +- copyright holder fails to notify you of the violation by some +- reasonable means prior to 60 days after the cessation. +- +- Moreover, your license from a particular copyright holder is +- reinstated permanently if the copyright holder notifies you of the +- violation by some reasonable means, this is the first time you have +- received notice of violation of this License (for any work) from +- that copyright holder, and you cure the violation prior to 30 days +- after your receipt of the notice. +- +- Termination of your rights under this section does not terminate +- the licenses of parties who have received copies or rights from +- you under this License. If your rights have been terminated and +- not permanently reinstated, receipt of a copy of some or all of +- the same material does not give you any rights to use it. +- +- 10. FUTURE REVISIONS OF THIS LICENSE +- +- The Free Software Foundation may publish new, revised versions of +- the GNU Free Documentation License from time to time. Such new +- versions will be similar in spirit to the present version, but may +- differ in detail to address new problems or concerns. See +- `http://www.gnu.org/copyleft/'. +- +- Each version of the License is given a distinguishing version +- number. If the Document specifies that a particular numbered +- version of this License "or any later version" applies to it, you +- have the option of following the terms and conditions either of +- that specified version or of any later version that has been +- published (not as a draft) by the Free Software Foundation. If +- the Document does not specify a version number of this License, +- you may choose any version ever published (not as a draft) by the +- Free Software Foundation. If the Document specifies that a proxy +- can decide which future versions of this License can be used, that +- proxy's public statement of acceptance of a version permanently +- authorizes you to choose that version for the Document. +- +- 11. RELICENSING +- +- "Massive Multiauthor Collaboration Site" (or "MMC Site") means any +- World Wide Web server that publishes copyrightable works and also +- provides prominent facilities for anybody to edit those works. A +- public wiki that anybody can edit is an example of such a server. +- A "Massive Multiauthor Collaboration" (or "MMC") contained in the +- site means any set of copyrightable works thus published on the MMC +- site. +- +- "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +- license published by Creative Commons Corporation, a not-for-profit +- corporation with a principal place of business in San Francisco, +- California, as well as future copyleft versions of that license +- published by that same organization. +- +- "Incorporate" means to publish or republish a Document, in whole or +- in part, as part of another Document. +- +- An MMC is "eligible for relicensing" if it is licensed under this +- License, and if all works that were first published under this +- License somewhere other than this MMC, and subsequently +- incorporated in whole or in part into the MMC, (1) had no cover +- texts or invariant sections, and (2) were thus incorporated prior +- to November 1, 2008. +- +- The operator of an MMC Site may republish an MMC contained in the +- site under CC-BY-SA on the same site at any time before August 1, +- 2009, provided the MMC is eligible for relicensing. +- +- +-ADDENDUM: How to use this License for your documents +-==================================================== +- +-To use this License in a document you have written, include a copy of +-the License in the document and put the following copyright and license +-notices just after the title page: +- +- Copyright (C) YEAR YOUR NAME. +- Permission is granted to copy, distribute and/or modify this document +- under the terms of the GNU Free Documentation License, Version 1.3 +- or any later version published by the Free Software Foundation; +- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +- Texts. A copy of the license is included in the section entitled ``GNU +- Free Documentation License''. +- +- If you have Invariant Sections, Front-Cover Texts and Back-Cover +-Texts, replace the "with...Texts." line with this: +- +- with the Invariant Sections being LIST THEIR TITLES, with +- the Front-Cover Texts being LIST, and with the Back-Cover Texts +- being LIST. +- +- If you have Invariant Sections without Cover Texts, or some other +-combination of the three, merge those two alternatives to suit the +-situation. +- +- If your document contains nontrivial examples of program code, we +-recommend releasing these examples in parallel under your choice of +-free software license, such as the GNU General Public License, to +-permit their use in free software. +- +- +-File: bfd.info, Node: BFD Index, Prev: GNU Free Documentation License, Up: Top +- +-BFD Index +-********* +- +-[index] +-* Menu: +- +-* _bfd_final_link_relocate: Relocating the section contents. +- (line 22) +-* _bfd_generic_link_add_archive_symbols: Adding symbols from an archive. +- (line 15) +-* _bfd_generic_link_add_one_symbol: Adding symbols from an object file. +- (line 19) +-* _bfd_generic_make_empty_symbol: symbol handling functions. +- (line 92) +-* _bfd_link_add_symbols in target vector: Adding Symbols to the Hash Table. +- (line 6) +-* _bfd_link_final_link in target vector: Performing the Final Link. +- (line 6) +-* _bfd_link_hash_table_create in target vector: Creating a Linker Hash Table. +- (line 6) +-* _bfd_relocate_contents: Relocating the section contents. +- (line 22) +-* aout_SIZE_machine_type: aout. (line 147) +-* aout_SIZE_mkobject: aout. (line 139) +-* aout_SIZE_new_section_hook: aout. (line 177) +-* aout_SIZE_set_arch_mach: aout. (line 164) +-* aout_SIZE_some_aout_object_p: aout. (line 125) +-* aout_SIZE_swap_exec_header_in: aout. (line 101) +-* aout_SIZE_swap_exec_header_out: aout. (line 113) +-* arelent_chain: typedef arelent. (line 336) +-* BFD: Overview. (line 6) +-* BFD canonical format: Canonical format. (line 11) +-* bfd_alloc: Opening and Closing. +- (line 218) +-* bfd_alloc2: Opening and Closing. +- (line 227) +-* bfd_alt_mach_code: Miscellaneous. (line 308) +-* bfd_arch_bits_per_address: Architectures. (line 584) +-* bfd_arch_bits_per_byte: Architectures. (line 576) +-* bfd_arch_default_fill: Architectures. (line 665) +-* bfd_arch_get_compatible: Architectures. (line 519) +-* bfd_arch_list: Architectures. (line 510) +-* bfd_arch_mach_octets_per_byte: Architectures. (line 653) +-* BFD_ARELOC_BFIN_ADD: howto manager. (line 1120) +-* BFD_ARELOC_BFIN_ADDR: howto manager. (line 1171) +-* BFD_ARELOC_BFIN_AND: howto manager. (line 1141) +-* BFD_ARELOC_BFIN_COMP: howto manager. (line 1162) +-* BFD_ARELOC_BFIN_CONST: howto manager. (line 1117) +-* BFD_ARELOC_BFIN_DIV: howto manager. (line 1129) +-* BFD_ARELOC_BFIN_HWPAGE: howto manager. (line 1168) +-* BFD_ARELOC_BFIN_LAND: howto manager. (line 1150) +-* BFD_ARELOC_BFIN_LEN: howto manager. (line 1156) +-* BFD_ARELOC_BFIN_LOR: howto manager. (line 1153) +-* BFD_ARELOC_BFIN_LSHIFT: howto manager. (line 1135) +-* BFD_ARELOC_BFIN_MOD: howto manager. (line 1132) +-* BFD_ARELOC_BFIN_MULT: howto manager. (line 1126) +-* BFD_ARELOC_BFIN_NEG: howto manager. (line 1159) +-* BFD_ARELOC_BFIN_OR: howto manager. (line 1144) +-* BFD_ARELOC_BFIN_PAGE: howto manager. (line 1165) +-* BFD_ARELOC_BFIN_PUSH: howto manager. (line 1114) +-* BFD_ARELOC_BFIN_RSHIFT: howto manager. (line 1138) +-* BFD_ARELOC_BFIN_SUB: howto manager. (line 1123) +-* BFD_ARELOC_BFIN_XOR: howto manager. (line 1147) +-* bfd_cache_close: File Caching. (line 26) +-* bfd_cache_close_all: File Caching. (line 39) +-* bfd_cache_init: File Caching. (line 18) +-* bfd_calc_gnu_debuglink_crc32: Opening and Closing. +- (line 254) +-* bfd_canonicalize_reloc: Miscellaneous. (line 19) +-* bfd_canonicalize_symtab: symbol handling functions. +- (line 50) +-* bfd_check_format: Formats. (line 21) +-* bfd_check_format_matches: Formats. (line 52) +-* bfd_check_overflow: typedef arelent. (line 348) +-* bfd_close: Opening and Closing. +- (line 143) +-* bfd_close_all_done: Opening and Closing. +- (line 161) +-* bfd_coff_backend_data: coff. (line 305) +-* bfd_copy_private_bfd_data: Miscellaneous. (line 158) +-* bfd_copy_private_header_data: Miscellaneous. (line 140) +-* bfd_copy_private_section_data: section prototypes. (line 278) +-* bfd_copy_private_symbol_data: symbol handling functions. +- (line 140) +-* bfd_core_file_failing_command: Core Files. (line 12) +-* bfd_core_file_failing_signal: Core Files. (line 21) +-* bfd_core_file_pid: Core Files. (line 30) +-* bfd_create: Opening and Closing. +- (line 180) +-* bfd_create_gnu_debuglink_section: Opening and Closing. +- (line 363) +-* bfd_decode_symclass: symbol handling functions. +- (line 111) +-* bfd_default_arch_struct: Architectures. (line 531) +-* bfd_default_compatible: Architectures. (line 593) +-* bfd_default_reloc_type_lookup: howto manager. (line 3268) +-* bfd_default_scan: Architectures. (line 602) +-* bfd_default_set_arch_mach: Architectures. (line 549) +-* bfd_demangle: Miscellaneous. (line 359) +-* bfd_emul_get_commonpagesize: Miscellaneous. (line 339) +-* bfd_emul_get_maxpagesize: Miscellaneous. (line 319) +-* bfd_emul_set_commonpagesize: Miscellaneous. (line 350) +-* bfd_emul_set_maxpagesize: Miscellaneous. (line 330) +-* bfd_errmsg: Error reporting. (line 67) +-* bfd_fdopenr: Opening and Closing. +- (line 51) +-* bfd_fill_in_gnu_debuglink_section: Opening and Closing. +- (line 377) +-* bfd_find_target: bfd_target. (line 473) +-* bfd_find_version_for_sym: Writing the symbol table. +- (line 81) +-* bfd_follow_gnu_debugaltlink: Opening and Closing. +- (line 343) +-* bfd_follow_gnu_debuglink: Opening and Closing. +- (line 322) +-* bfd_fopen: Opening and Closing. +- (line 12) +-* bfd_format_string: Formats. (line 79) +-* bfd_generic_define_common_symbol: Writing the symbol table. +- (line 68) +-* bfd_generic_discard_group: section prototypes. (line 304) +-* bfd_generic_gc_sections: howto manager. (line 3299) +-* bfd_generic_get_relocated_section_contents: howto manager. (line 3329) +-* bfd_generic_is_group_section: section prototypes. (line 296) +-* bfd_generic_lookup_section_flags: howto manager. (line 3309) +-* bfd_generic_merge_sections: howto manager. (line 3319) +-* bfd_generic_relax_section: howto manager. (line 3286) +-* bfd_get_alt_debug_link_info: Opening and Closing. +- (line 279) +-* bfd_get_arch: Architectures. (line 560) +-* bfd_get_arch_info: Architectures. (line 612) +-* bfd_get_arch_size: Miscellaneous. (line 63) +-* bfd_get_assert_handler: Error reporting. (line 150) +-* bfd_get_debug_link_info: Opening and Closing. +- (line 268) +-* bfd_get_error: Error reporting. (line 48) +-* bfd_get_error_handler: Error reporting. (line 118) +-* bfd_get_gp_size: Miscellaneous. (line 104) +-* bfd_get_linker_section: section prototypes. (line 36) +-* bfd_get_mach: Architectures. (line 568) +-* bfd_get_mtime: Miscellaneous. (line 410) +-* bfd_get_next_mapent: Archives. (line 58) +-* bfd_get_next_section_by_name: section prototypes. (line 26) +-* bfd_get_reloc_code_name: howto manager. (line 3277) +-* bfd_get_reloc_size: typedef arelent. (line 327) +-* bfd_get_reloc_upper_bound: Miscellaneous. (line 9) +-* bfd_get_section_by_name: section prototypes. (line 17) +-* bfd_get_section_by_name_if: section prototypes. (line 45) +-* bfd_get_section_contents: section prototypes. (line 251) +-* bfd_get_sign_extend_vma: Miscellaneous. (line 76) +-* bfd_get_size <1>: Miscellaneous. (line 419) +-* bfd_get_size: Internal. (line 25) +-* bfd_get_symtab_upper_bound: symbol handling functions. +- (line 6) +-* bfd_get_target_info: bfd_target. (line 489) +-* bfd_get_unique_section_name: section prototypes. (line 64) +-* bfd_h_put_size: Internal. (line 97) +-* bfd_hash_allocate: Creating and Freeing a Hash Table. +- (line 17) +-* bfd_hash_lookup: Looking Up or Entering a String. +- (line 6) +-* bfd_hash_newfunc: Creating and Freeing a Hash Table. +- (line 12) +-* bfd_hash_set_default_size: Creating and Freeing a Hash Table. +- (line 25) +-* bfd_hash_table_free: Creating and Freeing a Hash Table. +- (line 21) +-* bfd_hash_table_init: Creating and Freeing a Hash Table. +- (line 6) +-* bfd_hash_table_init_n: Creating and Freeing a Hash Table. +- (line 6) +-* bfd_hash_traverse: Traversing a Hash Table. +- (line 6) +-* bfd_hide_sym_by_version: Writing the symbol table. +- (line 93) +-* bfd_init: Initialization. (line 11) +-* bfd_install_relocation: typedef arelent. (line 389) +-* bfd_is_local_label: symbol handling functions. +- (line 17) +-* bfd_is_local_label_name: symbol handling functions. +- (line 26) +-* bfd_is_target_special_symbol: symbol handling functions. +- (line 38) +-* bfd_is_undefined_symclass: symbol handling functions. +- (line 120) +-* bfd_link_split_section: Writing the symbol table. +- (line 44) +-* bfd_log2: Internal. (line 164) +-* bfd_lookup_arch: Architectures. (line 620) +-* bfd_make_debug_symbol: symbol handling functions. +- (line 102) +-* bfd_make_empty_symbol: symbol handling functions. +- (line 78) +-* bfd_make_readable: Opening and Closing. +- (line 204) +-* bfd_make_section: section prototypes. (line 143) +-* bfd_make_section_anyway: section prototypes. (line 114) +-* bfd_make_section_anyway_with_flags: section prototypes. (line 96) +-* bfd_make_section_old_way: section prototypes. (line 76) +-* bfd_make_section_with_flags: section prototypes. (line 130) +-* bfd_make_writable: Opening and Closing. +- (line 190) +-* bfd_malloc_and_get_section: section prototypes. (line 268) +-* bfd_map_over_sections: section prototypes. (line 178) +-* bfd_merge_private_bfd_data: Miscellaneous. (line 174) +-* bfd_mmap: Miscellaneous. (line 448) +-* bfd_octets_per_byte: Architectures. (line 643) +-* bfd_open_file: File Caching. (line 52) +-* bfd_openr: Opening and Closing. +- (line 35) +-* bfd_openr_iovec: Opening and Closing. +- (line 83) +-* bfd_openr_next_archived_file: Archives. (line 84) +-* bfd_openstreamr: Opening and Closing. +- (line 74) +-* bfd_openw: Opening and Closing. +- (line 131) +-* bfd_perform_relocation: typedef arelent. (line 364) +-* bfd_perror: Error reporting. (line 76) +-* bfd_print_symbol_vandf: symbol handling functions. +- (line 70) +-* bfd_printable_arch_mach: Architectures. (line 631) +-* bfd_printable_name: Architectures. (line 491) +-* bfd_put_size: Internal. (line 22) +-* BFD_RELOC_12_PCREL: howto manager. (line 39) +-* BFD_RELOC_14: howto manager. (line 31) +-* BFD_RELOC_16: howto manager. (line 30) +-* BFD_RELOC_16_BASEREL: howto manager. (line 99) +-* BFD_RELOC_16_GOT_PCREL: howto manager. (line 52) +-* BFD_RELOC_16_GOTOFF: howto manager. (line 55) +-* BFD_RELOC_16_PCREL: howto manager. (line 38) +-* BFD_RELOC_16_PCREL_S2: howto manager. (line 111) +-* BFD_RELOC_16_PLT_PCREL: howto manager. (line 63) +-* BFD_RELOC_16_PLTOFF: howto manager. (line 67) +-* BFD_RELOC_16C_ABS20: howto manager. (line 2236) +-* BFD_RELOC_16C_ABS20_C: howto manager. (line 2237) +-* BFD_RELOC_16C_ABS24: howto manager. (line 2238) +-* BFD_RELOC_16C_ABS24_C: howto manager. (line 2239) +-* BFD_RELOC_16C_DISP04: howto manager. (line 2216) +-* BFD_RELOC_16C_DISP04_C: howto manager. (line 2217) +-* BFD_RELOC_16C_DISP08: howto manager. (line 2218) +-* BFD_RELOC_16C_DISP08_C: howto manager. (line 2219) +-* BFD_RELOC_16C_DISP16: howto manager. (line 2220) +-* BFD_RELOC_16C_DISP16_C: howto manager. (line 2221) +-* BFD_RELOC_16C_DISP24: howto manager. (line 2222) +-* BFD_RELOC_16C_DISP24_C: howto manager. (line 2223) +-* BFD_RELOC_16C_DISP24a: howto manager. (line 2224) +-* BFD_RELOC_16C_DISP24a_C: howto manager. (line 2225) +-* BFD_RELOC_16C_IMM04: howto manager. (line 2240) +-* BFD_RELOC_16C_IMM04_C: howto manager. (line 2241) +-* BFD_RELOC_16C_IMM16: howto manager. (line 2242) +-* BFD_RELOC_16C_IMM16_C: howto manager. (line 2243) +-* BFD_RELOC_16C_IMM20: howto manager. (line 2244) +-* BFD_RELOC_16C_IMM20_C: howto manager. (line 2245) +-* BFD_RELOC_16C_IMM24: howto manager. (line 2246) +-* BFD_RELOC_16C_IMM24_C: howto manager. (line 2247) +-* BFD_RELOC_16C_IMM32: howto manager. (line 2248) +-* BFD_RELOC_16C_IMM32_C: howto manager. (line 2249) +-* BFD_RELOC_16C_NUM08: howto manager. (line 2210) +-* BFD_RELOC_16C_NUM08_C: howto manager. (line 2211) +-* BFD_RELOC_16C_NUM16: howto manager. (line 2212) +-* BFD_RELOC_16C_NUM16_C: howto manager. (line 2213) +-* BFD_RELOC_16C_NUM32: howto manager. (line 2214) +-* BFD_RELOC_16C_NUM32_C: howto manager. (line 2215) +-* BFD_RELOC_16C_REG04: howto manager. (line 2226) +-* BFD_RELOC_16C_REG04_C: howto manager. (line 2227) +-* BFD_RELOC_16C_REG04a: howto manager. (line 2228) +-* BFD_RELOC_16C_REG04a_C: howto manager. (line 2229) +-* BFD_RELOC_16C_REG14: howto manager. (line 2230) +-* BFD_RELOC_16C_REG14_C: howto manager. (line 2231) +-* BFD_RELOC_16C_REG16: howto manager. (line 2232) +-* BFD_RELOC_16C_REG16_C: howto manager. (line 2233) +-* BFD_RELOC_16C_REG20: howto manager. (line 2234) +-* BFD_RELOC_16C_REG20_C: howto manager. (line 2235) +-* BFD_RELOC_23_PCREL_S2: howto manager. (line 112) +-* BFD_RELOC_24: howto manager. (line 29) +-* BFD_RELOC_24_PCREL: howto manager. (line 37) +-* BFD_RELOC_24_PLT_PCREL: howto manager. (line 62) +-* BFD_RELOC_26: howto manager. (line 28) +-* BFD_RELOC_32: howto manager. (line 27) +-* BFD_RELOC_32_BASEREL: howto manager. (line 98) +-* BFD_RELOC_32_GOT_PCREL: howto manager. (line 51) +-* BFD_RELOC_32_GOTOFF: howto manager. (line 54) +-* BFD_RELOC_32_PCREL: howto manager. (line 36) +-* BFD_RELOC_32_PCREL_S2: howto manager. (line 110) +-* BFD_RELOC_32_PLT_PCREL: howto manager. (line 61) +-* BFD_RELOC_32_PLTOFF: howto manager. (line 66) +-* BFD_RELOC_32_SECREL: howto manager. (line 48) +-* BFD_RELOC_386_COPY: howto manager. (line 577) +-* BFD_RELOC_386_GLOB_DAT: howto manager. (line 578) +-* BFD_RELOC_386_GOT32: howto manager. (line 575) +-* BFD_RELOC_386_GOTOFF: howto manager. (line 581) +-* BFD_RELOC_386_GOTPC: howto manager. (line 582) +-* BFD_RELOC_386_IRELATIVE: howto manager. (line 598) +-* BFD_RELOC_386_JUMP_SLOT: howto manager. (line 579) +-* BFD_RELOC_386_PLT32: howto manager. (line 576) +-* BFD_RELOC_386_RELATIVE: howto manager. (line 580) +-* BFD_RELOC_386_TLS_DESC: howto manager. (line 597) +-* BFD_RELOC_386_TLS_DESC_CALL: howto manager. (line 596) +-* BFD_RELOC_386_TLS_DTPMOD32: howto manager. (line 592) +-* BFD_RELOC_386_TLS_DTPOFF32: howto manager. (line 593) +-* BFD_RELOC_386_TLS_GD: howto manager. (line 587) +-* BFD_RELOC_386_TLS_GOTDESC: howto manager. (line 595) +-* BFD_RELOC_386_TLS_GOTIE: howto manager. (line 585) +-* BFD_RELOC_386_TLS_IE: howto manager. (line 584) +-* BFD_RELOC_386_TLS_IE_32: howto manager. (line 590) +-* BFD_RELOC_386_TLS_LDM: howto manager. (line 588) +-* BFD_RELOC_386_TLS_LDO_32: howto manager. (line 589) +-* BFD_RELOC_386_TLS_LE: howto manager. (line 586) +-* BFD_RELOC_386_TLS_LE_32: howto manager. (line 591) +-* BFD_RELOC_386_TLS_TPOFF: howto manager. (line 583) +-* BFD_RELOC_386_TLS_TPOFF32: howto manager. (line 594) +-* BFD_RELOC_390_12: howto manager. (line 1819) +-* BFD_RELOC_390_20: howto manager. (line 1931) +-* BFD_RELOC_390_COPY: howto manager. (line 1828) +-* BFD_RELOC_390_GLOB_DAT: howto manager. (line 1831) +-* BFD_RELOC_390_GOT12: howto manager. (line 1822) +-* BFD_RELOC_390_GOT16: howto manager. (line 1843) +-* BFD_RELOC_390_GOT20: howto manager. (line 1932) +-* BFD_RELOC_390_GOT64: howto manager. (line 1873) +-* BFD_RELOC_390_GOTENT: howto manager. (line 1879) +-* BFD_RELOC_390_GOTOFF64: howto manager. (line 1882) +-* BFD_RELOC_390_GOTPC: howto manager. (line 1840) +-* BFD_RELOC_390_GOTPCDBL: howto manager. (line 1870) +-* BFD_RELOC_390_GOTPLT12: howto manager. (line 1885) +-* BFD_RELOC_390_GOTPLT16: howto manager. (line 1888) +-* BFD_RELOC_390_GOTPLT20: howto manager. (line 1933) +-* BFD_RELOC_390_GOTPLT32: howto manager. (line 1891) +-* BFD_RELOC_390_GOTPLT64: howto manager. (line 1894) +-* BFD_RELOC_390_GOTPLTENT: howto manager. (line 1897) +-* BFD_RELOC_390_IRELATIVE: howto manager. (line 1937) +-* BFD_RELOC_390_JMP_SLOT: howto manager. (line 1834) +-* BFD_RELOC_390_PC12DBL: howto manager. (line 1846) +-* BFD_RELOC_390_PC16DBL: howto manager. (line 1852) +-* BFD_RELOC_390_PC24DBL: howto manager. (line 1858) +-* BFD_RELOC_390_PC32DBL: howto manager. (line 1864) +-* BFD_RELOC_390_PLT12DBL: howto manager. (line 1849) +-* BFD_RELOC_390_PLT16DBL: howto manager. (line 1855) +-* BFD_RELOC_390_PLT24DBL: howto manager. (line 1861) +-* BFD_RELOC_390_PLT32: howto manager. (line 1825) +-* BFD_RELOC_390_PLT32DBL: howto manager. (line 1867) +-* BFD_RELOC_390_PLT64: howto manager. (line 1876) +-* BFD_RELOC_390_PLTOFF16: howto manager. (line 1900) +-* BFD_RELOC_390_PLTOFF32: howto manager. (line 1903) +-* BFD_RELOC_390_PLTOFF64: howto manager. (line 1906) +-* BFD_RELOC_390_RELATIVE: howto manager. (line 1837) +-* BFD_RELOC_390_TLS_DTPMOD: howto manager. (line 1926) +-* BFD_RELOC_390_TLS_DTPOFF: howto manager. (line 1927) +-* BFD_RELOC_390_TLS_GD32: howto manager. (line 1912) +-* BFD_RELOC_390_TLS_GD64: howto manager. (line 1913) +-* BFD_RELOC_390_TLS_GDCALL: howto manager. (line 1910) +-* BFD_RELOC_390_TLS_GOTIE12: howto manager. (line 1914) +-* BFD_RELOC_390_TLS_GOTIE20: howto manager. (line 1934) +-* BFD_RELOC_390_TLS_GOTIE32: howto manager. (line 1915) +-* BFD_RELOC_390_TLS_GOTIE64: howto manager. (line 1916) +-* BFD_RELOC_390_TLS_IE32: howto manager. (line 1919) +-* BFD_RELOC_390_TLS_IE64: howto manager. (line 1920) +-* BFD_RELOC_390_TLS_IEENT: howto manager. (line 1921) +-* BFD_RELOC_390_TLS_LDCALL: howto manager. (line 1911) +-* BFD_RELOC_390_TLS_LDM32: howto manager. (line 1917) +-* BFD_RELOC_390_TLS_LDM64: howto manager. (line 1918) +-* BFD_RELOC_390_TLS_LDO32: howto manager. (line 1924) +-* BFD_RELOC_390_TLS_LDO64: howto manager. (line 1925) +-* BFD_RELOC_390_TLS_LE32: howto manager. (line 1922) +-* BFD_RELOC_390_TLS_LE64: howto manager. (line 1923) +-* BFD_RELOC_390_TLS_LOAD: howto manager. (line 1909) +-* BFD_RELOC_390_TLS_TPOFF: howto manager. (line 1928) +-* BFD_RELOC_64: howto manager. (line 26) +-* BFD_RELOC_64_PCREL: howto manager. (line 35) +-* BFD_RELOC_64_PLT_PCREL: howto manager. (line 60) +-* BFD_RELOC_64_PLTOFF: howto manager. (line 65) +-* BFD_RELOC_68K_GLOB_DAT: howto manager. (line 78) +-* BFD_RELOC_68K_JMP_SLOT: howto manager. (line 79) +-* BFD_RELOC_68K_RELATIVE: howto manager. (line 80) +-* BFD_RELOC_68K_TLS_GD16: howto manager. (line 82) +-* BFD_RELOC_68K_TLS_GD32: howto manager. (line 81) +-* BFD_RELOC_68K_TLS_GD8: howto manager. (line 83) +-* BFD_RELOC_68K_TLS_IE16: howto manager. (line 91) +-* BFD_RELOC_68K_TLS_IE32: howto manager. (line 90) +-* BFD_RELOC_68K_TLS_IE8: howto manager. (line 92) +-* BFD_RELOC_68K_TLS_LDM16: howto manager. (line 85) +-* BFD_RELOC_68K_TLS_LDM32: howto manager. (line 84) +-* BFD_RELOC_68K_TLS_LDM8: howto manager. (line 86) +-* BFD_RELOC_68K_TLS_LDO16: howto manager. (line 88) +-* BFD_RELOC_68K_TLS_LDO32: howto manager. (line 87) +-* BFD_RELOC_68K_TLS_LDO8: howto manager. (line 89) +-* BFD_RELOC_68K_TLS_LE16: howto manager. (line 94) +-* BFD_RELOC_68K_TLS_LE32: howto manager. (line 93) +-* BFD_RELOC_68K_TLS_LE8: howto manager. (line 95) +-* BFD_RELOC_8: howto manager. (line 32) +-* BFD_RELOC_860_COPY: howto manager. (line 2364) +-* BFD_RELOC_860_GLOB_DAT: howto manager. (line 2365) +-* BFD_RELOC_860_HAGOT: howto manager. (line 2390) +-* BFD_RELOC_860_HAGOTOFF: howto manager. (line 2391) +-* BFD_RELOC_860_HAPC: howto manager. (line 2392) +-* BFD_RELOC_860_HIGH: howto manager. (line 2393) +-* BFD_RELOC_860_HIGHADJ: howto manager. (line 2389) +-* BFD_RELOC_860_HIGOT: howto manager. (line 2394) +-* BFD_RELOC_860_HIGOTOFF: howto manager. (line 2395) +-* BFD_RELOC_860_JUMP_SLOT: howto manager. (line 2366) +-* BFD_RELOC_860_LOGOT0: howto manager. (line 2378) +-* BFD_RELOC_860_LOGOT1: howto manager. (line 2380) +-* BFD_RELOC_860_LOGOTOFF0: howto manager. (line 2382) +-* BFD_RELOC_860_LOGOTOFF1: howto manager. (line 2384) +-* BFD_RELOC_860_LOGOTOFF2: howto manager. (line 2386) +-* BFD_RELOC_860_LOGOTOFF3: howto manager. (line 2387) +-* BFD_RELOC_860_LOPC: howto manager. (line 2388) +-* BFD_RELOC_860_LOW0: howto manager. (line 2371) +-* BFD_RELOC_860_LOW1: howto manager. (line 2373) +-* BFD_RELOC_860_LOW2: howto manager. (line 2375) +-* BFD_RELOC_860_LOW3: howto manager. (line 2377) +-* BFD_RELOC_860_PC16: howto manager. (line 2370) +-* BFD_RELOC_860_PC26: howto manager. (line 2368) +-* BFD_RELOC_860_PLT26: howto manager. (line 2369) +-* BFD_RELOC_860_RELATIVE: howto manager. (line 2367) +-* BFD_RELOC_860_SPGOT0: howto manager. (line 2379) +-* BFD_RELOC_860_SPGOT1: howto manager. (line 2381) +-* BFD_RELOC_860_SPGOTOFF0: howto manager. (line 2383) +-* BFD_RELOC_860_SPGOTOFF1: howto manager. (line 2385) +-* BFD_RELOC_860_SPLIT0: howto manager. (line 2372) +-* BFD_RELOC_860_SPLIT1: howto manager. (line 2374) +-* BFD_RELOC_860_SPLIT2: howto manager. (line 2376) +-* BFD_RELOC_8_BASEREL: howto manager. (line 103) +-* BFD_RELOC_8_FFnn: howto manager. (line 107) +-* BFD_RELOC_8_GOT_PCREL: howto manager. (line 53) +-* BFD_RELOC_8_GOTOFF: howto manager. (line 59) +-* BFD_RELOC_8_PCREL: howto manager. (line 40) +-* BFD_RELOC_8_PLT_PCREL: howto manager. (line 64) +-* BFD_RELOC_8_PLTOFF: howto manager. (line 71) +-* BFD_RELOC_AARCH64_16: howto manager. (line 2755) +-* BFD_RELOC_AARCH64_16_PCREL: howto manager. (line 2762) +-* BFD_RELOC_AARCH64_32: howto manager. (line 2754) +-* BFD_RELOC_AARCH64_32_PCREL: howto manager. (line 2761) +-* BFD_RELOC_AARCH64_64: howto manager. (line 2753) +-* BFD_RELOC_AARCH64_64_PCREL: howto manager. (line 2760) +-* BFD_RELOC_AARCH64_ADD_LO12: howto manager. (line 2827) +-* BFD_RELOC_AARCH64_ADR_GOT_PAGE: howto manager. (line 2884) +-* BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL: howto manager. (line 2822) +-* BFD_RELOC_AARCH64_ADR_HI21_PCREL: howto manager. (line 2818) +-* BFD_RELOC_AARCH64_ADR_LO21_PCREL: howto manager. (line 2814) +-* BFD_RELOC_AARCH64_BRANCH19: howto manager. (line 2842) +-* BFD_RELOC_AARCH64_CALL26: howto manager. (line 2852) +-* BFD_RELOC_AARCH64_COPY: howto manager. (line 2985) +-* BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP: howto manager. (line 3019) +-* BFD_RELOC_AARCH64_GLOB_DAT: howto manager. (line 2988) +-* BFD_RELOC_AARCH64_GOT_LD_PREL19: howto manager. (line 2877) +-* BFD_RELOC_AARCH64_IRELATIVE: howto manager. (line 3009) +-* BFD_RELOC_AARCH64_JUMP26: howto manager. (line 2847) +-* BFD_RELOC_AARCH64_JUMP_SLOT: howto manager. (line 2991) +-* BFD_RELOC_AARCH64_LD32_GOT_LO12_NC: howto manager. (line 2894) +-* BFD_RELOC_AARCH64_LD64_GOT_LO12_NC: howto manager. (line 2889) +-* BFD_RELOC_AARCH64_LD_GOT_LO12_NC: howto manager. (line 3028) +-* BFD_RELOC_AARCH64_LD_LO19_PCREL: howto manager. (line 2809) +-* BFD_RELOC_AARCH64_LDST128_LO12: howto manager. (line 2872) +-* BFD_RELOC_AARCH64_LDST16_LO12: howto manager. (line 2857) +-* BFD_RELOC_AARCH64_LDST32_LO12: howto manager. (line 2862) +-* BFD_RELOC_AARCH64_LDST64_LO12: howto manager. (line 2867) +-* BFD_RELOC_AARCH64_LDST8_LO12: howto manager. (line 2832) +-* BFD_RELOC_AARCH64_LDST_LO12: howto manager. (line 3023) +-* BFD_RELOC_AARCH64_MOVW_G0: howto manager. (line 2766) +-* BFD_RELOC_AARCH64_MOVW_G0_NC: howto manager. (line 2770) +-* BFD_RELOC_AARCH64_MOVW_G0_S: howto manager. (line 2794) +-* BFD_RELOC_AARCH64_MOVW_G1: howto manager. (line 2774) +-* BFD_RELOC_AARCH64_MOVW_G1_NC: howto manager. (line 2778) +-* BFD_RELOC_AARCH64_MOVW_G1_S: howto manager. (line 2799) +-* BFD_RELOC_AARCH64_MOVW_G2: howto manager. (line 2782) +-* BFD_RELOC_AARCH64_MOVW_G2_NC: howto manager. (line 2786) +-* BFD_RELOC_AARCH64_MOVW_G2_S: howto manager. (line 2804) +-* BFD_RELOC_AARCH64_MOVW_G3: howto manager. (line 2790) +-* BFD_RELOC_AARCH64_NONE: howto manager. (line 2750) +-* BFD_RELOC_AARCH64_RELATIVE: howto manager. (line 2994) +-* BFD_RELOC_AARCH64_RELOC_END: howto manager. (line 3012) +-* BFD_RELOC_AARCH64_RELOC_START: howto manager. (line 2744) +-* BFD_RELOC_AARCH64_TLS_DTPMOD: howto manager. (line 2997) +-* BFD_RELOC_AARCH64_TLS_DTPREL: howto manager. (line 3000) +-* BFD_RELOC_AARCH64_TLS_TPREL: howto manager. (line 3003) +-* BFD_RELOC_AARCH64_TLSDESC: howto manager. (line 3006) +-* BFD_RELOC_AARCH64_TLSDESC_ADD: howto manager. (line 2979) +-* BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC: howto manager. (line 2967) +-* BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21: howto manager. (line 2958) +-* BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21: howto manager. (line 2955) +-* BFD_RELOC_AARCH64_TLSDESC_CALL: howto manager. (line 2982) +-* BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC: howto manager. (line 2964) +-* BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC: howto manager. (line 2961) +-* BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC: howto manager. (line 3036) +-* BFD_RELOC_AARCH64_TLSDESC_LD_PREL19: howto manager. (line 2952) +-* BFD_RELOC_AARCH64_TLSDESC_LDR: howto manager. (line 2976) +-* BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC: howto manager. (line 2973) +-* BFD_RELOC_AARCH64_TLSDESC_OFF_G1: howto manager. (line 2970) +-* BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC: howto manager. (line 2905) +-* BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21: howto manager. (line 2899) +-* BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: howto manager. +- (line 2916) +-* BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC: howto manager. +- (line 2922) +-* BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: howto manager. +- (line 2919) +-* BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC: howto manager. +- (line 3032) +-* BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19: howto manager. (line 2925) +-* BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC: howto manager. +- (line 2913) +-* BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1: howto manager. (line 2910) +-* BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12: howto manager. (line 2943) +-* BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12: howto manager. (line 2946) +-* BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC: howto manager. (line 2949) +-* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0: howto manager. (line 2937) +-* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC: howto manager. (line 2940) +-* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1: howto manager. (line 2931) +-* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC: howto manager. (line 2934) +-* BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2: howto manager. (line 2928) +-* BFD_RELOC_AARCH64_TSTBR14: howto manager. (line 2837) +-* BFD_RELOC_ALPHA_BOH: howto manager. (line 323) +-* BFD_RELOC_ALPHA_BRSGP: howto manager. (line 306) +-* BFD_RELOC_ALPHA_BSR: howto manager. (line 315) +-* BFD_RELOC_ALPHA_CODEADDR: howto manager. (line 297) +-* BFD_RELOC_ALPHA_DTPMOD64: howto manager. (line 329) +-* BFD_RELOC_ALPHA_DTPREL16: howto manager. (line 334) +-* BFD_RELOC_ALPHA_DTPREL64: howto manager. (line 331) +-* BFD_RELOC_ALPHA_DTPREL_HI16: howto manager. (line 332) +-* BFD_RELOC_ALPHA_DTPREL_LO16: howto manager. (line 333) +-* BFD_RELOC_ALPHA_ELF_LITERAL: howto manager. (line 262) +-* BFD_RELOC_ALPHA_GOTDTPREL16: howto manager. (line 330) +-* BFD_RELOC_ALPHA_GOTTPREL16: howto manager. (line 335) +-* BFD_RELOC_ALPHA_GPDISP: howto manager. (line 256) +-* BFD_RELOC_ALPHA_GPDISP_HI16: howto manager. (line 242) +-* BFD_RELOC_ALPHA_GPDISP_LO16: howto manager. (line 250) +-* BFD_RELOC_ALPHA_GPREL_HI16: howto manager. (line 301) +-* BFD_RELOC_ALPHA_GPREL_LO16: howto manager. (line 302) +-* BFD_RELOC_ALPHA_HINT: howto manager. (line 288) +-* BFD_RELOC_ALPHA_LDA: howto manager. (line 319) +-* BFD_RELOC_ALPHA_LINKAGE: howto manager. (line 293) +-* BFD_RELOC_ALPHA_LITERAL: howto manager. (line 261) +-* BFD_RELOC_ALPHA_LITUSE: howto manager. (line 263) +-* BFD_RELOC_ALPHA_NOP: howto manager. (line 311) +-* BFD_RELOC_ALPHA_TLSGD: howto manager. (line 327) +-* BFD_RELOC_ALPHA_TLSLDM: howto manager. (line 328) +-* BFD_RELOC_ALPHA_TPREL16: howto manager. (line 339) +-* BFD_RELOC_ALPHA_TPREL64: howto manager. (line 336) +-* BFD_RELOC_ALPHA_TPREL_HI16: howto manager. (line 337) +-* BFD_RELOC_ALPHA_TPREL_LO16: howto manager. (line 338) +-* BFD_RELOC_ARC_B22_PCREL: howto manager. (line 1049) +-* BFD_RELOC_ARC_B26: howto manager. (line 1054) +-* BFD_RELOC_ARM_ADR_IMM: howto manager. (line 935) +-* BFD_RELOC_ARM_ADRL_IMMEDIATE: howto manager. (line 921) +-* BFD_RELOC_ARM_ALU_PC_G0: howto manager. (line 885) +-* BFD_RELOC_ARM_ALU_PC_G0_NC: howto manager. (line 884) +-* BFD_RELOC_ARM_ALU_PC_G1: howto manager. (line 887) +-* BFD_RELOC_ARM_ALU_PC_G1_NC: howto manager. (line 886) +-* BFD_RELOC_ARM_ALU_PC_G2: howto manager. (line 888) +-* BFD_RELOC_ARM_ALU_SB_G0: howto manager. (line 899) +-* BFD_RELOC_ARM_ALU_SB_G0_NC: howto manager. (line 898) +-* BFD_RELOC_ARM_ALU_SB_G1: howto manager. (line 901) +-* BFD_RELOC_ARM_ALU_SB_G1_NC: howto manager. (line 900) +-* BFD_RELOC_ARM_ALU_SB_G2: howto manager. (line 902) +-* BFD_RELOC_ARM_CP_OFF_IMM: howto manager. (line 931) +-* BFD_RELOC_ARM_CP_OFF_IMM_S2: howto manager. (line 932) +-* BFD_RELOC_ARM_GLOB_DAT: howto manager. (line 859) +-* BFD_RELOC_ARM_GOT32: howto manager. (line 860) +-* BFD_RELOC_ARM_GOT_PREL: howto manager. (line 865) +-* BFD_RELOC_ARM_GOTOFF: howto manager. (line 863) +-* BFD_RELOC_ARM_GOTPC: howto manager. (line 864) +-* BFD_RELOC_ARM_HVC: howto manager. (line 928) +-* BFD_RELOC_ARM_HWLITERAL: howto manager. (line 942) +-* BFD_RELOC_ARM_IMMEDIATE: howto manager. (line 920) +-* BFD_RELOC_ARM_IN_POOL: howto manager. (line 938) +-* BFD_RELOC_ARM_IRELATIVE: howto manager. (line 917) +-* BFD_RELOC_ARM_JUMP_SLOT: howto manager. (line 858) +-* BFD_RELOC_ARM_LDC_PC_G0: howto manager. (line 895) +-* BFD_RELOC_ARM_LDC_PC_G1: howto manager. (line 896) +-* BFD_RELOC_ARM_LDC_PC_G2: howto manager. (line 897) +-* BFD_RELOC_ARM_LDC_SB_G0: howto manager. (line 909) +-* BFD_RELOC_ARM_LDC_SB_G1: howto manager. (line 910) +-* BFD_RELOC_ARM_LDC_SB_G2: howto manager. (line 911) +-* BFD_RELOC_ARM_LDR_IMM: howto manager. (line 936) +-* BFD_RELOC_ARM_LDR_PC_G0: howto manager. (line 889) +-* BFD_RELOC_ARM_LDR_PC_G1: howto manager. (line 890) +-* BFD_RELOC_ARM_LDR_PC_G2: howto manager. (line 891) +-* BFD_RELOC_ARM_LDR_SB_G0: howto manager. (line 903) +-* BFD_RELOC_ARM_LDR_SB_G1: howto manager. (line 904) +-* BFD_RELOC_ARM_LDR_SB_G2: howto manager. (line 905) +-* BFD_RELOC_ARM_LDRS_PC_G0: howto manager. (line 892) +-* BFD_RELOC_ARM_LDRS_PC_G1: howto manager. (line 893) +-* BFD_RELOC_ARM_LDRS_PC_G2: howto manager. (line 894) +-* BFD_RELOC_ARM_LDRS_SB_G0: howto manager. (line 906) +-* BFD_RELOC_ARM_LDRS_SB_G1: howto manager. (line 907) +-* BFD_RELOC_ARM_LDRS_SB_G2: howto manager. (line 908) +-* BFD_RELOC_ARM_LITERAL: howto manager. (line 937) +-* BFD_RELOC_ARM_MOVT: howto manager. (line 849) +-* BFD_RELOC_ARM_MOVT_PCREL: howto manager. (line 851) +-* BFD_RELOC_ARM_MOVW: howto manager. (line 848) +-* BFD_RELOC_ARM_MOVW_PCREL: howto manager. (line 850) +-* BFD_RELOC_ARM_MULTI: howto manager. (line 930) +-* BFD_RELOC_ARM_OFFSET_IMM: howto manager. (line 822) +-* BFD_RELOC_ARM_OFFSET_IMM8: howto manager. (line 939) +-* BFD_RELOC_ARM_PCREL_BLX: howto manager. (line 793) +-* BFD_RELOC_ARM_PCREL_BRANCH: howto manager. (line 789) +-* BFD_RELOC_ARM_PCREL_CALL: howto manager. (line 803) +-* BFD_RELOC_ARM_PCREL_JUMP: howto manager. (line 807) +-* BFD_RELOC_ARM_PLT32: howto manager. (line 861) +-* BFD_RELOC_ARM_PREL31: howto manager. (line 845) +-* BFD_RELOC_ARM_RELATIVE: howto manager. (line 862) +-* BFD_RELOC_ARM_ROSEGREL32: howto manager. (line 834) +-* BFD_RELOC_ARM_SBREL32: howto manager. (line 837) +-* BFD_RELOC_ARM_SHIFT_IMM: howto manager. (line 926) +-* BFD_RELOC_ARM_SMC: howto manager. (line 927) +-* BFD_RELOC_ARM_SWI: howto manager. (line 929) +-* BFD_RELOC_ARM_T32_ADD_IMM: howto manager. (line 923) +-* BFD_RELOC_ARM_T32_ADD_PC12: howto manager. (line 925) +-* BFD_RELOC_ARM_T32_CP_OFF_IMM: howto manager. (line 933) +-* BFD_RELOC_ARM_T32_CP_OFF_IMM_S2: howto manager. (line 934) +-* BFD_RELOC_ARM_T32_IMM12: howto manager. (line 924) +-* BFD_RELOC_ARM_T32_IMMEDIATE: howto manager. (line 922) +-* BFD_RELOC_ARM_T32_OFFSET_IMM: howto manager. (line 941) +-* BFD_RELOC_ARM_T32_OFFSET_U8: howto manager. (line 940) +-* BFD_RELOC_ARM_TARGET1: howto manager. (line 830) +-* BFD_RELOC_ARM_TARGET2: howto manager. (line 840) +-* BFD_RELOC_ARM_THM_TLS_CALL: howto manager. (line 878) +-* BFD_RELOC_ARM_THM_TLS_DESCSEQ: howto manager. (line 880) +-* BFD_RELOC_ARM_THUMB_ADD: howto manager. (line 943) +-* BFD_RELOC_ARM_THUMB_IMM: howto manager. (line 944) +-* BFD_RELOC_ARM_THUMB_MOVT: howto manager. (line 853) +-* BFD_RELOC_ARM_THUMB_MOVT_PCREL: howto manager. (line 855) +-* BFD_RELOC_ARM_THUMB_MOVW: howto manager. (line 852) +-* BFD_RELOC_ARM_THUMB_MOVW_PCREL: howto manager. (line 854) +-* BFD_RELOC_ARM_THUMB_OFFSET: howto manager. (line 826) +-* BFD_RELOC_ARM_THUMB_SHIFT: howto manager. (line 945) +-* BFD_RELOC_ARM_TLS_CALL: howto manager. (line 877) +-* BFD_RELOC_ARM_TLS_DESC: howto manager. (line 881) +-* BFD_RELOC_ARM_TLS_DESCSEQ: howto manager. (line 879) +-* BFD_RELOC_ARM_TLS_DTPMOD32: howto manager. (line 872) +-* BFD_RELOC_ARM_TLS_DTPOFF32: howto manager. (line 871) +-* BFD_RELOC_ARM_TLS_GD32: howto manager. (line 868) +-* BFD_RELOC_ARM_TLS_GOTDESC: howto manager. (line 876) +-* BFD_RELOC_ARM_TLS_IE32: howto manager. (line 874) +-* BFD_RELOC_ARM_TLS_LDM32: howto manager. (line 870) +-* BFD_RELOC_ARM_TLS_LDO32: howto manager. (line 869) +-* BFD_RELOC_ARM_TLS_LE32: howto manager. (line 875) +-* BFD_RELOC_ARM_TLS_TPOFF32: howto manager. (line 873) +-* BFD_RELOC_ARM_V4BX: howto manager. (line 914) +-* BFD_RELOC_AVR_13_PCREL: howto manager. (line 1644) +-* BFD_RELOC_AVR_16_PM: howto manager. (line 1648) +-* BFD_RELOC_AVR_6: howto manager. (line 1735) +-* BFD_RELOC_AVR_6_ADIW: howto manager. (line 1739) +-* BFD_RELOC_AVR_7_PCREL: howto manager. (line 1640) +-* BFD_RELOC_AVR_8_HI: howto manager. (line 1747) +-* BFD_RELOC_AVR_8_HLO: howto manager. (line 1751) +-* BFD_RELOC_AVR_8_LO: howto manager. (line 1743) +-* BFD_RELOC_AVR_CALL: howto manager. (line 1727) +-* BFD_RELOC_AVR_HH8_LDI: howto manager. (line 1660) +-* BFD_RELOC_AVR_HH8_LDI_NEG: howto manager. (line 1679) +-* BFD_RELOC_AVR_HH8_LDI_PM: howto manager. (line 1708) +-* BFD_RELOC_AVR_HH8_LDI_PM_NEG: howto manager. (line 1722) +-* BFD_RELOC_AVR_HI8_LDI: howto manager. (line 1656) +-* BFD_RELOC_AVR_HI8_LDI_GS: howto manager. (line 1702) +-* BFD_RELOC_AVR_HI8_LDI_NEG: howto manager. (line 1674) +-* BFD_RELOC_AVR_HI8_LDI_PM: howto manager. (line 1698) +-* BFD_RELOC_AVR_HI8_LDI_PM_NEG: howto manager. (line 1717) +-* BFD_RELOC_AVR_LDI: howto manager. (line 1731) +-* BFD_RELOC_AVR_LO8_LDI: howto manager. (line 1652) +-* BFD_RELOC_AVR_LO8_LDI_GS: howto manager. (line 1692) +-* BFD_RELOC_AVR_LO8_LDI_NEG: howto manager. (line 1669) +-* BFD_RELOC_AVR_LO8_LDI_PM: howto manager. (line 1688) +-* BFD_RELOC_AVR_LO8_LDI_PM_NEG: howto manager. (line 1713) +-* BFD_RELOC_AVR_MS8_LDI: howto manager. (line 1665) +-* BFD_RELOC_AVR_MS8_LDI_NEG: howto manager. (line 1684) +-* BFD_RELOC_BFIN_10_PCREL: howto manager. (line 1074) +-* BFD_RELOC_BFIN_11_PCREL: howto manager. (line 1077) +-* BFD_RELOC_BFIN_12_PCREL_JUMP: howto manager. (line 1080) +-* BFD_RELOC_BFIN_12_PCREL_JUMP_S: howto manager. (line 1083) +-* BFD_RELOC_BFIN_16_HIGH: howto manager. (line 1062) +-* BFD_RELOC_BFIN_16_IMM: howto manager. (line 1059) +-* BFD_RELOC_BFIN_16_LOW: howto manager. (line 1071) +-* BFD_RELOC_BFIN_24_PCREL_CALL_X: howto manager. (line 1086) +-* BFD_RELOC_BFIN_24_PCREL_JUMP_L: howto manager. (line 1089) +-* BFD_RELOC_BFIN_4_PCREL: howto manager. (line 1065) +-* BFD_RELOC_BFIN_5_PCREL: howto manager. (line 1068) +-* BFD_RELOC_BFIN_FUNCDESC: howto manager. (line 1095) +-* BFD_RELOC_BFIN_FUNCDESC_GOT17M4: howto manager. (line 1096) +-* BFD_RELOC_BFIN_FUNCDESC_GOTHI: howto manager. (line 1097) +-* BFD_RELOC_BFIN_FUNCDESC_GOTLO: howto manager. (line 1098) +-* BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4: howto manager. (line 1100) +-* BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI: howto manager. (line 1101) +-* BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO: howto manager. (line 1102) +-* BFD_RELOC_BFIN_FUNCDESC_VALUE: howto manager. (line 1099) +-* BFD_RELOC_BFIN_GOT: howto manager. (line 1108) +-* BFD_RELOC_BFIN_GOT17M4: howto manager. (line 1092) +-* BFD_RELOC_BFIN_GOTHI: howto manager. (line 1093) +-* BFD_RELOC_BFIN_GOTLO: howto manager. (line 1094) +-* BFD_RELOC_BFIN_GOTOFF17M4: howto manager. (line 1103) +-* BFD_RELOC_BFIN_GOTOFFHI: howto manager. (line 1104) +-* BFD_RELOC_BFIN_GOTOFFLO: howto manager. (line 1105) +-* BFD_RELOC_BFIN_PLTPC: howto manager. (line 1111) +-* BFD_RELOC_C6000_ABS_H16: howto manager. (line 1463) +-* BFD_RELOC_C6000_ABS_L16: howto manager. (line 1462) +-* BFD_RELOC_C6000_ABS_S16: howto manager. (line 1461) +-* BFD_RELOC_C6000_ALIGN: howto manager. (line 1484) +-* BFD_RELOC_C6000_COPY: howto manager. (line 1479) +-* BFD_RELOC_C6000_DSBT_INDEX: howto manager. (line 1477) +-* BFD_RELOC_C6000_EHTYPE: howto manager. (line 1481) +-* BFD_RELOC_C6000_FPHEAD: howto manager. (line 1485) +-* BFD_RELOC_C6000_JUMP_SLOT: howto manager. (line 1480) +-* BFD_RELOC_C6000_NOCMP: howto manager. (line 1486) +-* BFD_RELOC_C6000_PCR_H16: howto manager. (line 1482) +-* BFD_RELOC_C6000_PCR_L16: howto manager. (line 1483) +-* BFD_RELOC_C6000_PCR_S10: howto manager. (line 1459) +-* BFD_RELOC_C6000_PCR_S12: howto manager. (line 1458) +-* BFD_RELOC_C6000_PCR_S21: howto manager. (line 1457) +-* BFD_RELOC_C6000_PCR_S7: howto manager. (line 1460) +-* BFD_RELOC_C6000_PREL31: howto manager. (line 1478) +-* BFD_RELOC_C6000_SBR_GOT_H16_W: howto manager. (line 1476) +-* BFD_RELOC_C6000_SBR_GOT_L16_W: howto manager. (line 1475) +-* BFD_RELOC_C6000_SBR_GOT_U15_W: howto manager. (line 1474) +-* BFD_RELOC_C6000_SBR_H16_B: howto manager. (line 1471) +-* BFD_RELOC_C6000_SBR_H16_H: howto manager. (line 1472) +-* BFD_RELOC_C6000_SBR_H16_W: howto manager. (line 1473) +-* BFD_RELOC_C6000_SBR_L16_B: howto manager. (line 1468) +-* BFD_RELOC_C6000_SBR_L16_H: howto manager. (line 1469) +-* BFD_RELOC_C6000_SBR_L16_W: howto manager. (line 1470) +-* BFD_RELOC_C6000_SBR_S16: howto manager. (line 1467) +-* BFD_RELOC_C6000_SBR_U15_B: howto manager. (line 1464) +-* BFD_RELOC_C6000_SBR_U15_H: howto manager. (line 1465) +-* BFD_RELOC_C6000_SBR_U15_W: howto manager. (line 1466) +-* bfd_reloc_code_type: howto manager. (line 10) +-* BFD_RELOC_CR16_ABS20: howto manager. (line 2264) +-* BFD_RELOC_CR16_ABS24: howto manager. (line 2265) +-* BFD_RELOC_CR16_DISP16: howto manager. (line 2275) +-* BFD_RELOC_CR16_DISP20: howto manager. (line 2276) +-* BFD_RELOC_CR16_DISP24: howto manager. (line 2277) +-* BFD_RELOC_CR16_DISP24a: howto manager. (line 2278) +-* BFD_RELOC_CR16_DISP4: howto manager. (line 2273) +-* BFD_RELOC_CR16_DISP8: howto manager. (line 2274) +-* BFD_RELOC_CR16_GLOB_DAT: howto manager. (line 2284) +-* BFD_RELOC_CR16_GOT_REGREL20: howto manager. (line 2282) +-* BFD_RELOC_CR16_GOTC_REGREL20: howto manager. (line 2283) +-* BFD_RELOC_CR16_IMM16: howto manager. (line 2268) +-* BFD_RELOC_CR16_IMM20: howto manager. (line 2269) +-* BFD_RELOC_CR16_IMM24: howto manager. (line 2270) +-* BFD_RELOC_CR16_IMM32: howto manager. (line 2271) +-* BFD_RELOC_CR16_IMM32a: howto manager. (line 2272) +-* BFD_RELOC_CR16_IMM4: howto manager. (line 2266) +-* BFD_RELOC_CR16_IMM8: howto manager. (line 2267) +-* BFD_RELOC_CR16_NUM16: howto manager. (line 2253) +-* BFD_RELOC_CR16_NUM32: howto manager. (line 2254) +-* BFD_RELOC_CR16_NUM32a: howto manager. (line 2255) +-* BFD_RELOC_CR16_NUM8: howto manager. (line 2252) +-* BFD_RELOC_CR16_REGREL0: howto manager. (line 2256) +-* BFD_RELOC_CR16_REGREL14: howto manager. (line 2259) +-* BFD_RELOC_CR16_REGREL14a: howto manager. (line 2260) +-* BFD_RELOC_CR16_REGREL16: howto manager. (line 2261) +-* BFD_RELOC_CR16_REGREL20: howto manager. (line 2262) +-* BFD_RELOC_CR16_REGREL20a: howto manager. (line 2263) +-* BFD_RELOC_CR16_REGREL4: howto manager. (line 2257) +-* BFD_RELOC_CR16_REGREL4a: howto manager. (line 2258) +-* BFD_RELOC_CR16_SWITCH16: howto manager. (line 2280) +-* BFD_RELOC_CR16_SWITCH32: howto manager. (line 2281) +-* BFD_RELOC_CR16_SWITCH8: howto manager. (line 2279) +-* BFD_RELOC_CRIS_16_DTPREL: howto manager. (line 2355) +-* BFD_RELOC_CRIS_16_GOT: howto manager. (line 2331) +-* BFD_RELOC_CRIS_16_GOT_GD: howto manager. (line 2351) +-* BFD_RELOC_CRIS_16_GOT_TPREL: howto manager. (line 2357) +-* BFD_RELOC_CRIS_16_GOTPLT: howto manager. (line 2337) +-* BFD_RELOC_CRIS_16_TPREL: howto manager. (line 2359) +-* BFD_RELOC_CRIS_32_DTPREL: howto manager. (line 2354) +-* BFD_RELOC_CRIS_32_GD: howto manager. (line 2352) +-* BFD_RELOC_CRIS_32_GOT: howto manager. (line 2328) +-* BFD_RELOC_CRIS_32_GOT_GD: howto manager. (line 2350) +-* BFD_RELOC_CRIS_32_GOT_TPREL: howto manager. (line 2356) +-* BFD_RELOC_CRIS_32_GOTPLT: howto manager. (line 2334) +-* BFD_RELOC_CRIS_32_GOTREL: howto manager. (line 2340) +-* BFD_RELOC_CRIS_32_IE: howto manager. (line 2361) +-* BFD_RELOC_CRIS_32_PLT_GOTREL: howto manager. (line 2343) +-* BFD_RELOC_CRIS_32_PLT_PCREL: howto manager. (line 2346) +-* BFD_RELOC_CRIS_32_TPREL: howto manager. (line 2358) +-* BFD_RELOC_CRIS_BDISP8: howto manager. (line 2309) +-* BFD_RELOC_CRIS_COPY: howto manager. (line 2322) +-* BFD_RELOC_CRIS_DTP: howto manager. (line 2353) +-* BFD_RELOC_CRIS_DTPMOD: howto manager. (line 2360) +-* BFD_RELOC_CRIS_GLOB_DAT: howto manager. (line 2323) +-* BFD_RELOC_CRIS_JUMP_SLOT: howto manager. (line 2324) +-* BFD_RELOC_CRIS_LAPCQ_OFFSET: howto manager. (line 2317) +-* BFD_RELOC_CRIS_RELATIVE: howto manager. (line 2325) +-* BFD_RELOC_CRIS_SIGNED_16: howto manager. (line 2315) +-* BFD_RELOC_CRIS_SIGNED_6: howto manager. (line 2311) +-* BFD_RELOC_CRIS_SIGNED_8: howto manager. (line 2313) +-* BFD_RELOC_CRIS_UNSIGNED_16: howto manager. (line 2316) +-* BFD_RELOC_CRIS_UNSIGNED_4: howto manager. (line 2318) +-* BFD_RELOC_CRIS_UNSIGNED_5: howto manager. (line 2310) +-* BFD_RELOC_CRIS_UNSIGNED_6: howto manager. (line 2312) +-* BFD_RELOC_CRIS_UNSIGNED_8: howto manager. (line 2314) +-* BFD_RELOC_CRX_ABS16: howto manager. (line 2297) +-* BFD_RELOC_CRX_ABS32: howto manager. (line 2298) +-* BFD_RELOC_CRX_IMM16: howto manager. (line 2302) +-* BFD_RELOC_CRX_IMM32: howto manager. (line 2303) +-* BFD_RELOC_CRX_NUM16: howto manager. (line 2300) +-* BFD_RELOC_CRX_NUM32: howto manager. (line 2301) +-* BFD_RELOC_CRX_NUM8: howto manager. (line 2299) +-* BFD_RELOC_CRX_REGREL12: howto manager. (line 2293) +-* BFD_RELOC_CRX_REGREL22: howto manager. (line 2294) +-* BFD_RELOC_CRX_REGREL28: howto manager. (line 2295) +-* BFD_RELOC_CRX_REGREL32: howto manager. (line 2296) +-* BFD_RELOC_CRX_REL16: howto manager. (line 2290) +-* BFD_RELOC_CRX_REL24: howto manager. (line 2291) +-* BFD_RELOC_CRX_REL32: howto manager. (line 2292) +-* BFD_RELOC_CRX_REL4: howto manager. (line 2287) +-* BFD_RELOC_CRX_REL8: howto manager. (line 2288) +-* BFD_RELOC_CRX_REL8_CMP: howto manager. (line 2289) +-* BFD_RELOC_CRX_SWITCH16: howto manager. (line 2305) +-* BFD_RELOC_CRX_SWITCH32: howto manager. (line 2306) +-* BFD_RELOC_CRX_SWITCH8: howto manager. (line 2304) +-* BFD_RELOC_CTOR: howto manager. (line 783) +-* BFD_RELOC_D10V_10_PCREL_L: howto manager. (line 1178) +-* BFD_RELOC_D10V_10_PCREL_R: howto manager. (line 1174) +-* BFD_RELOC_D10V_18: howto manager. (line 1183) +-* BFD_RELOC_D10V_18_PCREL: howto manager. (line 1186) +-* BFD_RELOC_D30V_15: howto manager. (line 1201) +-* BFD_RELOC_D30V_15_PCREL: howto manager. (line 1205) +-* BFD_RELOC_D30V_15_PCREL_R: howto manager. (line 1209) +-* BFD_RELOC_D30V_21: howto manager. (line 1214) +-* BFD_RELOC_D30V_21_PCREL: howto manager. (line 1218) +-* BFD_RELOC_D30V_21_PCREL_R: howto manager. (line 1222) +-* BFD_RELOC_D30V_32: howto manager. (line 1227) +-* BFD_RELOC_D30V_32_PCREL: howto manager. (line 1230) +-* BFD_RELOC_D30V_6: howto manager. (line 1189) +-* BFD_RELOC_D30V_9_PCREL: howto manager. (line 1192) +-* BFD_RELOC_D30V_9_PCREL_R: howto manager. (line 1196) +-* BFD_RELOC_DLX_HI16_S: howto manager. (line 1233) +-* BFD_RELOC_DLX_JMP26: howto manager. (line 1239) +-* BFD_RELOC_DLX_LO16: howto manager. (line 1236) +-* BFD_RELOC_EPIPHANY_HIGH: howto manager. (line 3238) +-* BFD_RELOC_EPIPHANY_IMM11: howto manager. (line 3247) +-* BFD_RELOC_EPIPHANY_IMM8: howto manager. (line 3251) +-* BFD_RELOC_EPIPHANY_LOW: howto manager. (line 3241) +-* BFD_RELOC_EPIPHANY_SIMM11: howto manager. (line 3244) +-* BFD_RELOC_EPIPHANY_SIMM24: howto manager. (line 3235) +-* BFD_RELOC_EPIPHANY_SIMM8: howto manager. (line 3232) +-* BFD_RELOC_FR30_10_IN_8: howto manager. (line 1508) +-* BFD_RELOC_FR30_12_PCREL: howto manager. (line 1516) +-* BFD_RELOC_FR30_20: howto manager. (line 1492) +-* BFD_RELOC_FR30_48: howto manager. (line 1489) +-* BFD_RELOC_FR30_6_IN_4: howto manager. (line 1496) +-* BFD_RELOC_FR30_8_IN_8: howto manager. (line 1500) +-* BFD_RELOC_FR30_9_IN_8: howto manager. (line 1504) +-* BFD_RELOC_FR30_9_PCREL: howto manager. (line 1512) +-* BFD_RELOC_FRV_FUNCDESC: howto manager. (line 491) +-* BFD_RELOC_FRV_FUNCDESC_GOT12: howto manager. (line 492) +-* BFD_RELOC_FRV_FUNCDESC_GOTHI: howto manager. (line 493) +-* BFD_RELOC_FRV_FUNCDESC_GOTLO: howto manager. (line 494) +-* BFD_RELOC_FRV_FUNCDESC_GOTOFF12: howto manager. (line 496) +-* BFD_RELOC_FRV_FUNCDESC_GOTOFFHI: howto manager. (line 497) +-* BFD_RELOC_FRV_FUNCDESC_GOTOFFLO: howto manager. (line 498) +-* BFD_RELOC_FRV_FUNCDESC_VALUE: howto manager. (line 495) +-* BFD_RELOC_FRV_GETTLSOFF: howto manager. (line 502) +-* BFD_RELOC_FRV_GETTLSOFF_RELAX: howto manager. (line 515) +-* BFD_RELOC_FRV_GOT12: howto manager. (line 488) +-* BFD_RELOC_FRV_GOTHI: howto manager. (line 489) +-* BFD_RELOC_FRV_GOTLO: howto manager. (line 490) +-* BFD_RELOC_FRV_GOTOFF12: howto manager. (line 499) +-* BFD_RELOC_FRV_GOTOFFHI: howto manager. (line 500) +-* BFD_RELOC_FRV_GOTOFFLO: howto manager. (line 501) +-* BFD_RELOC_FRV_GOTTLSDESC12: howto manager. (line 504) +-* BFD_RELOC_FRV_GOTTLSDESCHI: howto manager. (line 505) +-* BFD_RELOC_FRV_GOTTLSDESCLO: howto manager. (line 506) +-* BFD_RELOC_FRV_GOTTLSOFF12: howto manager. (line 510) +-* BFD_RELOC_FRV_GOTTLSOFFHI: howto manager. (line 511) +-* BFD_RELOC_FRV_GOTTLSOFFLO: howto manager. (line 512) +-* BFD_RELOC_FRV_GPREL12: howto manager. (line 483) +-* BFD_RELOC_FRV_GPREL32: howto manager. (line 485) +-* BFD_RELOC_FRV_GPRELHI: howto manager. (line 486) +-* BFD_RELOC_FRV_GPRELLO: howto manager. (line 487) +-* BFD_RELOC_FRV_GPRELU12: howto manager. (line 484) +-* BFD_RELOC_FRV_HI16: howto manager. (line 482) +-* BFD_RELOC_FRV_LABEL16: howto manager. (line 479) +-* BFD_RELOC_FRV_LABEL24: howto manager. (line 480) +-* BFD_RELOC_FRV_LO16: howto manager. (line 481) +-* BFD_RELOC_FRV_TLSDESC_RELAX: howto manager. (line 514) +-* BFD_RELOC_FRV_TLSDESC_VALUE: howto manager. (line 503) +-* BFD_RELOC_FRV_TLSMOFF: howto manager. (line 517) +-* BFD_RELOC_FRV_TLSMOFF12: howto manager. (line 507) +-* BFD_RELOC_FRV_TLSMOFFHI: howto manager. (line 508) +-* BFD_RELOC_FRV_TLSMOFFLO: howto manager. (line 509) +-* BFD_RELOC_FRV_TLSOFF: howto manager. (line 513) +-* BFD_RELOC_FRV_TLSOFF_RELAX: howto manager. (line 516) +-* BFD_RELOC_GPREL16: howto manager. (line 125) +-* BFD_RELOC_GPREL32: howto manager. (line 126) +-* BFD_RELOC_H8_DIR16A8: howto manager. (line 2402) +-* BFD_RELOC_H8_DIR16R8: howto manager. (line 2403) +-* BFD_RELOC_H8_DIR24A8: howto manager. (line 2404) +-* BFD_RELOC_H8_DIR24R8: howto manager. (line 2405) +-* BFD_RELOC_H8_DIR32A16: howto manager. (line 2406) +-* BFD_RELOC_H8_DISP32A16: howto manager. (line 2407) +-* BFD_RELOC_HI16: howto manager. (line 352) +-* BFD_RELOC_HI16_BASEREL: howto manager. (line 101) +-* BFD_RELOC_HI16_GOTOFF: howto manager. (line 57) +-* BFD_RELOC_HI16_PCREL: howto manager. (line 364) +-* BFD_RELOC_HI16_PLTOFF: howto manager. (line 69) +-* BFD_RELOC_HI16_S: howto manager. (line 355) +-* BFD_RELOC_HI16_S_BASEREL: howto manager. (line 102) +-* BFD_RELOC_HI16_S_GOTOFF: howto manager. (line 58) +-* BFD_RELOC_HI16_S_PCREL: howto manager. (line 367) +-* BFD_RELOC_HI16_S_PLTOFF: howto manager. (line 70) +-* BFD_RELOC_HI22: howto manager. (line 120) +-* BFD_RELOC_I370_D12: howto manager. (line 780) +-* BFD_RELOC_I960_CALLJ: howto manager. (line 132) +-* BFD_RELOC_IA64_COPY: howto manager. (line 2084) +-* BFD_RELOC_IA64_DIR32LSB: howto manager. (line 2029) +-* BFD_RELOC_IA64_DIR32MSB: howto manager. (line 2028) +-* BFD_RELOC_IA64_DIR64LSB: howto manager. (line 2031) +-* BFD_RELOC_IA64_DIR64MSB: howto manager. (line 2030) +-* BFD_RELOC_IA64_DTPMOD64LSB: howto manager. (line 2094) +-* BFD_RELOC_IA64_DTPMOD64MSB: howto manager. (line 2093) +-* BFD_RELOC_IA64_DTPREL14: howto manager. (line 2096) +-* BFD_RELOC_IA64_DTPREL22: howto manager. (line 2097) +-* BFD_RELOC_IA64_DTPREL32LSB: howto manager. (line 2100) +-* BFD_RELOC_IA64_DTPREL32MSB: howto manager. (line 2099) +-* BFD_RELOC_IA64_DTPREL64I: howto manager. (line 2098) +-* BFD_RELOC_IA64_DTPREL64LSB: howto manager. (line 2102) +-* BFD_RELOC_IA64_DTPREL64MSB: howto manager. (line 2101) +-* BFD_RELOC_IA64_FPTR32LSB: howto manager. (line 2046) +-* BFD_RELOC_IA64_FPTR32MSB: howto manager. (line 2045) +-* BFD_RELOC_IA64_FPTR64I: howto manager. (line 2044) +-* BFD_RELOC_IA64_FPTR64LSB: howto manager. (line 2048) +-* BFD_RELOC_IA64_FPTR64MSB: howto manager. (line 2047) +-* BFD_RELOC_IA64_GPREL22: howto manager. (line 2032) +-* BFD_RELOC_IA64_GPREL32LSB: howto manager. (line 2035) +-* BFD_RELOC_IA64_GPREL32MSB: howto manager. (line 2034) +-* BFD_RELOC_IA64_GPREL64I: howto manager. (line 2033) +-* BFD_RELOC_IA64_GPREL64LSB: howto manager. (line 2037) +-* BFD_RELOC_IA64_GPREL64MSB: howto manager. (line 2036) +-* BFD_RELOC_IA64_IMM14: howto manager. (line 2025) +-* BFD_RELOC_IA64_IMM22: howto manager. (line 2026) +-* BFD_RELOC_IA64_IMM64: howto manager. (line 2027) +-* BFD_RELOC_IA64_IPLTLSB: howto manager. (line 2083) +-* BFD_RELOC_IA64_IPLTMSB: howto manager. (line 2082) +-* BFD_RELOC_IA64_LDXMOV: howto manager. (line 2086) +-* BFD_RELOC_IA64_LTOFF22: howto manager. (line 2038) +-* BFD_RELOC_IA64_LTOFF22X: howto manager. (line 2085) +-* BFD_RELOC_IA64_LTOFF64I: howto manager. (line 2039) +-* BFD_RELOC_IA64_LTOFF_DTPMOD22: howto manager. (line 2095) +-* BFD_RELOC_IA64_LTOFF_DTPREL22: howto manager. (line 2103) +-* BFD_RELOC_IA64_LTOFF_FPTR22: howto manager. (line 2060) +-* BFD_RELOC_IA64_LTOFF_FPTR32LSB: howto manager. (line 2063) +-* BFD_RELOC_IA64_LTOFF_FPTR32MSB: howto manager. (line 2062) +-* BFD_RELOC_IA64_LTOFF_FPTR64I: howto manager. (line 2061) +-* BFD_RELOC_IA64_LTOFF_FPTR64LSB: howto manager. (line 2065) +-* BFD_RELOC_IA64_LTOFF_FPTR64MSB: howto manager. (line 2064) +-* BFD_RELOC_IA64_LTOFF_TPREL22: howto manager. (line 2092) +-* BFD_RELOC_IA64_LTV32LSB: howto manager. (line 2079) +-* BFD_RELOC_IA64_LTV32MSB: howto manager. (line 2078) +-* BFD_RELOC_IA64_LTV64LSB: howto manager. (line 2081) +-* BFD_RELOC_IA64_LTV64MSB: howto manager. (line 2080) +-* BFD_RELOC_IA64_PCREL21B: howto manager. (line 2049) +-* BFD_RELOC_IA64_PCREL21BI: howto manager. (line 2050) +-* BFD_RELOC_IA64_PCREL21F: howto manager. (line 2052) +-* BFD_RELOC_IA64_PCREL21M: howto manager. (line 2051) +-* BFD_RELOC_IA64_PCREL22: howto manager. (line 2053) +-* BFD_RELOC_IA64_PCREL32LSB: howto manager. (line 2057) +-* BFD_RELOC_IA64_PCREL32MSB: howto manager. (line 2056) +-* BFD_RELOC_IA64_PCREL60B: howto manager. (line 2054) +-* BFD_RELOC_IA64_PCREL64I: howto manager. (line 2055) +-* BFD_RELOC_IA64_PCREL64LSB: howto manager. (line 2059) +-* BFD_RELOC_IA64_PCREL64MSB: howto manager. (line 2058) +-* BFD_RELOC_IA64_PLTOFF22: howto manager. (line 2040) +-* BFD_RELOC_IA64_PLTOFF64I: howto manager. (line 2041) +-* BFD_RELOC_IA64_PLTOFF64LSB: howto manager. (line 2043) +-* BFD_RELOC_IA64_PLTOFF64MSB: howto manager. (line 2042) +-* BFD_RELOC_IA64_REL32LSB: howto manager. (line 2075) +-* BFD_RELOC_IA64_REL32MSB: howto manager. (line 2074) +-* BFD_RELOC_IA64_REL64LSB: howto manager. (line 2077) +-* BFD_RELOC_IA64_REL64MSB: howto manager. (line 2076) +-* BFD_RELOC_IA64_SECREL32LSB: howto manager. (line 2071) +-* BFD_RELOC_IA64_SECREL32MSB: howto manager. (line 2070) +-* BFD_RELOC_IA64_SECREL64LSB: howto manager. (line 2073) +-* BFD_RELOC_IA64_SECREL64MSB: howto manager. (line 2072) +-* BFD_RELOC_IA64_SEGREL32LSB: howto manager. (line 2067) +-* BFD_RELOC_IA64_SEGREL32MSB: howto manager. (line 2066) +-* BFD_RELOC_IA64_SEGREL64LSB: howto manager. (line 2069) +-* BFD_RELOC_IA64_SEGREL64MSB: howto manager. (line 2068) +-* BFD_RELOC_IA64_TPREL14: howto manager. (line 2087) +-* BFD_RELOC_IA64_TPREL22: howto manager. (line 2088) +-* BFD_RELOC_IA64_TPREL64I: howto manager. (line 2089) +-* BFD_RELOC_IA64_TPREL64LSB: howto manager. (line 2091) +-* BFD_RELOC_IA64_TPREL64MSB: howto manager. (line 2090) +-* BFD_RELOC_IP2K_ADDR16CJP: howto manager. (line 1977) +-* BFD_RELOC_IP2K_BANK: howto manager. (line 1974) +-* BFD_RELOC_IP2K_EX8DATA: howto manager. (line 1985) +-* BFD_RELOC_IP2K_FR9: howto manager. (line 1971) +-* BFD_RELOC_IP2K_FR_OFFSET: howto manager. (line 1998) +-* BFD_RELOC_IP2K_HI8DATA: howto manager. (line 1984) +-* BFD_RELOC_IP2K_HI8INSN: howto manager. (line 1989) +-* BFD_RELOC_IP2K_LO8DATA: howto manager. (line 1983) +-* BFD_RELOC_IP2K_LO8INSN: howto manager. (line 1988) +-* BFD_RELOC_IP2K_PAGE3: howto manager. (line 1980) +-* BFD_RELOC_IP2K_PC_SKIP: howto manager. (line 1992) +-* BFD_RELOC_IP2K_TEXT: howto manager. (line 1995) +-* BFD_RELOC_IQ2000_OFFSET_16: howto manager. (line 2508) +-* BFD_RELOC_IQ2000_OFFSET_21: howto manager. (line 2509) +-* BFD_RELOC_IQ2000_UHI16: howto manager. (line 2510) +-* BFD_RELOC_LM32_16_GOT: howto manager. (line 2615) +-* BFD_RELOC_LM32_BRANCH: howto manager. (line 2614) +-* BFD_RELOC_LM32_CALL: howto manager. (line 2613) +-* BFD_RELOC_LM32_COPY: howto manager. (line 2618) +-* BFD_RELOC_LM32_GLOB_DAT: howto manager. (line 2619) +-* BFD_RELOC_LM32_GOTOFF_HI16: howto manager. (line 2616) +-* BFD_RELOC_LM32_GOTOFF_LO16: howto manager. (line 2617) +-* BFD_RELOC_LM32_JMP_SLOT: howto manager. (line 2620) +-* BFD_RELOC_LM32_RELATIVE: howto manager. (line 2621) +-* BFD_RELOC_LO10: howto manager. (line 121) +-* BFD_RELOC_LO16: howto manager. (line 361) +-* BFD_RELOC_LO16_BASEREL: howto manager. (line 100) +-* BFD_RELOC_LO16_GOTOFF: howto manager. (line 56) +-* BFD_RELOC_LO16_PCREL: howto manager. (line 370) +-* BFD_RELOC_LO16_PLTOFF: howto manager. (line 68) +-* BFD_RELOC_M32C_HI8: howto manager. (line 1242) +-* BFD_RELOC_M32C_RL_1ADDR: howto manager. (line 1244) +-* BFD_RELOC_M32C_RL_2ADDR: howto manager. (line 1245) +-* BFD_RELOC_M32C_RL_JUMP: howto manager. (line 1243) +-* BFD_RELOC_M32R_10_PCREL: howto manager. (line 1252) +-* BFD_RELOC_M32R_18_PCREL: howto manager. (line 1256) +-* BFD_RELOC_M32R_24: howto manager. (line 1248) +-* BFD_RELOC_M32R_26_PCREL: howto manager. (line 1259) +-* BFD_RELOC_M32R_26_PLTREL: howto manager. (line 1278) +-* BFD_RELOC_M32R_COPY: howto manager. (line 1279) +-* BFD_RELOC_M32R_GLOB_DAT: howto manager. (line 1280) +-* BFD_RELOC_M32R_GOT16_HI_SLO: howto manager. (line 1289) +-* BFD_RELOC_M32R_GOT16_HI_ULO: howto manager. (line 1288) +-* BFD_RELOC_M32R_GOT16_LO: howto manager. (line 1290) +-* BFD_RELOC_M32R_GOT24: howto manager. (line 1277) +-* BFD_RELOC_M32R_GOTOFF: howto manager. (line 1283) +-* BFD_RELOC_M32R_GOTOFF_HI_SLO: howto manager. (line 1285) +-* BFD_RELOC_M32R_GOTOFF_HI_ULO: howto manager. (line 1284) +-* BFD_RELOC_M32R_GOTOFF_LO: howto manager. (line 1286) +-* BFD_RELOC_M32R_GOTPC24: howto manager. (line 1287) +-* BFD_RELOC_M32R_GOTPC_HI_SLO: howto manager. (line 1292) +-* BFD_RELOC_M32R_GOTPC_HI_ULO: howto manager. (line 1291) +-* BFD_RELOC_M32R_GOTPC_LO: howto manager. (line 1293) +-* BFD_RELOC_M32R_HI16_SLO: howto manager. (line 1266) +-* BFD_RELOC_M32R_HI16_ULO: howto manager. (line 1262) +-* BFD_RELOC_M32R_JMP_SLOT: howto manager. (line 1281) +-* BFD_RELOC_M32R_LO16: howto manager. (line 1270) +-* BFD_RELOC_M32R_RELATIVE: howto manager. (line 1282) +-* BFD_RELOC_M32R_SDA16: howto manager. (line 1273) +-* BFD_RELOC_M68HC11_24: howto manager. (line 2139) +-* BFD_RELOC_M68HC11_3B: howto manager. (line 2114) +-* BFD_RELOC_M68HC11_HI8: howto manager. (line 2106) +-* BFD_RELOC_M68HC11_LO16: howto manager. (line 2128) +-* BFD_RELOC_M68HC11_LO8: howto manager. (line 2110) +-* BFD_RELOC_M68HC11_PAGE: howto manager. (line 2134) +-* BFD_RELOC_M68HC11_RL_GROUP: howto manager. (line 2123) +-* BFD_RELOC_M68HC11_RL_JUMP: howto manager. (line 2117) +-* BFD_RELOC_M68HC12_10_PCREL: howto manager. (line 2199) +-* BFD_RELOC_M68HC12_16B: howto manager. (line 2193) +-* BFD_RELOC_M68HC12_5B: howto manager. (line 2145) +-* BFD_RELOC_M68HC12_9_PCREL: howto manager. (line 2196) +-* BFD_RELOC_M68HC12_9B: howto manager. (line 2190) +-* BFD_RELOC_M68HC12_HI8XG: howto manager. (line 2206) +-* BFD_RELOC_M68HC12_LO8XG: howto manager. (line 2202) +-* BFD_RELOC_MACH_O_LOCAL_SECTDIFF: howto manager. (line 2628) +-* BFD_RELOC_MACH_O_PAIR: howto manager. (line 2631) +-* BFD_RELOC_MACH_O_SECTDIFF: howto manager. (line 2624) +-* BFD_RELOC_MACH_O_X86_64_BRANCH32: howto manager. (line 2634) +-* BFD_RELOC_MACH_O_X86_64_BRANCH8: howto manager. (line 2635) +-* BFD_RELOC_MACH_O_X86_64_GOT: howto manager. (line 2639) +-* BFD_RELOC_MACH_O_X86_64_GOT_LOAD: howto manager. (line 2642) +-* BFD_RELOC_MACH_O_X86_64_PCREL32_1: howto manager. (line 2652) +-* BFD_RELOC_MACH_O_X86_64_PCREL32_2: howto manager. (line 2655) +-* BFD_RELOC_MACH_O_X86_64_PCREL32_4: howto manager. (line 2658) +-* BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32: howto manager. (line 2646) +-* BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64: howto manager. (line 2649) +-* BFD_RELOC_MCORE_PCREL_32: howto manager. (line 1523) +-* BFD_RELOC_MCORE_PCREL_IMM11BY2: howto manager. (line 1521) +-* BFD_RELOC_MCORE_PCREL_IMM4BY2: howto manager. (line 1522) +-* BFD_RELOC_MCORE_PCREL_IMM8BY4: howto manager. (line 1520) +-* BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2: howto manager. (line 1524) +-* BFD_RELOC_MCORE_RVA: howto manager. (line 1525) +-* BFD_RELOC_MEP_16: howto manager. (line 1529) +-* BFD_RELOC_MEP_32: howto manager. (line 1530) +-* BFD_RELOC_MEP_8: howto manager. (line 1528) +-* BFD_RELOC_MEP_ADDR24A4: howto manager. (line 1545) +-* BFD_RELOC_MEP_GNU_VTENTRY: howto manager. (line 1547) +-* BFD_RELOC_MEP_GNU_VTINHERIT: howto manager. (line 1546) +-* BFD_RELOC_MEP_GPREL: howto manager. (line 1539) +-* BFD_RELOC_MEP_HI16S: howto manager. (line 1538) +-* BFD_RELOC_MEP_HI16U: howto manager. (line 1537) +-* BFD_RELOC_MEP_LOW16: howto manager. (line 1536) +-* BFD_RELOC_MEP_PCABS24A2: howto manager. (line 1535) +-* BFD_RELOC_MEP_PCREL12A2: howto manager. (line 1532) +-* BFD_RELOC_MEP_PCREL17A2: howto manager. (line 1533) +-* BFD_RELOC_MEP_PCREL24A2: howto manager. (line 1534) +-* BFD_RELOC_MEP_PCREL8A2: howto manager. (line 1531) +-* BFD_RELOC_MEP_TPREL: howto manager. (line 1540) +-* BFD_RELOC_MEP_TPREL7: howto manager. (line 1541) +-* BFD_RELOC_MEP_TPREL7A2: howto manager. (line 1542) +-* BFD_RELOC_MEP_TPREL7A4: howto manager. (line 1543) +-* BFD_RELOC_MEP_UIMM24: howto manager. (line 1544) +-* BFD_RELOC_METAG_COPY: howto manager. (line 1569) +-* BFD_RELOC_METAG_GETSET_GOT: howto manager. (line 1561) +-* BFD_RELOC_METAG_GETSET_GOTOFF: howto manager. (line 1560) +-* BFD_RELOC_METAG_GETSETOFF: howto manager. (line 1553) +-* BFD_RELOC_METAG_GLOB_DAT: howto manager. (line 1572) +-* BFD_RELOC_METAG_GOTOFF: howto manager. (line 1567) +-* BFD_RELOC_METAG_HI16_GOTOFF: howto manager. (line 1558) +-* BFD_RELOC_METAG_HI16_GOTPC: howto manager. (line 1562) +-* BFD_RELOC_METAG_HI16_PLT: howto manager. (line 1564) +-* BFD_RELOC_METAG_HIADDR16: howto manager. (line 1550) +-* BFD_RELOC_METAG_HIOG: howto manager. (line 1554) +-* BFD_RELOC_METAG_JMP_SLOT: howto manager. (line 1570) +-* BFD_RELOC_METAG_LO16_GOTOFF: howto manager. (line 1559) +-* BFD_RELOC_METAG_LO16_GOTPC: howto manager. (line 1563) +-* BFD_RELOC_METAG_LO16_PLT: howto manager. (line 1565) +-* BFD_RELOC_METAG_LOADDR16: howto manager. (line 1551) +-* BFD_RELOC_METAG_LOOG: howto manager. (line 1555) +-* BFD_RELOC_METAG_PLT: howto manager. (line 1568) +-* BFD_RELOC_METAG_REL16: howto manager. (line 1557) +-* BFD_RELOC_METAG_REL8: howto manager. (line 1556) +-* BFD_RELOC_METAG_RELATIVE: howto manager. (line 1571) +-* BFD_RELOC_METAG_RELBRANCH: howto manager. (line 1552) +-* BFD_RELOC_METAG_RELBRANCH_PLT: howto manager. (line 1566) +-* BFD_RELOC_METAG_TLS_DTPMOD: howto manager. (line 1583) +-* BFD_RELOC_METAG_TLS_DTPOFF: howto manager. (line 1584) +-* BFD_RELOC_METAG_TLS_GD: howto manager. (line 1573) +-* BFD_RELOC_METAG_TLS_IE: howto manager. (line 1578) +-* BFD_RELOC_METAG_TLS_IENONPIC: howto manager. (line 1579) +-* BFD_RELOC_METAG_TLS_IENONPIC_HI16: howto manager. (line 1580) +-* BFD_RELOC_METAG_TLS_IENONPIC_LO16: howto manager. (line 1581) +-* BFD_RELOC_METAG_TLS_LDM: howto manager. (line 1574) +-* BFD_RELOC_METAG_TLS_LDO: howto manager. (line 1577) +-* BFD_RELOC_METAG_TLS_LDO_HI16: howto manager. (line 1575) +-* BFD_RELOC_METAG_TLS_LDO_LO16: howto manager. (line 1576) +-* BFD_RELOC_METAG_TLS_LE: howto manager. (line 1585) +-* BFD_RELOC_METAG_TLS_LE_HI16: howto manager. (line 1586) +-* BFD_RELOC_METAG_TLS_LE_LO16: howto manager. (line 1587) +-* BFD_RELOC_METAG_TLS_TPOFF: howto manager. (line 1582) +-* BFD_RELOC_MICROBLAZE_32_GOTOFF: howto manager. (line 2705) +-* BFD_RELOC_MICROBLAZE_32_LO: howto manager. (line 2661) +-* BFD_RELOC_MICROBLAZE_32_LO_PCREL: howto manager. (line 2665) +-* BFD_RELOC_MICROBLAZE_32_ROSDA: howto manager. (line 2669) +-* BFD_RELOC_MICROBLAZE_32_RWSDA: howto manager. (line 2673) +-* BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: howto manager. (line 2677) +-* BFD_RELOC_MICROBLAZE_32_TLSDTPMOD: howto manager. (line 2726) +-* BFD_RELOC_MICROBLAZE_32_TLSDTPREL: howto manager. (line 2729) +-* BFD_RELOC_MICROBLAZE_64_GOT: howto manager. (line 2691) +-* BFD_RELOC_MICROBLAZE_64_GOTOFF: howto manager. (line 2700) +-* BFD_RELOC_MICROBLAZE_64_GOTPC: howto manager. (line 2686) +-* BFD_RELOC_MICROBLAZE_64_NONE: howto manager. (line 2681) +-* BFD_RELOC_MICROBLAZE_64_PLT: howto manager. (line 2695) +-* BFD_RELOC_MICROBLAZE_64_TLS: howto manager. (line 2713) +-* BFD_RELOC_MICROBLAZE_64_TLSDTPREL: howto manager. (line 2732) +-* BFD_RELOC_MICROBLAZE_64_TLSGD: howto manager. (line 2716) +-* BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: howto manager. (line 2736) +-* BFD_RELOC_MICROBLAZE_64_TLSLD: howto manager. (line 2721) +-* BFD_RELOC_MICROBLAZE_64_TLSTPREL: howto manager. (line 2740) +-* BFD_RELOC_MICROBLAZE_COPY: howto manager. (line 2709) +-* BFD_RELOC_MICROMIPS_10_PCREL_S1: howto manager. (line 404) +-* BFD_RELOC_MICROMIPS_16_PCREL_S1: howto manager. (line 405) +-* BFD_RELOC_MICROMIPS_7_PCREL_S1: howto manager. (line 403) +-* BFD_RELOC_MICROMIPS_CALL16: howto manager. (line 417) +-* BFD_RELOC_MICROMIPS_CALL_HI16: howto manager. (line 423) +-* BFD_RELOC_MICROMIPS_CALL_LO16: howto manager. (line 425) +-* BFD_RELOC_MICROMIPS_GOT16: howto manager. (line 415) +-* BFD_RELOC_MICROMIPS_GOT_DISP: howto manager. (line 433) +-* BFD_RELOC_MICROMIPS_GOT_HI16: howto manager. (line 419) +-* BFD_RELOC_MICROMIPS_GOT_LO16: howto manager. (line 421) +-* BFD_RELOC_MICROMIPS_GOT_OFST: howto manager. (line 431) +-* BFD_RELOC_MICROMIPS_GOT_PAGE: howto manager. (line 429) +-* BFD_RELOC_MICROMIPS_GPREL16: howto manager. (line 408) +-* BFD_RELOC_MICROMIPS_HI16: howto manager. (line 409) +-* BFD_RELOC_MICROMIPS_HI16_S: howto manager. (line 410) +-* BFD_RELOC_MICROMIPS_HIGHER: howto manager. (line 442) +-* BFD_RELOC_MICROMIPS_HIGHEST: howto manager. (line 440) +-* BFD_RELOC_MICROMIPS_JALR: howto manager. (line 448) +-* BFD_RELOC_MICROMIPS_JMP: howto manager. (line 343) +-* BFD_RELOC_MICROMIPS_LITERAL: howto manager. (line 400) +-* BFD_RELOC_MICROMIPS_LO16: howto manager. (line 411) +-* BFD_RELOC_MICROMIPS_SCN_DISP: howto manager. (line 444) +-* BFD_RELOC_MICROMIPS_SUB: howto manager. (line 427) +-* BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16: howto manager. (line 458) +-* BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16: howto manager. (line 460) +-* BFD_RELOC_MICROMIPS_TLS_GD: howto manager. (line 454) +-* BFD_RELOC_MICROMIPS_TLS_GOTTPREL: howto manager. (line 462) +-* BFD_RELOC_MICROMIPS_TLS_LDM: howto manager. (line 456) +-* BFD_RELOC_MICROMIPS_TLS_TPREL_HI16: howto manager. (line 466) +-* BFD_RELOC_MICROMIPS_TLS_TPREL_LO16: howto manager. (line 468) +-* BFD_RELOC_MIPS16_CALL16: howto manager. (line 374) +-* BFD_RELOC_MIPS16_GOT16: howto manager. (line 373) +-* BFD_RELOC_MIPS16_GPREL: howto manager. (line 349) +-* BFD_RELOC_MIPS16_HI16: howto manager. (line 378) +-* BFD_RELOC_MIPS16_HI16_S: howto manager. (line 381) +-* BFD_RELOC_MIPS16_JMP: howto manager. (line 346) +-* BFD_RELOC_MIPS16_LO16: howto manager. (line 387) +-* BFD_RELOC_MIPS16_TLS_DTPREL_HI16: howto manager. (line 392) +-* BFD_RELOC_MIPS16_TLS_DTPREL_LO16: howto manager. (line 393) +-* BFD_RELOC_MIPS16_TLS_GD: howto manager. (line 390) +-* BFD_RELOC_MIPS16_TLS_GOTTPREL: howto manager. (line 394) +-* BFD_RELOC_MIPS16_TLS_LDM: howto manager. (line 391) +-* BFD_RELOC_MIPS16_TLS_TPREL_HI16: howto manager. (line 395) +-* BFD_RELOC_MIPS16_TLS_TPREL_LO16: howto manager. (line 396) +-* BFD_RELOC_MIPS_CALL16: howto manager. (line 416) +-* BFD_RELOC_MIPS_CALL_HI16: howto manager. (line 422) +-* BFD_RELOC_MIPS_CALL_LO16: howto manager. (line 424) +-* BFD_RELOC_MIPS_COPY: howto manager. (line 472) +-* BFD_RELOC_MIPS_DELETE: howto manager. (line 438) +-* BFD_RELOC_MIPS_EH: howto manager. (line 469) +-* BFD_RELOC_MIPS_GOT16: howto manager. (line 414) +-* BFD_RELOC_MIPS_GOT_DISP: howto manager. (line 432) +-* BFD_RELOC_MIPS_GOT_HI16: howto manager. (line 418) +-* BFD_RELOC_MIPS_GOT_LO16: howto manager. (line 420) +-* BFD_RELOC_MIPS_GOT_OFST: howto manager. (line 430) +-* BFD_RELOC_MIPS_GOT_PAGE: howto manager. (line 428) +-* BFD_RELOC_MIPS_HIGHER: howto manager. (line 441) +-* BFD_RELOC_MIPS_HIGHEST: howto manager. (line 439) +-* BFD_RELOC_MIPS_INSERT_A: howto manager. (line 436) +-* BFD_RELOC_MIPS_INSERT_B: howto manager. (line 437) +-* BFD_RELOC_MIPS_JALR: howto manager. (line 447) +-* BFD_RELOC_MIPS_JMP: howto manager. (line 342) +-* BFD_RELOC_MIPS_JUMP_SLOT: howto manager. (line 473) +-* BFD_RELOC_MIPS_LITERAL: howto manager. (line 399) +-* BFD_RELOC_MIPS_REL16: howto manager. (line 445) +-* BFD_RELOC_MIPS_RELGOT: howto manager. (line 446) +-* BFD_RELOC_MIPS_SCN_DISP: howto manager. (line 443) +-* BFD_RELOC_MIPS_SHIFT5: howto manager. (line 434) +-* BFD_RELOC_MIPS_SHIFT6: howto manager. (line 435) +-* BFD_RELOC_MIPS_SUB: howto manager. (line 426) +-* BFD_RELOC_MIPS_TLS_DTPMOD32: howto manager. (line 449) +-* BFD_RELOC_MIPS_TLS_DTPMOD64: howto manager. (line 451) +-* BFD_RELOC_MIPS_TLS_DTPREL32: howto manager. (line 450) +-* BFD_RELOC_MIPS_TLS_DTPREL64: howto manager. (line 452) +-* BFD_RELOC_MIPS_TLS_DTPREL_HI16: howto manager. (line 457) +-* BFD_RELOC_MIPS_TLS_DTPREL_LO16: howto manager. (line 459) +-* BFD_RELOC_MIPS_TLS_GD: howto manager. (line 453) +-* BFD_RELOC_MIPS_TLS_GOTTPREL: howto manager. (line 461) +-* BFD_RELOC_MIPS_TLS_LDM: howto manager. (line 455) +-* BFD_RELOC_MIPS_TLS_TPREL32: howto manager. (line 463) +-* BFD_RELOC_MIPS_TLS_TPREL64: howto manager. (line 464) +-* BFD_RELOC_MIPS_TLS_TPREL_HI16: howto manager. (line 465) +-* BFD_RELOC_MIPS_TLS_TPREL_LO16: howto manager. (line 467) +-* BFD_RELOC_MMIX_ADDR19: howto manager. (line 1616) +-* BFD_RELOC_MMIX_ADDR27: howto manager. (line 1620) +-* BFD_RELOC_MMIX_BASE_PLUS_OFFSET: howto manager. (line 1632) +-* BFD_RELOC_MMIX_CBRANCH: howto manager. (line 1596) +-* BFD_RELOC_MMIX_CBRANCH_1: howto manager. (line 1598) +-* BFD_RELOC_MMIX_CBRANCH_2: howto manager. (line 1599) +-* BFD_RELOC_MMIX_CBRANCH_3: howto manager. (line 1600) +-* BFD_RELOC_MMIX_CBRANCH_J: howto manager. (line 1597) +-* BFD_RELOC_MMIX_GETA: howto manager. (line 1590) +-* BFD_RELOC_MMIX_GETA_1: howto manager. (line 1591) +-* BFD_RELOC_MMIX_GETA_2: howto manager. (line 1592) +-* BFD_RELOC_MMIX_GETA_3: howto manager. (line 1593) +-* BFD_RELOC_MMIX_JMP: howto manager. (line 1610) +-* BFD_RELOC_MMIX_JMP_1: howto manager. (line 1611) +-* BFD_RELOC_MMIX_JMP_2: howto manager. (line 1612) +-* BFD_RELOC_MMIX_JMP_3: howto manager. (line 1613) +-* BFD_RELOC_MMIX_LOCAL: howto manager. (line 1636) +-* BFD_RELOC_MMIX_PUSHJ: howto manager. (line 1603) +-* BFD_RELOC_MMIX_PUSHJ_1: howto manager. (line 1604) +-* BFD_RELOC_MMIX_PUSHJ_2: howto manager. (line 1605) +-* BFD_RELOC_MMIX_PUSHJ_3: howto manager. (line 1606) +-* BFD_RELOC_MMIX_PUSHJ_STUBBABLE: howto manager. (line 1607) +-* BFD_RELOC_MMIX_REG: howto manager. (line 1628) +-* BFD_RELOC_MMIX_REG_OR_BYTE: howto manager. (line 1624) +-* BFD_RELOC_MN10300_16_PCREL: howto manager. (line 571) +-* BFD_RELOC_MN10300_32_PCREL: howto manager. (line 567) +-* BFD_RELOC_MN10300_ALIGN: howto manager. (line 552) +-* BFD_RELOC_MN10300_COPY: howto manager. (line 535) +-* BFD_RELOC_MN10300_GLOB_DAT: howto manager. (line 538) +-* BFD_RELOC_MN10300_GOT16: howto manager. (line 531) +-* BFD_RELOC_MN10300_GOT24: howto manager. (line 527) +-* BFD_RELOC_MN10300_GOT32: howto manager. (line 523) +-* BFD_RELOC_MN10300_GOTOFF24: howto manager. (line 520) +-* BFD_RELOC_MN10300_JMP_SLOT: howto manager. (line 541) +-* BFD_RELOC_MN10300_RELATIVE: howto manager. (line 544) +-* BFD_RELOC_MN10300_SYM_DIFF: howto manager. (line 547) +-* BFD_RELOC_MN10300_TLS_DTPMOD: howto manager. (line 562) +-* BFD_RELOC_MN10300_TLS_DTPOFF: howto manager. (line 563) +-* BFD_RELOC_MN10300_TLS_GD: howto manager. (line 556) +-* BFD_RELOC_MN10300_TLS_GOTIE: howto manager. (line 559) +-* BFD_RELOC_MN10300_TLS_IE: howto manager. (line 560) +-* BFD_RELOC_MN10300_TLS_LD: howto manager. (line 557) +-* BFD_RELOC_MN10300_TLS_LDO: howto manager. (line 558) +-* BFD_RELOC_MN10300_TLS_LE: howto manager. (line 561) +-* BFD_RELOC_MN10300_TLS_TPOFF: howto manager. (line 564) +-* BFD_RELOC_MOXIE_10_PCREL: howto manager. (line 476) +-* BFD_RELOC_MSP430_10_PCREL: howto manager. (line 2448) +-* BFD_RELOC_MSP430_16: howto manager. (line 2450) +-* BFD_RELOC_MSP430_16_BYTE: howto manager. (line 2452) +-* BFD_RELOC_MSP430_16_PCREL: howto manager. (line 2449) +-* BFD_RELOC_MSP430_16_PCREL_BYTE: howto manager. (line 2451) +-* BFD_RELOC_MSP430_2X_PCREL: howto manager. (line 2453) +-* BFD_RELOC_MSP430_ABS8: howto manager. (line 2455) +-* BFD_RELOC_MSP430_ABS_HI16: howto manager. (line 2467) +-* BFD_RELOC_MSP430_PREL31: howto manager. (line 2468) +-* BFD_RELOC_MSP430_RL_PCREL: howto manager. (line 2454) +-* BFD_RELOC_MSP430_SYM_DIFF: howto manager. (line 2469) +-* BFD_RELOC_MSP430X_ABS16: howto manager. (line 2466) +-* BFD_RELOC_MSP430X_ABS20_ADR_DST: howto manager. (line 2463) +-* BFD_RELOC_MSP430X_ABS20_ADR_SRC: howto manager. (line 2462) +-* BFD_RELOC_MSP430X_ABS20_EXT_DST: howto manager. (line 2460) +-* BFD_RELOC_MSP430X_ABS20_EXT_ODST: howto manager. (line 2461) +-* BFD_RELOC_MSP430X_ABS20_EXT_SRC: howto manager. (line 2459) +-* BFD_RELOC_MSP430X_PCR16: howto manager. (line 2464) +-* BFD_RELOC_MSP430X_PCR20_CALL: howto manager. (line 2465) +-* BFD_RELOC_MSP430X_PCR20_EXT_DST: howto manager. (line 2457) +-* BFD_RELOC_MSP430X_PCR20_EXT_ODST: howto manager. (line 2458) +-* BFD_RELOC_MSP430X_PCR20_EXT_SRC: howto manager. (line 2456) +-* BFD_RELOC_MT_GNU_VTENTRY: howto manager. (line 2442) +-* BFD_RELOC_MT_GNU_VTINHERIT: howto manager. (line 2439) +-* BFD_RELOC_MT_HI16: howto manager. (line 2433) +-* BFD_RELOC_MT_LO16: howto manager. (line 2436) +-* BFD_RELOC_MT_PC16: howto manager. (line 2430) +-* BFD_RELOC_MT_PCINSN8: howto manager. (line 2445) +-* BFD_RELOC_NIOS2_ALIGN: howto manager. (line 2486) +-* BFD_RELOC_NIOS2_CACHE_OPX: howto manager. (line 2476) +-* BFD_RELOC_NIOS2_CALL16: howto manager. (line 2488) +-* BFD_RELOC_NIOS2_CALL26: howto manager. (line 2474) +-* BFD_RELOC_NIOS2_CALLR: howto manager. (line 2485) +-* BFD_RELOC_NIOS2_CJMP: howto manager. (line 2484) +-* BFD_RELOC_NIOS2_COPY: howto manager. (line 2501) +-* BFD_RELOC_NIOS2_GLOB_DAT: howto manager. (line 2502) +-* BFD_RELOC_NIOS2_GOT16: howto manager. (line 2487) +-* BFD_RELOC_NIOS2_GOTOFF: howto manager. (line 2505) +-* BFD_RELOC_NIOS2_GOTOFF_HA: howto manager. (line 2490) +-* BFD_RELOC_NIOS2_GOTOFF_LO: howto manager. (line 2489) +-* BFD_RELOC_NIOS2_GPREL: howto manager. (line 2482) +-* BFD_RELOC_NIOS2_HI16: howto manager. (line 2479) +-* BFD_RELOC_NIOS2_HIADJ16: howto manager. (line 2481) +-* BFD_RELOC_NIOS2_IMM5: howto manager. (line 2475) +-* BFD_RELOC_NIOS2_IMM6: howto manager. (line 2477) +-* BFD_RELOC_NIOS2_IMM8: howto manager. (line 2478) +-* BFD_RELOC_NIOS2_JUMP_SLOT: howto manager. (line 2503) +-* BFD_RELOC_NIOS2_LO16: howto manager. (line 2480) +-* BFD_RELOC_NIOS2_PCREL_HA: howto manager. (line 2492) +-* BFD_RELOC_NIOS2_PCREL_LO: howto manager. (line 2491) +-* BFD_RELOC_NIOS2_RELATIVE: howto manager. (line 2504) +-* BFD_RELOC_NIOS2_S16: howto manager. (line 2472) +-* BFD_RELOC_NIOS2_TLS_DTPMOD: howto manager. (line 2498) +-* BFD_RELOC_NIOS2_TLS_DTPREL: howto manager. (line 2499) +-* BFD_RELOC_NIOS2_TLS_GD16: howto manager. (line 2493) +-* BFD_RELOC_NIOS2_TLS_IE16: howto manager. (line 2496) +-* BFD_RELOC_NIOS2_TLS_LDM16: howto manager. (line 2494) +-* BFD_RELOC_NIOS2_TLS_LDO16: howto manager. (line 2495) +-* BFD_RELOC_NIOS2_TLS_LE16: howto manager. (line 2497) +-* BFD_RELOC_NIOS2_TLS_TPREL: howto manager. (line 2500) +-* BFD_RELOC_NIOS2_U16: howto manager. (line 2473) +-* BFD_RELOC_NIOS2_UJMP: howto manager. (line 2483) +-* BFD_RELOC_NONE: howto manager. (line 135) +-* BFD_RELOC_NS32K_DISP_16: howto manager. (line 639) +-* BFD_RELOC_NS32K_DISP_16_PCREL: howto manager. (line 642) +-* BFD_RELOC_NS32K_DISP_32: howto manager. (line 640) +-* BFD_RELOC_NS32K_DISP_32_PCREL: howto manager. (line 643) +-* BFD_RELOC_NS32K_DISP_8: howto manager. (line 638) +-* BFD_RELOC_NS32K_DISP_8_PCREL: howto manager. (line 641) +-* BFD_RELOC_NS32K_IMM_16: howto manager. (line 633) +-* BFD_RELOC_NS32K_IMM_16_PCREL: howto manager. (line 636) +-* BFD_RELOC_NS32K_IMM_32: howto manager. (line 634) +-* BFD_RELOC_NS32K_IMM_32_PCREL: howto manager. (line 637) +-* BFD_RELOC_NS32K_IMM_8: howto manager. (line 632) +-* BFD_RELOC_NS32K_IMM_8_PCREL: howto manager. (line 635) +-* BFD_RELOC_OPENRISC_ABS_26: howto manager. (line 2398) +-* BFD_RELOC_OPENRISC_REL_26: howto manager. (line 2399) +-* BFD_RELOC_PDP11_DISP_6_PCREL: howto manager. (line 647) +-* BFD_RELOC_PDP11_DISP_8_PCREL: howto manager. (line 646) +-* BFD_RELOC_PJ_CODE_DIR16: howto manager. (line 652) +-* BFD_RELOC_PJ_CODE_DIR32: howto manager. (line 653) +-* BFD_RELOC_PJ_CODE_HI16: howto manager. (line 650) +-* BFD_RELOC_PJ_CODE_LO16: howto manager. (line 651) +-* BFD_RELOC_PJ_CODE_REL16: howto manager. (line 654) +-* BFD_RELOC_PJ_CODE_REL32: howto manager. (line 655) +-* BFD_RELOC_PPC64_ADDR16_DS: howto manager. (line 717) +-* BFD_RELOC_PPC64_ADDR16_HIGH: howto manager. (line 728) +-* BFD_RELOC_PPC64_ADDR16_HIGHA: howto manager. (line 729) +-* BFD_RELOC_PPC64_ADDR16_LO_DS: howto manager. (line 718) +-* BFD_RELOC_PPC64_DTPREL16_DS: howto manager. (line 768) +-* BFD_RELOC_PPC64_DTPREL16_HIGH: howto manager. (line 776) +-* BFD_RELOC_PPC64_DTPREL16_HIGHA: howto manager. (line 777) +-* BFD_RELOC_PPC64_DTPREL16_HIGHER: howto manager. (line 770) +-* BFD_RELOC_PPC64_DTPREL16_HIGHERA: howto manager. (line 771) +-* BFD_RELOC_PPC64_DTPREL16_HIGHEST: howto manager. (line 772) +-* BFD_RELOC_PPC64_DTPREL16_HIGHESTA: howto manager. (line 773) +-* BFD_RELOC_PPC64_DTPREL16_LO_DS: howto manager. (line 769) +-* BFD_RELOC_PPC64_GOT16_DS: howto manager. (line 719) +-* BFD_RELOC_PPC64_GOT16_LO_DS: howto manager. (line 720) +-* BFD_RELOC_PPC64_HIGHER: howto manager. (line 705) +-* BFD_RELOC_PPC64_HIGHER_S: howto manager. (line 706) +-* BFD_RELOC_PPC64_HIGHEST: howto manager. (line 707) +-* BFD_RELOC_PPC64_HIGHEST_S: howto manager. (line 708) +-* BFD_RELOC_PPC64_PLT16_LO_DS: howto manager. (line 721) +-* BFD_RELOC_PPC64_PLTGOT16: howto manager. (line 713) +-* BFD_RELOC_PPC64_PLTGOT16_DS: howto manager. (line 726) +-* BFD_RELOC_PPC64_PLTGOT16_HA: howto manager. (line 716) +-* BFD_RELOC_PPC64_PLTGOT16_HI: howto manager. (line 715) +-* BFD_RELOC_PPC64_PLTGOT16_LO: howto manager. (line 714) +-* BFD_RELOC_PPC64_PLTGOT16_LO_DS: howto manager. (line 727) +-* BFD_RELOC_PPC64_SECTOFF_DS: howto manager. (line 722) +-* BFD_RELOC_PPC64_SECTOFF_LO_DS: howto manager. (line 723) +-* BFD_RELOC_PPC64_TOC: howto manager. (line 712) +-* BFD_RELOC_PPC64_TOC16_DS: howto manager. (line 724) +-* BFD_RELOC_PPC64_TOC16_HA: howto manager. (line 711) +-* BFD_RELOC_PPC64_TOC16_HI: howto manager. (line 710) +-* BFD_RELOC_PPC64_TOC16_LO: howto manager. (line 709) +-* BFD_RELOC_PPC64_TOC16_LO_DS: howto manager. (line 725) +-* BFD_RELOC_PPC64_TPREL16_DS: howto manager. (line 762) +-* BFD_RELOC_PPC64_TPREL16_HIGH: howto manager. (line 774) +-* BFD_RELOC_PPC64_TPREL16_HIGHA: howto manager. (line 775) +-* BFD_RELOC_PPC64_TPREL16_HIGHER: howto manager. (line 764) +-* BFD_RELOC_PPC64_TPREL16_HIGHERA: howto manager. (line 765) +-* BFD_RELOC_PPC64_TPREL16_HIGHEST: howto manager. (line 766) +-* BFD_RELOC_PPC64_TPREL16_HIGHESTA: howto manager. (line 767) +-* BFD_RELOC_PPC64_TPREL16_LO_DS: howto manager. (line 763) +-* BFD_RELOC_PPC_B16: howto manager. (line 661) +-* BFD_RELOC_PPC_B16_BRNTAKEN: howto manager. (line 663) +-* BFD_RELOC_PPC_B16_BRTAKEN: howto manager. (line 662) +-* BFD_RELOC_PPC_B26: howto manager. (line 658) +-* BFD_RELOC_PPC_BA16: howto manager. (line 664) +-* BFD_RELOC_PPC_BA16_BRNTAKEN: howto manager. (line 666) +-* BFD_RELOC_PPC_BA16_BRTAKEN: howto manager. (line 665) +-* BFD_RELOC_PPC_BA26: howto manager. (line 659) +-* BFD_RELOC_PPC_COPY: howto manager. (line 667) +-* BFD_RELOC_PPC_DTPMOD: howto manager. (line 735) +-* BFD_RELOC_PPC_DTPREL: howto manager. (line 745) +-* BFD_RELOC_PPC_DTPREL16: howto manager. (line 741) +-* BFD_RELOC_PPC_DTPREL16_HA: howto manager. (line 744) +-* BFD_RELOC_PPC_DTPREL16_HI: howto manager. (line 743) +-* BFD_RELOC_PPC_DTPREL16_LO: howto manager. (line 742) +-* BFD_RELOC_PPC_EMB_BIT_FLD: howto manager. (line 686) +-* BFD_RELOC_PPC_EMB_MRKREF: howto manager. (line 681) +-* BFD_RELOC_PPC_EMB_NADDR16: howto manager. (line 673) +-* BFD_RELOC_PPC_EMB_NADDR16_HA: howto manager. (line 676) +-* BFD_RELOC_PPC_EMB_NADDR16_HI: howto manager. (line 675) +-* BFD_RELOC_PPC_EMB_NADDR16_LO: howto manager. (line 674) +-* BFD_RELOC_PPC_EMB_NADDR32: howto manager. (line 672) +-* BFD_RELOC_PPC_EMB_RELSDA: howto manager. (line 687) +-* BFD_RELOC_PPC_EMB_RELSEC16: howto manager. (line 682) +-* BFD_RELOC_PPC_EMB_RELST_HA: howto manager. (line 685) +-* BFD_RELOC_PPC_EMB_RELST_HI: howto manager. (line 684) +-* BFD_RELOC_PPC_EMB_RELST_LO: howto manager. (line 683) +-* BFD_RELOC_PPC_EMB_SDA21: howto manager. (line 680) +-* BFD_RELOC_PPC_EMB_SDA2I16: howto manager. (line 678) +-* BFD_RELOC_PPC_EMB_SDA2REL: howto manager. (line 679) +-* BFD_RELOC_PPC_EMB_SDAI16: howto manager. (line 677) +-* BFD_RELOC_PPC_GLOB_DAT: howto manager. (line 668) +-* BFD_RELOC_PPC_GOT_DTPREL16: howto manager. (line 758) +-* BFD_RELOC_PPC_GOT_DTPREL16_HA: howto manager. (line 761) +-* BFD_RELOC_PPC_GOT_DTPREL16_HI: howto manager. (line 760) +-* BFD_RELOC_PPC_GOT_DTPREL16_LO: howto manager. (line 759) +-* BFD_RELOC_PPC_GOT_TLSGD16: howto manager. (line 746) +-* BFD_RELOC_PPC_GOT_TLSGD16_HA: howto manager. (line 749) +-* BFD_RELOC_PPC_GOT_TLSGD16_HI: howto manager. (line 748) +-* BFD_RELOC_PPC_GOT_TLSGD16_LO: howto manager. (line 747) +-* BFD_RELOC_PPC_GOT_TLSLD16: howto manager. (line 750) +-* BFD_RELOC_PPC_GOT_TLSLD16_HA: howto manager. (line 753) +-* BFD_RELOC_PPC_GOT_TLSLD16_HI: howto manager. (line 752) +-* BFD_RELOC_PPC_GOT_TLSLD16_LO: howto manager. (line 751) +-* BFD_RELOC_PPC_GOT_TPREL16: howto manager. (line 754) +-* BFD_RELOC_PPC_GOT_TPREL16_HA: howto manager. (line 757) +-* BFD_RELOC_PPC_GOT_TPREL16_HI: howto manager. (line 756) +-* BFD_RELOC_PPC_GOT_TPREL16_LO: howto manager. (line 755) +-* BFD_RELOC_PPC_JMP_SLOT: howto manager. (line 669) +-* BFD_RELOC_PPC_LOCAL24PC: howto manager. (line 671) +-* BFD_RELOC_PPC_RELATIVE: howto manager. (line 670) +-* BFD_RELOC_PPC_TLS: howto manager. (line 732) +-* BFD_RELOC_PPC_TLSGD: howto manager. (line 733) +-* BFD_RELOC_PPC_TLSLD: howto manager. (line 734) +-* BFD_RELOC_PPC_TOC16: howto manager. (line 660) +-* BFD_RELOC_PPC_TPREL: howto manager. (line 740) +-* BFD_RELOC_PPC_TPREL16: howto manager. (line 736) +-* BFD_RELOC_PPC_TPREL16_HA: howto manager. (line 739) +-* BFD_RELOC_PPC_TPREL16_HI: howto manager. (line 738) +-* BFD_RELOC_PPC_TPREL16_LO: howto manager. (line 737) +-* BFD_RELOC_PPC_VLE_HA16A: howto manager. (line 695) +-* BFD_RELOC_PPC_VLE_HA16D: howto manager. (line 696) +-* BFD_RELOC_PPC_VLE_HI16A: howto manager. (line 693) +-* BFD_RELOC_PPC_VLE_HI16D: howto manager. (line 694) +-* BFD_RELOC_PPC_VLE_LO16A: howto manager. (line 691) +-* BFD_RELOC_PPC_VLE_LO16D: howto manager. (line 692) +-* BFD_RELOC_PPC_VLE_REL15: howto manager. (line 689) +-* BFD_RELOC_PPC_VLE_REL24: howto manager. (line 690) +-* BFD_RELOC_PPC_VLE_REL8: howto manager. (line 688) +-* BFD_RELOC_PPC_VLE_SDA21: howto manager. (line 697) +-* BFD_RELOC_PPC_VLE_SDA21_LO: howto manager. (line 698) +-* BFD_RELOC_PPC_VLE_SDAREL_HA16A: howto manager. (line 703) +-* BFD_RELOC_PPC_VLE_SDAREL_HA16D: howto manager. (line 704) +-* BFD_RELOC_PPC_VLE_SDAREL_HI16A: howto manager. (line 701) +-* BFD_RELOC_PPC_VLE_SDAREL_HI16D: howto manager. (line 702) +-* BFD_RELOC_PPC_VLE_SDAREL_LO16A: howto manager. (line 699) +-* BFD_RELOC_PPC_VLE_SDAREL_LO16D: howto manager. (line 700) +-* BFD_RELOC_RELC: howto manager. (line 2416) +-* BFD_RELOC_RL78_16_OP: howto manager. (line 1759) +-* BFD_RELOC_RL78_16U: howto manager. (line 1763) +-* BFD_RELOC_RL78_24_OP: howto manager. (line 1760) +-* BFD_RELOC_RL78_24U: howto manager. (line 1764) +-* BFD_RELOC_RL78_32_OP: howto manager. (line 1761) +-* BFD_RELOC_RL78_8U: howto manager. (line 1762) +-* BFD_RELOC_RL78_ABS16: howto manager. (line 1776) +-* BFD_RELOC_RL78_ABS16_REV: howto manager. (line 1777) +-* BFD_RELOC_RL78_ABS16U: howto manager. (line 1780) +-* BFD_RELOC_RL78_ABS16UL: howto manager. (line 1782) +-* BFD_RELOC_RL78_ABS16UW: howto manager. (line 1781) +-* BFD_RELOC_RL78_ABS32: howto manager. (line 1778) +-* BFD_RELOC_RL78_ABS32_REV: howto manager. (line 1779) +-* BFD_RELOC_RL78_ABS8: howto manager. (line 1775) +-* BFD_RELOC_RL78_CODE: howto manager. (line 1787) +-* BFD_RELOC_RL78_DIFF: howto manager. (line 1766) +-* BFD_RELOC_RL78_DIR3U_PCREL: howto manager. (line 1765) +-* BFD_RELOC_RL78_GPRELB: howto manager. (line 1767) +-* BFD_RELOC_RL78_GPRELL: howto manager. (line 1769) +-* BFD_RELOC_RL78_GPRELW: howto manager. (line 1768) +-* BFD_RELOC_RL78_HI16: howto manager. (line 1784) +-* BFD_RELOC_RL78_HI8: howto manager. (line 1785) +-* BFD_RELOC_RL78_LO16: howto manager. (line 1786) +-* BFD_RELOC_RL78_NEG16: howto manager. (line 1756) +-* BFD_RELOC_RL78_NEG24: howto manager. (line 1757) +-* BFD_RELOC_RL78_NEG32: howto manager. (line 1758) +-* BFD_RELOC_RL78_NEG8: howto manager. (line 1755) +-* BFD_RELOC_RL78_OP_AND: howto manager. (line 1773) +-* BFD_RELOC_RL78_OP_NEG: howto manager. (line 1772) +-* BFD_RELOC_RL78_OP_SHRA: howto manager. (line 1774) +-* BFD_RELOC_RL78_OP_SUBTRACT: howto manager. (line 1771) +-* BFD_RELOC_RL78_RELAX: howto manager. (line 1783) +-* BFD_RELOC_RL78_SYM: howto manager. (line 1770) +-* BFD_RELOC_RVA: howto manager. (line 104) +-* BFD_RELOC_RX_16_OP: howto manager. (line 1794) +-* BFD_RELOC_RX_16U: howto manager. (line 1798) +-* BFD_RELOC_RX_24_OP: howto manager. (line 1795) +-* BFD_RELOC_RX_24U: howto manager. (line 1799) +-* BFD_RELOC_RX_32_OP: howto manager. (line 1796) +-* BFD_RELOC_RX_8U: howto manager. (line 1797) +-* BFD_RELOC_RX_ABS16: howto manager. (line 1809) +-* BFD_RELOC_RX_ABS16_REV: howto manager. (line 1810) +-* BFD_RELOC_RX_ABS16U: howto manager. (line 1813) +-* BFD_RELOC_RX_ABS16UL: howto manager. (line 1815) +-* BFD_RELOC_RX_ABS16UW: howto manager. (line 1814) +-* BFD_RELOC_RX_ABS32: howto manager. (line 1811) +-* BFD_RELOC_RX_ABS32_REV: howto manager. (line 1812) +-* BFD_RELOC_RX_ABS8: howto manager. (line 1808) +-* BFD_RELOC_RX_DIFF: howto manager. (line 1801) +-* BFD_RELOC_RX_DIR3U_PCREL: howto manager. (line 1800) +-* BFD_RELOC_RX_GPRELB: howto manager. (line 1802) +-* BFD_RELOC_RX_GPRELL: howto manager. (line 1804) +-* BFD_RELOC_RX_GPRELW: howto manager. (line 1803) +-* BFD_RELOC_RX_NEG16: howto manager. (line 1791) +-* BFD_RELOC_RX_NEG24: howto manager. (line 1792) +-* BFD_RELOC_RX_NEG32: howto manager. (line 1793) +-* BFD_RELOC_RX_NEG8: howto manager. (line 1790) +-* BFD_RELOC_RX_OP_NEG: howto manager. (line 1807) +-* BFD_RELOC_RX_OP_SUBTRACT: howto manager. (line 1806) +-* BFD_RELOC_RX_RELAX: howto manager. (line 1816) +-* BFD_RELOC_RX_SYM: howto manager. (line 1805) +-* BFD_RELOC_SCORE16_BRANCH: howto manager. (line 1959) +-* BFD_RELOC_SCORE16_JMP: howto manager. (line 1956) +-* BFD_RELOC_SCORE_BCMP: howto manager. (line 1962) +-* BFD_RELOC_SCORE_BRANCH: howto manager. (line 1947) +-* BFD_RELOC_SCORE_CALL15: howto manager. (line 1967) +-* BFD_RELOC_SCORE_DUMMY2: howto manager. (line 1943) +-* BFD_RELOC_SCORE_DUMMY_HI16: howto manager. (line 1968) +-* BFD_RELOC_SCORE_GOT15: howto manager. (line 1965) +-* BFD_RELOC_SCORE_GOT_LO16: howto manager. (line 1966) +-* BFD_RELOC_SCORE_GPREL15: howto manager. (line 1940) +-* BFD_RELOC_SCORE_IMM30: howto manager. (line 1950) +-* BFD_RELOC_SCORE_IMM32: howto manager. (line 1953) +-* BFD_RELOC_SCORE_JMP: howto manager. (line 1944) +-* BFD_RELOC_SH_ALIGN: howto manager. (line 971) +-* BFD_RELOC_SH_CODE: howto manager. (line 972) +-* BFD_RELOC_SH_COPY: howto manager. (line 977) +-* BFD_RELOC_SH_COPY64: howto manager. (line 1002) +-* BFD_RELOC_SH_COUNT: howto manager. (line 970) +-* BFD_RELOC_SH_DATA: howto manager. (line 973) +-* BFD_RELOC_SH_DISP12: howto manager. (line 953) +-* BFD_RELOC_SH_DISP12BY2: howto manager. (line 954) +-* BFD_RELOC_SH_DISP12BY4: howto manager. (line 955) +-* BFD_RELOC_SH_DISP12BY8: howto manager. (line 956) +-* BFD_RELOC_SH_DISP20: howto manager. (line 957) +-* BFD_RELOC_SH_DISP20BY8: howto manager. (line 958) +-* BFD_RELOC_SH_FUNCDESC: howto manager. (line 1045) +-* BFD_RELOC_SH_GLOB_DAT: howto manager. (line 978) +-* BFD_RELOC_SH_GLOB_DAT64: howto manager. (line 1003) +-* BFD_RELOC_SH_GOT10BY4: howto manager. (line 1006) +-* BFD_RELOC_SH_GOT10BY8: howto manager. (line 1007) +-* BFD_RELOC_SH_GOT20: howto manager. (line 1039) +-* BFD_RELOC_SH_GOT_HI16: howto manager. (line 985) +-* BFD_RELOC_SH_GOT_LOW16: howto manager. (line 982) +-* BFD_RELOC_SH_GOT_MEDHI16: howto manager. (line 984) +-* BFD_RELOC_SH_GOT_MEDLOW16: howto manager. (line 983) +-* BFD_RELOC_SH_GOTFUNCDESC: howto manager. (line 1041) +-* BFD_RELOC_SH_GOTFUNCDESC20: howto manager. (line 1042) +-* BFD_RELOC_SH_GOTOFF20: howto manager. (line 1040) +-* BFD_RELOC_SH_GOTOFF_HI16: howto manager. (line 997) +-* BFD_RELOC_SH_GOTOFF_LOW16: howto manager. (line 994) +-* BFD_RELOC_SH_GOTOFF_MEDHI16: howto manager. (line 996) +-* BFD_RELOC_SH_GOTOFF_MEDLOW16: howto manager. (line 995) +-* BFD_RELOC_SH_GOTOFFFUNCDESC: howto manager. (line 1043) +-* BFD_RELOC_SH_GOTOFFFUNCDESC20: howto manager. (line 1044) +-* BFD_RELOC_SH_GOTPC: howto manager. (line 981) +-* BFD_RELOC_SH_GOTPC_HI16: howto manager. (line 1001) +-* BFD_RELOC_SH_GOTPC_LOW16: howto manager. (line 998) +-* BFD_RELOC_SH_GOTPC_MEDHI16: howto manager. (line 1000) +-* BFD_RELOC_SH_GOTPC_MEDLOW16: howto manager. (line 999) +-* BFD_RELOC_SH_GOTPLT10BY4: howto manager. (line 1008) +-* BFD_RELOC_SH_GOTPLT10BY8: howto manager. (line 1009) +-* BFD_RELOC_SH_GOTPLT32: howto manager. (line 1010) +-* BFD_RELOC_SH_GOTPLT_HI16: howto manager. (line 989) +-* BFD_RELOC_SH_GOTPLT_LOW16: howto manager. (line 986) +-* BFD_RELOC_SH_GOTPLT_MEDHI16: howto manager. (line 988) +-* BFD_RELOC_SH_GOTPLT_MEDLOW16: howto manager. (line 987) +-* BFD_RELOC_SH_IMM3: howto manager. (line 951) +-* BFD_RELOC_SH_IMM3U: howto manager. (line 952) +-* BFD_RELOC_SH_IMM4: howto manager. (line 959) +-* BFD_RELOC_SH_IMM4BY2: howto manager. (line 960) +-* BFD_RELOC_SH_IMM4BY4: howto manager. (line 961) +-* BFD_RELOC_SH_IMM8: howto manager. (line 962) +-* BFD_RELOC_SH_IMM8BY2: howto manager. (line 963) +-* BFD_RELOC_SH_IMM8BY4: howto manager. (line 964) +-* BFD_RELOC_SH_IMM_HI16: howto manager. (line 1028) +-* BFD_RELOC_SH_IMM_HI16_PCREL: howto manager. (line 1029) +-* BFD_RELOC_SH_IMM_LOW16: howto manager. (line 1022) +-* BFD_RELOC_SH_IMM_LOW16_PCREL: howto manager. (line 1023) +-* BFD_RELOC_SH_IMM_MEDHI16: howto manager. (line 1026) +-* BFD_RELOC_SH_IMM_MEDHI16_PCREL: howto manager. (line 1027) +-* BFD_RELOC_SH_IMM_MEDLOW16: howto manager. (line 1024) +-* BFD_RELOC_SH_IMM_MEDLOW16_PCREL: howto manager. (line 1025) +-* BFD_RELOC_SH_IMMS10: howto manager. (line 1016) +-* BFD_RELOC_SH_IMMS10BY2: howto manager. (line 1017) +-* BFD_RELOC_SH_IMMS10BY4: howto manager. (line 1018) +-* BFD_RELOC_SH_IMMS10BY8: howto manager. (line 1019) +-* BFD_RELOC_SH_IMMS16: howto manager. (line 1020) +-* BFD_RELOC_SH_IMMS6: howto manager. (line 1013) +-* BFD_RELOC_SH_IMMS6BY32: howto manager. (line 1014) +-* BFD_RELOC_SH_IMMU16: howto manager. (line 1021) +-* BFD_RELOC_SH_IMMU5: howto manager. (line 1012) +-* BFD_RELOC_SH_IMMU6: howto manager. (line 1015) +-* BFD_RELOC_SH_JMP_SLOT: howto manager. (line 979) +-* BFD_RELOC_SH_JMP_SLOT64: howto manager. (line 1004) +-* BFD_RELOC_SH_LABEL: howto manager. (line 974) +-* BFD_RELOC_SH_LOOP_END: howto manager. (line 976) +-* BFD_RELOC_SH_LOOP_START: howto manager. (line 975) +-* BFD_RELOC_SH_PCDISP12BY2: howto manager. (line 950) +-* BFD_RELOC_SH_PCDISP8BY2: howto manager. (line 949) +-* BFD_RELOC_SH_PCRELIMM8BY2: howto manager. (line 965) +-* BFD_RELOC_SH_PCRELIMM8BY4: howto manager. (line 966) +-* BFD_RELOC_SH_PLT_HI16: howto manager. (line 993) +-* BFD_RELOC_SH_PLT_LOW16: howto manager. (line 990) +-* BFD_RELOC_SH_PLT_MEDHI16: howto manager. (line 992) +-* BFD_RELOC_SH_PLT_MEDLOW16: howto manager. (line 991) +-* BFD_RELOC_SH_PT_16: howto manager. (line 1030) +-* BFD_RELOC_SH_RELATIVE: howto manager. (line 980) +-* BFD_RELOC_SH_RELATIVE64: howto manager. (line 1005) +-* BFD_RELOC_SH_SHMEDIA_CODE: howto manager. (line 1011) +-* BFD_RELOC_SH_SWITCH16: howto manager. (line 967) +-* BFD_RELOC_SH_SWITCH32: howto manager. (line 968) +-* BFD_RELOC_SH_TLS_DTPMOD32: howto manager. (line 1036) +-* BFD_RELOC_SH_TLS_DTPOFF32: howto manager. (line 1037) +-* BFD_RELOC_SH_TLS_GD_32: howto manager. (line 1031) +-* BFD_RELOC_SH_TLS_IE_32: howto manager. (line 1034) +-* BFD_RELOC_SH_TLS_LD_32: howto manager. (line 1032) +-* BFD_RELOC_SH_TLS_LDO_32: howto manager. (line 1033) +-* BFD_RELOC_SH_TLS_LE_32: howto manager. (line 1035) +-* BFD_RELOC_SH_TLS_TPOFF32: howto manager. (line 1038) +-* BFD_RELOC_SH_USES: howto manager. (line 969) +-* BFD_RELOC_SIZE32: howto manager. (line 74) +-* BFD_RELOC_SIZE64: howto manager. (line 75) +-* BFD_RELOC_SPARC13: howto manager. (line 138) +-* BFD_RELOC_SPARC22: howto manager. (line 137) +-* BFD_RELOC_SPARC_10: howto manager. (line 167) +-* BFD_RELOC_SPARC_11: howto manager. (line 168) +-* BFD_RELOC_SPARC_5: howto manager. (line 180) +-* BFD_RELOC_SPARC_6: howto manager. (line 179) +-* BFD_RELOC_SPARC_64: howto manager. (line 166) +-* BFD_RELOC_SPARC_7: howto manager. (line 178) +-* BFD_RELOC_SPARC_BASE13: howto manager. (line 162) +-* BFD_RELOC_SPARC_BASE22: howto manager. (line 163) +-* BFD_RELOC_SPARC_COPY: howto manager. (line 145) +-* BFD_RELOC_SPARC_DISP64: howto manager. (line 181) +-* BFD_RELOC_SPARC_GLOB_DAT: howto manager. (line 146) +-* BFD_RELOC_SPARC_GOT10: howto manager. (line 139) +-* BFD_RELOC_SPARC_GOT13: howto manager. (line 140) +-* BFD_RELOC_SPARC_GOT22: howto manager. (line 141) +-* BFD_RELOC_SPARC_GOTDATA_HIX22: howto manager. (line 152) +-* BFD_RELOC_SPARC_GOTDATA_LOX10: howto manager. (line 153) +-* BFD_RELOC_SPARC_GOTDATA_OP: howto manager. (line 156) +-* BFD_RELOC_SPARC_GOTDATA_OP_HIX22: howto manager. (line 154) +-* BFD_RELOC_SPARC_GOTDATA_OP_LOX10: howto manager. (line 155) +-* BFD_RELOC_SPARC_H34: howto manager. (line 190) +-* BFD_RELOC_SPARC_H44: howto manager. (line 186) +-* BFD_RELOC_SPARC_HH22: howto manager. (line 170) +-* BFD_RELOC_SPARC_HIX22: howto manager. (line 184) +-* BFD_RELOC_SPARC_HM10: howto manager. (line 171) +-* BFD_RELOC_SPARC_IRELATIVE: howto manager. (line 158) +-* BFD_RELOC_SPARC_JMP_IREL: howto manager. (line 157) +-* BFD_RELOC_SPARC_JMP_SLOT: howto manager. (line 147) +-* BFD_RELOC_SPARC_L44: howto manager. (line 188) +-* BFD_RELOC_SPARC_LM22: howto manager. (line 172) +-* BFD_RELOC_SPARC_LOX10: howto manager. (line 185) +-* BFD_RELOC_SPARC_M44: howto manager. (line 187) +-* BFD_RELOC_SPARC_OLO10: howto manager. (line 169) +-* BFD_RELOC_SPARC_PC10: howto manager. (line 142) +-* BFD_RELOC_SPARC_PC22: howto manager. (line 143) +-* BFD_RELOC_SPARC_PC_HH22: howto manager. (line 173) +-* BFD_RELOC_SPARC_PC_HM10: howto manager. (line 174) +-* BFD_RELOC_SPARC_PC_LM22: howto manager. (line 175) +-* BFD_RELOC_SPARC_PLT32: howto manager. (line 182) +-* BFD_RELOC_SPARC_PLT64: howto manager. (line 183) +-* BFD_RELOC_SPARC_REGISTER: howto manager. (line 189) +-* BFD_RELOC_SPARC_RELATIVE: howto manager. (line 148) +-* BFD_RELOC_SPARC_REV32: howto manager. (line 196) +-* BFD_RELOC_SPARC_SIZE32: howto manager. (line 191) +-* BFD_RELOC_SPARC_SIZE64: howto manager. (line 192) +-* BFD_RELOC_SPARC_TLS_DTPMOD32: howto manager. (line 217) +-* BFD_RELOC_SPARC_TLS_DTPMOD64: howto manager. (line 218) +-* BFD_RELOC_SPARC_TLS_DTPOFF32: howto manager. (line 219) +-* BFD_RELOC_SPARC_TLS_DTPOFF64: howto manager. (line 220) +-* BFD_RELOC_SPARC_TLS_GD_ADD: howto manager. (line 201) +-* BFD_RELOC_SPARC_TLS_GD_CALL: howto manager. (line 202) +-* BFD_RELOC_SPARC_TLS_GD_HI22: howto manager. (line 199) +-* BFD_RELOC_SPARC_TLS_GD_LO10: howto manager. (line 200) +-* BFD_RELOC_SPARC_TLS_IE_ADD: howto manager. (line 214) +-* BFD_RELOC_SPARC_TLS_IE_HI22: howto manager. (line 210) +-* BFD_RELOC_SPARC_TLS_IE_LD: howto manager. (line 212) +-* BFD_RELOC_SPARC_TLS_IE_LDX: howto manager. (line 213) +-* BFD_RELOC_SPARC_TLS_IE_LO10: howto manager. (line 211) +-* BFD_RELOC_SPARC_TLS_LDM_ADD: howto manager. (line 205) +-* BFD_RELOC_SPARC_TLS_LDM_CALL: howto manager. (line 206) +-* BFD_RELOC_SPARC_TLS_LDM_HI22: howto manager. (line 203) +-* BFD_RELOC_SPARC_TLS_LDM_LO10: howto manager. (line 204) +-* BFD_RELOC_SPARC_TLS_LDO_ADD: howto manager. (line 209) +-* BFD_RELOC_SPARC_TLS_LDO_HIX22: howto manager. (line 207) +-* BFD_RELOC_SPARC_TLS_LDO_LOX10: howto manager. (line 208) +-* BFD_RELOC_SPARC_TLS_LE_HIX22: howto manager. (line 215) +-* BFD_RELOC_SPARC_TLS_LE_LOX10: howto manager. (line 216) +-* BFD_RELOC_SPARC_TLS_TPOFF32: howto manager. (line 221) +-* BFD_RELOC_SPARC_TLS_TPOFF64: howto manager. (line 222) +-* BFD_RELOC_SPARC_UA16: howto manager. (line 149) +-* BFD_RELOC_SPARC_UA32: howto manager. (line 150) +-* BFD_RELOC_SPARC_UA64: howto manager. (line 151) +-* BFD_RELOC_SPARC_WDISP10: howto manager. (line 193) +-* BFD_RELOC_SPARC_WDISP16: howto manager. (line 176) +-* BFD_RELOC_SPARC_WDISP19: howto manager. (line 177) +-* BFD_RELOC_SPARC_WDISP22: howto manager. (line 136) +-* BFD_RELOC_SPARC_WPLT30: howto manager. (line 144) +-* BFD_RELOC_SPU_ADD_PIC: howto manager. (line 239) +-* BFD_RELOC_SPU_HI16: howto manager. (line 236) +-* BFD_RELOC_SPU_IMM10: howto manager. (line 227) +-* BFD_RELOC_SPU_IMM10W: howto manager. (line 228) +-* BFD_RELOC_SPU_IMM16: howto manager. (line 229) +-* BFD_RELOC_SPU_IMM16W: howto manager. (line 230) +-* BFD_RELOC_SPU_IMM18: howto manager. (line 231) +-* BFD_RELOC_SPU_IMM7: howto manager. (line 225) +-* BFD_RELOC_SPU_IMM8: howto manager. (line 226) +-* BFD_RELOC_SPU_LO16: howto manager. (line 235) +-* BFD_RELOC_SPU_PCREL16: howto manager. (line 234) +-* BFD_RELOC_SPU_PCREL9a: howto manager. (line 232) +-* BFD_RELOC_SPU_PCREL9b: howto manager. (line 233) +-* BFD_RELOC_SPU_PPU32: howto manager. (line 237) +-* BFD_RELOC_SPU_PPU64: howto manager. (line 238) +-* BFD_RELOC_THUMB_PCREL_BLX: howto manager. (line 798) +-* BFD_RELOC_THUMB_PCREL_BRANCH12: howto manager. (line 812) +-* BFD_RELOC_THUMB_PCREL_BRANCH20: howto manager. (line 813) +-* BFD_RELOC_THUMB_PCREL_BRANCH23: howto manager. (line 814) +-* BFD_RELOC_THUMB_PCREL_BRANCH25: howto manager. (line 815) +-* BFD_RELOC_THUMB_PCREL_BRANCH7: howto manager. (line 810) +-* BFD_RELOC_THUMB_PCREL_BRANCH9: howto manager. (line 811) +-* BFD_RELOC_TIC30_LDP: howto manager. (line 1430) +-* BFD_RELOC_TIC54X_16_OF_23: howto manager. (line 1448) +-* BFD_RELOC_TIC54X_23: howto manager. (line 1445) +-* BFD_RELOC_TIC54X_MS7_OF_23: howto manager. (line 1453) +-* BFD_RELOC_TIC54X_PARTLS7: howto manager. (line 1435) +-* BFD_RELOC_TIC54X_PARTMS9: howto manager. (line 1440) +-* BFD_RELOC_TILEGX_BROFF_X1: howto manager. (line 3132) +-* BFD_RELOC_TILEGX_COPY: howto manager. (line 3128) +-* BFD_RELOC_TILEGX_DEST_IMM8_X1: howto manager. (line 3139) +-* BFD_RELOC_TILEGX_GLOB_DAT: howto manager. (line 3129) +-* BFD_RELOC_TILEGX_HW0: howto manager. (line 3121) +-* BFD_RELOC_TILEGX_HW0_LAST: howto manager. (line 3125) +-* BFD_RELOC_TILEGX_HW1: howto manager. (line 3122) +-* BFD_RELOC_TILEGX_HW1_LAST: howto manager. (line 3126) +-* BFD_RELOC_TILEGX_HW2: howto manager. (line 3123) +-* BFD_RELOC_TILEGX_HW2_LAST: howto manager. (line 3127) +-* BFD_RELOC_TILEGX_HW3: howto manager. (line 3124) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0: howto manager. (line 3148) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT: howto manager. (line 3176) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST: howto manager. (line 3156) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT: howto manager. (line 3184) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL: howto manager. (line 3170) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: howto manager. +- (line 3204) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: howto manager. (line 3198) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: howto manager. (line 3210) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: howto manager. (line 3194) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL: howto manager. (line 3162) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL: howto manager. (line 3178) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD: howto manager. (line 3190) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE: howto manager. (line 3202) +-* BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE: howto manager. (line 3192) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1: howto manager. (line 3150) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST: howto manager. (line 3158) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT: howto manager. (line 3186) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL: howto manager. (line 3172) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: howto manager. +- (line 3206) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: howto manager. (line 3200) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: howto manager. (line 3212) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: howto manager. (line 3196) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL: howto manager. (line 3164) +-* BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL: howto manager. (line 3180) +-* BFD_RELOC_TILEGX_IMM16_X0_HW2: howto manager. (line 3152) +-* BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST: howto manager. (line 3160) +-* BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL: howto manager. (line 3174) +-* BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: howto manager. +- (line 3208) +-* BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL: howto manager. (line 3166) +-* BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL: howto manager. (line 3182) +-* BFD_RELOC_TILEGX_IMM16_X0_HW3: howto manager. (line 3154) +-* BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL: howto manager. (line 3168) +-* BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL: howto manager. (line 3188) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0: howto manager. (line 3149) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT: howto manager. (line 3177) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST: howto manager. (line 3157) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT: howto manager. (line 3185) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL: howto manager. (line 3171) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: howto manager. +- (line 3205) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: howto manager. (line 3199) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: howto manager. (line 3211) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: howto manager. (line 3195) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL: howto manager. (line 3163) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL: howto manager. (line 3179) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD: howto manager. (line 3191) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE: howto manager. (line 3203) +-* BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE: howto manager. (line 3193) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1: howto manager. (line 3151) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST: howto manager. (line 3159) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT: howto manager. (line 3187) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL: howto manager. (line 3173) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: howto manager. +- (line 3207) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: howto manager. (line 3201) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: howto manager. (line 3213) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: howto manager. (line 3197) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL: howto manager. (line 3165) +-* BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL: howto manager. (line 3181) +-* BFD_RELOC_TILEGX_IMM16_X1_HW2: howto manager. (line 3153) +-* BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST: howto manager. (line 3161) +-* BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL: howto manager. (line 3175) +-* BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: howto manager. +- (line 3209) +-* BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL: howto manager. (line 3167) +-* BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL: howto manager. (line 3183) +-* BFD_RELOC_TILEGX_IMM16_X1_HW3: howto manager. (line 3155) +-* BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL: howto manager. (line 3169) +-* BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL: howto manager. (line 3189) +-* BFD_RELOC_TILEGX_IMM8_X0: howto manager. (line 3135) +-* BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD: howto manager. (line 3226) +-* BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD: howto manager. (line 3221) +-* BFD_RELOC_TILEGX_IMM8_X1: howto manager. (line 3137) +-* BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD: howto manager. (line 3227) +-* BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD: howto manager. (line 3222) +-* BFD_RELOC_TILEGX_IMM8_Y0: howto manager. (line 3136) +-* BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD: howto manager. (line 3228) +-* BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD: howto manager. (line 3223) +-* BFD_RELOC_TILEGX_IMM8_Y1: howto manager. (line 3138) +-* BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD: howto manager. (line 3229) +-* BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD: howto manager. (line 3224) +-* BFD_RELOC_TILEGX_JMP_SLOT: howto manager. (line 3130) +-* BFD_RELOC_TILEGX_JUMPOFF_X1: howto manager. (line 3133) +-* BFD_RELOC_TILEGX_JUMPOFF_X1_PLT: howto manager. (line 3134) +-* BFD_RELOC_TILEGX_MF_IMM14_X1: howto manager. (line 3141) +-* BFD_RELOC_TILEGX_MMEND_X0: howto manager. (line 3143) +-* BFD_RELOC_TILEGX_MMSTART_X0: howto manager. (line 3142) +-* BFD_RELOC_TILEGX_MT_IMM14_X1: howto manager. (line 3140) +-* BFD_RELOC_TILEGX_RELATIVE: howto manager. (line 3131) +-* BFD_RELOC_TILEGX_SHAMT_X0: howto manager. (line 3144) +-* BFD_RELOC_TILEGX_SHAMT_X1: howto manager. (line 3145) +-* BFD_RELOC_TILEGX_SHAMT_Y0: howto manager. (line 3146) +-* BFD_RELOC_TILEGX_SHAMT_Y1: howto manager. (line 3147) +-* BFD_RELOC_TILEGX_TLS_DTPMOD32: howto manager. (line 3217) +-* BFD_RELOC_TILEGX_TLS_DTPMOD64: howto manager. (line 3214) +-* BFD_RELOC_TILEGX_TLS_DTPOFF32: howto manager. (line 3218) +-* BFD_RELOC_TILEGX_TLS_DTPOFF64: howto manager. (line 3215) +-* BFD_RELOC_TILEGX_TLS_GD_CALL: howto manager. (line 3220) +-* BFD_RELOC_TILEGX_TLS_IE_LOAD: howto manager. (line 3225) +-* BFD_RELOC_TILEGX_TLS_TPOFF32: howto manager. (line 3219) +-* BFD_RELOC_TILEGX_TLS_TPOFF64: howto manager. (line 3216) +-* BFD_RELOC_TILEPRO_BROFF_X1: howto manager. (line 3044) +-* BFD_RELOC_TILEPRO_COPY: howto manager. (line 3040) +-* BFD_RELOC_TILEPRO_DEST_IMM8_X1: howto manager. (line 3051) +-* BFD_RELOC_TILEPRO_GLOB_DAT: howto manager. (line 3041) +-* BFD_RELOC_TILEPRO_IMM16_X0: howto manager. (line 3054) +-* BFD_RELOC_TILEPRO_IMM16_X0_GOT: howto manager. (line 3070) +-* BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA: howto manager. (line 3076) +-* BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI: howto manager. (line 3074) +-* BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO: howto manager. (line 3072) +-* BFD_RELOC_TILEPRO_IMM16_X0_HA: howto manager. (line 3060) +-* BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL: howto manager. (line 3068) +-* BFD_RELOC_TILEPRO_IMM16_X0_HI: howto manager. (line 3058) +-* BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL: howto manager. (line 3066) +-* BFD_RELOC_TILEPRO_IMM16_X0_LO: howto manager. (line 3056) +-* BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL: howto manager. (line 3064) +-* BFD_RELOC_TILEPRO_IMM16_X0_PCREL: howto manager. (line 3062) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD: howto manager. (line 3092) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA: howto manager. (line 3098) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI: howto manager. (line 3096) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO: howto manager. (line 3094) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE: howto manager. (line 3100) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA: howto manager. (line 3106) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI: howto manager. (line 3104) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO: howto manager. (line 3102) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE: howto manager. (line 3111) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA: howto manager. (line 3117) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI: howto manager. (line 3115) +-* BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO: howto manager. (line 3113) +-* BFD_RELOC_TILEPRO_IMM16_X1: howto manager. (line 3055) +-* BFD_RELOC_TILEPRO_IMM16_X1_GOT: howto manager. (line 3071) +-* BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA: howto manager. (line 3077) +-* BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI: howto manager. (line 3075) +-* BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO: howto manager. (line 3073) +-* BFD_RELOC_TILEPRO_IMM16_X1_HA: howto manager. (line 3061) +-* BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL: howto manager. (line 3069) +-* BFD_RELOC_TILEPRO_IMM16_X1_HI: howto manager. (line 3059) +-* BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL: howto manager. (line 3067) +-* BFD_RELOC_TILEPRO_IMM16_X1_LO: howto manager. (line 3057) +-* BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL: howto manager. (line 3065) +-* BFD_RELOC_TILEPRO_IMM16_X1_PCREL: howto manager. (line 3063) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD: howto manager. (line 3093) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA: howto manager. (line 3099) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI: howto manager. (line 3097) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO: howto manager. (line 3095) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE: howto manager. (line 3101) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA: howto manager. (line 3107) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI: howto manager. (line 3105) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO: howto manager. (line 3103) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE: howto manager. (line 3112) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA: howto manager. (line 3118) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI: howto manager. (line 3116) +-* BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO: howto manager. (line 3114) +-* BFD_RELOC_TILEPRO_IMM8_X0: howto manager. (line 3047) +-* BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD: howto manager. (line 3087) +-* BFD_RELOC_TILEPRO_IMM8_X1: howto manager. (line 3049) +-* BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD: howto manager. (line 3088) +-* BFD_RELOC_TILEPRO_IMM8_Y0: howto manager. (line 3048) +-* BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD: howto manager. (line 3089) +-* BFD_RELOC_TILEPRO_IMM8_Y1: howto manager. (line 3050) +-* BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD: howto manager. (line 3090) +-* BFD_RELOC_TILEPRO_JMP_SLOT: howto manager. (line 3042) +-* BFD_RELOC_TILEPRO_JOFFLONG_X1: howto manager. (line 3045) +-* BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT: howto manager. (line 3046) +-* BFD_RELOC_TILEPRO_MF_IMM15_X1: howto manager. (line 3053) +-* BFD_RELOC_TILEPRO_MMEND_X0: howto manager. (line 3079) +-* BFD_RELOC_TILEPRO_MMEND_X1: howto manager. (line 3081) +-* BFD_RELOC_TILEPRO_MMSTART_X0: howto manager. (line 3078) +-* BFD_RELOC_TILEPRO_MMSTART_X1: howto manager. (line 3080) +-* BFD_RELOC_TILEPRO_MT_IMM15_X1: howto manager. (line 3052) +-* BFD_RELOC_TILEPRO_RELATIVE: howto manager. (line 3043) +-* BFD_RELOC_TILEPRO_SHAMT_X0: howto manager. (line 3082) +-* BFD_RELOC_TILEPRO_SHAMT_X1: howto manager. (line 3083) +-* BFD_RELOC_TILEPRO_SHAMT_Y0: howto manager. (line 3084) +-* BFD_RELOC_TILEPRO_SHAMT_Y1: howto manager. (line 3085) +-* BFD_RELOC_TILEPRO_TLS_DTPMOD32: howto manager. (line 3108) +-* BFD_RELOC_TILEPRO_TLS_DTPOFF32: howto manager. (line 3109) +-* BFD_RELOC_TILEPRO_TLS_GD_CALL: howto manager. (line 3086) +-* BFD_RELOC_TILEPRO_TLS_IE_LOAD: howto manager. (line 3091) +-* BFD_RELOC_TILEPRO_TLS_TPOFF32: howto manager. (line 3110) +-* bfd_reloc_type_lookup: howto manager. (line 3255) +-* BFD_RELOC_V850_16_GOT: howto manager. (line 1394) +-* BFD_RELOC_V850_16_GOTOFF: howto manager. (line 1418) +-* BFD_RELOC_V850_16_PCREL: howto manager. (line 1364) +-* BFD_RELOC_V850_16_S1: howto manager. (line 1382) +-* BFD_RELOC_V850_16_SPLIT_OFFSET: howto manager. (line 1379) +-* BFD_RELOC_V850_17_PCREL: howto manager. (line 1367) +-* BFD_RELOC_V850_22_PCREL: howto manager. (line 1299) +-* BFD_RELOC_V850_22_PLT_PCREL: howto manager. (line 1400) +-* BFD_RELOC_V850_23: howto manager. (line 1370) +-* BFD_RELOC_V850_32_ABS: howto manager. (line 1376) +-* BFD_RELOC_V850_32_GOT: howto manager. (line 1397) +-* BFD_RELOC_V850_32_GOTOFF: howto manager. (line 1421) +-* BFD_RELOC_V850_32_GOTPCREL: howto manager. (line 1391) +-* BFD_RELOC_V850_32_PCREL: howto manager. (line 1373) +-* BFD_RELOC_V850_32_PLT_PCREL: howto manager. (line 1403) +-* BFD_RELOC_V850_9_PCREL: howto manager. (line 1296) +-* BFD_RELOC_V850_ALIGN: howto manager. (line 1357) +-* BFD_RELOC_V850_CALLT_15_16_OFFSET: howto manager. (line 1388) +-* BFD_RELOC_V850_CALLT_16_16_OFFSET: howto manager. (line 1348) +-* BFD_RELOC_V850_CALLT_6_7_OFFSET: howto manager. (line 1345) +-* BFD_RELOC_V850_CODE: howto manager. (line 1424) +-* BFD_RELOC_V850_COPY: howto manager. (line 1406) +-* BFD_RELOC_V850_DATA: howto manager. (line 1427) +-* BFD_RELOC_V850_GLOB_DAT: howto manager. (line 1409) +-* BFD_RELOC_V850_JMP_SLOT: howto manager. (line 1412) +-* BFD_RELOC_V850_LO16_S1: howto manager. (line 1385) +-* BFD_RELOC_V850_LO16_SPLIT_OFFSET: howto manager. (line 1360) +-* BFD_RELOC_V850_LONGCALL: howto manager. (line 1351) +-* BFD_RELOC_V850_LONGJUMP: howto manager. (line 1354) +-* BFD_RELOC_V850_RELATIVE: howto manager. (line 1415) +-* BFD_RELOC_V850_SDA_15_16_OFFSET: howto manager. (line 1305) +-* BFD_RELOC_V850_SDA_16_16_OFFSET: howto manager. (line 1302) +-* BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET: howto manager. (line 1337) +-* BFD_RELOC_V850_TDA_16_16_OFFSET: howto manager. (line 1327) +-* BFD_RELOC_V850_TDA_4_4_OFFSET: howto manager. (line 1334) +-* BFD_RELOC_V850_TDA_4_5_OFFSET: howto manager. (line 1330) +-* BFD_RELOC_V850_TDA_6_8_OFFSET: howto manager. (line 1316) +-* BFD_RELOC_V850_TDA_7_7_OFFSET: howto manager. (line 1324) +-* BFD_RELOC_V850_TDA_7_8_OFFSET: howto manager. (line 1320) +-* BFD_RELOC_V850_ZDA_15_16_OFFSET: howto manager. (line 1312) +-* BFD_RELOC_V850_ZDA_16_16_OFFSET: howto manager. (line 1309) +-* BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET: howto manager. (line 1341) +-* BFD_RELOC_VAX_GLOB_DAT: howto manager. (line 2425) +-* BFD_RELOC_VAX_JMP_SLOT: howto manager. (line 2426) +-* BFD_RELOC_VAX_RELATIVE: howto manager. (line 2427) +-* BFD_RELOC_VPE4KMATH_DATA: howto manager. (line 2001) +-* BFD_RELOC_VPE4KMATH_INSN: howto manager. (line 2002) +-* BFD_RELOC_VTABLE_ENTRY: howto manager. (line 2006) +-* BFD_RELOC_VTABLE_INHERIT: howto manager. (line 2005) +-* BFD_RELOC_X86_64_32S: howto manager. (line 608) +-* BFD_RELOC_X86_64_COPY: howto manager. (line 603) +-* BFD_RELOC_X86_64_DTPMOD64: howto manager. (line 609) +-* BFD_RELOC_X86_64_DTPOFF32: howto manager. (line 614) +-* BFD_RELOC_X86_64_DTPOFF64: howto manager. (line 610) +-* BFD_RELOC_X86_64_GLOB_DAT: howto manager. (line 604) +-* BFD_RELOC_X86_64_GOT32: howto manager. (line 601) +-* BFD_RELOC_X86_64_GOT64: howto manager. (line 619) +-* BFD_RELOC_X86_64_GOTOFF64: howto manager. (line 617) +-* BFD_RELOC_X86_64_GOTPC32: howto manager. (line 618) +-* BFD_RELOC_X86_64_GOTPC32_TLSDESC: howto manager. (line 624) +-* BFD_RELOC_X86_64_GOTPC64: howto manager. (line 621) +-* BFD_RELOC_X86_64_GOTPCREL: howto manager. (line 607) +-* BFD_RELOC_X86_64_GOTPCREL64: howto manager. (line 620) +-* BFD_RELOC_X86_64_GOTPLT64: howto manager. (line 622) +-* BFD_RELOC_X86_64_GOTTPOFF: howto manager. (line 615) +-* BFD_RELOC_X86_64_IRELATIVE: howto manager. (line 627) +-* BFD_RELOC_X86_64_JUMP_SLOT: howto manager. (line 605) +-* BFD_RELOC_X86_64_PC32_BND: howto manager. (line 628) +-* BFD_RELOC_X86_64_PLT32: howto manager. (line 602) +-* BFD_RELOC_X86_64_PLT32_BND: howto manager. (line 629) +-* BFD_RELOC_X86_64_PLTOFF64: howto manager. (line 623) +-* BFD_RELOC_X86_64_RELATIVE: howto manager. (line 606) +-* BFD_RELOC_X86_64_TLSDESC: howto manager. (line 626) +-* BFD_RELOC_X86_64_TLSDESC_CALL: howto manager. (line 625) +-* BFD_RELOC_X86_64_TLSGD: howto manager. (line 612) +-* BFD_RELOC_X86_64_TLSLD: howto manager. (line 613) +-* BFD_RELOC_X86_64_TPOFF32: howto manager. (line 616) +-* BFD_RELOC_X86_64_TPOFF64: howto manager. (line 611) +-* BFD_RELOC_XC16X_PAG: howto manager. (line 2419) +-* BFD_RELOC_XC16X_POF: howto manager. (line 2420) +-* BFD_RELOC_XC16X_SEG: howto manager. (line 2421) +-* BFD_RELOC_XC16X_SOF: howto manager. (line 2422) +-* BFD_RELOC_XGATE_24: howto manager. (line 2164) +-* BFD_RELOC_XGATE_GPAGE: howto manager. (line 2161) +-* BFD_RELOC_XGATE_IMM3: howto manager. (line 2181) +-* BFD_RELOC_XGATE_IMM4: howto manager. (line 2184) +-* BFD_RELOC_XGATE_IMM5: howto manager. (line 2187) +-* BFD_RELOC_XGATE_IMM8_HI: howto manager. (line 2177) +-* BFD_RELOC_XGATE_IMM8_LO: howto manager. (line 2173) +-* BFD_RELOC_XGATE_LO16: howto manager. (line 2157) +-* BFD_RELOC_XGATE_PCREL_10: howto manager. (line 2170) +-* BFD_RELOC_XGATE_PCREL_9: howto manager. (line 2167) +-* BFD_RELOC_XGATE_RL_GROUP: howto manager. (line 2152) +-* BFD_RELOC_XGATE_RL_JUMP: howto manager. (line 2148) +-* BFD_RELOC_XSTORMY16_12: howto manager. (line 2411) +-* BFD_RELOC_XSTORMY16_24: howto manager. (line 2412) +-* BFD_RELOC_XSTORMY16_FPTR16: howto manager. (line 2413) +-* BFD_RELOC_XSTORMY16_REL_12: howto manager. (line 2410) +-* BFD_RELOC_XTENSA_ASM_EXPAND: howto manager. (line 2582) +-* BFD_RELOC_XTENSA_ASM_SIMPLIFY: howto manager. (line 2587) +-* BFD_RELOC_XTENSA_DIFF16: howto manager. (line 2529) +-* BFD_RELOC_XTENSA_DIFF32: howto manager. (line 2530) +-* BFD_RELOC_XTENSA_DIFF8: howto manager. (line 2528) +-* BFD_RELOC_XTENSA_GLOB_DAT: howto manager. (line 2518) +-* BFD_RELOC_XTENSA_JMP_SLOT: howto manager. (line 2519) +-* BFD_RELOC_XTENSA_OP0: howto manager. (line 2576) +-* BFD_RELOC_XTENSA_OP1: howto manager. (line 2577) +-* BFD_RELOC_XTENSA_OP2: howto manager. (line 2578) +-* BFD_RELOC_XTENSA_PLT: howto manager. (line 2523) +-* BFD_RELOC_XTENSA_RELATIVE: howto manager. (line 2520) +-* BFD_RELOC_XTENSA_RTLD: howto manager. (line 2513) +-* BFD_RELOC_XTENSA_SLOT0_ALT: howto manager. (line 2558) +-* BFD_RELOC_XTENSA_SLOT0_OP: howto manager. (line 2538) +-* BFD_RELOC_XTENSA_SLOT10_ALT: howto manager. (line 2568) +-* BFD_RELOC_XTENSA_SLOT10_OP: howto manager. (line 2548) +-* BFD_RELOC_XTENSA_SLOT11_ALT: howto manager. (line 2569) +-* BFD_RELOC_XTENSA_SLOT11_OP: howto manager. (line 2549) +-* BFD_RELOC_XTENSA_SLOT12_ALT: howto manager. (line 2570) +-* BFD_RELOC_XTENSA_SLOT12_OP: howto manager. (line 2550) +-* BFD_RELOC_XTENSA_SLOT13_ALT: howto manager. (line 2571) +-* BFD_RELOC_XTENSA_SLOT13_OP: howto manager. (line 2551) +-* BFD_RELOC_XTENSA_SLOT14_ALT: howto manager. (line 2572) +-* BFD_RELOC_XTENSA_SLOT14_OP: howto manager. (line 2552) +-* BFD_RELOC_XTENSA_SLOT1_ALT: howto manager. (line 2559) +-* BFD_RELOC_XTENSA_SLOT1_OP: howto manager. (line 2539) +-* BFD_RELOC_XTENSA_SLOT2_ALT: howto manager. (line 2560) +-* BFD_RELOC_XTENSA_SLOT2_OP: howto manager. (line 2540) +-* BFD_RELOC_XTENSA_SLOT3_ALT: howto manager. (line 2561) +-* BFD_RELOC_XTENSA_SLOT3_OP: howto manager. (line 2541) +-* BFD_RELOC_XTENSA_SLOT4_ALT: howto manager. (line 2562) +-* BFD_RELOC_XTENSA_SLOT4_OP: howto manager. (line 2542) +-* BFD_RELOC_XTENSA_SLOT5_ALT: howto manager. (line 2563) +-* BFD_RELOC_XTENSA_SLOT5_OP: howto manager. (line 2543) +-* BFD_RELOC_XTENSA_SLOT6_ALT: howto manager. (line 2564) +-* BFD_RELOC_XTENSA_SLOT6_OP: howto manager. (line 2544) +-* BFD_RELOC_XTENSA_SLOT7_ALT: howto manager. (line 2565) +-* BFD_RELOC_XTENSA_SLOT7_OP: howto manager. (line 2545) +-* BFD_RELOC_XTENSA_SLOT8_ALT: howto manager. (line 2566) +-* BFD_RELOC_XTENSA_SLOT8_OP: howto manager. (line 2546) +-* BFD_RELOC_XTENSA_SLOT9_ALT: howto manager. (line 2567) +-* BFD_RELOC_XTENSA_SLOT9_OP: howto manager. (line 2547) +-* BFD_RELOC_XTENSA_TLS_ARG: howto manager. (line 2597) +-* BFD_RELOC_XTENSA_TLS_CALL: howto manager. (line 2598) +-* BFD_RELOC_XTENSA_TLS_DTPOFF: howto manager. (line 2594) +-* BFD_RELOC_XTENSA_TLS_FUNC: howto manager. (line 2596) +-* BFD_RELOC_XTENSA_TLS_TPOFF: howto manager. (line 2595) +-* BFD_RELOC_XTENSA_TLSDESC_ARG: howto manager. (line 2593) +-* BFD_RELOC_XTENSA_TLSDESC_FN: howto manager. (line 2592) +-* BFD_RELOC_Z80_DISP8: howto manager. (line 2601) +-* BFD_RELOC_Z8K_CALLR: howto manager. (line 2607) +-* BFD_RELOC_Z8K_DISP7: howto manager. (line 2604) +-* BFD_RELOC_Z8K_IMM4L: howto manager. (line 2610) +-* bfd_rename_section: section prototypes. (line 169) +-* bfd_scan_arch: Architectures. (line 500) +-* bfd_scan_vma: Miscellaneous. (line 124) +-* bfd_seach_for_target: bfd_target. (line 524) +-* bfd_section_already_linked: Writing the symbol table. +- (line 55) +-* bfd_section_list_clear: section prototypes. (line 8) +-* bfd_sections_find_if: section prototypes. (line 199) +-* bfd_set_arch_info: Architectures. (line 541) +-* bfd_set_archive_head: Archives. (line 75) +-* bfd_set_assert_handler: Error reporting. (line 141) +-* bfd_set_default_target: bfd_target. (line 463) +-* bfd_set_error: Error reporting. (line 57) +-* bfd_set_error_handler: Error reporting. (line 99) +-* bfd_set_error_program_name: Error reporting. (line 108) +-* bfd_set_file_flags: Miscellaneous. (line 44) +-* bfd_set_format: Formats. (line 68) +-* bfd_set_gp_size: Miscellaneous. (line 114) +-* bfd_set_private_flags: Miscellaneous. (line 191) +-* bfd_set_reloc: Miscellaneous. (line 34) +-* bfd_set_section_contents: section prototypes. (line 230) +-* bfd_set_section_flags: section prototypes. (line 154) +-* bfd_set_section_size: section prototypes. (line 216) +-* bfd_set_start_address: Miscellaneous. (line 93) +-* bfd_set_symtab: symbol handling functions. +- (line 60) +-* bfd_symbol_info: symbol handling functions. +- (line 130) +-* bfd_target_list: bfd_target. (line 515) +-* bfd_write_bigendian_4byte_int: Internal. (line 13) +-* bfd_zalloc: Opening and Closing. +- (line 236) +-* bfd_zalloc2: Opening and Closing. +- (line 245) +-* coff_symbol_type: coff. (line 245) +-* core_file_matches_executable_p: Core Files. (line 39) +-* find_separate_debug_file: Opening and Closing. +- (line 308) +-* generic_core_file_matches_executable_p: Core Files. (line 49) +-* Hash tables: Hash Tables. (line 6) +-* internal object-file format: Canonical format. (line 11) +-* Linker: Linker Functions. (line 6) +-* Other functions: Miscellaneous. (line 206) +-* separate_alt_debug_file_exists: Opening and Closing. +- (line 299) +-* separate_debug_file_exists: Opening and Closing. +- (line 290) +-* struct bfd_iovec: Miscellaneous. (line 370) +-* target vector (_bfd_final_link): Performing the Final Link. +- (line 6) +-* target vector (_bfd_link_add_symbols): Adding Symbols to the Hash Table. +- (line 6) +-* target vector (_bfd_link_hash_table_create): Creating a Linker Hash Table. +- (line 6) +-* The HOWTO Macro: typedef arelent. (line 288) +-* what is it?: Overview. (line 6) +- +- +- +-Tag Table: +-Node: Top1060 +-Node: Overview1399 +-Node: History2450 +-Node: How It Works3396 +-Node: What BFD Version 2 Can Do4939 +-Node: BFD information loss6254 +-Node: Canonical format8786 +-Node: BFD front end13158 +-Node: typedef bfd13582 +-Node: Error reporting24300 +-Node: Miscellaneous29167 +-Node: Memory Usage46310 +-Node: Initialization47538 +-Node: Sections47997 +-Node: Section Input48480 +-Node: Section Output49845 +-Node: typedef asection52331 +-Node: section prototypes77563 +-Node: Symbols87820 +-Node: Reading Symbols89415 +-Node: Writing Symbols90522 +-Node: Mini Symbols92263 +-Node: typedef asymbol93237 +-Node: symbol handling functions99296 +-Node: Archives104638 +-Node: Formats108667 +-Node: Relocations111615 +-Node: typedef arelent112342 +-Node: howto manager127978 +-Node: Core Files234626 +-Node: Targets236664 +-Node: bfd_target238634 +-Node: Architectures261856 +-Node: Opening and Closing288730 +-Node: Internal302076 +-Node: File Caching308421 +-Node: Linker Functions310335 +-Node: Creating a Linker Hash Table312008 +-Node: Adding Symbols to the Hash Table313746 +-Node: Differing file formats314646 +-Node: Adding symbols from an object file316371 +-Node: Adding symbols from an archive318522 +-Node: Performing the Final Link321451 +-Node: Information provided by the linker322693 +-Node: Relocating the section contents323847 +-Node: Writing the symbol table325598 +-Node: Hash Tables329982 +-Node: Creating and Freeing a Hash Table331180 +-Node: Looking Up or Entering a String332430 +-Node: Traversing a Hash Table333683 +-Node: Deriving a New Hash Table Type334472 +-Node: Define the Derived Structures335538 +-Node: Write the Derived Creation Routine336619 +-Node: Write Other Derived Routines339243 +-Node: BFD back ends340558 +-Node: What to Put Where340828 +-Node: aout341008 +-Node: coff347326 +-Node: elf375763 +-Node: mmo376164 +-Node: File layout377092 +-Node: Symbol-table382739 +-Node: mmo section mapping386508 +-Node: GNU Free Documentation License390160 +-Node: BFD Index415243 +- +-End Tag Table +diff -Nur binutils-2.24.orig/bfd/doc/bfdio.texi binutils-2.24/bfd/doc/bfdio.texi +--- binutils-2.24.orig/bfd/doc/bfdio.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/bfdio.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,95 +0,0 @@ +-@findex struct bfd_iovec +-@subsubsection @code{struct bfd_iovec} +-@strong{Description}@* +-The @code{struct bfd_iovec} contains the internal file I/O class. +-Each @code{BFD} has an instance of this class and all file I/O is +-routed through it (it is assumed that the instance implements +-all methods listed below). +-@example +-struct bfd_iovec +-@{ +- /* To avoid problems with macros, a "b" rather than "f" +- prefix is prepended to each method name. */ +- /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching +- bytes starting at PTR. Return the number of bytes actually +- transfered (a read past end-of-file returns less than NBYTES), +- or -1 (setting @code{bfd_error}) if an error occurs. */ +- file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes); +- file_ptr (*bwrite) (struct bfd *abfd, const void *ptr, +- file_ptr nbytes); +- /* Return the current IOSTREAM file offset, or -1 (setting @code{bfd_error} +- if an error occurs. */ +- file_ptr (*btell) (struct bfd *abfd); +- /* For the following, on successful completion a value of 0 is returned. +- Otherwise, a value of -1 is returned (and @code{bfd_error} is set). */ +- int (*bseek) (struct bfd *abfd, file_ptr offset, int whence); +- int (*bclose) (struct bfd *abfd); +- int (*bflush) (struct bfd *abfd); +- int (*bstat) (struct bfd *abfd, struct stat *sb); +- /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual +- mmap parameter, except that LEN and OFFSET do not need to be page +- aligned. Returns (void *)-1 on failure, mmapped address on success. +- Also write in MAP_ADDR the address of the page aligned buffer and in +- MAP_LEN the size mapped (a page multiple). Use unmap with MAP_ADDR and +- MAP_LEN to unmap. */ +- void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, +- int prot, int flags, file_ptr offset, +- void **map_addr, bfd_size_type *map_len); +-@}; +-extern const struct bfd_iovec _bfd_memory_iovec; +-@end example +- +-@findex bfd_get_mtime +-@subsubsection @code{bfd_get_mtime} +-@strong{Synopsis} +-@example +-long bfd_get_mtime (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the file modification time (as read from the file system, or +-from the archive header for archive members). +- +-@findex bfd_get_size +-@subsubsection @code{bfd_get_size} +-@strong{Synopsis} +-@example +-file_ptr bfd_get_size (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the file size (as read from file system) for the file +-associated with BFD @var{abfd}. +- +-The initial motivation for, and use of, this routine is not +-so we can get the exact size of the object the BFD applies to, since +-that might not be generally possible (archive members for example). +-It would be ideal if someone could eventually modify +-it so that such results were guaranteed. +- +-Instead, we want to ask questions like "is this NNN byte sized +-object I'm about to try read from file offset YYY reasonable?" +-As as example of where we might do this, some object formats +-use string tables for which the first @code{sizeof (long)} bytes of the +-table contain the size of the table itself, including the size bytes. +-If an application tries to read what it thinks is one of these +-string tables, without some way to validate the size, and for +-some reason the size is wrong (byte swapping error, wrong location +-for the string table, etc.), the only clue is likely to be a read +-error when it tries to read the table, or a "virtual memory +-exhausted" error when it tries to allocate 15 bazillon bytes +-of space for the 15 bazillon byte table it is about to read. +-This function at least allows us to answer the question, "is the +-size reasonable?". +- +-@findex bfd_mmap +-@subsubsection @code{bfd_mmap} +-@strong{Synopsis} +-@example +-void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, +- int prot, int flags, file_ptr offset, +- void **map_addr, bfd_size_type *map_len); +-@end example +-@strong{Description}@* +-Return mmap()ed region of the file, if possible and implemented. +-LEN and OFFSET do not need to be page aligned. The page aligned +-address and length are written to MAP_ADDR and MAP_LEN. +- +diff -Nur binutils-2.24.orig/bfd/doc/bfdt.texi binutils-2.24/bfd/doc/bfdt.texi +--- binutils-2.24.orig/bfd/doc/bfdt.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/bfdt.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,888 +0,0 @@ +-@node typedef bfd, Error reporting, BFD front end, BFD front end +-@section @code{typedef bfd} +-A BFD has type @code{bfd}; objects of this type are the +-cornerstone of any application using BFD. Using BFD +-consists of making references though the BFD and to data in the BFD. +- +-Here is the structure that defines the type @code{bfd}. It +-contains the major data about the file and pointers +-to the rest of the data. +- +- +-@example +- +-enum bfd_direction +- @{ +- no_direction = 0, +- read_direction = 1, +- write_direction = 2, +- both_direction = 3 +- @}; +- +-struct bfd +-@{ +- /* A unique identifier of the BFD */ +- unsigned int id; +- +- /* The filename the application opened the BFD with. */ +- const char *filename; +- +- /* A pointer to the target jump table. */ +- const struct bfd_target *xvec; +- +- /* The IOSTREAM, and corresponding IO vector that provide access +- to the file backing the BFD. */ +- void *iostream; +- const struct bfd_iovec *iovec; +- +- /* The caching routines use these to maintain a +- least-recently-used list of BFDs. */ +- struct bfd *lru_prev, *lru_next; +- +- /* When a file is closed by the caching routines, BFD retains +- state information on the file here... */ +- ufile_ptr where; +- +- /* File modified time, if mtime_set is TRUE. */ +- long mtime; +- +- /* Reserved for an unimplemented file locking extension. */ +- int ifd; +- +- /* The format which belongs to the BFD. (object, core, etc.) */ +- bfd_format format; +- +- /* The direction with which the BFD was opened. */ +- enum bfd_direction direction; +- +- /* Format_specific flags. */ +- flagword flags; +- +- /* Values that may appear in the flags field of a BFD. These also +- appear in the object_flags field of the bfd_target structure, where +- they indicate the set of flags used by that backend (not all flags +- are meaningful for all object file formats) (FIXME: at the moment, +- the object_flags values have mostly just been copied from backend +- to another, and are not necessarily correct). */ +- +-#define BFD_NO_FLAGS 0x00 +- +- /* BFD contains relocation entries. */ +-#define HAS_RELOC 0x01 +- +- /* BFD is directly executable. */ +-#define EXEC_P 0x02 +- +- /* BFD has line number information (basically used for F_LNNO in a +- COFF header). */ +-#define HAS_LINENO 0x04 +- +- /* BFD has debugging information. */ +-#define HAS_DEBUG 0x08 +- +- /* BFD has symbols. */ +-#define HAS_SYMS 0x10 +- +- /* BFD has local symbols (basically used for F_LSYMS in a COFF +- header). */ +-#define HAS_LOCALS 0x20 +- +- /* BFD is a dynamic object. */ +-#define DYNAMIC 0x40 +- +- /* Text section is write protected (if D_PAGED is not set, this is +- like an a.out NMAGIC file) (the linker sets this by default, but +- clears it for -r or -N). */ +-#define WP_TEXT 0x80 +- +- /* BFD is dynamically paged (this is like an a.out ZMAGIC file) (the +- linker sets this by default, but clears it for -r or -n or -N). */ +-#define D_PAGED 0x100 +- +- /* BFD is relaxable (this means that bfd_relax_section may be able to +- do something) (sometimes bfd_relax_section can do something even if +- this is not set). */ +-#define BFD_IS_RELAXABLE 0x200 +- +- /* This may be set before writing out a BFD to request using a +- traditional format. For example, this is used to request that when +- writing out an a.out object the symbols not be hashed to eliminate +- duplicates. */ +-#define BFD_TRADITIONAL_FORMAT 0x400 +- +- /* This flag indicates that the BFD contents are actually cached +- in memory. If this is set, iostream points to a bfd_in_memory +- struct. */ +-#define BFD_IN_MEMORY 0x800 +- +- /* The sections in this BFD specify a memory page. */ +-#define HAS_LOAD_PAGE 0x1000 +- +- /* This BFD has been created by the linker and doesn't correspond +- to any input file. */ +-#define BFD_LINKER_CREATED 0x2000 +- +- /* This may be set before writing out a BFD to request that it +- be written using values for UIDs, GIDs, timestamps, etc. that +- will be consistent from run to run. */ +-#define BFD_DETERMINISTIC_OUTPUT 0x4000 +- +- /* Compress sections in this BFD. */ +-#define BFD_COMPRESS 0x8000 +- +- /* Decompress sections in this BFD. */ +-#define BFD_DECOMPRESS 0x10000 +- +- /* BFD is a dummy, for plugins. */ +-#define BFD_PLUGIN 0x20000 +- +- /* Flags bits to be saved in bfd_preserve_save. */ +-#define BFD_FLAGS_SAVED \ +- (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_PLUGIN) +- +- /* Flags bits which are for BFD use only. */ +-#define BFD_FLAGS_FOR_BFD_USE_MASK \ +- (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \ +- | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT) +- +- /* Currently my_archive is tested before adding origin to +- anything. I believe that this can become always an add of +- origin, with origin set to 0 for non archive files. */ +- ufile_ptr origin; +- +- /* The origin in the archive of the proxy entry. This will +- normally be the same as origin, except for thin archives, +- when it will contain the current offset of the proxy in the +- thin archive rather than the offset of the bfd in its actual +- container. */ +- ufile_ptr proxy_origin; +- +- /* A hash table for section names. */ +- struct bfd_hash_table section_htab; +- +- /* Pointer to linked list of sections. */ +- struct bfd_section *sections; +- +- /* The last section on the section list. */ +- struct bfd_section *section_last; +- +- /* The number of sections. */ +- unsigned int section_count; +- +- /* Stuff only useful for object files: +- The start address. */ +- bfd_vma start_address; +- +- /* Used for input and output. */ +- unsigned int symcount; +- +- /* Symbol table for output BFD (with symcount entries). +- Also used by the linker to cache input BFD symbols. */ +- struct bfd_symbol **outsymbols; +- +- /* Used for slurped dynamic symbol tables. */ +- unsigned int dynsymcount; +- +- /* Pointer to structure which contains architecture information. */ +- const struct bfd_arch_info *arch_info; +- +- /* Stuff only useful for archives. */ +- void *arelt_data; +- struct bfd *my_archive; /* The containing archive BFD. */ +- struct bfd *archive_next; /* The next BFD in the archive. */ +- struct bfd *archive_head; /* The first BFD in the archive. */ +- struct bfd *nested_archives; /* List of nested archive in a flattened +- thin archive. */ +- +- /* A chain of BFD structures involved in a link. */ +- struct bfd *link_next; +- +- /* A field used by _bfd_generic_link_add_archive_symbols. This will +- be used only for archive elements. */ +- int archive_pass; +- +- /* Used by the back end to hold private data. */ +- union +- @{ +- struct aout_data_struct *aout_data; +- struct artdata *aout_ar_data; +- struct _oasys_data *oasys_obj_data; +- struct _oasys_ar_data *oasys_ar_data; +- struct coff_tdata *coff_obj_data; +- struct pe_tdata *pe_obj_data; +- struct xcoff_tdata *xcoff_obj_data; +- struct ecoff_tdata *ecoff_obj_data; +- struct ieee_data_struct *ieee_data; +- struct ieee_ar_data_struct *ieee_ar_data; +- struct srec_data_struct *srec_data; +- struct verilog_data_struct *verilog_data; +- struct ihex_data_struct *ihex_data; +- struct tekhex_data_struct *tekhex_data; +- struct elf_obj_tdata *elf_obj_data; +- struct nlm_obj_tdata *nlm_obj_data; +- struct bout_data_struct *bout_data; +- struct mmo_data_struct *mmo_data; +- struct sun_core_struct *sun_core_data; +- struct sco5_core_struct *sco5_core_data; +- struct trad_core_struct *trad_core_data; +- struct som_data_struct *som_data; +- struct hpux_core_struct *hpux_core_data; +- struct hppabsd_core_struct *hppabsd_core_data; +- struct sgi_core_struct *sgi_core_data; +- struct lynx_core_struct *lynx_core_data; +- struct osf_core_struct *osf_core_data; +- struct cisco_core_struct *cisco_core_data; +- struct versados_data_struct *versados_data; +- struct netbsd_core_struct *netbsd_core_data; +- struct mach_o_data_struct *mach_o_data; +- struct mach_o_fat_data_struct *mach_o_fat_data; +- struct plugin_data_struct *plugin_data; +- struct bfd_pef_data_struct *pef_data; +- struct bfd_pef_xlib_data_struct *pef_xlib_data; +- struct bfd_sym_data_struct *sym_data; +- void *any; +- @} +- tdata; +- +- /* Used by the application to hold private data. */ +- void *usrdata; +- +- /* Where all the allocated stuff under this BFD goes. This is a +- struct objalloc *, but we use void * to avoid requiring the inclusion +- of objalloc.h. */ +- void *memory; +- +- /* Is the file descriptor being cached? That is, can it be closed as +- needed, and re-opened when accessed later? */ +- unsigned int cacheable : 1; +- +- /* Marks whether there was a default target specified when the +- BFD was opened. This is used to select which matching algorithm +- to use to choose the back end. */ +- unsigned int target_defaulted : 1; +- +- /* ... and here: (``once'' means at least once). */ +- unsigned int opened_once : 1; +- +- /* Set if we have a locally maintained mtime value, rather than +- getting it from the file each time. */ +- unsigned int mtime_set : 1; +- +- /* Flag set if symbols from this BFD should not be exported. */ +- unsigned int no_export : 1; +- +- /* Remember when output has begun, to stop strange things +- from happening. */ +- unsigned int output_has_begun : 1; +- +- /* Have archive map. */ +- unsigned int has_armap : 1; +- +- /* Set if this is a thin archive. */ +- unsigned int is_thin_archive : 1; +- +- /* Set if only required symbols should be added in the link hash table for +- this object. Used by VMS linkers. */ +- unsigned int selective_search : 1; +-@}; +- +-@end example +-@node Error reporting, Miscellaneous, typedef bfd, BFD front end +-@section Error reporting +-Most BFD functions return nonzero on success (check their +-individual documentation for precise semantics). On an error, +-they call @code{bfd_set_error} to set an error condition that callers +-can check by calling @code{bfd_get_error}. +-If that returns @code{bfd_error_system_call}, then check +-@code{errno}. +- +-The easiest way to report a BFD error to the user is to +-use @code{bfd_perror}. +- +-@subsection Type @code{bfd_error_type} +-The values returned by @code{bfd_get_error} are defined by the +-enumerated type @code{bfd_error_type}. +- +- +-@example +- +-typedef enum bfd_error +-@{ +- bfd_error_no_error = 0, +- bfd_error_system_call, +- bfd_error_invalid_target, +- bfd_error_wrong_format, +- bfd_error_wrong_object_format, +- bfd_error_invalid_operation, +- bfd_error_no_memory, +- bfd_error_no_symbols, +- bfd_error_no_armap, +- bfd_error_no_more_archived_files, +- bfd_error_malformed_archive, +- bfd_error_missing_dso, +- bfd_error_file_not_recognized, +- bfd_error_file_ambiguously_recognized, +- bfd_error_no_contents, +- bfd_error_nonrepresentable_section, +- bfd_error_no_debug_section, +- bfd_error_bad_value, +- bfd_error_file_truncated, +- bfd_error_file_too_big, +- bfd_error_on_input, +- bfd_error_invalid_error_code +-@} +-bfd_error_type; +- +-@end example +-@findex bfd_get_error +-@subsubsection @code{bfd_get_error} +-@strong{Synopsis} +-@example +-bfd_error_type bfd_get_error (void); +-@end example +-@strong{Description}@* +-Return the current BFD error condition. +- +-@findex bfd_set_error +-@subsubsection @code{bfd_set_error} +-@strong{Synopsis} +-@example +-void bfd_set_error (bfd_error_type error_tag, ...); +-@end example +-@strong{Description}@* +-Set the BFD error condition to be @var{error_tag}. +-If @var{error_tag} is bfd_error_on_input, then this function +-takes two more parameters, the input bfd where the error +-occurred, and the bfd_error_type error. +- +-@findex bfd_errmsg +-@subsubsection @code{bfd_errmsg} +-@strong{Synopsis} +-@example +-const char *bfd_errmsg (bfd_error_type error_tag); +-@end example +-@strong{Description}@* +-Return a string describing the error @var{error_tag}, or +-the system error if @var{error_tag} is @code{bfd_error_system_call}. +- +-@findex bfd_perror +-@subsubsection @code{bfd_perror} +-@strong{Synopsis} +-@example +-void bfd_perror (const char *message); +-@end example +-@strong{Description}@* +-Print to the standard error stream a string describing the +-last BFD error that occurred, or the last system error if +-the last BFD error was a system call failure. If @var{message} +-is non-NULL and non-empty, the error string printed is preceded +-by @var{message}, a colon, and a space. It is followed by a newline. +- +-@subsection BFD error handler +-Some BFD functions want to print messages describing the +-problem. They call a BFD error handler function. This +-function may be overridden by the program. +- +-The BFD error handler acts like printf. +- +- +-@example +- +-typedef void (*bfd_error_handler_type) (const char *, ...); +- +-@end example +-@findex bfd_set_error_handler +-@subsubsection @code{bfd_set_error_handler} +-@strong{Synopsis} +-@example +-bfd_error_handler_type bfd_set_error_handler (bfd_error_handler_type); +-@end example +-@strong{Description}@* +-Set the BFD error handler function. Returns the previous +-function. +- +-@findex bfd_set_error_program_name +-@subsubsection @code{bfd_set_error_program_name} +-@strong{Synopsis} +-@example +-void bfd_set_error_program_name (const char *); +-@end example +-@strong{Description}@* +-Set the program name to use when printing a BFD error. This +-is printed before the error message followed by a colon and +-space. The string must not be changed after it is passed to +-this function. +- +-@findex bfd_get_error_handler +-@subsubsection @code{bfd_get_error_handler} +-@strong{Synopsis} +-@example +-bfd_error_handler_type bfd_get_error_handler (void); +-@end example +-@strong{Description}@* +-Return the BFD error handler function. +- +-@subsection BFD assert handler +-If BFD finds an internal inconsistency, the bfd assert +-handler is called with information on the BFD version, BFD +-source file and line. If this happens, most programs linked +-against BFD are expected to want to exit with an error, or mark +-the current BFD operation as failed, so it is recommended to +-override the default handler, which just calls +-_bfd_error_handler and continues. +- +- +-@example +- +-typedef void (*bfd_assert_handler_type) (const char *bfd_formatmsg, +- const char *bfd_version, +- const char *bfd_file, +- int bfd_line); +- +-@end example +-@findex bfd_set_assert_handler +-@subsubsection @code{bfd_set_assert_handler} +-@strong{Synopsis} +-@example +-bfd_assert_handler_type bfd_set_assert_handler (bfd_assert_handler_type); +-@end example +-@strong{Description}@* +-Set the BFD assert handler function. Returns the previous +-function. +- +-@findex bfd_get_assert_handler +-@subsubsection @code{bfd_get_assert_handler} +-@strong{Synopsis} +-@example +-bfd_assert_handler_type bfd_get_assert_handler (void); +-@end example +-@strong{Description}@* +-Return the BFD assert handler function. +- +-@node Miscellaneous, Memory Usage, Error reporting, BFD front end +-@section Miscellaneous +- +- +-@subsection Miscellaneous functions +- +- +-@findex bfd_get_reloc_upper_bound +-@subsubsection @code{bfd_get_reloc_upper_bound} +-@strong{Synopsis} +-@example +-long bfd_get_reloc_upper_bound (bfd *abfd, asection *sect); +-@end example +-@strong{Description}@* +-Return the number of bytes required to store the +-relocation information associated with section @var{sect} +-attached to bfd @var{abfd}. If an error occurs, return -1. +- +-@findex bfd_canonicalize_reloc +-@subsubsection @code{bfd_canonicalize_reloc} +-@strong{Synopsis} +-@example +-long bfd_canonicalize_reloc +- (bfd *abfd, asection *sec, arelent **loc, asymbol **syms); +-@end example +-@strong{Description}@* +-Call the back end associated with the open BFD +-@var{abfd} and translate the external form of the relocation +-information attached to @var{sec} into the internal canonical +-form. Place the table into memory at @var{loc}, which has +-been preallocated, usually by a call to +-@code{bfd_get_reloc_upper_bound}. Returns the number of relocs, or +--1 on error. +- +-The @var{syms} table is also needed for horrible internal magic +-reasons. +- +-@findex bfd_set_reloc +-@subsubsection @code{bfd_set_reloc} +-@strong{Synopsis} +-@example +-void bfd_set_reloc +- (bfd *abfd, asection *sec, arelent **rel, unsigned int count); +-@end example +-@strong{Description}@* +-Set the relocation pointer and count within +-section @var{sec} to the values @var{rel} and @var{count}. +-The argument @var{abfd} is ignored. +- +-@findex bfd_set_file_flags +-@subsubsection @code{bfd_set_file_flags} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_file_flags (bfd *abfd, flagword flags); +-@end example +-@strong{Description}@* +-Set the flag word in the BFD @var{abfd} to the value @var{flags}. +- +-Possible errors are: +-@itemize @bullet +- +-@item +-@code{bfd_error_wrong_format} - The target bfd was not of object format. +-@item +-@code{bfd_error_invalid_operation} - The target bfd was open for reading. +-@item +-@code{bfd_error_invalid_operation} - +-The flag word contained a bit which was not applicable to the +-type of file. E.g., an attempt was made to set the @code{D_PAGED} bit +-on a BFD format which does not support demand paging. +-@end itemize +- +-@findex bfd_get_arch_size +-@subsubsection @code{bfd_get_arch_size} +-@strong{Synopsis} +-@example +-int bfd_get_arch_size (bfd *abfd); +-@end example +-@strong{Description}@* +-Returns the architecture address size, in bits, as determined +-by the object file's format. For ELF, this information is +-included in the header. +- +-@strong{Returns}@* +-Returns the arch size in bits if known, @code{-1} otherwise. +- +-@findex bfd_get_sign_extend_vma +-@subsubsection @code{bfd_get_sign_extend_vma} +-@strong{Synopsis} +-@example +-int bfd_get_sign_extend_vma (bfd *abfd); +-@end example +-@strong{Description}@* +-Indicates if the target architecture "naturally" sign extends +-an address. Some architectures implicitly sign extend address +-values when they are converted to types larger than the size +-of an address. For instance, bfd_get_start_address() will +-return an address sign extended to fill a bfd_vma when this is +-the case. +- +-@strong{Returns}@* +-Returns @code{1} if the target architecture is known to sign +-extend addresses, @code{0} if the target architecture is known to +-not sign extend addresses, and @code{-1} otherwise. +- +-@findex bfd_set_start_address +-@subsubsection @code{bfd_set_start_address} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_start_address (bfd *abfd, bfd_vma vma); +-@end example +-@strong{Description}@* +-Make @var{vma} the entry point of output BFD @var{abfd}. +- +-@strong{Returns}@* +-Returns @code{TRUE} on success, @code{FALSE} otherwise. +- +-@findex bfd_get_gp_size +-@subsubsection @code{bfd_get_gp_size} +-@strong{Synopsis} +-@example +-unsigned int bfd_get_gp_size (bfd *abfd); +-@end example +-@strong{Description}@* +-Return the maximum size of objects to be optimized using the GP +-register under MIPS ECOFF. This is typically set by the @code{-G} +-argument to the compiler, assembler or linker. +- +-@findex bfd_set_gp_size +-@subsubsection @code{bfd_set_gp_size} +-@strong{Synopsis} +-@example +-void bfd_set_gp_size (bfd *abfd, unsigned int i); +-@end example +-@strong{Description}@* +-Set the maximum size of objects to be optimized using the GP +-register under ECOFF or MIPS ELF. This is typically set by +-the @code{-G} argument to the compiler, assembler or linker. +- +-@findex bfd_scan_vma +-@subsubsection @code{bfd_scan_vma} +-@strong{Synopsis} +-@example +-bfd_vma bfd_scan_vma (const char *string, const char **end, int base); +-@end example +-@strong{Description}@* +-Convert, like @code{strtoul}, a numerical expression +-@var{string} into a @code{bfd_vma} integer, and return that integer. +-(Though without as many bells and whistles as @code{strtoul}.) +-The expression is assumed to be unsigned (i.e., positive). +-If given a @var{base}, it is used as the base for conversion. +-A base of 0 causes the function to interpret the string +-in hex if a leading "0x" or "0X" is found, otherwise +-in octal if a leading zero is found, otherwise in decimal. +- +-If the value would overflow, the maximum @code{bfd_vma} value is +-returned. +- +-@findex bfd_copy_private_header_data +-@subsubsection @code{bfd_copy_private_header_data} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_copy_private_header_data (bfd *ibfd, bfd *obfd); +-@end example +-@strong{Description}@* +-Copy private BFD header information from the BFD @var{ibfd} to the +-the BFD @var{obfd}. This copies information that may require +-sections to exist, but does not require symbol tables. Return +-@code{true} on success, @code{false} on error. +-Possible error returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_no_memory} - +-Not enough memory exists to create private data for @var{obfd}. +-@end itemize +-@example +-#define bfd_copy_private_header_data(ibfd, obfd) \ +- BFD_SEND (obfd, _bfd_copy_private_header_data, \ +- (ibfd, obfd)) +-@end example +- +-@findex bfd_copy_private_bfd_data +-@subsubsection @code{bfd_copy_private_bfd_data} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd); +-@end example +-@strong{Description}@* +-Copy private BFD information from the BFD @var{ibfd} to the +-the BFD @var{obfd}. Return @code{TRUE} on success, @code{FALSE} on error. +-Possible error returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_no_memory} - +-Not enough memory exists to create private data for @var{obfd}. +-@end itemize +-@example +-#define bfd_copy_private_bfd_data(ibfd, obfd) \ +- BFD_SEND (obfd, _bfd_copy_private_bfd_data, \ +- (ibfd, obfd)) +-@end example +- +-@findex bfd_merge_private_bfd_data +-@subsubsection @code{bfd_merge_private_bfd_data} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_merge_private_bfd_data (bfd *ibfd, bfd *obfd); +-@end example +-@strong{Description}@* +-Merge private BFD information from the BFD @var{ibfd} to the +-the output file BFD @var{obfd} when linking. Return @code{TRUE} +-on success, @code{FALSE} on error. Possible error returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_no_memory} - +-Not enough memory exists to create private data for @var{obfd}. +-@end itemize +-@example +-#define bfd_merge_private_bfd_data(ibfd, obfd) \ +- BFD_SEND (obfd, _bfd_merge_private_bfd_data, \ +- (ibfd, obfd)) +-@end example +- +-@findex bfd_set_private_flags +-@subsubsection @code{bfd_set_private_flags} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); +-@end example +-@strong{Description}@* +-Set private BFD flag information in the BFD @var{abfd}. +-Return @code{TRUE} on success, @code{FALSE} on error. Possible error +-returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_no_memory} - +-Not enough memory exists to create private data for @var{obfd}. +-@end itemize +-@example +-#define bfd_set_private_flags(abfd, flags) \ +- BFD_SEND (abfd, _bfd_set_private_flags, (abfd, flags)) +-@end example +- +-@findex Other functions +-@subsubsection @code{Other functions} +-@strong{Description}@* +-The following functions exist but have not yet been documented. +-@example +-#define bfd_sizeof_headers(abfd, info) \ +- BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, info)) +- +-#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \ +- BFD_SEND (abfd, _bfd_find_nearest_line, \ +- (abfd, sec, syms, off, file, func, line)) +- +-#define bfd_find_nearest_line_discriminator(abfd, sec, syms, off, file, func, \ +- line, disc) \ +- BFD_SEND (abfd, _bfd_find_nearest_line_discriminator, \ +- (abfd, sec, syms, off, file, func, line, disc)) +- +-#define bfd_find_line(abfd, syms, sym, file, line) \ +- BFD_SEND (abfd, _bfd_find_line, \ +- (abfd, syms, sym, file, line)) +- +-#define bfd_find_inliner_info(abfd, file, func, line) \ +- BFD_SEND (abfd, _bfd_find_inliner_info, \ +- (abfd, file, func, line)) +- +-#define bfd_debug_info_start(abfd) \ +- BFD_SEND (abfd, _bfd_debug_info_start, (abfd)) +- +-#define bfd_debug_info_end(abfd) \ +- BFD_SEND (abfd, _bfd_debug_info_end, (abfd)) +- +-#define bfd_debug_info_accumulate(abfd, section) \ +- BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section)) +- +-#define bfd_stat_arch_elt(abfd, stat) \ +- BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat)) +- +-#define bfd_update_armap_timestamp(abfd) \ +- BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd)) +- +-#define bfd_set_arch_mach(abfd, arch, mach)\ +- BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach)) +- +-#define bfd_relax_section(abfd, section, link_info, again) \ +- BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again)) +- +-#define bfd_gc_sections(abfd, link_info) \ +- BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info)) +- +-#define bfd_lookup_section_flags(link_info, flag_info, section) \ +- BFD_SEND (abfd, _bfd_lookup_section_flags, (link_info, flag_info, section)) +- +-#define bfd_merge_sections(abfd, link_info) \ +- BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info)) +- +-#define bfd_is_group_section(abfd, sec) \ +- BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec)) +- +-#define bfd_discard_group(abfd, sec) \ +- BFD_SEND (abfd, _bfd_discard_group, (abfd, sec)) +- +-#define bfd_link_hash_table_create(abfd) \ +- BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd)) +- +-#define bfd_link_hash_table_free(abfd, hash) \ +- BFD_SEND (abfd, _bfd_link_hash_table_free, (hash)) +- +-#define bfd_link_add_symbols(abfd, info) \ +- BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info)) +- +-#define bfd_link_just_syms(abfd, sec, info) \ +- BFD_SEND (abfd, _bfd_link_just_syms, (sec, info)) +- +-#define bfd_final_link(abfd, info) \ +- BFD_SEND (abfd, _bfd_final_link, (abfd, info)) +- +-#define bfd_free_cached_info(abfd) \ +- BFD_SEND (abfd, _bfd_free_cached_info, (abfd)) +- +-#define bfd_get_dynamic_symtab_upper_bound(abfd) \ +- BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd)) +- +-#define bfd_print_private_bfd_data(abfd, file)\ +- BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file)) +- +-#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ +- BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) +- +-#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ +- BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ +- dyncount, dynsyms, ret)) +- +-#define bfd_get_dynamic_reloc_upper_bound(abfd) \ +- BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) +- +-#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \ +- BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms)) +- +-extern bfd_byte *bfd_get_relocated_section_contents +- (bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, +- bfd_boolean, asymbol **); +- +-@end example +- +-@findex bfd_alt_mach_code +-@subsubsection @code{bfd_alt_mach_code} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_alt_mach_code (bfd *abfd, int alternative); +-@end example +-@strong{Description}@* +-When more than one machine code number is available for the +-same machine type, this function can be used to switch between +-the preferred one (alternative == 0) and any others. Currently, +-only ELF supports this feature, with up to two alternate +-machine codes. +- +-@findex bfd_emul_get_maxpagesize +-@subsubsection @code{bfd_emul_get_maxpagesize} +-@strong{Synopsis} +-@example +-bfd_vma bfd_emul_get_maxpagesize (const char *); +-@end example +-@strong{Description}@* +-Returns the maximum page size, in bytes, as determined by +-emulation. +- +-@strong{Returns}@* +-Returns the maximum page size in bytes for ELF, 0 otherwise. +- +-@findex bfd_emul_set_maxpagesize +-@subsubsection @code{bfd_emul_set_maxpagesize} +-@strong{Synopsis} +-@example +-void bfd_emul_set_maxpagesize (const char *, bfd_vma); +-@end example +-@strong{Description}@* +-For ELF, set the maximum page size for the emulation. It is +-a no-op for other formats. +- +-@findex bfd_emul_get_commonpagesize +-@subsubsection @code{bfd_emul_get_commonpagesize} +-@strong{Synopsis} +-@example +-bfd_vma bfd_emul_get_commonpagesize (const char *); +-@end example +-@strong{Description}@* +-Returns the common page size, in bytes, as determined by +-emulation. +- +-@strong{Returns}@* +-Returns the common page size in bytes for ELF, 0 otherwise. +- +-@findex bfd_emul_set_commonpagesize +-@subsubsection @code{bfd_emul_set_commonpagesize} +-@strong{Synopsis} +-@example +-void bfd_emul_set_commonpagesize (const char *, bfd_vma); +-@end example +-@strong{Description}@* +-For ELF, set the common page size for the emulation. It is +-a no-op for other formats. +- +-@findex bfd_demangle +-@subsubsection @code{bfd_demangle} +-@strong{Synopsis} +-@example +-char *bfd_demangle (bfd *, const char *, int); +-@end example +-@strong{Description}@* +-Wrapper around cplus_demangle. Strips leading underscores and +-other such chars that would otherwise confuse the demangler. +-If passed a g++ v3 ABI mangled name, returns a buffer allocated +-with malloc holding the demangled name. Returns NULL otherwise +-and on memory alloc failure. +- +diff -Nur binutils-2.24.orig/bfd/doc/bfdver.texi binutils-2.24/bfd/doc/bfdver.texi +--- binutils-2.24.orig/bfd/doc/bfdver.texi 2013-12-02 10:32:19.000000000 +0100 ++++ binutils-2.24/bfd/doc/bfdver.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,4 +0,0 @@ +-@set VERSION 2.24 +-@set VERSION_PACKAGE (GNU Binutils) +-@set UPDATED December 2013 +-@set BUGURL @uref{http://www.sourceware.org/bugzilla/} +diff -Nur binutils-2.24.orig/bfd/doc/bfdwin.texi binutils-2.24/bfd/doc/bfdwin.texi +--- binutils-2.24.orig/bfd/doc/bfdwin.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/bfdwin.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2 +0,0 @@ +-@findex +-@subsubsection @code{} +diff -Nur binutils-2.24.orig/bfd/doc/cache.texi binutils-2.24/bfd/doc/cache.texi +--- binutils-2.24.orig/bfd/doc/cache.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/cache.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,65 +0,0 @@ +-@section File caching +-The file caching mechanism is embedded within BFD and allows +-the application to open as many BFDs as it wants without +-regard to the underlying operating system's file descriptor +-limit (often as low as 20 open files). The module in +-@code{cache.c} maintains a least recently used list of +-@code{bfd_cache_max_open} files, and exports the name +-@code{bfd_cache_lookup}, which runs around and makes sure that +-the required BFD is open. If not, then it chooses a file to +-close, closes it and opens the one wanted, returning its file +-handle. +- +-@subsection Caching functions +- +- +-@findex bfd_cache_init +-@subsubsection @code{bfd_cache_init} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_cache_init (bfd *abfd); +-@end example +-@strong{Description}@* +-Add a newly opened BFD to the cache. +- +-@findex bfd_cache_close +-@subsubsection @code{bfd_cache_close} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_cache_close (bfd *abfd); +-@end example +-@strong{Description}@* +-Remove the BFD @var{abfd} from the cache. If the attached file is open, +-then close it too. +- +-@strong{Returns}@* +-@code{FALSE} is returned if closing the file fails, @code{TRUE} is +-returned if all is well. +- +-@findex bfd_cache_close_all +-@subsubsection @code{bfd_cache_close_all} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_cache_close_all (void); +-@end example +-@strong{Description}@* +-Remove all BFDs from the cache. If the attached file is open, +-then close it too. +- +-@strong{Returns}@* +-@code{FALSE} is returned if closing one of the file fails, @code{TRUE} is +-returned if all is well. +- +-@findex bfd_open_file +-@subsubsection @code{bfd_open_file} +-@strong{Synopsis} +-@example +-FILE* bfd_open_file (bfd *abfd); +-@end example +-@strong{Description}@* +-Call the OS to open a file for @var{abfd}. Return the @code{FILE *} +-(possibly @code{NULL}) that results from this operation. Set up the +-BFD so that future accesses know the file is open. If the @code{FILE *} +-returned is @code{NULL}, then it won't have been put in the +-cache, so it won't have to be removed from it. +- +diff -Nur binutils-2.24.orig/bfd/doc/coffcode.texi binutils-2.24/bfd/doc/coffcode.texi +--- binutils-2.24.orig/bfd/doc/coffcode.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/coffcode.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,686 +0,0 @@ +-@section coff backends +-BFD supports a number of different flavours of coff format. +-The major differences between formats are the sizes and +-alignments of fields in structures on disk, and the occasional +-extra field. +- +-Coff in all its varieties is implemented with a few common +-files and a number of implementation specific files. For +-example, The 88k bcs coff format is implemented in the file +-@file{coff-m88k.c}. This file @code{#include}s +-@file{coff/m88k.h} which defines the external structure of the +-coff format for the 88k, and @file{coff/internal.h} which +-defines the internal structure. @file{coff-m88k.c} also +-defines the relocations used by the 88k format +-@xref{Relocations}. +- +-The Intel i960 processor version of coff is implemented in +-@file{coff-i960.c}. This file has the same structure as +-@file{coff-m88k.c}, except that it includes @file{coff/i960.h} +-rather than @file{coff-m88k.h}. +- +-@subsection Porting to a new version of coff +-The recommended method is to select from the existing +-implementations the version of coff which is most like the one +-you want to use. For example, we'll say that i386 coff is +-the one you select, and that your coff flavour is called foo. +-Copy @file{i386coff.c} to @file{foocoff.c}, copy +-@file{../include/coff/i386.h} to @file{../include/coff/foo.h}, +-and add the lines to @file{targets.c} and @file{Makefile.in} +-so that your new back end is used. Alter the shapes of the +-structures in @file{../include/coff/foo.h} so that they match +-what you need. You will probably also have to add +-@code{#ifdef}s to the code in @file{coff/internal.h} and +-@file{coffcode.h} if your version of coff is too wild. +- +-You can verify that your new BFD backend works quite simply by +-building @file{objdump} from the @file{binutils} directory, +-and making sure that its version of what's going on and your +-host system's idea (assuming it has the pretty standard coff +-dump utility, usually called @code{att-dump} or just +-@code{dump}) are the same. Then clean up your code, and send +-what you've done to Cygnus. Then your stuff will be in the +-next release, and you won't have to keep integrating it. +- +-@subsection How the coff backend works +- +- +-@subsubsection File layout +-The Coff backend is split into generic routines that are +-applicable to any Coff target and routines that are specific +-to a particular target. The target-specific routines are +-further split into ones which are basically the same for all +-Coff targets except that they use the external symbol format +-or use different values for certain constants. +- +-The generic routines are in @file{coffgen.c}. These routines +-work for any Coff target. They use some hooks into the target +-specific code; the hooks are in a @code{bfd_coff_backend_data} +-structure, one of which exists for each target. +- +-The essentially similar target-specific routines are in +-@file{coffcode.h}. This header file includes executable C code. +-The various Coff targets first include the appropriate Coff +-header file, make any special defines that are needed, and +-then include @file{coffcode.h}. +- +-Some of the Coff targets then also have additional routines in +-the target source file itself. +- +-For example, @file{coff-i960.c} includes +-@file{coff/internal.h} and @file{coff/i960.h}. It then +-defines a few constants, such as @code{I960}, and includes +-@file{coffcode.h}. Since the i960 has complex relocation +-types, @file{coff-i960.c} also includes some code to +-manipulate the i960 relocs. This code is not in +-@file{coffcode.h} because it would not be used by any other +-target. +- +-@subsubsection Coff long section names +-In the standard Coff object format, section names are limited to +-the eight bytes available in the @code{s_name} field of the +-@code{SCNHDR} section header structure. The format requires the +-field to be NUL-padded, but not necessarily NUL-terminated, so +-the longest section names permitted are a full eight characters. +- +-The Microsoft PE variants of the Coff object file format add +-an extension to support the use of long section names. This +-extension is defined in section 4 of the Microsoft PE/COFF +-specification (rev 8.1). If a section name is too long to fit +-into the section header's @code{s_name} field, it is instead +-placed into the string table, and the @code{s_name} field is +-filled with a slash ("/") followed by the ASCII decimal +-representation of the offset of the full name relative to the +-string table base. +- +-Note that this implies that the extension can only be used in object +-files, as executables do not contain a string table. The standard +-specifies that long section names from objects emitted into executable +-images are to be truncated. +- +-However, as a GNU extension, BFD can generate executable images +-that contain a string table and long section names. This +-would appear to be technically valid, as the standard only says +-that Coff debugging information is deprecated, not forbidden, +-and in practice it works, although some tools that parse PE files +-expecting the MS standard format may become confused; @file{PEview} is +-one known example. +- +-The functionality is supported in BFD by code implemented under +-the control of the macro @code{COFF_LONG_SECTION_NAMES}. If not +-defined, the format does not support long section names in any way. +-If defined, it is used to initialise a flag, +-@code{_bfd_coff_long_section_names}, and a hook function pointer, +-@code{_bfd_coff_set_long_section_names}, in the Coff backend data +-structure. The flag controls the generation of long section names +-in output BFDs at runtime; if it is false, as it will be by default +-when generating an executable image, long section names are truncated; +-if true, the long section names extension is employed. The hook +-points to a function that allows the value of the flag to be altered +-at runtime, on formats that support long section names at all; on +-other formats it points to a stub that returns an error indication. +- +-With input BFDs, the flag is set according to whether any long section +-names are detected while reading the section headers. For a completely +-new BFD, the flag is set to the default for the target format. This +-information can be used by a client of the BFD library when deciding +-what output format to generate, and means that a BFD that is opened +-for read and subsequently converted to a writeable BFD and modified +-in-place will retain whatever format it had on input. +- +-If @code{COFF_LONG_SECTION_NAMES} is simply defined (blank), or is +-defined to the value "1", then long section names are enabled by +-default; if it is defined to the value zero, they are disabled by +-default (but still accepted in input BFDs). The header @file{coffcode.h} +-defines a macro, @code{COFF_DEFAULT_LONG_SECTION_NAMES}, which is +-used in the backends to initialise the backend data structure fields +-appropriately; see the comments for further detail. +- +-@subsubsection Bit twiddling +-Each flavour of coff supported in BFD has its own header file +-describing the external layout of the structures. There is also +-an internal description of the coff layout, in +-@file{coff/internal.h}. A major function of the +-coff backend is swapping the bytes and twiddling the bits to +-translate the external form of the structures into the normal +-internal form. This is all performed in the +-@code{bfd_swap}_@i{thing}_@i{direction} routines. Some +-elements are different sizes between different versions of +-coff; it is the duty of the coff version specific include file +-to override the definitions of various packing routines in +-@file{coffcode.h}. E.g., the size of line number entry in coff is +-sometimes 16 bits, and sometimes 32 bits. @code{#define}ing +-@code{PUT_LNSZ_LNNO} and @code{GET_LNSZ_LNNO} will select the +-correct one. No doubt, some day someone will find a version of +-coff which has a varying field size not catered to at the +-moment. To port BFD, that person will have to add more @code{#defines}. +-Three of the bit twiddling routines are exported to +-@code{gdb}; @code{coff_swap_aux_in}, @code{coff_swap_sym_in} +-and @code{coff_swap_lineno_in}. @code{GDB} reads the symbol +-table on its own, but uses BFD to fix things up. More of the +-bit twiddlers are exported for @code{gas}; +-@code{coff_swap_aux_out}, @code{coff_swap_sym_out}, +-@code{coff_swap_lineno_out}, @code{coff_swap_reloc_out}, +-@code{coff_swap_filehdr_out}, @code{coff_swap_aouthdr_out}, +-@code{coff_swap_scnhdr_out}. @code{Gas} currently keeps track +-of all the symbol table and reloc drudgery itself, thereby +-saving the internal BFD overhead, but uses BFD to swap things +-on the way out, making cross ports much safer. Doing so also +-allows BFD (and thus the linker) to use the same header files +-as @code{gas}, which makes one avenue to disaster disappear. +- +-@subsubsection Symbol reading +-The simple canonical form for symbols used by BFD is not rich +-enough to keep all the information available in a coff symbol +-table. The back end gets around this problem by keeping the original +-symbol table around, "behind the scenes". +- +-When a symbol table is requested (through a call to +-@code{bfd_canonicalize_symtab}), a request gets through to +-@code{coff_get_normalized_symtab}. This reads the symbol table from +-the coff file and swaps all the structures inside into the +-internal form. It also fixes up all the pointers in the table +-(represented in the file by offsets from the first symbol in +-the table) into physical pointers to elements in the new +-internal table. This involves some work since the meanings of +-fields change depending upon context: a field that is a +-pointer to another structure in the symbol table at one moment +-may be the size in bytes of a structure at the next. Another +-pass is made over the table. All symbols which mark file names +-(@code{C_FILE} symbols) are modified so that the internal +-string points to the value in the auxent (the real filename) +-rather than the normal text associated with the symbol +-(@code{".file"}). +- +-At this time the symbol names are moved around. Coff stores +-all symbols less than nine characters long physically +-within the symbol table; longer strings are kept at the end of +-the file in the string table. This pass moves all strings +-into memory and replaces them with pointers to the strings. +- +-The symbol table is massaged once again, this time to create +-the canonical table used by the BFD application. Each symbol +-is inspected in turn, and a decision made (using the +-@code{sclass} field) about the various flags to set in the +-@code{asymbol}. @xref{Symbols}. The generated canonical table +-shares strings with the hidden internal symbol table. +- +-Any linenumbers are read from the coff file too, and attached +-to the symbols which own the functions the linenumbers belong to. +- +-@subsubsection Symbol writing +-Writing a symbol to a coff file which didn't come from a coff +-file will lose any debugging information. The @code{asymbol} +-structure remembers the BFD from which the symbol was taken, and on +-output the back end makes sure that the same destination target as +-source target is present. +- +-When the symbols have come from a coff file then all the +-debugging information is preserved. +- +-Symbol tables are provided for writing to the back end in a +-vector of pointers to pointers. This allows applications like +-the linker to accumulate and output large symbol tables +-without having to do too much byte copying. +- +-This function runs through the provided symbol table and +-patches each symbol marked as a file place holder +-(@code{C_FILE}) to point to the next file place holder in the +-list. It also marks each @code{offset} field in the list with +-the offset from the first symbol of the current symbol. +- +-Another function of this procedure is to turn the canonical +-value form of BFD into the form used by coff. Internally, BFD +-expects symbol values to be offsets from a section base; so a +-symbol physically at 0x120, but in a section starting at +-0x100, would have the value 0x20. Coff expects symbols to +-contain their final value, so symbols have their values +-changed at this point to reflect their sum with their owning +-section. This transformation uses the +-@code{output_section} field of the @code{asymbol}'s +-@code{asection} @xref{Sections}. +- +-@itemize @bullet +- +-@item +-@code{coff_mangle_symbols} +-@end itemize +-This routine runs though the provided symbol table and uses +-the offsets generated by the previous pass and the pointers +-generated when the symbol table was read in to create the +-structured hierarchy required by coff. It changes each pointer +-to a symbol into the index into the symbol table of the asymbol. +- +-@itemize @bullet +- +-@item +-@code{coff_write_symbols} +-@end itemize +-This routine runs through the symbol table and patches up the +-symbols from their internal form into the coff way, calls the +-bit twiddlers, and writes out the table to the file. +- +-@findex coff_symbol_type +-@subsubsection @code{coff_symbol_type} +-@strong{Description}@* +-The hidden information for an @code{asymbol} is described in a +-@code{combined_entry_type}: +- +- +-@example +- +-typedef struct coff_ptr_struct +-@{ +- /* Remembers the offset from the first symbol in the file for +- this symbol. Generated by coff_renumber_symbols. */ +- unsigned int offset; +- +- /* Should the value of this symbol be renumbered. Used for +- XCOFF C_BSTAT symbols. Set by coff_slurp_symbol_table. */ +- unsigned int fix_value : 1; +- +- /* Should the tag field of this symbol be renumbered. +- Created by coff_pointerize_aux. */ +- unsigned int fix_tag : 1; +- +- /* Should the endidx field of this symbol be renumbered. +- Created by coff_pointerize_aux. */ +- unsigned int fix_end : 1; +- +- /* Should the x_csect.x_scnlen field be renumbered. +- Created by coff_pointerize_aux. */ +- unsigned int fix_scnlen : 1; +- +- /* Fix up an XCOFF C_BINCL/C_EINCL symbol. The value is the +- index into the line number entries. Set by coff_slurp_symbol_table. */ +- unsigned int fix_line : 1; +- +- /* The container for the symbol structure as read and translated +- from the file. */ +- union +- @{ +- union internal_auxent auxent; +- struct internal_syment syment; +- @} u; +-@} combined_entry_type; +- +- +-/* Each canonical asymbol really looks like this: */ +- +-typedef struct coff_symbol_struct +-@{ +- /* The actual symbol which the rest of BFD works with */ +- asymbol symbol; +- +- /* A pointer to the hidden information for this symbol */ +- combined_entry_type *native; +- +- /* A pointer to the linenumber information for this symbol */ +- struct lineno_cache_entry *lineno; +- +- /* Have the line numbers been relocated yet ? */ +- bfd_boolean done_lineno; +-@} coff_symbol_type; +-@end example +-@findex bfd_coff_backend_data +-@subsubsection @code{bfd_coff_backend_data} +- +-@example +-/* COFF symbol classifications. */ +- +-enum coff_symbol_classification +-@{ +- /* Global symbol. */ +- COFF_SYMBOL_GLOBAL, +- /* Common symbol. */ +- COFF_SYMBOL_COMMON, +- /* Undefined symbol. */ +- COFF_SYMBOL_UNDEFINED, +- /* Local symbol. */ +- COFF_SYMBOL_LOCAL, +- /* PE section symbol. */ +- COFF_SYMBOL_PE_SECTION +-@}; +- +-@end example +-Special entry points for gdb to swap in coff symbol table parts: +-@example +-typedef struct +-@{ +- void (*_bfd_coff_swap_aux_in) +- (bfd *, void *, int, int, int, int, void *); +- +- void (*_bfd_coff_swap_sym_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_lineno_in) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_aux_out) +- (bfd *, void *, int, int, int, int, void *); +- +- unsigned int (*_bfd_coff_swap_sym_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_lineno_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_reloc_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_filehdr_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_aouthdr_out) +- (bfd *, void *, void *); +- +- unsigned int (*_bfd_coff_swap_scnhdr_out) +- (bfd *, void *, void *); +- +- unsigned int _bfd_filhsz; +- unsigned int _bfd_aoutsz; +- unsigned int _bfd_scnhsz; +- unsigned int _bfd_symesz; +- unsigned int _bfd_auxesz; +- unsigned int _bfd_relsz; +- unsigned int _bfd_linesz; +- unsigned int _bfd_filnmlen; +- bfd_boolean _bfd_coff_long_filenames; +- +- bfd_boolean _bfd_coff_long_section_names; +- bfd_boolean (*_bfd_coff_set_long_section_names) +- (bfd *, int); +- +- unsigned int _bfd_coff_default_section_alignment_power; +- bfd_boolean _bfd_coff_force_symnames_in_strings; +- unsigned int _bfd_coff_debug_string_prefix_length; +- +- void (*_bfd_coff_swap_filehdr_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_aouthdr_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_scnhdr_in) +- (bfd *, void *, void *); +- +- void (*_bfd_coff_swap_reloc_in) +- (bfd *abfd, void *, void *); +- +- bfd_boolean (*_bfd_coff_bad_format_hook) +- (bfd *, void *); +- +- bfd_boolean (*_bfd_coff_set_arch_mach_hook) +- (bfd *, void *); +- +- void * (*_bfd_coff_mkobject_hook) +- (bfd *, void *, void *); +- +- bfd_boolean (*_bfd_styp_to_sec_flags_hook) +- (bfd *, void *, const char *, asection *, flagword *); +- +- void (*_bfd_set_alignment_hook) +- (bfd *, asection *, void *); +- +- bfd_boolean (*_bfd_coff_slurp_symbol_table) +- (bfd *); +- +- bfd_boolean (*_bfd_coff_symname_in_debug) +- (bfd *, struct internal_syment *); +- +- bfd_boolean (*_bfd_coff_pointerize_aux_hook) +- (bfd *, combined_entry_type *, combined_entry_type *, +- unsigned int, combined_entry_type *); +- +- bfd_boolean (*_bfd_coff_print_aux) +- (bfd *, FILE *, combined_entry_type *, combined_entry_type *, +- combined_entry_type *, unsigned int); +- +- void (*_bfd_coff_reloc16_extra_cases) +- (bfd *, struct bfd_link_info *, struct bfd_link_order *, arelent *, +- bfd_byte *, unsigned int *, unsigned int *); +- +- int (*_bfd_coff_reloc16_estimate) +- (bfd *, asection *, arelent *, unsigned int, +- struct bfd_link_info *); +- +- enum coff_symbol_classification (*_bfd_coff_classify_symbol) +- (bfd *, struct internal_syment *); +- +- bfd_boolean (*_bfd_coff_compute_section_file_positions) +- (bfd *); +- +- bfd_boolean (*_bfd_coff_start_final_link) +- (bfd *, struct bfd_link_info *); +- +- bfd_boolean (*_bfd_coff_relocate_section) +- (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, +- struct internal_reloc *, struct internal_syment *, asection **); +- +- reloc_howto_type *(*_bfd_coff_rtype_to_howto) +- (bfd *, asection *, struct internal_reloc *, +- struct coff_link_hash_entry *, struct internal_syment *, +- bfd_vma *); +- +- bfd_boolean (*_bfd_coff_adjust_symndx) +- (bfd *, struct bfd_link_info *, bfd *, asection *, +- struct internal_reloc *, bfd_boolean *); +- +- bfd_boolean (*_bfd_coff_link_add_one_symbol) +- (struct bfd_link_info *, bfd *, const char *, flagword, +- asection *, bfd_vma, const char *, bfd_boolean, bfd_boolean, +- struct bfd_link_hash_entry **); +- +- bfd_boolean (*_bfd_coff_link_output_has_begun) +- (bfd *, struct coff_final_link_info *); +- +- bfd_boolean (*_bfd_coff_final_link_postscript) +- (bfd *, struct coff_final_link_info *); +- +- bfd_boolean (*_bfd_coff_print_pdata) +- (bfd *, void *); +- +-@} bfd_coff_backend_data; +- +-#define coff_backend_info(abfd) \ +- ((bfd_coff_backend_data *) (abfd)->xvec->backend_data) +- +-#define bfd_coff_swap_aux_in(a,e,t,c,ind,num,i) \ +- ((coff_backend_info (a)->_bfd_coff_swap_aux_in) (a,e,t,c,ind,num,i)) +- +-#define bfd_coff_swap_sym_in(a,e,i) \ +- ((coff_backend_info (a)->_bfd_coff_swap_sym_in) (a,e,i)) +- +-#define bfd_coff_swap_lineno_in(a,e,i) \ +- ((coff_backend_info ( a)->_bfd_coff_swap_lineno_in) (a,e,i)) +- +-#define bfd_coff_swap_reloc_out(abfd, i, o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_out) (abfd, i, o)) +- +-#define bfd_coff_swap_lineno_out(abfd, i, o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_lineno_out) (abfd, i, o)) +- +-#define bfd_coff_swap_aux_out(a,i,t,c,ind,num,o) \ +- ((coff_backend_info (a)->_bfd_coff_swap_aux_out) (a,i,t,c,ind,num,o)) +- +-#define bfd_coff_swap_sym_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_sym_out) (abfd, i, o)) +- +-#define bfd_coff_swap_scnhdr_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_out) (abfd, i, o)) +- +-#define bfd_coff_swap_filehdr_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_out) (abfd, i, o)) +- +-#define bfd_coff_swap_aouthdr_out(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_out) (abfd, i, o)) +- +-#define bfd_coff_filhsz(abfd) (coff_backend_info (abfd)->_bfd_filhsz) +-#define bfd_coff_aoutsz(abfd) (coff_backend_info (abfd)->_bfd_aoutsz) +-#define bfd_coff_scnhsz(abfd) (coff_backend_info (abfd)->_bfd_scnhsz) +-#define bfd_coff_symesz(abfd) (coff_backend_info (abfd)->_bfd_symesz) +-#define bfd_coff_auxesz(abfd) (coff_backend_info (abfd)->_bfd_auxesz) +-#define bfd_coff_relsz(abfd) (coff_backend_info (abfd)->_bfd_relsz) +-#define bfd_coff_linesz(abfd) (coff_backend_info (abfd)->_bfd_linesz) +-#define bfd_coff_filnmlen(abfd) (coff_backend_info (abfd)->_bfd_filnmlen) +-#define bfd_coff_long_filenames(abfd) \ +- (coff_backend_info (abfd)->_bfd_coff_long_filenames) +-#define bfd_coff_long_section_names(abfd) \ +- (coff_backend_info (abfd)->_bfd_coff_long_section_names) +-#define bfd_coff_set_long_section_names(abfd, enable) \ +- ((coff_backend_info (abfd)->_bfd_coff_set_long_section_names) (abfd, enable)) +-#define bfd_coff_default_section_alignment_power(abfd) \ +- (coff_backend_info (abfd)->_bfd_coff_default_section_alignment_power) +-#define bfd_coff_swap_filehdr_in(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_filehdr_in) (abfd, i, o)) +- +-#define bfd_coff_swap_aouthdr_in(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_aouthdr_in) (abfd, i, o)) +- +-#define bfd_coff_swap_scnhdr_in(abfd, i,o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_scnhdr_in) (abfd, i, o)) +- +-#define bfd_coff_swap_reloc_in(abfd, i, o) \ +- ((coff_backend_info (abfd)->_bfd_coff_swap_reloc_in) (abfd, i, o)) +- +-#define bfd_coff_bad_format_hook(abfd, filehdr) \ +- ((coff_backend_info (abfd)->_bfd_coff_bad_format_hook) (abfd, filehdr)) +- +-#define bfd_coff_set_arch_mach_hook(abfd, filehdr)\ +- ((coff_backend_info (abfd)->_bfd_coff_set_arch_mach_hook) (abfd, filehdr)) +-#define bfd_coff_mkobject_hook(abfd, filehdr, aouthdr)\ +- ((coff_backend_info (abfd)->_bfd_coff_mkobject_hook)\ +- (abfd, filehdr, aouthdr)) +- +-#define bfd_coff_styp_to_sec_flags_hook(abfd, scnhdr, name, section, flags_ptr)\ +- ((coff_backend_info (abfd)->_bfd_styp_to_sec_flags_hook)\ +- (abfd, scnhdr, name, section, flags_ptr)) +- +-#define bfd_coff_set_alignment_hook(abfd, sec, scnhdr)\ +- ((coff_backend_info (abfd)->_bfd_set_alignment_hook) (abfd, sec, scnhdr)) +- +-#define bfd_coff_slurp_symbol_table(abfd)\ +- ((coff_backend_info (abfd)->_bfd_coff_slurp_symbol_table) (abfd)) +- +-#define bfd_coff_symname_in_debug(abfd, sym)\ +- ((coff_backend_info (abfd)->_bfd_coff_symname_in_debug) (abfd, sym)) +- +-#define bfd_coff_force_symnames_in_strings(abfd)\ +- (coff_backend_info (abfd)->_bfd_coff_force_symnames_in_strings) +- +-#define bfd_coff_debug_string_prefix_length(abfd)\ +- (coff_backend_info (abfd)->_bfd_coff_debug_string_prefix_length) +- +-#define bfd_coff_print_aux(abfd, file, base, symbol, aux, indaux)\ +- ((coff_backend_info (abfd)->_bfd_coff_print_aux)\ +- (abfd, file, base, symbol, aux, indaux)) +- +-#define bfd_coff_reloc16_extra_cases(abfd, link_info, link_order,\ +- reloc, data, src_ptr, dst_ptr)\ +- ((coff_backend_info (abfd)->_bfd_coff_reloc16_extra_cases)\ +- (abfd, link_info, link_order, reloc, data, src_ptr, dst_ptr)) +- +-#define bfd_coff_reloc16_estimate(abfd, section, reloc, shrink, link_info)\ +- ((coff_backend_info (abfd)->_bfd_coff_reloc16_estimate)\ +- (abfd, section, reloc, shrink, link_info)) +- +-#define bfd_coff_classify_symbol(abfd, sym)\ +- ((coff_backend_info (abfd)->_bfd_coff_classify_symbol)\ +- (abfd, sym)) +- +-#define bfd_coff_compute_section_file_positions(abfd)\ +- ((coff_backend_info (abfd)->_bfd_coff_compute_section_file_positions)\ +- (abfd)) +- +-#define bfd_coff_start_final_link(obfd, info)\ +- ((coff_backend_info (obfd)->_bfd_coff_start_final_link)\ +- (obfd, info)) +-#define bfd_coff_relocate_section(obfd,info,ibfd,o,con,rel,isyms,secs)\ +- ((coff_backend_info (ibfd)->_bfd_coff_relocate_section)\ +- (obfd, info, ibfd, o, con, rel, isyms, secs)) +-#define bfd_coff_rtype_to_howto(abfd, sec, rel, h, sym, addendp)\ +- ((coff_backend_info (abfd)->_bfd_coff_rtype_to_howto)\ +- (abfd, sec, rel, h, sym, addendp)) +-#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\ +- ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\ +- (obfd, info, ibfd, sec, rel, adjustedp)) +-#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\ +- value, string, cp, coll, hashp)\ +- ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\ +- (info, abfd, name, flags, section, value, string, cp, coll, hashp)) +- +-#define bfd_coff_link_output_has_begun(a,p) \ +- ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p)) +-#define bfd_coff_final_link_postscript(a,p) \ +- ((coff_backend_info (a)->_bfd_coff_final_link_postscript) (a, p)) +- +-#define bfd_coff_have_print_pdata(a) \ +- (coff_backend_info (a)->_bfd_coff_print_pdata) +-#define bfd_coff_print_pdata(a,p) \ +- ((coff_backend_info (a)->_bfd_coff_print_pdata) (a, p)) +- +-/* Macro: Returns true if the bfd is a PE executable as opposed to a +- PE object file. */ +-#define bfd_pei_p(abfd) \ +- (CONST_STRNEQ ((abfd)->xvec->name, "pei-")) +-@end example +-@subsubsection Writing relocations +-To write relocations, the back end steps though the +-canonical relocation table and create an +-@code{internal_reloc}. The symbol index to use is removed from +-the @code{offset} field in the symbol table supplied. The +-address comes directly from the sum of the section base +-address and the relocation offset; the type is dug directly +-from the howto field. Then the @code{internal_reloc} is +-swapped into the shape of an @code{external_reloc} and written +-out to disk. +- +-@subsubsection Reading linenumbers +-Creating the linenumber table is done by reading in the entire +-coff linenumber table, and creating another table for internal use. +- +-A coff linenumber table is structured so that each function +-is marked as having a line number of 0. Each line within the +-function is an offset from the first line in the function. The +-base of the line number information for the table is stored in +-the symbol associated with the function. +- +-Note: The PE format uses line number 0 for a flag indicating a +-new source file. +- +-The information is copied from the external to the internal +-table, and each symbol which marks a function is marked by +-pointing its... +- +-How does this work ? +- +-@subsubsection Reading relocations +-Coff relocations are easily transformed into the internal BFD form +-(@code{arelent}). +- +-Reading a coff relocation table is done in the following stages: +- +-@itemize @bullet +- +-@item +-Read the entire coff relocation table into memory. +- +-@item +-Process each relocation in turn; first swap it from the +-external to the internal form. +- +-@item +-Turn the symbol referenced in the relocation's symbol index +-into a pointer into the canonical symbol table. +-This table is the same as the one returned by a call to +-@code{bfd_canonicalize_symtab}. The back end will call that +-routine and save the result if a canonicalization hasn't been done. +- +-@item +-The reloc index is turned into a pointer to a howto +-structure, in a back end specific way. For instance, the 386 +-and 960 use the @code{r_type} to directly produce an index +-into a howto table vector; the 88k subtracts a number from the +-@code{r_type} field and creates an addend field. +-@end itemize +- +diff -Nur binutils-2.24.orig/bfd/doc/core.texi binutils-2.24/bfd/doc/core.texi +--- binutils-2.24.orig/bfd/doc/core.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/core.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,70 +0,0 @@ +-@section Core files +- +- +-@subsection Core file functions +- +- +-@strong{Description}@* +-These are functions pertaining to core files. +- +-@findex bfd_core_file_failing_command +-@subsubsection @code{bfd_core_file_failing_command} +-@strong{Synopsis} +-@example +-const char *bfd_core_file_failing_command (bfd *abfd); +-@end example +-@strong{Description}@* +-Return a read-only string explaining which program was running +-when it failed and produced the core file @var{abfd}. +- +-@findex bfd_core_file_failing_signal +-@subsubsection @code{bfd_core_file_failing_signal} +-@strong{Synopsis} +-@example +-int bfd_core_file_failing_signal (bfd *abfd); +-@end example +-@strong{Description}@* +-Returns the signal number which caused the core dump which +-generated the file the BFD @var{abfd} is attached to. +- +-@findex bfd_core_file_pid +-@subsubsection @code{bfd_core_file_pid} +-@strong{Synopsis} +-@example +-int bfd_core_file_pid (bfd *abfd); +-@end example +-@strong{Description}@* +-Returns the PID of the process the core dump the BFD +-@var{abfd} is attached to was generated from. +- +-@findex core_file_matches_executable_p +-@subsubsection @code{core_file_matches_executable_p} +-@strong{Synopsis} +-@example +-bfd_boolean core_file_matches_executable_p +- (bfd *core_bfd, bfd *exec_bfd); +-@end example +-@strong{Description}@* +-Return @code{TRUE} if the core file attached to @var{core_bfd} +-was generated by a run of the executable file attached to +-@var{exec_bfd}, @code{FALSE} otherwise. +- +-@findex generic_core_file_matches_executable_p +-@subsubsection @code{generic_core_file_matches_executable_p} +-@strong{Synopsis} +-@example +-bfd_boolean generic_core_file_matches_executable_p +- (bfd *core_bfd, bfd *exec_bfd); +-@end example +-@strong{Description}@* +-Return TRUE if the core file attached to @var{core_bfd} +-was generated by a run of the executable file attached +-to @var{exec_bfd}. The match is based on executable +-basenames only. +- +-Note: When not able to determine the core file failing +-command or the executable name, we still return TRUE even +-though we're not sure that core file and executable match. +-This is to avoid generating a false warning in situations +-where we really don't know whether they match or not. +- +diff -Nur binutils-2.24.orig/bfd/doc/elf.texi binutils-2.24/bfd/doc/elf.texi +--- binutils-2.24.orig/bfd/doc/elf.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/elf.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,9 +0,0 @@ +-@section ELF backends +-BFD support for ELF formats is being worked on. +-Currently, the best supported back ends are for sparc and i386 +-(running svr4 or Solaris 2). +- +-Documentation of the internals of the support code still needs +-to be written. The code is changing quickly enough that we +-haven't bothered yet. +- +diff -Nur binutils-2.24.orig/bfd/doc/format.texi binutils-2.24/bfd/doc/format.texi +--- binutils-2.24.orig/bfd/doc/format.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/format.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,112 +0,0 @@ +-@section File formats +-A format is a BFD concept of high level file contents type. The +-formats supported by BFD are: +- +-@itemize @bullet +- +-@item +-@code{bfd_object} +-@end itemize +-The BFD may contain data, symbols, relocations and debug info. +- +-@itemize @bullet +- +-@item +-@code{bfd_archive} +-@end itemize +-The BFD contains other BFDs and an optional index. +- +-@itemize @bullet +- +-@item +-@code{bfd_core} +-@end itemize +-The BFD contains the result of an executable core dump. +- +-@subsection File format functions +- +- +-@findex bfd_check_format +-@subsubsection @code{bfd_check_format} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); +-@end example +-@strong{Description}@* +-Verify if the file attached to the BFD @var{abfd} is compatible +-with the format @var{format} (i.e., one of @code{bfd_object}, +-@code{bfd_archive} or @code{bfd_core}). +- +-If the BFD has been set to a specific target before the +-call, only the named target and format combination is +-checked. If the target has not been set, or has been set to +-@code{default}, then all the known target backends is +-interrogated to determine a match. If the default target +-matches, it is used. If not, exactly one target must recognize +-the file, or an error results. +- +-The function returns @code{TRUE} on success, otherwise @code{FALSE} +-with one of the following error codes: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_invalid_operation} - +-if @code{format} is not one of @code{bfd_object}, @code{bfd_archive} or +-@code{bfd_core}. +- +-@item +-@code{bfd_error_system_call} - +-if an error occured during a read - even some file mismatches +-can cause bfd_error_system_calls. +- +-@item +-@code{file_not_recognised} - +-none of the backends recognised the file format. +- +-@item +-@code{bfd_error_file_ambiguously_recognized} - +-more than one backend recognised the file format. +-@end itemize +- +-@findex bfd_check_format_matches +-@subsubsection @code{bfd_check_format_matches} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_check_format_matches +- (bfd *abfd, bfd_format format, char ***matching); +-@end example +-@strong{Description}@* +-Like @code{bfd_check_format}, except when it returns FALSE with +-@code{bfd_errno} set to @code{bfd_error_file_ambiguously_recognized}. In that +-case, if @var{matching} is not NULL, it will be filled in with +-a NULL-terminated list of the names of the formats that matched, +-allocated with @code{malloc}. +-Then the user may choose a format and try again. +- +-When done with the list that @var{matching} points to, the caller +-should free it. +- +-@findex bfd_set_format +-@subsubsection @code{bfd_set_format} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); +-@end example +-@strong{Description}@* +-This function sets the file format of the BFD @var{abfd} to the +-format @var{format}. If the target set in the BFD does not +-support the format requested, the format is invalid, or the BFD +-is not open for writing, then an error occurs. +- +-@findex bfd_format_string +-@subsubsection @code{bfd_format_string} +-@strong{Synopsis} +-@example +-const char *bfd_format_string (bfd_format format); +-@end example +-@strong{Description}@* +-Return a pointer to a const string +-@code{invalid}, @code{object}, @code{archive}, @code{core}, or @code{unknown}, +-depending upon the value of @var{format}. +- +diff -Nur binutils-2.24.orig/bfd/doc/hash.texi binutils-2.24/bfd/doc/hash.texi +--- binutils-2.24.orig/bfd/doc/hash.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/hash.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,247 +0,0 @@ +-@section Hash Tables +-@cindex Hash tables +-BFD provides a simple set of hash table functions. Routines +-are provided to initialize a hash table, to free a hash table, +-to look up a string in a hash table and optionally create an +-entry for it, and to traverse a hash table. There is +-currently no routine to delete an string from a hash table. +- +-The basic hash table does not permit any data to be stored +-with a string. However, a hash table is designed to present a +-base class from which other types of hash tables may be +-derived. These derived types may store additional information +-with the string. Hash tables were implemented in this way, +-rather than simply providing a data pointer in a hash table +-entry, because they were designed for use by the linker back +-ends. The linker may create thousands of hash table entries, +-and the overhead of allocating private data and storing and +-following pointers becomes noticeable. +- +-The basic hash table code is in @code{hash.c}. +- +-@menu +-* Creating and Freeing a Hash Table:: +-* Looking Up or Entering a String:: +-* Traversing a Hash Table:: +-* Deriving a New Hash Table Type:: +-@end menu +- +-@node Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables +-@subsection Creating and freeing a hash table +-@findex bfd_hash_table_init +-@findex bfd_hash_table_init_n +-To create a hash table, create an instance of a @code{struct +-bfd_hash_table} (defined in @code{bfd.h}) and call +-@code{bfd_hash_table_init} (if you know approximately how many +-entries you will need, the function @code{bfd_hash_table_init_n}, +-which takes a @var{size} argument, may be used). +-@code{bfd_hash_table_init} returns @code{FALSE} if some sort of +-error occurs. +- +-@findex bfd_hash_newfunc +-The function @code{bfd_hash_table_init} take as an argument a +-function to use to create new entries. For a basic hash +-table, use the function @code{bfd_hash_newfunc}. @xref{Deriving +-a New Hash Table Type}, for why you would want to use a +-different value for this argument. +- +-@findex bfd_hash_allocate +-@code{bfd_hash_table_init} will create an objalloc which will be +-used to allocate new entries. You may allocate memory on this +-objalloc using @code{bfd_hash_allocate}. +- +-@findex bfd_hash_table_free +-Use @code{bfd_hash_table_free} to free up all the memory that has +-been allocated for a hash table. This will not free up the +-@code{struct bfd_hash_table} itself, which you must provide. +- +-@findex bfd_hash_set_default_size +-Use @code{bfd_hash_set_default_size} to set the default size of +-hash table to use. +- +-@node Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables +-@subsection Looking up or entering a string +-@findex bfd_hash_lookup +-The function @code{bfd_hash_lookup} is used both to look up a +-string in the hash table and to create a new entry. +- +-If the @var{create} argument is @code{FALSE}, @code{bfd_hash_lookup} +-will look up a string. If the string is found, it will +-returns a pointer to a @code{struct bfd_hash_entry}. If the +-string is not found in the table @code{bfd_hash_lookup} will +-return @code{NULL}. You should not modify any of the fields in +-the returns @code{struct bfd_hash_entry}. +- +-If the @var{create} argument is @code{TRUE}, the string will be +-entered into the hash table if it is not already there. +-Either way a pointer to a @code{struct bfd_hash_entry} will be +-returned, either to the existing structure or to a newly +-created one. In this case, a @code{NULL} return means that an +-error occurred. +- +-If the @var{create} argument is @code{TRUE}, and a new entry is +-created, the @var{copy} argument is used to decide whether to +-copy the string onto the hash table objalloc or not. If +-@var{copy} is passed as @code{FALSE}, you must be careful not to +-deallocate or modify the string as long as the hash table +-exists. +- +-@node Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables +-@subsection Traversing a hash table +-@findex bfd_hash_traverse +-The function @code{bfd_hash_traverse} may be used to traverse a +-hash table, calling a function on each element. The traversal +-is done in a random order. +- +-@code{bfd_hash_traverse} takes as arguments a function and a +-generic @code{void *} pointer. The function is called with a +-hash table entry (a @code{struct bfd_hash_entry *}) and the +-generic pointer passed to @code{bfd_hash_traverse}. The function +-must return a @code{boolean} value, which indicates whether to +-continue traversing the hash table. If the function returns +-@code{FALSE}, @code{bfd_hash_traverse} will stop the traversal and +-return immediately. +- +-@node Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables +-@subsection Deriving a new hash table type +-Many uses of hash tables want to store additional information +-which each entry in the hash table. Some also find it +-convenient to store additional information with the hash table +-itself. This may be done using a derived hash table. +- +-Since C is not an object oriented language, creating a derived +-hash table requires sticking together some boilerplate +-routines with a few differences specific to the type of hash +-table you want to create. +- +-An example of a derived hash table is the linker hash table. +-The structures for this are defined in @code{bfdlink.h}. The +-functions are in @code{linker.c}. +- +-You may also derive a hash table from an already derived hash +-table. For example, the a.out linker backend code uses a hash +-table derived from the linker hash table. +- +-@menu +-* Define the Derived Structures:: +-* Write the Derived Creation Routine:: +-* Write Other Derived Routines:: +-@end menu +- +-@node Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type +-@subsubsection Define the derived structures +-You must define a structure for an entry in the hash table, +-and a structure for the hash table itself. +- +-The first field in the structure for an entry in the hash +-table must be of the type used for an entry in the hash table +-you are deriving from. If you are deriving from a basic hash +-table this is @code{struct bfd_hash_entry}, which is defined in +-@code{bfd.h}. The first field in the structure for the hash +-table itself must be of the type of the hash table you are +-deriving from itself. If you are deriving from a basic hash +-table, this is @code{struct bfd_hash_table}. +- +-For example, the linker hash table defines @code{struct +-bfd_link_hash_entry} (in @code{bfdlink.h}). The first field, +-@code{root}, is of type @code{struct bfd_hash_entry}. Similarly, +-the first field in @code{struct bfd_link_hash_table}, @code{table}, +-is of type @code{struct bfd_hash_table}. +- +-@node Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type +-@subsubsection Write the derived creation routine +-You must write a routine which will create and initialize an +-entry in the hash table. This routine is passed as the +-function argument to @code{bfd_hash_table_init}. +- +-In order to permit other hash tables to be derived from the +-hash table you are creating, this routine must be written in a +-standard way. +- +-The first argument to the creation routine is a pointer to a +-hash table entry. This may be @code{NULL}, in which case the +-routine should allocate the right amount of space. Otherwise +-the space has already been allocated by a hash table type +-derived from this one. +- +-After allocating space, the creation routine must call the +-creation routine of the hash table type it is derived from, +-passing in a pointer to the space it just allocated. This +-will initialize any fields used by the base hash table. +- +-Finally the creation routine must initialize any local fields +-for the new hash table type. +- +-Here is a boilerplate example of a creation routine. +-@var{function_name} is the name of the routine. +-@var{entry_type} is the type of an entry in the hash table you +-are creating. @var{base_newfunc} is the name of the creation +-routine of the hash table type your hash table is derived +-from. +- +- +-@example +-struct bfd_hash_entry * +-@var{function_name} (struct bfd_hash_entry *entry, +- struct bfd_hash_table *table, +- const char *string) +-@{ +- struct @var{entry_type} *ret = (@var{entry_type} *) entry; +- +- /* Allocate the structure if it has not already been allocated by a +- derived class. */ +- if (ret == NULL) +- @{ +- ret = bfd_hash_allocate (table, sizeof (* ret)); +- if (ret == NULL) +- return NULL; +- @} +- +- /* Call the allocation method of the base class. */ +- ret = ((@var{entry_type} *) +- @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string)); +- +- /* Initialize the local fields here. */ +- +- return (struct bfd_hash_entry *) ret; +-@} +-@end example +-@strong{Description}@* +-The creation routine for the linker hash table, which is in +-@code{linker.c}, looks just like this example. +-@var{function_name} is @code{_bfd_link_hash_newfunc}. +-@var{entry_type} is @code{struct bfd_link_hash_entry}. +-@var{base_newfunc} is @code{bfd_hash_newfunc}, the creation +-routine for a basic hash table. +- +-@code{_bfd_link_hash_newfunc} also initializes the local fields +-in a linker hash table entry: @code{type}, @code{written} and +-@code{next}. +- +-@node Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type +-@subsubsection Write other derived routines +-You will want to write other routines for your new hash table, +-as well. +- +-You will want an initialization routine which calls the +-initialization routine of the hash table you are deriving from +-and initializes any other local fields. For the linker hash +-table, this is @code{_bfd_link_hash_table_init} in @code{linker.c}. +- +-You will want a lookup routine which calls the lookup routine +-of the hash table you are deriving from and casts the result. +-The linker hash table uses @code{bfd_link_hash_lookup} in +-@code{linker.c} (this actually takes an additional argument which +-it uses to decide how to return the looked up value). +- +-You may want a traversal routine. This should just call the +-traversal routine of the hash table you are deriving from with +-appropriate casts. The linker hash table uses +-@code{bfd_link_hash_traverse} in @code{linker.c}. +- +-These routines may simply be defined as macros. For example, +-the a.out backend linker hash table, which is derived from the +-linker hash table, uses macros for the lookup and traversal +-routines. These are @code{aout_link_hash_lookup} and +-@code{aout_link_hash_traverse} in aoutx.h. +- +diff -Nur binutils-2.24.orig/bfd/doc/init.texi binutils-2.24/bfd/doc/init.texi +--- binutils-2.24.orig/bfd/doc/init.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/init.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,16 +0,0 @@ +-@section Initialization +- +- +-@subsection Initialization functions +-These are the functions that handle initializing a BFD. +- +-@findex bfd_init +-@subsubsection @code{bfd_init} +-@strong{Synopsis} +-@example +-void bfd_init (void); +-@end example +-@strong{Description}@* +-This routine must be called before any other BFD function to +-initialize magical internal data structures. +- +diff -Nur binutils-2.24.orig/bfd/doc/libbfd.texi binutils-2.24/bfd/doc/libbfd.texi +--- binutils-2.24.orig/bfd/doc/libbfd.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/libbfd.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,179 +0,0 @@ +-@section Implementation details +- +- +-@subsection Internal functions +- +- +-@strong{Description}@* +-These routines are used within BFD. +-They are not intended for export, but are documented here for +-completeness. +- +-@findex bfd_write_bigendian_4byte_int +-@subsubsection @code{bfd_write_bigendian_4byte_int} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int); +-@end example +-@strong{Description}@* +-Write a 4 byte integer @var{i} to the output BFD @var{abfd}, in big +-endian order regardless of what else is going on. This is useful in +-archives. +- +-@findex bfd_put_size +-@subsubsection @code{bfd_put_size} +-@findex bfd_get_size +-@subsubsection @code{bfd_get_size} +-@strong{Description}@* +-These macros as used for reading and writing raw data in +-sections; each access (except for bytes) is vectored through +-the target format of the BFD and mangled accordingly. The +-mangling performs any necessary endian translations and +-removes alignment restrictions. Note that types accepted and +-returned by these macros are identical so they can be swapped +-around in macros---for example, @file{libaout.h} defines @code{GET_WORD} +-to either @code{bfd_get_32} or @code{bfd_get_64}. +- +-In the put routines, @var{val} must be a @code{bfd_vma}. If we are on a +-system without prototypes, the caller is responsible for making +-sure that is true, with a cast if necessary. We don't cast +-them in the macro definitions because that would prevent @code{lint} +-or @code{gcc -Wall} from detecting sins such as passing a pointer. +-To detect calling these with less than a @code{bfd_vma}, use +-@code{gcc -Wconversion} on a host with 64 bit @code{bfd_vma}'s. +-@example +- +-/* Byte swapping macros for user section data. */ +- +-#define bfd_put_8(abfd, val, ptr) \ +- ((void) (*((unsigned char *) (ptr)) = (val) & 0xff)) +-#define bfd_put_signed_8 \ +- bfd_put_8 +-#define bfd_get_8(abfd, ptr) \ +- (*(const unsigned char *) (ptr) & 0xff) +-#define bfd_get_signed_8(abfd, ptr) \ +- (((*(const unsigned char *) (ptr) & 0xff) ^ 0x80) - 0x80) +- +-#define bfd_put_16(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_putx16, ((val),(ptr))) +-#define bfd_put_signed_16 \ +- bfd_put_16 +-#define bfd_get_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx16, (ptr)) +-#define bfd_get_signed_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx_signed_16, (ptr)) +- +-#define bfd_put_32(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_putx32, ((val),(ptr))) +-#define bfd_put_signed_32 \ +- bfd_put_32 +-#define bfd_get_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx32, (ptr)) +-#define bfd_get_signed_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx_signed_32, (ptr)) +- +-#define bfd_put_64(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_putx64, ((val), (ptr))) +-#define bfd_put_signed_64 \ +- bfd_put_64 +-#define bfd_get_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx64, (ptr)) +-#define bfd_get_signed_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_getx_signed_64, (ptr)) +- +-#define bfd_get(bits, abfd, ptr) \ +- ((bits) == 8 ? (bfd_vma) bfd_get_8 (abfd, ptr) \ +- : (bits) == 16 ? bfd_get_16 (abfd, ptr) \ +- : (bits) == 32 ? bfd_get_32 (abfd, ptr) \ +- : (bits) == 64 ? bfd_get_64 (abfd, ptr) \ +- : (abort (), (bfd_vma) - 1)) +- +-#define bfd_put(bits, abfd, val, ptr) \ +- ((bits) == 8 ? bfd_put_8 (abfd, val, ptr) \ +- : (bits) == 16 ? bfd_put_16 (abfd, val, ptr) \ +- : (bits) == 32 ? bfd_put_32 (abfd, val, ptr) \ +- : (bits) == 64 ? bfd_put_64 (abfd, val, ptr) \ +- : (abort (), (void) 0)) +- +-@end example +- +-@findex bfd_h_put_size +-@subsubsection @code{bfd_h_put_size} +-@strong{Description}@* +-These macros have the same function as their @code{bfd_get_x} +-brethren, except that they are used for removing information +-for the header records of object files. Believe it or not, +-some object files keep their header records in big endian +-order and their data in little endian order. +-@example +- +-/* Byte swapping macros for file header data. */ +- +-#define bfd_h_put_8(abfd, val, ptr) \ +- bfd_put_8 (abfd, val, ptr) +-#define bfd_h_put_signed_8(abfd, val, ptr) \ +- bfd_put_8 (abfd, val, ptr) +-#define bfd_h_get_8(abfd, ptr) \ +- bfd_get_8 (abfd, ptr) +-#define bfd_h_get_signed_8(abfd, ptr) \ +- bfd_get_signed_8 (abfd, ptr) +- +-#define bfd_h_put_16(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_h_putx16, (val, ptr)) +-#define bfd_h_put_signed_16 \ +- bfd_h_put_16 +-#define bfd_h_get_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx16, (ptr)) +-#define bfd_h_get_signed_16(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx_signed_16, (ptr)) +- +-#define bfd_h_put_32(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_h_putx32, (val, ptr)) +-#define bfd_h_put_signed_32 \ +- bfd_h_put_32 +-#define bfd_h_get_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx32, (ptr)) +-#define bfd_h_get_signed_32(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx_signed_32, (ptr)) +- +-#define bfd_h_put_64(abfd, val, ptr) \ +- BFD_SEND (abfd, bfd_h_putx64, (val, ptr)) +-#define bfd_h_put_signed_64 \ +- bfd_h_put_64 +-#define bfd_h_get_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx64, (ptr)) +-#define bfd_h_get_signed_64(abfd, ptr) \ +- BFD_SEND (abfd, bfd_h_getx_signed_64, (ptr)) +- +-/* Aliases for the above, which should eventually go away. */ +- +-#define H_PUT_64 bfd_h_put_64 +-#define H_PUT_32 bfd_h_put_32 +-#define H_PUT_16 bfd_h_put_16 +-#define H_PUT_8 bfd_h_put_8 +-#define H_PUT_S64 bfd_h_put_signed_64 +-#define H_PUT_S32 bfd_h_put_signed_32 +-#define H_PUT_S16 bfd_h_put_signed_16 +-#define H_PUT_S8 bfd_h_put_signed_8 +-#define H_GET_64 bfd_h_get_64 +-#define H_GET_32 bfd_h_get_32 +-#define H_GET_16 bfd_h_get_16 +-#define H_GET_8 bfd_h_get_8 +-#define H_GET_S64 bfd_h_get_signed_64 +-#define H_GET_S32 bfd_h_get_signed_32 +-#define H_GET_S16 bfd_h_get_signed_16 +-#define H_GET_S8 bfd_h_get_signed_8 +- +- +-@end example +- +-@findex bfd_log2 +-@subsubsection @code{bfd_log2} +-@strong{Synopsis} +-@example +-unsigned int bfd_log2 (bfd_vma x); +-@end example +-@strong{Description}@* +-Return the log base 2 of the value supplied, rounded up. E.g., an +-@var{x} of 1025 returns 11. A @var{x} of 0 returns 0. +- +diff -Nur binutils-2.24.orig/bfd/doc/linker.texi binutils-2.24/bfd/doc/linker.texi +--- binutils-2.24.orig/bfd/doc/linker.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/linker.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,432 +0,0 @@ +-@section Linker Functions +-@cindex Linker +-The linker uses three special entry points in the BFD target +-vector. It is not necessary to write special routines for +-these entry points when creating a new BFD back end, since +-generic versions are provided. However, writing them can +-speed up linking and make it use significantly less runtime +-memory. +- +-The first routine creates a hash table used by the other +-routines. The second routine adds the symbols from an object +-file to the hash table. The third routine takes all the +-object files and links them together to create the output +-file. These routines are designed so that the linker proper +-does not need to know anything about the symbols in the object +-files that it is linking. The linker merely arranges the +-sections as directed by the linker script and lets BFD handle +-the details of symbols and relocs. +- +-The second routine and third routines are passed a pointer to +-a @code{struct bfd_link_info} structure (defined in +-@code{bfdlink.h}) which holds information relevant to the link, +-including the linker hash table (which was created by the +-first routine) and a set of callback functions to the linker +-proper. +- +-The generic linker routines are in @code{linker.c}, and use the +-header file @code{genlink.h}. As of this writing, the only back +-ends which have implemented versions of these routines are +-a.out (in @code{aoutx.h}) and ECOFF (in @code{ecoff.c}). The a.out +-routines are used as examples throughout this section. +- +-@menu +-* Creating a Linker Hash Table:: +-* Adding Symbols to the Hash Table:: +-* Performing the Final Link:: +-@end menu +- +-@node Creating a Linker Hash Table, Adding Symbols to the Hash Table, Linker Functions, Linker Functions +-@subsection Creating a linker hash table +-@cindex _bfd_link_hash_table_create in target vector +-@cindex target vector (_bfd_link_hash_table_create) +-The linker routines must create a hash table, which must be +-derived from @code{struct bfd_link_hash_table} described in +-@code{bfdlink.c}. @xref{Hash Tables}, for information on how to +-create a derived hash table. This entry point is called using +-the target vector of the linker output file. +- +-The @code{_bfd_link_hash_table_create} entry point must allocate +-and initialize an instance of the desired hash table. If the +-back end does not require any additional information to be +-stored with the entries in the hash table, the entry point may +-simply create a @code{struct bfd_link_hash_table}. Most likely, +-however, some additional information will be needed. +- +-For example, with each entry in the hash table the a.out +-linker keeps the index the symbol has in the final output file +-(this index number is used so that when doing a relocatable +-link the symbol index used in the output file can be quickly +-filled in when copying over a reloc). The a.out linker code +-defines the required structures and functions for a hash table +-derived from @code{struct bfd_link_hash_table}. The a.out linker +-hash table is created by the function +-@code{NAME(aout,link_hash_table_create)}; it simply allocates +-space for the hash table, initializes it, and returns a +-pointer to it. +- +-When writing the linker routines for a new back end, you will +-generally not know exactly which fields will be required until +-you have finished. You should simply create a new hash table +-which defines no additional fields, and then simply add fields +-as they become necessary. +- +-@node Adding Symbols to the Hash Table, Performing the Final Link, Creating a Linker Hash Table, Linker Functions +-@subsection Adding symbols to the hash table +-@cindex _bfd_link_add_symbols in target vector +-@cindex target vector (_bfd_link_add_symbols) +-The linker proper will call the @code{_bfd_link_add_symbols} +-entry point for each object file or archive which is to be +-linked (typically these are the files named on the command +-line, but some may also come from the linker script). The +-entry point is responsible for examining the file. For an +-object file, BFD must add any relevant symbol information to +-the hash table. For an archive, BFD must determine which +-elements of the archive should be used and adding them to the +-link. +- +-The a.out version of this entry point is +-@code{NAME(aout,link_add_symbols)}. +- +-@menu +-* Differing file formats:: +-* Adding symbols from an object file:: +-* Adding symbols from an archive:: +-@end menu +- +-@node Differing file formats, Adding symbols from an object file, Adding Symbols to the Hash Table, Adding Symbols to the Hash Table +-@subsubsection Differing file formats +-Normally all the files involved in a link will be of the same +-format, but it is also possible to link together different +-format object files, and the back end must support that. The +-@code{_bfd_link_add_symbols} entry point is called via the target +-vector of the file to be added. This has an important +-consequence: the function may not assume that the hash table +-is the type created by the corresponding +-@code{_bfd_link_hash_table_create} vector. All the +-@code{_bfd_link_add_symbols} function can assume about the hash +-table is that it is derived from @code{struct +-bfd_link_hash_table}. +- +-Sometimes the @code{_bfd_link_add_symbols} function must store +-some information in the hash table entry to be used by the +-@code{_bfd_final_link} function. In such a case the output bfd +-xvec must be checked to make sure that the hash table was +-created by an object file of the same format. +- +-The @code{_bfd_final_link} routine must be prepared to handle a +-hash entry without any extra information added by the +-@code{_bfd_link_add_symbols} function. A hash entry without +-extra information will also occur when the linker script +-directs the linker to create a symbol. Note that, regardless +-of how a hash table entry is added, all the fields will be +-initialized to some sort of null value by the hash table entry +-initialization function. +- +-See @code{ecoff_link_add_externals} for an example of how to +-check the output bfd before saving information (in this +-case, the ECOFF external symbol debugging information) in a +-hash table entry. +- +-@node Adding symbols from an object file, Adding symbols from an archive, Differing file formats, Adding Symbols to the Hash Table +-@subsubsection Adding symbols from an object file +-When the @code{_bfd_link_add_symbols} routine is passed an object +-file, it must add all externally visible symbols in that +-object file to the hash table. The actual work of adding the +-symbol to the hash table is normally handled by the function +-@code{_bfd_generic_link_add_one_symbol}. The +-@code{_bfd_link_add_symbols} routine is responsible for reading +-all the symbols from the object file and passing the correct +-information to @code{_bfd_generic_link_add_one_symbol}. +- +-The @code{_bfd_link_add_symbols} routine should not use +-@code{bfd_canonicalize_symtab} to read the symbols. The point of +-providing this routine is to avoid the overhead of converting +-the symbols into generic @code{asymbol} structures. +- +-@findex _bfd_generic_link_add_one_symbol +-@code{_bfd_generic_link_add_one_symbol} handles the details of +-combining common symbols, warning about multiple definitions, +-and so forth. It takes arguments which describe the symbol to +-add, notably symbol flags, a section, and an offset. The +-symbol flags include such things as @code{BSF_WEAK} or +-@code{BSF_INDIRECT}. The section is a section in the object +-file, or something like @code{bfd_und_section_ptr} for an undefined +-symbol or @code{bfd_com_section_ptr} for a common symbol. +- +-If the @code{_bfd_final_link} routine is also going to need to +-read the symbol information, the @code{_bfd_link_add_symbols} +-routine should save it somewhere attached to the object file +-BFD. However, the information should only be saved if the +-@code{keep_memory} field of the @code{info} argument is TRUE, so +-that the @code{-no-keep-memory} linker switch is effective. +- +-The a.out function which adds symbols from an object file is +-@code{aout_link_add_object_symbols}, and most of the interesting +-work is in @code{aout_link_add_symbols}. The latter saves +-pointers to the hash tables entries created by +-@code{_bfd_generic_link_add_one_symbol} indexed by symbol number, +-so that the @code{_bfd_final_link} routine does not have to call +-the hash table lookup routine to locate the entry. +- +-@node Adding symbols from an archive, , Adding symbols from an object file, Adding Symbols to the Hash Table +-@subsubsection Adding symbols from an archive +-When the @code{_bfd_link_add_symbols} routine is passed an +-archive, it must look through the symbols defined by the +-archive and decide which elements of the archive should be +-included in the link. For each such element it must call the +-@code{add_archive_element} linker callback, and it must add the +-symbols from the object file to the linker hash table. (The +-callback may in fact indicate that a replacement BFD should be +-used, in which case the symbols from that BFD should be added +-to the linker hash table instead.) +- +-@findex _bfd_generic_link_add_archive_symbols +-In most cases the work of looking through the symbols in the +-archive should be done by the +-@code{_bfd_generic_link_add_archive_symbols} function. This +-function builds a hash table from the archive symbol table and +-looks through the list of undefined symbols to see which +-elements should be included. +-@code{_bfd_generic_link_add_archive_symbols} is passed a function +-to call to make the final decision about adding an archive +-element to the link and to do the actual work of adding the +-symbols to the linker hash table. +- +-The function passed to +-@code{_bfd_generic_link_add_archive_symbols} must read the +-symbols of the archive element and decide whether the archive +-element should be included in the link. If the element is to +-be included, the @code{add_archive_element} linker callback +-routine must be called with the element as an argument, and +-the element's symbols must be added to the linker hash table +-just as though the element had itself been passed to the +-@code{_bfd_link_add_symbols} function. The @code{add_archive_element} +-callback has the option to indicate that it would like to +-replace the element archive with a substitute BFD, in which +-case it is the symbols of that substitute BFD that must be +-added to the linker hash table instead. +- +-When the a.out @code{_bfd_link_add_symbols} function receives an +-archive, it calls @code{_bfd_generic_link_add_archive_symbols} +-passing @code{aout_link_check_archive_element} as the function +-argument. @code{aout_link_check_archive_element} calls +-@code{aout_link_check_ar_symbols}. If the latter decides to add +-the element (an element is only added if it provides a real, +-non-common, definition for a previously undefined or common +-symbol) it calls the @code{add_archive_element} callback and then +-@code{aout_link_check_archive_element} calls +-@code{aout_link_add_symbols} to actually add the symbols to the +-linker hash table - possibly those of a substitute BFD, if the +-@code{add_archive_element} callback avails itself of that option. +- +-The ECOFF back end is unusual in that it does not normally +-call @code{_bfd_generic_link_add_archive_symbols}, because ECOFF +-archives already contain a hash table of symbols. The ECOFF +-back end searches the archive itself to avoid the overhead of +-creating a new hash table. +- +-@node Performing the Final Link, , Adding Symbols to the Hash Table, Linker Functions +-@subsection Performing the final link +-@cindex _bfd_link_final_link in target vector +-@cindex target vector (_bfd_final_link) +-When all the input files have been processed, the linker calls +-the @code{_bfd_final_link} entry point of the output BFD. This +-routine is responsible for producing the final output file, +-which has several aspects. It must relocate the contents of +-the input sections and copy the data into the output sections. +-It must build an output symbol table including any local +-symbols from the input files and the global symbols from the +-hash table. When producing relocatable output, it must +-modify the input relocs and write them into the output file. +-There may also be object format dependent work to be done. +- +-The linker will also call the @code{write_object_contents} entry +-point when the BFD is closed. The two entry points must work +-together in order to produce the correct output file. +- +-The details of how this works are inevitably dependent upon +-the specific object file format. The a.out +-@code{_bfd_final_link} routine is @code{NAME(aout,final_link)}. +- +-@menu +-* Information provided by the linker:: +-* Relocating the section contents:: +-* Writing the symbol table:: +-@end menu +- +-@node Information provided by the linker, Relocating the section contents, Performing the Final Link, Performing the Final Link +-@subsubsection Information provided by the linker +-Before the linker calls the @code{_bfd_final_link} entry point, +-it sets up some data structures for the function to use. +- +-The @code{input_bfds} field of the @code{bfd_link_info} structure +-will point to a list of all the input files included in the +-link. These files are linked through the @code{link_next} field +-of the @code{bfd} structure. +- +-Each section in the output file will have a list of +-@code{link_order} structures attached to the @code{map_head.link_order} +-field (the @code{link_order} structure is defined in +-@code{bfdlink.h}). These structures describe how to create the +-contents of the output section in terms of the contents of +-various input sections, fill constants, and, eventually, other +-types of information. They also describe relocs that must be +-created by the BFD backend, but do not correspond to any input +-file; this is used to support -Ur, which builds constructors +-while generating a relocatable object file. +- +-@node Relocating the section contents, Writing the symbol table, Information provided by the linker, Performing the Final Link +-@subsubsection Relocating the section contents +-The @code{_bfd_final_link} function should look through the +-@code{link_order} structures attached to each section of the +-output file. Each @code{link_order} structure should either be +-handled specially, or it should be passed to the function +-@code{_bfd_default_link_order} which will do the right thing +-(@code{_bfd_default_link_order} is defined in @code{linker.c}). +- +-For efficiency, a @code{link_order} of type +-@code{bfd_indirect_link_order} whose associated section belongs +-to a BFD of the same format as the output BFD must be handled +-specially. This type of @code{link_order} describes part of an +-output section in terms of a section belonging to one of the +-input files. The @code{_bfd_final_link} function should read the +-contents of the section and any associated relocs, apply the +-relocs to the section contents, and write out the modified +-section contents. If performing a relocatable link, the +-relocs themselves must also be modified and written out. +- +-@findex _bfd_relocate_contents +-@findex _bfd_final_link_relocate +-The functions @code{_bfd_relocate_contents} and +-@code{_bfd_final_link_relocate} provide some general support for +-performing the actual relocations, notably overflow checking. +-Their arguments include information about the symbol the +-relocation is against and a @code{reloc_howto_type} argument +-which describes the relocation to perform. These functions +-are defined in @code{reloc.c}. +- +-The a.out function which handles reading, relocating, and +-writing section contents is @code{aout_link_input_section}. The +-actual relocation is done in @code{aout_link_input_section_std} +-and @code{aout_link_input_section_ext}. +- +-@node Writing the symbol table, , Relocating the section contents, Performing the Final Link +-@subsubsection Writing the symbol table +-The @code{_bfd_final_link} function must gather all the symbols +-in the input files and write them out. It must also write out +-all the symbols in the global hash table. This must be +-controlled by the @code{strip} and @code{discard} fields of the +-@code{bfd_link_info} structure. +- +-The local symbols of the input files will not have been +-entered into the linker hash table. The @code{_bfd_final_link} +-routine must consider each input file and include the symbols +-in the output file. It may be convenient to do this when +-looking through the @code{link_order} structures, or it may be +-done by stepping through the @code{input_bfds} list. +- +-The @code{_bfd_final_link} routine must also traverse the global +-hash table to gather all the externally visible symbols. It +-is possible that most of the externally visible symbols may be +-written out when considering the symbols of each input file, +-but it is still necessary to traverse the hash table since the +-linker script may have defined some symbols that are not in +-any of the input files. +- +-The @code{strip} field of the @code{bfd_link_info} structure +-controls which symbols are written out. The possible values +-are listed in @code{bfdlink.h}. If the value is @code{strip_some}, +-then the @code{keep_hash} field of the @code{bfd_link_info} +-structure is a hash table of symbols to keep; each symbol +-should be looked up in this hash table, and only symbols which +-are present should be included in the output file. +- +-If the @code{strip} field of the @code{bfd_link_info} structure +-permits local symbols to be written out, the @code{discard} field +-is used to further controls which local symbols are included +-in the output file. If the value is @code{discard_l}, then all +-local symbols which begin with a certain prefix are discarded; +-this is controlled by the @code{bfd_is_local_label_name} entry point. +- +-The a.out backend handles symbols by calling +-@code{aout_link_write_symbols} on each input BFD and then +-traversing the global hash table with the function +-@code{aout_link_write_other_symbol}. It builds a string table +-while writing out the symbols, which is written to the output +-file at the end of @code{NAME(aout,final_link)}. +- +-@findex bfd_link_split_section +-@subsubsection @code{bfd_link_split_section} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec); +-@end example +-@strong{Description}@* +-Return nonzero if @var{sec} should be split during a +-reloceatable or final link. +-@example +-#define bfd_link_split_section(abfd, sec) \ +- BFD_SEND (abfd, _bfd_link_split_section, (abfd, sec)) +- +-@end example +- +-@findex bfd_section_already_linked +-@subsubsection @code{bfd_section_already_linked} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_section_already_linked (bfd *abfd, +- asection *sec, +- struct bfd_link_info *info); +-@end example +-@strong{Description}@* +-Check if @var{data} has been already linked during a reloceatable +-or final link. Return TRUE if it has. +-@example +-#define bfd_section_already_linked(abfd, sec, info) \ +- BFD_SEND (abfd, _section_already_linked, (abfd, sec, info)) +- +-@end example +- +-@findex bfd_generic_define_common_symbol +-@subsubsection @code{bfd_generic_define_common_symbol} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_define_common_symbol +- (bfd *output_bfd, struct bfd_link_info *info, +- struct bfd_link_hash_entry *h); +-@end example +-@strong{Description}@* +-Convert common symbol @var{h} into a defined symbol. +-Return TRUE on success and FALSE on failure. +-@example +-#define bfd_define_common_symbol(output_bfd, info, h) \ +- BFD_SEND (output_bfd, _bfd_define_common_symbol, (output_bfd, info, h)) +- +-@end example +- +-@findex bfd_find_version_for_sym +-@subsubsection @code{bfd_find_version_for_sym} +-@strong{Synopsis} +-@example +-struct bfd_elf_version_tree * bfd_find_version_for_sym +- (struct bfd_elf_version_tree *verdefs, +- const char *sym_name, bfd_boolean *hide); +-@end example +-@strong{Description}@* +-Search an elf version script tree for symbol versioning +-info and export / don't-export status for a given symbol. +-Return non-NULL on success and NULL on failure; also sets +-the output @samp{hide} boolean parameter. +- +-@findex bfd_hide_sym_by_version +-@subsubsection @code{bfd_hide_sym_by_version} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_hide_sym_by_version +- (struct bfd_elf_version_tree *verdefs, const char *sym_name); +-@end example +-@strong{Description}@* +-Search an elf version script tree for symbol versioning +-info for a given symbol. Return TRUE if the symbol is hidden. +- +diff -Nur binutils-2.24.orig/bfd/doc/mmo.texi binutils-2.24/bfd/doc/mmo.texi +--- binutils-2.24.orig/bfd/doc/mmo.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/mmo.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,365 +0,0 @@ +-@section mmo backend +-The mmo object format is used exclusively together with Professor +-Donald E.@: Knuth's educational 64-bit processor MMIX. The simulator +-@command{mmix} which is available at +-@url{http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz} +-understands this format. That package also includes a combined +-assembler and linker called @command{mmixal}. The mmo format has +-no advantages feature-wise compared to e.g. ELF. It is a simple +-non-relocatable object format with no support for archives or +-debugging information, except for symbol value information and +-line numbers (which is not yet implemented in BFD). See +-@url{http://www-cs-faculty.stanford.edu/~knuth/mmix.html} for more +-information about MMIX. The ELF format is used for intermediate +-object files in the BFD implementation. +- +-@c We want to xref the symbol table node. A feature in "chew" +-@c requires that "commands" do not contain spaces in the +-@c arguments. Hence the hyphen in "Symbol-table". +-@menu +-* File layout:: +-* Symbol-table:: +-* mmo section mapping:: +-@end menu +- +-@node File layout, Symbol-table, mmo, mmo +-@subsection File layout +-The mmo file contents is not partitioned into named sections as +-with e.g.@: ELF. Memory areas is formed by specifying the +-location of the data that follows. Only the memory area +-@samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} is executable, so +-it is used for code (and constants) and the area +-@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} is used for +-writable data. @xref{mmo section mapping}. +- +-There is provision for specifying ``special data'' of 65536 +-different types. We use type 80 (decimal), arbitrarily chosen the +-same as the ELF @code{e_machine} number for MMIX, filling it with +-section information normally found in ELF objects. @xref{mmo +-section mapping}. +- +-Contents is entered as 32-bit words, xor:ed over previous +-contents, always zero-initialized. A word that starts with the +-byte @samp{0x98} forms a command called a @samp{lopcode}, where +-the next byte distinguished between the thirteen lopcodes. The +-two remaining bytes, called the @samp{Y} and @samp{Z} fields, or +-the @samp{YZ} field (a 16-bit big-endian number), are used for +-various purposes different for each lopcode. As documented in +-@url{http://www-cs-faculty.stanford.edu/~knuth/mmixal-intro.ps.gz}, +-the lopcodes are: +- +-@table @code +-@item lop_quote +-0x98000001. The next word is contents, regardless of whether it +-starts with 0x98 or not. +- +-@item lop_loc +-0x9801YYZZ, where @samp{Z} is 1 or 2. This is a location +-directive, setting the location for the next data to the next +-32-bit word (for @math{Z = 1}) or 64-bit word (for @math{Z = 2}), +-plus @math{Y * 2^56}. Normally @samp{Y} is 0 for the text segment +-and 2 for the data segment. +- +-@item lop_skip +-0x9802YYZZ. Increase the current location by @samp{YZ} bytes. +- +-@item lop_fixo +-0x9803YYZZ, where @samp{Z} is 1 or 2. Store the current location +-as 64 bits into the location pointed to by the next 32-bit +-(@math{Z = 1}) or 64-bit (@math{Z = 2}) word, plus @math{Y * +-2^56}. +- +-@item lop_fixr +-0x9804YYZZ. @samp{YZ} is stored into the current location plus +-@math{2 - 4 * YZ}. +- +-@item lop_fixrx +-0x980500ZZ. @samp{Z} is 16 or 24. A value @samp{L} derived from +-the following 32-bit word are used in a manner similar to +-@samp{YZ} in lop_fixr: it is xor:ed into the current location +-minus @math{4 * L}. The first byte of the word is 0 or 1. If it +-is 1, then @math{L = (@var{lowest 24 bits of word}) - 2^Z}, if 0, +-then @math{L = (@var{lowest 24 bits of word})}. +- +-@item lop_file +-0x9806YYZZ. @samp{Y} is the file number, @samp{Z} is count of +-32-bit words. Set the file number to @samp{Y} and the line +-counter to 0. The next @math{Z * 4} bytes contain the file name, +-padded with zeros if the count is not a multiple of four. The +-same @samp{Y} may occur multiple times, but @samp{Z} must be 0 for +-all but the first occurrence. +- +-@item lop_line +-0x9807YYZZ. @samp{YZ} is the line number. Together with +-lop_file, it forms the source location for the next 32-bit word. +-Note that for each non-lopcode 32-bit word, line numbers are +-assumed incremented by one. +- +-@item lop_spec +-0x9808YYZZ. @samp{YZ} is the type number. Data until the next +-lopcode other than lop_quote forms special data of type @samp{YZ}. +-@xref{mmo section mapping}. +- +-Other types than 80, (or type 80 with a content that does not +-parse) is stored in sections named @code{.MMIX.spec_data.@var{n}} +-where @var{n} is the @samp{YZ}-type. The flags for such a +-sections say not to allocate or load the data. The vma is 0. +-Contents of multiple occurrences of special data @var{n} is +-concatenated to the data of the previous lop_spec @var{n}s. The +-location in data or code at which the lop_spec occurred is lost. +- +-@item lop_pre +-0x980901ZZ. The first lopcode in a file. The @samp{Z} field forms the +-length of header information in 32-bit words, where the first word +-tells the time in seconds since @samp{00:00:00 GMT Jan 1 1970}. +- +-@item lop_post +-0x980a00ZZ. @math{Z > 32}. This lopcode follows after all +-content-generating lopcodes in a program. The @samp{Z} field +-denotes the value of @samp{rG} at the beginning of the program. +-The following @math{256 - Z} big-endian 64-bit words are loaded +-into global registers @samp{$G} @dots{} @samp{$255}. +- +-@item lop_stab +-0x980b0000. The next-to-last lopcode in a program. Must follow +-immediately after the lop_post lopcode and its data. After this +-lopcode follows all symbols in a compressed format +-(@pxref{Symbol-table}). +- +-@item lop_end +-0x980cYYZZ. The last lopcode in a program. It must follow the +-lop_stab lopcode and its data. The @samp{YZ} field contains the +-number of 32-bit words of symbol table information after the +-preceding lop_stab lopcode. +-@end table +- +-Note that the lopcode "fixups"; @code{lop_fixr}, @code{lop_fixrx} and +-@code{lop_fixo} are not generated by BFD, but are handled. They are +-generated by @code{mmixal}. +- +-This trivial one-label, one-instruction file: +- +-@example +- :Main TRAP 1,2,3 +-@end example +- +-can be represented this way in mmo: +- +-@example +- 0x98090101 - lop_pre, one 32-bit word with timestamp. +- +- 0x98010002 - lop_loc, text segment, using a 64-bit address. +- Note that mmixal does not emit this for the file above. +- 0x00000000 - Address, high 32 bits. +- 0x00000000 - Address, low 32 bits. +- 0x98060002 - lop_file, 2 32-bit words for file-name. +- 0x74657374 - "test" +- 0x2e730000 - ".s\0\0" +- 0x98070001 - lop_line, line 1. +- 0x00010203 - TRAP 1,2,3 +- 0x980a00ff - lop_post, setting $255 to 0. +- 0x00000000 +- 0x00000000 +- 0x980b0000 - lop_stab for ":Main" = 0, serial 1. +- 0x203a4040 @xref{Symbol-table}. +- 0x10404020 +- 0x4d206120 +- 0x69016e00 +- 0x81000000 +- 0x980c0005 - lop_end; symbol table contained five 32-bit words. +-@end example +-@node Symbol-table, mmo section mapping, File layout, mmo +-@subsection Symbol table format +-From mmixal.w (or really, the generated mmixal.tex) in +-@url{http://www-cs-faculty.stanford.edu/~knuth/programs/mmix.tar.gz}): +-``Symbols are stored and retrieved by means of a @samp{ternary +-search trie}, following ideas of Bentley and Sedgewick. (See +-ACM--SIAM Symp.@: on Discrete Algorithms @samp{8} (1997), 360--369; +-R.@:Sedgewick, @samp{Algorithms in C} (Reading, Mass.@: +-Addison--Wesley, 1998), @samp{15.4}.) Each trie node stores a +-character, and there are branches to subtries for the cases where +-a given character is less than, equal to, or greater than the +-character in the trie. There also is a pointer to a symbol table +-entry if a symbol ends at the current node.'' +- +-So it's a tree encoded as a stream of bytes. The stream of bytes +-acts on a single virtual global symbol, adding and removing +-characters and signalling complete symbol points. Here, we read +-the stream and create symbols at the completion points. +- +-First, there's a control byte @code{m}. If any of the listed bits +-in @code{m} is nonzero, we execute what stands at the right, in +-the listed order: +- +-@example +- (MMO3_LEFT) +- 0x40 - Traverse left trie. +- (Read a new command byte and recurse.) +- +- (MMO3_SYMBITS) +- 0x2f - Read the next byte as a character and store it in the +- current character position; increment character position. +- Test the bits of @code{m}: +- +- (MMO3_WCHAR) +- 0x80 - The character is 16-bit (so read another byte, +- merge into current character. +- +- (MMO3_TYPEBITS) +- 0xf - We have a complete symbol; parse the type, value +- and serial number and do what should be done +- with a symbol. The type and length information +- is in j = (m & 0xf). +- +- (MMO3_REGQUAL_BITS) +- j == 0xf: A register variable. The following +- byte tells which register. +- j <= 8: An absolute symbol. Read j bytes as the +- big-endian number the symbol equals. +- A j = 2 with two zero bytes denotes an +- unknown symbol. +- j > 8: As with j <= 8, but add (0x20 << 56) +- to the value in the following j - 8 +- bytes. +- +- Then comes the serial number, as a variant of +- uleb128, but better named ubeb128: +- Read bytes and shift the previous value left 7 +- (multiply by 128). Add in the new byte, repeat +- until a byte has bit 7 set. The serial number +- is the computed value minus 128. +- +- (MMO3_MIDDLE) +- 0x20 - Traverse middle trie. (Read a new command byte +- and recurse.) Decrement character position. +- +- (MMO3_RIGHT) +- 0x10 - Traverse right trie. (Read a new command byte and +- recurse.) +-@end example +- +-Let's look again at the @code{lop_stab} for the trivial file +-(@pxref{File layout}). +- +-@example +- 0x980b0000 - lop_stab for ":Main" = 0, serial 1. +- 0x203a4040 +- 0x10404020 +- 0x4d206120 +- 0x69016e00 +- 0x81000000 +-@end example +- +-This forms the trivial trie (note that the path between ``:'' and +-``M'' is redundant): +- +-@example +- 203a ":" +- 40 / +- 40 / +- 10 \ +- 40 / +- 40 / +- 204d "M" +- 2061 "a" +- 2069 "i" +- 016e "n" is the last character in a full symbol, and +- with a value represented in one byte. +- 00 The value is 0. +- 81 The serial number is 1. +-@end example +- +-@node mmo section mapping, , Symbol-table, mmo +-@subsection mmo section mapping +-The implementation in BFD uses special data type 80 (decimal) to +-encapsulate and describe named sections, containing e.g.@: debug +-information. If needed, any datum in the encapsulation will be +-quoted using lop_quote. First comes a 32-bit word holding the +-number of 32-bit words containing the zero-terminated zero-padded +-segment name. After the name there's a 32-bit word holding flags +-describing the section type. Then comes a 64-bit big-endian word +-with the section length (in bytes), then another with the section +-start address. Depending on the type of section, the contents +-might follow, zero-padded to 32-bit boundary. For a loadable +-section (such as data or code), the contents might follow at some +-later point, not necessarily immediately, as a lop_loc with the +-same start address as in the section description, followed by the +-contents. This in effect forms a descriptor that must be emitted +-before the actual contents. Sections described this way must not +-overlap. +- +-For areas that don't have such descriptors, synthetic sections are +-formed by BFD. Consecutive contents in the two memory areas +-@samp{0x0000@dots{}00} to @samp{0x01ff@dots{}ff} and +-@samp{0x2000@dots{}00} to @samp{0x20ff@dots{}ff} are entered in +-sections named @code{.text} and @code{.data} respectively. If an area +-is not otherwise described, but would together with a neighboring +-lower area be less than @samp{0x40000000} bytes long, it is joined +-with the lower area and the gap is zero-filled. For other cases, +-a new section is formed, named @code{.MMIX.sec.@var{n}}. Here, +-@var{n} is a number, a running count through the mmo file, +-starting at 0. +- +-A loadable section specified as: +- +-@example +- .section secname,"ax" +- TETRA 1,2,3,4,-1,-2009 +- BYTE 80 +-@end example +- +-and linked to address @samp{0x4}, is represented by the sequence: +- +-@example +- 0x98080050 - lop_spec 80 +- 0x00000002 - two 32-bit words for the section name +- 0x7365636e - "secn" +- 0x616d6500 - "ame\0" +- 0x00000033 - flags CODE, READONLY, LOAD, ALLOC +- 0x00000000 - high 32 bits of section length +- 0x0000001c - section length is 28 bytes; 6 * 4 + 1 + alignment to 32 bits +- 0x00000000 - high 32 bits of section address +- 0x00000004 - section address is 4 +- 0x98010002 - 64 bits with address of following data +- 0x00000000 - high 32 bits of address +- 0x00000004 - low 32 bits: data starts at address 4 +- 0x00000001 - 1 +- 0x00000002 - 2 +- 0x00000003 - 3 +- 0x00000004 - 4 +- 0xffffffff - -1 +- 0xfffff827 - -2009 +- 0x50000000 - 80 as a byte, padded with zeros. +-@end example +- +-Note that the lop_spec wrapping does not include the section +-contents. Compare this to a non-loaded section specified as: +- +-@example +- .section thirdsec +- TETRA 200001,100002 +- BYTE 38,40 +-@end example +- +-This, when linked to address @samp{0x200000000000001c}, is +-represented by: +- +-@example +- 0x98080050 - lop_spec 80 +- 0x00000002 - two 32-bit words for the section name +- 0x7365636e - "thir" +- 0x616d6500 - "dsec" +- 0x00000010 - flag READONLY +- 0x00000000 - high 32 bits of section length +- 0x0000000c - section length is 12 bytes; 2 * 4 + 2 + alignment to 32 bits +- 0x20000000 - high 32 bits of address +- 0x0000001c - low 32 bits of address 0x200000000000001c +- 0x00030d41 - 200001 +- 0x000186a2 - 100002 +- 0x26280000 - 38, 40 as bytes, padded with zeros +-@end example +- +-For the latter example, the section contents must not be +-loaded in memory, and is therefore specified as part of the +-special data. The address is usually unimportant but might +-provide information for e.g.@: the DWARF 2 debugging format. +diff -Nur binutils-2.24.orig/bfd/doc/opncls.texi binutils-2.24/bfd/doc/opncls.texi +--- binutils-2.24.orig/bfd/doc/opncls.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/opncls.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,432 +0,0 @@ +- +-@example +-/* Set to N to open the next N BFDs using an alternate id space. */ +-extern unsigned int bfd_use_reserved_id; +-@end example +-@section Opening and closing BFDs +- +- +-@subsection Functions for opening and closing +- +- +-@findex bfd_fopen +-@subsubsection @code{bfd_fopen} +-@strong{Synopsis} +-@example +-bfd *bfd_fopen (const char *filename, const char *target, +- const char *mode, int fd); +-@end example +-@strong{Description}@* +-Open the file @var{filename} with the target @var{target}. +-Return a pointer to the created BFD. If @var{fd} is not -1, +-then @code{fdopen} is used to open the file; otherwise, @code{fopen} +-is used. @var{mode} is passed directly to @code{fopen} or +-@code{fdopen}. +- +-Calls @code{bfd_find_target}, so @var{target} is interpreted as by +-that function. +- +-The new BFD is marked as cacheable iff @var{fd} is -1. +- +-If @code{NULL} is returned then an error has occured. Possible errors +-are @code{bfd_error_no_memory}, @code{bfd_error_invalid_target} or +-@code{system_call} error. +- +-On error, @var{fd} is always closed. +- +-@findex bfd_openr +-@subsubsection @code{bfd_openr} +-@strong{Synopsis} +-@example +-bfd *bfd_openr (const char *filename, const char *target); +-@end example +-@strong{Description}@* +-Open the file @var{filename} (using @code{fopen}) with the target +-@var{target}. Return a pointer to the created BFD. +- +-Calls @code{bfd_find_target}, so @var{target} is interpreted as by +-that function. +- +-If @code{NULL} is returned then an error has occured. Possible errors +-are @code{bfd_error_no_memory}, @code{bfd_error_invalid_target} or +-@code{system_call} error. +- +-@findex bfd_fdopenr +-@subsubsection @code{bfd_fdopenr} +-@strong{Synopsis} +-@example +-bfd *bfd_fdopenr (const char *filename, const char *target, int fd); +-@end example +-@strong{Description}@* +-@code{bfd_fdopenr} is to @code{bfd_fopenr} much like @code{fdopen} is to +-@code{fopen}. It opens a BFD on a file already described by the +-@var{fd} supplied. +- +-When the file is later @code{bfd_close}d, the file descriptor will +-be closed. If the caller desires that this file descriptor be +-cached by BFD (opened as needed, closed as needed to free +-descriptors for other opens), with the supplied @var{fd} used as +-an initial file descriptor (but subject to closure at any time), +-call bfd_set_cacheable(bfd, 1) on the returned BFD. The default +-is to assume no caching; the file descriptor will remain open +-until @code{bfd_close}, and will not be affected by BFD operations +-on other files. +- +-Possible errors are @code{bfd_error_no_memory}, +-@code{bfd_error_invalid_target} and @code{bfd_error_system_call}. +- +-On error, @var{fd} is closed. +- +-@findex bfd_openstreamr +-@subsubsection @code{bfd_openstreamr} +-@strong{Synopsis} +-@example +-bfd *bfd_openstreamr (const char *, const char *, void *); +-@end example +-@strong{Description}@* +-Open a BFD for read access on an existing stdio stream. When +-the BFD is passed to @code{bfd_close}, the stream will be closed. +- +-@findex bfd_openr_iovec +-@subsubsection @code{bfd_openr_iovec} +-@strong{Synopsis} +-@example +-bfd *bfd_openr_iovec (const char *filename, const char *target, +- void *(*open_func) (struct bfd *nbfd, +- void *open_closure), +- void *open_closure, +- file_ptr (*pread_func) (struct bfd *nbfd, +- void *stream, +- void *buf, +- file_ptr nbytes, +- file_ptr offset), +- int (*close_func) (struct bfd *nbfd, +- void *stream), +- int (*stat_func) (struct bfd *abfd, +- void *stream, +- struct stat *sb)); +-@end example +-@strong{Description}@* +-Create and return a BFD backed by a read-only @var{stream}. +-The @var{stream} is created using @var{open_func}, accessed using +-@var{pread_func} and destroyed using @var{close_func}. +- +-Calls @code{bfd_find_target}, so @var{target} is interpreted as by +-that function. +- +-Calls @var{open_func} (which can call @code{bfd_zalloc} and +-@code{bfd_get_filename}) to obtain the read-only stream backing +-the BFD. @var{open_func} either succeeds returning the +-non-@code{NULL} @var{stream}, or fails returning @code{NULL} +-(setting @code{bfd_error}). +- +-Calls @var{pread_func} to request @var{nbytes} of data from +-@var{stream} starting at @var{offset} (e.g., via a call to +-@code{bfd_read}). @var{pread_func} either succeeds returning the +-number of bytes read (which can be less than @var{nbytes} when +-end-of-file), or fails returning -1 (setting @code{bfd_error}). +- +-Calls @var{close_func} when the BFD is later closed using +-@code{bfd_close}. @var{close_func} either succeeds returning 0, or +-fails returning -1 (setting @code{bfd_error}). +- +-Calls @var{stat_func} to fill in a stat structure for bfd_stat, +-bfd_get_size, and bfd_get_mtime calls. @var{stat_func} returns 0 +-on success, or returns -1 on failure (setting @code{bfd_error}). +- +-If @code{bfd_openr_iovec} returns @code{NULL} then an error has +-occurred. Possible errors are @code{bfd_error_no_memory}, +-@code{bfd_error_invalid_target} and @code{bfd_error_system_call}. +- +-@findex bfd_openw +-@subsubsection @code{bfd_openw} +-@strong{Synopsis} +-@example +-bfd *bfd_openw (const char *filename, const char *target); +-@end example +-@strong{Description}@* +-Create a BFD, associated with file @var{filename}, using the +-file format @var{target}, and return a pointer to it. +- +-Possible errors are @code{bfd_error_system_call}, @code{bfd_error_no_memory}, +-@code{bfd_error_invalid_target}. +- +-@findex bfd_close +-@subsubsection @code{bfd_close} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_close (bfd *abfd); +-@end example +-@strong{Description}@* +-Close a BFD. If the BFD was open for writing, then pending +-operations are completed and the file written out and closed. +-If the created file is executable, then @code{chmod} is called +-to mark it as such. +- +-All memory attached to the BFD is released. +- +-The file descriptor associated with the BFD is closed (even +-if it was passed in to BFD by @code{bfd_fdopenr}). +- +-@strong{Returns}@* +-@code{TRUE} is returned if all is ok, otherwise @code{FALSE}. +- +-@findex bfd_close_all_done +-@subsubsection @code{bfd_close_all_done} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_close_all_done (bfd *); +-@end example +-@strong{Description}@* +-Close a BFD. Differs from @code{bfd_close} since it does not +-complete any pending operations. This routine would be used +-if the application had just used BFD for swapping and didn't +-want to use any of the writing code. +- +-If the created file is executable, then @code{chmod} is called +-to mark it as such. +- +-All memory attached to the BFD is released. +- +-@strong{Returns}@* +-@code{TRUE} is returned if all is ok, otherwise @code{FALSE}. +- +-@findex bfd_create +-@subsubsection @code{bfd_create} +-@strong{Synopsis} +-@example +-bfd *bfd_create (const char *filename, bfd *templ); +-@end example +-@strong{Description}@* +-Create a new BFD in the manner of @code{bfd_openw}, but without +-opening a file. The new BFD takes the target from the target +-used by @var{templ}. The format is always set to @code{bfd_object}. +- +-@findex bfd_make_writable +-@subsubsection @code{bfd_make_writable} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_make_writable (bfd *abfd); +-@end example +-@strong{Description}@* +-Takes a BFD as created by @code{bfd_create} and converts it +-into one like as returned by @code{bfd_openw}. It does this +-by converting the BFD to BFD_IN_MEMORY. It's assumed that +-you will call @code{bfd_make_readable} on this bfd later. +- +-@strong{Returns}@* +-@code{TRUE} is returned if all is ok, otherwise @code{FALSE}. +- +-@findex bfd_make_readable +-@subsubsection @code{bfd_make_readable} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_make_readable (bfd *abfd); +-@end example +-@strong{Description}@* +-Takes a BFD as created by @code{bfd_create} and +-@code{bfd_make_writable} and converts it into one like as +-returned by @code{bfd_openr}. It does this by writing the +-contents out to the memory buffer, then reversing the +-direction. +- +-@strong{Returns}@* +-@code{TRUE} is returned if all is ok, otherwise @code{FALSE}. +- +-@findex bfd_alloc +-@subsubsection @code{bfd_alloc} +-@strong{Synopsis} +-@example +-void *bfd_alloc (bfd *abfd, bfd_size_type wanted); +-@end example +-@strong{Description}@* +-Allocate a block of @var{wanted} bytes of memory attached to +-@code{abfd} and return a pointer to it. +- +-@findex bfd_alloc2 +-@subsubsection @code{bfd_alloc2} +-@strong{Synopsis} +-@example +-void *bfd_alloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size); +-@end example +-@strong{Description}@* +-Allocate a block of @var{nmemb} elements of @var{size} bytes each +-of memory attached to @code{abfd} and return a pointer to it. +- +-@findex bfd_zalloc +-@subsubsection @code{bfd_zalloc} +-@strong{Synopsis} +-@example +-void *bfd_zalloc (bfd *abfd, bfd_size_type wanted); +-@end example +-@strong{Description}@* +-Allocate a block of @var{wanted} bytes of zeroed memory +-attached to @code{abfd} and return a pointer to it. +- +-@findex bfd_zalloc2 +-@subsubsection @code{bfd_zalloc2} +-@strong{Synopsis} +-@example +-void *bfd_zalloc2 (bfd *abfd, bfd_size_type nmemb, bfd_size_type size); +-@end example +-@strong{Description}@* +-Allocate a block of @var{nmemb} elements of @var{size} bytes each +-of zeroed memory attached to @code{abfd} and return a pointer to it. +- +-@findex bfd_calc_gnu_debuglink_crc32 +-@subsubsection @code{bfd_calc_gnu_debuglink_crc32} +-@strong{Synopsis} +-@example +-unsigned long bfd_calc_gnu_debuglink_crc32 +- (unsigned long crc, const unsigned char *buf, bfd_size_type len); +-@end example +-@strong{Description}@* +-Computes a CRC value as used in the .gnu_debuglink section. +-Advances the previously computed @var{crc} value by computing +-and adding in the crc32 for @var{len} bytes of @var{buf}. +- +-@strong{Returns}@* +-Return the updated CRC32 value. +- +-@findex bfd_get_debug_link_info +-@subsubsection @code{bfd_get_debug_link_info} +-@strong{Synopsis} +-@example +-char *bfd_get_debug_link_info (bfd *abfd, unsigned long *crc32_out); +-@end example +-@strong{Description}@* +-fetch the filename and CRC32 value for any separate debuginfo +-associated with @var{abfd}. Return NULL if no such info found, +-otherwise return filename and update @var{crc32_out}. The +-returned filename is allocated with @code{malloc}; freeing it +-is the responsibility of the caller. +- +-@findex bfd_get_alt_debug_link_info +-@subsubsection @code{bfd_get_alt_debug_link_info} +-@strong{Synopsis} +-@example +-char *bfd_get_alt_debug_link_info (bfd *abfd, unsigned long *crc32_out); +-@end example +-@strong{Description}@* +-Fetch the filename and BuildID value for any alternate debuginfo +-associated with @var{abfd}. Return NULL if no such info found, +-otherwise return filename and update @var{buildid_out}. The +-returned filename is allocated with @code{malloc}; freeing it +-is the responsibility of the caller. +- +-@findex separate_debug_file_exists +-@subsubsection @code{separate_debug_file_exists} +-@strong{Synopsis} +-@example +-bfd_boolean separate_debug_file_exists +- (char *name, unsigned long crc32); +-@end example +-@strong{Description}@* +-Checks to see if @var{name} is a file and if its contents +-match @var{crc32}. +- +-@findex separate_alt_debug_file_exists +-@subsubsection @code{separate_alt_debug_file_exists} +-@strong{Synopsis} +-@example +-bfd_boolean separate_alt_debug_file_exists +- (char *name, unsigned long crc32); +-@end example +-@strong{Description}@* +-Checks to see if @var{name} is a file and if its BuildID +-matches @var{buildid}. +- +-@findex find_separate_debug_file +-@subsubsection @code{find_separate_debug_file} +-@strong{Synopsis} +-@example +-char *find_separate_debug_file (bfd *abfd); +-@end example +-@strong{Description}@* +-Searches @var{abfd} for a section called @var{section_name} which +-is expected to contain a reference to a file containing separate +-debugging information. The function scans various locations in +-the filesystem, including the file tree rooted at +-@var{debug_file_directory}, and returns the first matching +-filename that it finds. If @var{check_crc} is TRUE then the +-contents of the file must also match the CRC value contained in +-@var{section_name}. Returns NULL if no valid file could be found. +- +-@findex bfd_follow_gnu_debuglink +-@subsubsection @code{bfd_follow_gnu_debuglink} +-@strong{Synopsis} +-@example +-char *bfd_follow_gnu_debuglink (bfd *abfd, const char *dir); +-@end example +-@strong{Description}@* +-Takes a BFD and searches it for a .gnu_debuglink section. If this +-section is found, it examines the section for the name and checksum +-of a '.debug' file containing auxiliary debugging information. It +-then searches the filesystem for this .debug file in some standard +-locations, including the directory tree rooted at @var{dir}, and if +-found returns the full filename. +- +-If @var{dir} is NULL, it will search a default path configured into +-libbfd at build time. [XXX this feature is not currently +-implemented]. +- +-@strong{Returns}@* +-@code{NULL} on any errors or failure to locate the .debug file, +-otherwise a pointer to a heap-allocated string containing the +-filename. The caller is responsible for freeing this string. +- +-@findex bfd_follow_gnu_debugaltlink +-@subsubsection @code{bfd_follow_gnu_debugaltlink} +-@strong{Synopsis} +-@example +-char *bfd_follow_gnu_debugaltlink (bfd *abfd, const char *dir); +-@end example +-@strong{Description}@* +-Takes a BFD and searches it for a .gnu_debugaltlink section. If this +-section is found, it examines the section for the name of a file +-containing auxiliary debugging information. It then searches the +-filesystem for this file in a set of standard locations, including +-the directory tree rooted at @var{dir}, and if found returns the +-full filename. +- +-If @var{dir} is NULL, it will search a default path configured into +-libbfd at build time. [FIXME: This feature is not currently +-implemented]. +- +-@strong{Returns}@* +-@code{NULL} on any errors or failure to locate the debug file, +-otherwise a pointer to a heap-allocated string containing the +-filename. The caller is responsible for freeing this string. +- +-@findex bfd_create_gnu_debuglink_section +-@subsubsection @code{bfd_create_gnu_debuglink_section} +-@strong{Synopsis} +-@example +-struct bfd_section *bfd_create_gnu_debuglink_section +- (bfd *abfd, const char *filename); +-@end example +-@strong{Description}@* +-Takes a @var{BFD} and adds a .gnu_debuglink section to it. The section is sized +-to be big enough to contain a link to the specified @var{filename}. +- +-@strong{Returns}@* +-A pointer to the new section is returned if all is ok. Otherwise @code{NULL} is +-returned and bfd_error is set. +- +-@findex bfd_fill_in_gnu_debuglink_section +-@subsubsection @code{bfd_fill_in_gnu_debuglink_section} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_fill_in_gnu_debuglink_section +- (bfd *abfd, struct bfd_section *sect, const char *filename); +-@end example +-@strong{Description}@* +-Takes a @var{BFD} and containing a .gnu_debuglink section @var{SECT} +-and fills in the contents of the section to contain a link to the +-specified @var{filename}. The filename should be relative to the +-current directory. +- +-@strong{Returns}@* +-@code{TRUE} is returned if all is ok. Otherwise @code{FALSE} is returned +-and bfd_error is set. +- +diff -Nur binutils-2.24.orig/bfd/doc/reloc.texi binutils-2.24/bfd/doc/reloc.texi +--- binutils-2.24.orig/bfd/doc/reloc.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/reloc.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,3849 +0,0 @@ +-@section Relocations +-BFD maintains relocations in much the same way it maintains +-symbols: they are left alone until required, then read in +-en-masse and translated into an internal form. A common +-routine @code{bfd_perform_relocation} acts upon the +-canonical form to do the fixup. +- +-Relocations are maintained on a per section basis, +-while symbols are maintained on a per BFD basis. +- +-All that a back end has to do to fit the BFD interface is to create +-a @code{struct reloc_cache_entry} for each relocation +-in a particular section, and fill in the right bits of the structures. +- +-@menu +-* typedef arelent:: +-* howto manager:: +-@end menu +- +- +-@node typedef arelent, howto manager, Relocations, Relocations +-@subsection typedef arelent +-This is the structure of a relocation entry: +- +- +-@example +- +-typedef enum bfd_reloc_status +-@{ +- /* No errors detected. */ +- bfd_reloc_ok, +- +- /* The relocation was performed, but there was an overflow. */ +- bfd_reloc_overflow, +- +- /* The address to relocate was not within the section supplied. */ +- bfd_reloc_outofrange, +- +- /* Used by special functions. */ +- bfd_reloc_continue, +- +- /* Unsupported relocation size requested. */ +- bfd_reloc_notsupported, +- +- /* Unused. */ +- bfd_reloc_other, +- +- /* The symbol to relocate against was undefined. */ +- bfd_reloc_undefined, +- +- /* The relocation was performed, but may not be ok - presently +- generated only when linking i960 coff files with i960 b.out +- symbols. If this type is returned, the error_message argument +- to bfd_perform_relocation will be set. */ +- bfd_reloc_dangerous +- @} +- bfd_reloc_status_type; +- +- +-typedef struct reloc_cache_entry +-@{ +- /* A pointer into the canonical table of pointers. */ +- struct bfd_symbol **sym_ptr_ptr; +- +- /* offset in section. */ +- bfd_size_type address; +- +- /* addend for relocation value. */ +- bfd_vma addend; +- +- /* Pointer to how to perform the required relocation. */ +- reloc_howto_type *howto; +- +-@} +-arelent; +- +-@end example +-@strong{Description}@* +-Here is a description of each of the fields within an @code{arelent}: +- +-@itemize @bullet +- +-@item +-@code{sym_ptr_ptr} +-@end itemize +-The symbol table pointer points to a pointer to the symbol +-associated with the relocation request. It is the pointer +-into the table returned by the back end's +-@code{canonicalize_symtab} action. @xref{Symbols}. The symbol is +-referenced through a pointer to a pointer so that tools like +-the linker can fix up all the symbols of the same name by +-modifying only one pointer. The relocation routine looks in +-the symbol and uses the base of the section the symbol is +-attached to and the value of the symbol as the initial +-relocation offset. If the symbol pointer is zero, then the +-section provided is looked up. +- +-@itemize @bullet +- +-@item +-@code{address} +-@end itemize +-The @code{address} field gives the offset in bytes from the base of +-the section data which owns the relocation record to the first +-byte of relocatable information. The actual data relocated +-will be relative to this point; for example, a relocation +-type which modifies the bottom two bytes of a four byte word +-would not touch the first byte pointed to in a big endian +-world. +- +-@itemize @bullet +- +-@item +-@code{addend} +-@end itemize +-The @code{addend} is a value provided by the back end to be added (!) +-to the relocation offset. Its interpretation is dependent upon +-the howto. For example, on the 68k the code: +- +-@example +- char foo[]; +- main() +- @{ +- return foo[0x12345678]; +- @} +-@end example +- +-Could be compiled into: +- +-@example +- linkw fp,#-4 +- moveb @@#12345678,d0 +- extbl d0 +- unlk fp +- rts +-@end example +- +-This could create a reloc pointing to @code{foo}, but leave the +-offset in the data, something like: +- +-@example +-RELOCATION RECORDS FOR [.text]: +-offset type value +-00000006 32 _foo +- +-00000000 4e56 fffc ; linkw fp,#-4 +-00000004 1039 1234 5678 ; moveb @@#12345678,d0 +-0000000a 49c0 ; extbl d0 +-0000000c 4e5e ; unlk fp +-0000000e 4e75 ; rts +-@end example +- +-Using coff and an 88k, some instructions don't have enough +-space in them to represent the full address range, and +-pointers have to be loaded in two parts. So you'd get something like: +- +-@example +- or.u r13,r0,hi16(_foo+0x12345678) +- ld.b r2,r13,lo16(_foo+0x12345678) +- jmp r1 +-@end example +- +-This should create two relocs, both pointing to @code{_foo}, and with +-0x12340000 in their addend field. The data would consist of: +- +-@example +-RELOCATION RECORDS FOR [.text]: +-offset type value +-00000002 HVRT16 _foo+0x12340000 +-00000006 LVRT16 _foo+0x12340000 +- +-00000000 5da05678 ; or.u r13,r0,0x5678 +-00000004 1c4d5678 ; ld.b r2,r13,0x5678 +-00000008 f400c001 ; jmp r1 +-@end example +- +-The relocation routine digs out the value from the data, adds +-it to the addend to get the original offset, and then adds the +-value of @code{_foo}. Note that all 32 bits have to be kept around +-somewhere, to cope with carry from bit 15 to bit 16. +- +-One further example is the sparc and the a.out format. The +-sparc has a similar problem to the 88k, in that some +-instructions don't have room for an entire offset, but on the +-sparc the parts are created in odd sized lumps. The designers of +-the a.out format chose to not use the data within the section +-for storing part of the offset; all the offset is kept within +-the reloc. Anything in the data should be ignored. +- +-@example +- save %sp,-112,%sp +- sethi %hi(_foo+0x12345678),%g2 +- ldsb [%g2+%lo(_foo+0x12345678)],%i0 +- ret +- restore +-@end example +- +-Both relocs contain a pointer to @code{foo}, and the offsets +-contain junk. +- +-@example +-RELOCATION RECORDS FOR [.text]: +-offset type value +-00000004 HI22 _foo+0x12345678 +-00000008 LO10 _foo+0x12345678 +- +-00000000 9de3bf90 ; save %sp,-112,%sp +-00000004 05000000 ; sethi %hi(_foo+0),%g2 +-00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0 +-0000000c 81c7e008 ; ret +-00000010 81e80000 ; restore +-@end example +- +-@itemize @bullet +- +-@item +-@code{howto} +-@end itemize +-The @code{howto} field can be imagined as a +-relocation instruction. It is a pointer to a structure which +-contains information on what to do with all of the other +-information in the reloc record and data section. A back end +-would normally have a relocation instruction set and turn +-relocations into pointers to the correct structure on input - +-but it would be possible to create each howto field on demand. +- +-@subsubsection @code{enum complain_overflow} +-Indicates what sort of overflow checking should be done when +-performing a relocation. +- +- +-@example +- +-enum complain_overflow +-@{ +- /* Do not complain on overflow. */ +- complain_overflow_dont, +- +- /* Complain if the value overflows when considered as a signed +- number one bit larger than the field. ie. A bitfield of N bits +- is allowed to represent -2**n to 2**n-1. */ +- complain_overflow_bitfield, +- +- /* Complain if the value overflows when considered as a signed +- number. */ +- complain_overflow_signed, +- +- /* Complain if the value overflows when considered as an +- unsigned number. */ +- complain_overflow_unsigned +-@}; +-@end example +-@subsubsection @code{reloc_howto_type} +-The @code{reloc_howto_type} is a structure which contains all the +-information that libbfd needs to know to tie up a back end's data. +- +- +-@example +-struct bfd_symbol; /* Forward declaration. */ +- +-struct reloc_howto_struct +-@{ +- /* The type field has mainly a documentary use - the back end can +- do what it wants with it, though normally the back end's +- external idea of what a reloc number is stored +- in this field. For example, a PC relative word relocation +- in a coff environment has the type 023 - because that's +- what the outside world calls a R_PCRWORD reloc. */ +- unsigned int type; +- +- /* The value the final relocation is shifted right by. This drops +- unwanted data from the relocation. */ +- unsigned int rightshift; +- +- /* The size of the item to be relocated. This is *not* a +- power-of-two measure. To get the number of bytes operated +- on by a type of relocation, use bfd_get_reloc_size. */ +- int size; +- +- /* The number of bits in the item to be relocated. This is used +- when doing overflow checking. */ +- unsigned int bitsize; +- +- /* The relocation is relative to the field being relocated. */ +- bfd_boolean pc_relative; +- +- /* The bit position of the reloc value in the destination. +- The relocated value is left shifted by this amount. */ +- unsigned int bitpos; +- +- /* What type of overflow error should be checked for when +- relocating. */ +- enum complain_overflow complain_on_overflow; +- +- /* If this field is non null, then the supplied function is +- called rather than the normal function. This allows really +- strange relocation methods to be accommodated (e.g., i960 callj +- instructions). */ +- bfd_reloc_status_type (*special_function) +- (bfd *, arelent *, struct bfd_symbol *, void *, asection *, +- bfd *, char **); +- +- /* The textual name of the relocation type. */ +- char *name; +- +- /* Some formats record a relocation addend in the section contents +- rather than with the relocation. For ELF formats this is the +- distinction between USE_REL and USE_RELA (though the code checks +- for USE_REL == 1/0). The value of this field is TRUE if the +- addend is recorded with the section contents; when performing a +- partial link (ld -r) the section contents (the data) will be +- modified. The value of this field is FALSE if addends are +- recorded with the relocation (in arelent.addend); when performing +- a partial link the relocation will be modified. +- All relocations for all ELF USE_RELA targets should set this field +- to FALSE (values of TRUE should be looked on with suspicion). +- However, the converse is not true: not all relocations of all ELF +- USE_REL targets set this field to TRUE. Why this is so is peculiar +- to each particular target. For relocs that aren't used in partial +- links (e.g. GOT stuff) it doesn't matter what this is set to. */ +- bfd_boolean partial_inplace; +- +- /* src_mask selects the part of the instruction (or data) to be used +- in the relocation sum. If the target relocations don't have an +- addend in the reloc, eg. ELF USE_REL, src_mask will normally equal +- dst_mask to extract the addend from the section contents. If +- relocations do have an addend in the reloc, eg. ELF USE_RELA, this +- field should be zero. Non-zero values for ELF USE_RELA targets are +- bogus as in those cases the value in the dst_mask part of the +- section contents should be treated as garbage. */ +- bfd_vma src_mask; +- +- /* dst_mask selects which parts of the instruction (or data) are +- replaced with a relocated value. */ +- bfd_vma dst_mask; +- +- /* When some formats create PC relative instructions, they leave +- the value of the pc of the place being relocated in the offset +- slot of the instruction, so that a PC relative relocation can +- be made just by adding in an ordinary offset (e.g., sun3 a.out). +- Some formats leave the displacement part of an instruction +- empty (e.g., m88k bcs); this flag signals the fact. */ +- bfd_boolean pcrel_offset; +-@}; +- +-@end example +-@findex The HOWTO Macro +-@subsubsection @code{The HOWTO Macro} +-@strong{Description}@* +-The HOWTO define is horrible and will go away. +-@example +-#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ +- @{ (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC @} +-@end example +- +-@strong{Description}@* +-And will be replaced with the totally magic way. But for the +-moment, we are compatible, so do it this way. +-@example +-#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \ +- HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \ +- NAME, FALSE, 0, 0, IN) +- +-@end example +- +-@strong{Description}@* +-This is used to fill in an empty howto entry in an array. +-@example +-#define EMPTY_HOWTO(C) \ +- HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ +- NULL, FALSE, 0, 0, FALSE) +- +-@end example +- +-@strong{Description}@* +-Helper routine to turn a symbol into a relocation value. +-@example +-#define HOWTO_PREPARE(relocation, symbol) \ +- @{ \ +- if (symbol != NULL) \ +- @{ \ +- if (bfd_is_com_section (symbol->section)) \ +- @{ \ +- relocation = 0; \ +- @} \ +- else \ +- @{ \ +- relocation = symbol->value; \ +- @} \ +- @} \ +- @} +- +-@end example +- +-@findex bfd_get_reloc_size +-@subsubsection @code{bfd_get_reloc_size} +-@strong{Synopsis} +-@example +-unsigned int bfd_get_reloc_size (reloc_howto_type *); +-@end example +-@strong{Description}@* +-For a reloc_howto_type that operates on a fixed number of bytes, +-this returns the number of bytes operated on. +- +-@findex arelent_chain +-@subsubsection @code{arelent_chain} +-@strong{Description}@* +-How relocs are tied together in an @code{asection}: +-@example +-typedef struct relent_chain +-@{ +- arelent relent; +- struct relent_chain *next; +-@} +-arelent_chain; +- +-@end example +- +-@findex bfd_check_overflow +-@subsubsection @code{bfd_check_overflow} +-@strong{Synopsis} +-@example +-bfd_reloc_status_type bfd_check_overflow +- (enum complain_overflow how, +- unsigned int bitsize, +- unsigned int rightshift, +- unsigned int addrsize, +- bfd_vma relocation); +-@end example +-@strong{Description}@* +-Perform overflow checking on @var{relocation} which has +-@var{bitsize} significant bits and will be shifted right by +-@var{rightshift} bits, on a machine with addresses containing +-@var{addrsize} significant bits. The result is either of +-@code{bfd_reloc_ok} or @code{bfd_reloc_overflow}. +- +-@findex bfd_perform_relocation +-@subsubsection @code{bfd_perform_relocation} +-@strong{Synopsis} +-@example +-bfd_reloc_status_type bfd_perform_relocation +- (bfd *abfd, +- arelent *reloc_entry, +- void *data, +- asection *input_section, +- bfd *output_bfd, +- char **error_message); +-@end example +-@strong{Description}@* +-If @var{output_bfd} is supplied to this function, the +-generated image will be relocatable; the relocations are +-copied to the output file after they have been changed to +-reflect the new state of the world. There are two ways of +-reflecting the results of partial linkage in an output file: +-by modifying the output data in place, and by modifying the +-relocation record. Some native formats (e.g., basic a.out and +-basic coff) have no way of specifying an addend in the +-relocation type, so the addend has to go in the output data. +-This is no big deal since in these formats the output data +-slot will always be big enough for the addend. Complex reloc +-types with addends were invented to solve just this problem. +-The @var{error_message} argument is set to an error message if +-this return @code{bfd_reloc_dangerous}. +- +-@findex bfd_install_relocation +-@subsubsection @code{bfd_install_relocation} +-@strong{Synopsis} +-@example +-bfd_reloc_status_type bfd_install_relocation +- (bfd *abfd, +- arelent *reloc_entry, +- void *data, bfd_vma data_start, +- asection *input_section, +- char **error_message); +-@end example +-@strong{Description}@* +-This looks remarkably like @code{bfd_perform_relocation}, except it +-does not expect that the section contents have been filled in. +-I.e., it's suitable for use when creating, rather than applying +-a relocation. +- +-For now, this function should be considered reserved for the +-assembler. +- +- +-@node howto manager, , typedef arelent, Relocations +-@subsection The howto manager +-When an application wants to create a relocation, but doesn't +-know what the target machine might call it, it can find out by +-using this bit of code. +- +-@findex bfd_reloc_code_type +-@subsubsection @code{bfd_reloc_code_type} +-@strong{Description}@* +-The insides of a reloc code. The idea is that, eventually, there +-will be one enumerator for every type of relocation we ever do. +-Pass one of these values to @code{bfd_reloc_type_lookup}, and it'll +-return a howto pointer. +- +-This does mean that the application must determine the correct +-enumerator value; you can't get a howto pointer from a random set +-of attributes. +- +-Here are the possible values for @code{enum bfd_reloc_code_real}: +- +-@deffn {} BFD_RELOC_64 +-@deffnx {} BFD_RELOC_32 +-@deffnx {} BFD_RELOC_26 +-@deffnx {} BFD_RELOC_24 +-@deffnx {} BFD_RELOC_16 +-@deffnx {} BFD_RELOC_14 +-@deffnx {} BFD_RELOC_8 +-Basic absolute relocations of N bits. +-@end deffn +-@deffn {} BFD_RELOC_64_PCREL +-@deffnx {} BFD_RELOC_32_PCREL +-@deffnx {} BFD_RELOC_24_PCREL +-@deffnx {} BFD_RELOC_16_PCREL +-@deffnx {} BFD_RELOC_12_PCREL +-@deffnx {} BFD_RELOC_8_PCREL +-PC-relative relocations. Sometimes these are relative to the address +-of the relocation itself; sometimes they are relative to the start of +-the section containing the relocation. It depends on the specific target. +- +-The 24-bit relocation is used in some Intel 960 configurations. +-@end deffn +-@deffn {} BFD_RELOC_32_SECREL +-Section relative relocations. Some targets need this for DWARF2. +-@end deffn +-@deffn {} BFD_RELOC_32_GOT_PCREL +-@deffnx {} BFD_RELOC_16_GOT_PCREL +-@deffnx {} BFD_RELOC_8_GOT_PCREL +-@deffnx {} BFD_RELOC_32_GOTOFF +-@deffnx {} BFD_RELOC_16_GOTOFF +-@deffnx {} BFD_RELOC_LO16_GOTOFF +-@deffnx {} BFD_RELOC_HI16_GOTOFF +-@deffnx {} BFD_RELOC_HI16_S_GOTOFF +-@deffnx {} BFD_RELOC_8_GOTOFF +-@deffnx {} BFD_RELOC_64_PLT_PCREL +-@deffnx {} BFD_RELOC_32_PLT_PCREL +-@deffnx {} BFD_RELOC_24_PLT_PCREL +-@deffnx {} BFD_RELOC_16_PLT_PCREL +-@deffnx {} BFD_RELOC_8_PLT_PCREL +-@deffnx {} BFD_RELOC_64_PLTOFF +-@deffnx {} BFD_RELOC_32_PLTOFF +-@deffnx {} BFD_RELOC_16_PLTOFF +-@deffnx {} BFD_RELOC_LO16_PLTOFF +-@deffnx {} BFD_RELOC_HI16_PLTOFF +-@deffnx {} BFD_RELOC_HI16_S_PLTOFF +-@deffnx {} BFD_RELOC_8_PLTOFF +-For ELF. +-@end deffn +-@deffn {} BFD_RELOC_SIZE32 +-@deffnx {} BFD_RELOC_SIZE64 +-Size relocations. +-@end deffn +-@deffn {} BFD_RELOC_68K_GLOB_DAT +-@deffnx {} BFD_RELOC_68K_JMP_SLOT +-@deffnx {} BFD_RELOC_68K_RELATIVE +-@deffnx {} BFD_RELOC_68K_TLS_GD32 +-@deffnx {} BFD_RELOC_68K_TLS_GD16 +-@deffnx {} BFD_RELOC_68K_TLS_GD8 +-@deffnx {} BFD_RELOC_68K_TLS_LDM32 +-@deffnx {} BFD_RELOC_68K_TLS_LDM16 +-@deffnx {} BFD_RELOC_68K_TLS_LDM8 +-@deffnx {} BFD_RELOC_68K_TLS_LDO32 +-@deffnx {} BFD_RELOC_68K_TLS_LDO16 +-@deffnx {} BFD_RELOC_68K_TLS_LDO8 +-@deffnx {} BFD_RELOC_68K_TLS_IE32 +-@deffnx {} BFD_RELOC_68K_TLS_IE16 +-@deffnx {} BFD_RELOC_68K_TLS_IE8 +-@deffnx {} BFD_RELOC_68K_TLS_LE32 +-@deffnx {} BFD_RELOC_68K_TLS_LE16 +-@deffnx {} BFD_RELOC_68K_TLS_LE8 +-Relocations used by 68K ELF. +-@end deffn +-@deffn {} BFD_RELOC_32_BASEREL +-@deffnx {} BFD_RELOC_16_BASEREL +-@deffnx {} BFD_RELOC_LO16_BASEREL +-@deffnx {} BFD_RELOC_HI16_BASEREL +-@deffnx {} BFD_RELOC_HI16_S_BASEREL +-@deffnx {} BFD_RELOC_8_BASEREL +-@deffnx {} BFD_RELOC_RVA +-Linkage-table relative. +-@end deffn +-@deffn {} BFD_RELOC_8_FFnn +-Absolute 8-bit relocation, but used to form an address like 0xFFnn. +-@end deffn +-@deffn {} BFD_RELOC_32_PCREL_S2 +-@deffnx {} BFD_RELOC_16_PCREL_S2 +-@deffnx {} BFD_RELOC_23_PCREL_S2 +-These PC-relative relocations are stored as word displacements -- +-i.e., byte displacements shifted right two bits. The 30-bit word +-displacement (<<32_PCREL_S2>> -- 32 bits, shifted 2) is used on the +-SPARC. (SPARC tools generally refer to this as <>.) The +-signed 16-bit displacement is used on the MIPS, and the 23-bit +-displacement is used on the Alpha. +-@end deffn +-@deffn {} BFD_RELOC_HI22 +-@deffnx {} BFD_RELOC_LO10 +-High 22 bits and low 10 bits of 32-bit value, placed into lower bits of +-the target word. These are used on the SPARC. +-@end deffn +-@deffn {} BFD_RELOC_GPREL16 +-@deffnx {} BFD_RELOC_GPREL32 +-For systems that allocate a Global Pointer register, these are +-displacements off that register. These relocation types are +-handled specially, because the value the register will have is +-decided relatively late. +-@end deffn +-@deffn {} BFD_RELOC_I960_CALLJ +-Reloc types used for i960/b.out. +-@end deffn +-@deffn {} BFD_RELOC_NONE +-@deffnx {} BFD_RELOC_SPARC_WDISP22 +-@deffnx {} BFD_RELOC_SPARC22 +-@deffnx {} BFD_RELOC_SPARC13 +-@deffnx {} BFD_RELOC_SPARC_GOT10 +-@deffnx {} BFD_RELOC_SPARC_GOT13 +-@deffnx {} BFD_RELOC_SPARC_GOT22 +-@deffnx {} BFD_RELOC_SPARC_PC10 +-@deffnx {} BFD_RELOC_SPARC_PC22 +-@deffnx {} BFD_RELOC_SPARC_WPLT30 +-@deffnx {} BFD_RELOC_SPARC_COPY +-@deffnx {} BFD_RELOC_SPARC_GLOB_DAT +-@deffnx {} BFD_RELOC_SPARC_JMP_SLOT +-@deffnx {} BFD_RELOC_SPARC_RELATIVE +-@deffnx {} BFD_RELOC_SPARC_UA16 +-@deffnx {} BFD_RELOC_SPARC_UA32 +-@deffnx {} BFD_RELOC_SPARC_UA64 +-@deffnx {} BFD_RELOC_SPARC_GOTDATA_HIX22 +-@deffnx {} BFD_RELOC_SPARC_GOTDATA_LOX10 +-@deffnx {} BFD_RELOC_SPARC_GOTDATA_OP_HIX22 +-@deffnx {} BFD_RELOC_SPARC_GOTDATA_OP_LOX10 +-@deffnx {} BFD_RELOC_SPARC_GOTDATA_OP +-@deffnx {} BFD_RELOC_SPARC_JMP_IREL +-@deffnx {} BFD_RELOC_SPARC_IRELATIVE +-SPARC ELF relocations. There is probably some overlap with other +-relocation types already defined. +-@end deffn +-@deffn {} BFD_RELOC_SPARC_BASE13 +-@deffnx {} BFD_RELOC_SPARC_BASE22 +-I think these are specific to SPARC a.out (e.g., Sun 4). +-@end deffn +-@deffn {} BFD_RELOC_SPARC_64 +-@deffnx {} BFD_RELOC_SPARC_10 +-@deffnx {} BFD_RELOC_SPARC_11 +-@deffnx {} BFD_RELOC_SPARC_OLO10 +-@deffnx {} BFD_RELOC_SPARC_HH22 +-@deffnx {} BFD_RELOC_SPARC_HM10 +-@deffnx {} BFD_RELOC_SPARC_LM22 +-@deffnx {} BFD_RELOC_SPARC_PC_HH22 +-@deffnx {} BFD_RELOC_SPARC_PC_HM10 +-@deffnx {} BFD_RELOC_SPARC_PC_LM22 +-@deffnx {} BFD_RELOC_SPARC_WDISP16 +-@deffnx {} BFD_RELOC_SPARC_WDISP19 +-@deffnx {} BFD_RELOC_SPARC_7 +-@deffnx {} BFD_RELOC_SPARC_6 +-@deffnx {} BFD_RELOC_SPARC_5 +-@deffnx {} BFD_RELOC_SPARC_DISP64 +-@deffnx {} BFD_RELOC_SPARC_PLT32 +-@deffnx {} BFD_RELOC_SPARC_PLT64 +-@deffnx {} BFD_RELOC_SPARC_HIX22 +-@deffnx {} BFD_RELOC_SPARC_LOX10 +-@deffnx {} BFD_RELOC_SPARC_H44 +-@deffnx {} BFD_RELOC_SPARC_M44 +-@deffnx {} BFD_RELOC_SPARC_L44 +-@deffnx {} BFD_RELOC_SPARC_REGISTER +-@deffnx {} BFD_RELOC_SPARC_H34 +-@deffnx {} BFD_RELOC_SPARC_SIZE32 +-@deffnx {} BFD_RELOC_SPARC_SIZE64 +-@deffnx {} BFD_RELOC_SPARC_WDISP10 +-SPARC64 relocations +-@end deffn +-@deffn {} BFD_RELOC_SPARC_REV32 +-SPARC little endian relocation +-@end deffn +-@deffn {} BFD_RELOC_SPARC_TLS_GD_HI22 +-@deffnx {} BFD_RELOC_SPARC_TLS_GD_LO10 +-@deffnx {} BFD_RELOC_SPARC_TLS_GD_ADD +-@deffnx {} BFD_RELOC_SPARC_TLS_GD_CALL +-@deffnx {} BFD_RELOC_SPARC_TLS_LDM_HI22 +-@deffnx {} BFD_RELOC_SPARC_TLS_LDM_LO10 +-@deffnx {} BFD_RELOC_SPARC_TLS_LDM_ADD +-@deffnx {} BFD_RELOC_SPARC_TLS_LDM_CALL +-@deffnx {} BFD_RELOC_SPARC_TLS_LDO_HIX22 +-@deffnx {} BFD_RELOC_SPARC_TLS_LDO_LOX10 +-@deffnx {} BFD_RELOC_SPARC_TLS_LDO_ADD +-@deffnx {} BFD_RELOC_SPARC_TLS_IE_HI22 +-@deffnx {} BFD_RELOC_SPARC_TLS_IE_LO10 +-@deffnx {} BFD_RELOC_SPARC_TLS_IE_LD +-@deffnx {} BFD_RELOC_SPARC_TLS_IE_LDX +-@deffnx {} BFD_RELOC_SPARC_TLS_IE_ADD +-@deffnx {} BFD_RELOC_SPARC_TLS_LE_HIX22 +-@deffnx {} BFD_RELOC_SPARC_TLS_LE_LOX10 +-@deffnx {} BFD_RELOC_SPARC_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_SPARC_TLS_DTPMOD64 +-@deffnx {} BFD_RELOC_SPARC_TLS_DTPOFF32 +-@deffnx {} BFD_RELOC_SPARC_TLS_DTPOFF64 +-@deffnx {} BFD_RELOC_SPARC_TLS_TPOFF32 +-@deffnx {} BFD_RELOC_SPARC_TLS_TPOFF64 +-SPARC TLS relocations +-@end deffn +-@deffn {} BFD_RELOC_SPU_IMM7 +-@deffnx {} BFD_RELOC_SPU_IMM8 +-@deffnx {} BFD_RELOC_SPU_IMM10 +-@deffnx {} BFD_RELOC_SPU_IMM10W +-@deffnx {} BFD_RELOC_SPU_IMM16 +-@deffnx {} BFD_RELOC_SPU_IMM16W +-@deffnx {} BFD_RELOC_SPU_IMM18 +-@deffnx {} BFD_RELOC_SPU_PCREL9a +-@deffnx {} BFD_RELOC_SPU_PCREL9b +-@deffnx {} BFD_RELOC_SPU_PCREL16 +-@deffnx {} BFD_RELOC_SPU_LO16 +-@deffnx {} BFD_RELOC_SPU_HI16 +-@deffnx {} BFD_RELOC_SPU_PPU32 +-@deffnx {} BFD_RELOC_SPU_PPU64 +-@deffnx {} BFD_RELOC_SPU_ADD_PIC +-SPU Relocations. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_GPDISP_HI16 +-Alpha ECOFF and ELF relocations. Some of these treat the symbol or +-"addend" in some special way. +-For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when +-writing; when reading, it will be the absolute section symbol. The +-addend is the displacement in bytes of the "lda" instruction from +-the "ldah" instruction (which is at the address of this reloc). +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_GPDISP_LO16 +-For GPDISP_LO16 ("ignore") relocations, the symbol is handled as +-with GPDISP_HI16 relocs. The addend is ignored when writing the +-relocations out, and is filled in with the file's GP value on +-reading, for convenience. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_GPDISP +-The ELF GPDISP relocation is exactly the same as the GPDISP_HI16 +-relocation except that there is no accompanying GPDISP_LO16 +-relocation. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_LITERAL +-@deffnx {} BFD_RELOC_ALPHA_ELF_LITERAL +-@deffnx {} BFD_RELOC_ALPHA_LITUSE +-The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; +-the assembler turns it into a LDQ instruction to load the address of +-the symbol, and then fills in a register in the real instruction. +- +-The LITERAL reloc, at the LDQ instruction, refers to the .lita +-section symbol. The addend is ignored when writing, but is filled +-in with the file's GP value on reading, for convenience, as with the +-GPDISP_LO16 reloc. +- +-The ELF_LITERAL reloc is somewhere between 16_GOTOFF and GPDISP_LO16. +-It should refer to the symbol to be referenced, as with 16_GOTOFF, +-but it generates output not based on the position within the .got +-section, but relative to the GP value chosen for the file during the +-final link stage. +- +-The LITUSE reloc, on the instruction using the loaded address, gives +-information to the linker that it might be able to use to optimize +-away some literal section references. The symbol is ignored (read +-as the absolute section symbol), and the "addend" indicates the type +-of instruction using the register: +-1 - "memory" fmt insn +-2 - byte-manipulation (byte offset reg) +-3 - jsr (target of branch) +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_HINT +-The HINT relocation indicates a value that should be filled into the +-"hint" field of a jmp/jsr/ret instruction, for possible branch- +-prediction logic which may be provided on some processors. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_LINKAGE +-The LINKAGE relocation outputs a linkage pair in the object file, +-which is filled by the linker. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_CODEADDR +-The CODEADDR relocation outputs a STO_CA in the object file, +-which is filled by the linker. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_GPREL_HI16 +-@deffnx {} BFD_RELOC_ALPHA_GPREL_LO16 +-The GPREL_HI/LO relocations together form a 32-bit offset from the +-GP register. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_BRSGP +-Like BFD_RELOC_23_PCREL_S2, except that the source and target must +-share a common GP, and the target address is adjusted for +-STO_ALPHA_STD_GPLOAD. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_NOP +-The NOP relocation outputs a NOP if the longword displacement +-between two procedure entry points is < 2^21. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_BSR +-The BSR relocation outputs a BSR if the longword displacement +-between two procedure entry points is < 2^21. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_LDA +-The LDA relocation outputs a LDA if the longword displacement +-between two procedure entry points is < 2^16. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_BOH +-The BOH relocation outputs a BSR if the longword displacement +-between two procedure entry points is < 2^21, or else a hint. +-@end deffn +-@deffn {} BFD_RELOC_ALPHA_TLSGD +-@deffnx {} BFD_RELOC_ALPHA_TLSLDM +-@deffnx {} BFD_RELOC_ALPHA_DTPMOD64 +-@deffnx {} BFD_RELOC_ALPHA_GOTDTPREL16 +-@deffnx {} BFD_RELOC_ALPHA_DTPREL64 +-@deffnx {} BFD_RELOC_ALPHA_DTPREL_HI16 +-@deffnx {} BFD_RELOC_ALPHA_DTPREL_LO16 +-@deffnx {} BFD_RELOC_ALPHA_DTPREL16 +-@deffnx {} BFD_RELOC_ALPHA_GOTTPREL16 +-@deffnx {} BFD_RELOC_ALPHA_TPREL64 +-@deffnx {} BFD_RELOC_ALPHA_TPREL_HI16 +-@deffnx {} BFD_RELOC_ALPHA_TPREL_LO16 +-@deffnx {} BFD_RELOC_ALPHA_TPREL16 +-Alpha thread-local storage relocations. +-@end deffn +-@deffn {} BFD_RELOC_MIPS_JMP +-@deffnx {} BFD_RELOC_MICROMIPS_JMP +-The MIPS jump instruction. +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_JMP +-The MIPS16 jump instruction. +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_GPREL +-MIPS16 GP relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_HI16 +-High 16 bits of 32-bit value; simple reloc. +-@end deffn +-@deffn {} BFD_RELOC_HI16_S +-High 16 bits of 32-bit value but the low 16 bits will be sign +-extended and added to form the final result. If the low 16 +-bits form a negative number, we need to add one to the high value +-to compensate for the borrow when the low bits are added. +-@end deffn +-@deffn {} BFD_RELOC_LO16 +-Low 16 bits. +-@end deffn +-@deffn {} BFD_RELOC_HI16_PCREL +-High 16 bits of 32-bit pc-relative value +-@end deffn +-@deffn {} BFD_RELOC_HI16_S_PCREL +-High 16 bits of 32-bit pc-relative value, adjusted +-@end deffn +-@deffn {} BFD_RELOC_LO16_PCREL +-Low 16 bits of pc-relative value +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_GOT16 +-@deffnx {} BFD_RELOC_MIPS16_CALL16 +-Equivalent of BFD_RELOC_MIPS_*, but with the MIPS16 layout of +-16-bit immediate fields +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_HI16 +-MIPS16 high 16 bits of 32-bit value. +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_HI16_S +-MIPS16 high 16 bits of 32-bit value but the low 16 bits will be sign +-extended and added to form the final result. If the low 16 +-bits form a negative number, we need to add one to the high value +-to compensate for the borrow when the low bits are added. +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_LO16 +-MIPS16 low 16 bits. +-@end deffn +-@deffn {} BFD_RELOC_MIPS16_TLS_GD +-@deffnx {} BFD_RELOC_MIPS16_TLS_LDM +-@deffnx {} BFD_RELOC_MIPS16_TLS_DTPREL_HI16 +-@deffnx {} BFD_RELOC_MIPS16_TLS_DTPREL_LO16 +-@deffnx {} BFD_RELOC_MIPS16_TLS_GOTTPREL +-@deffnx {} BFD_RELOC_MIPS16_TLS_TPREL_HI16 +-@deffnx {} BFD_RELOC_MIPS16_TLS_TPREL_LO16 +-MIPS16 TLS relocations +-@end deffn +-@deffn {} BFD_RELOC_MIPS_LITERAL +-@deffnx {} BFD_RELOC_MICROMIPS_LITERAL +-Relocation against a MIPS literal section. +-@end deffn +-@deffn {} BFD_RELOC_MICROMIPS_7_PCREL_S1 +-@deffnx {} BFD_RELOC_MICROMIPS_10_PCREL_S1 +-@deffnx {} BFD_RELOC_MICROMIPS_16_PCREL_S1 +-microMIPS PC-relative relocations. +-@end deffn +-@deffn {} BFD_RELOC_MICROMIPS_GPREL16 +-@deffnx {} BFD_RELOC_MICROMIPS_HI16 +-@deffnx {} BFD_RELOC_MICROMIPS_HI16_S +-@deffnx {} BFD_RELOC_MICROMIPS_LO16 +-microMIPS versions of generic BFD relocs. +-@end deffn +-@deffn {} BFD_RELOC_MIPS_GOT16 +-@deffnx {} BFD_RELOC_MICROMIPS_GOT16 +-@deffnx {} BFD_RELOC_MIPS_CALL16 +-@deffnx {} BFD_RELOC_MICROMIPS_CALL16 +-@deffnx {} BFD_RELOC_MIPS_GOT_HI16 +-@deffnx {} BFD_RELOC_MICROMIPS_GOT_HI16 +-@deffnx {} BFD_RELOC_MIPS_GOT_LO16 +-@deffnx {} BFD_RELOC_MICROMIPS_GOT_LO16 +-@deffnx {} BFD_RELOC_MIPS_CALL_HI16 +-@deffnx {} BFD_RELOC_MICROMIPS_CALL_HI16 +-@deffnx {} BFD_RELOC_MIPS_CALL_LO16 +-@deffnx {} BFD_RELOC_MICROMIPS_CALL_LO16 +-@deffnx {} BFD_RELOC_MIPS_SUB +-@deffnx {} BFD_RELOC_MICROMIPS_SUB +-@deffnx {} BFD_RELOC_MIPS_GOT_PAGE +-@deffnx {} BFD_RELOC_MICROMIPS_GOT_PAGE +-@deffnx {} BFD_RELOC_MIPS_GOT_OFST +-@deffnx {} BFD_RELOC_MICROMIPS_GOT_OFST +-@deffnx {} BFD_RELOC_MIPS_GOT_DISP +-@deffnx {} BFD_RELOC_MICROMIPS_GOT_DISP +-@deffnx {} BFD_RELOC_MIPS_SHIFT5 +-@deffnx {} BFD_RELOC_MIPS_SHIFT6 +-@deffnx {} BFD_RELOC_MIPS_INSERT_A +-@deffnx {} BFD_RELOC_MIPS_INSERT_B +-@deffnx {} BFD_RELOC_MIPS_DELETE +-@deffnx {} BFD_RELOC_MIPS_HIGHEST +-@deffnx {} BFD_RELOC_MICROMIPS_HIGHEST +-@deffnx {} BFD_RELOC_MIPS_HIGHER +-@deffnx {} BFD_RELOC_MICROMIPS_HIGHER +-@deffnx {} BFD_RELOC_MIPS_SCN_DISP +-@deffnx {} BFD_RELOC_MICROMIPS_SCN_DISP +-@deffnx {} BFD_RELOC_MIPS_REL16 +-@deffnx {} BFD_RELOC_MIPS_RELGOT +-@deffnx {} BFD_RELOC_MIPS_JALR +-@deffnx {} BFD_RELOC_MICROMIPS_JALR +-@deffnx {} BFD_RELOC_MIPS_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL32 +-@deffnx {} BFD_RELOC_MIPS_TLS_DTPMOD64 +-@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL64 +-@deffnx {} BFD_RELOC_MIPS_TLS_GD +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_GD +-@deffnx {} BFD_RELOC_MIPS_TLS_LDM +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_LDM +-@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL_HI16 +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_DTPREL_HI16 +-@deffnx {} BFD_RELOC_MIPS_TLS_DTPREL_LO16 +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_DTPREL_LO16 +-@deffnx {} BFD_RELOC_MIPS_TLS_GOTTPREL +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_GOTTPREL +-@deffnx {} BFD_RELOC_MIPS_TLS_TPREL32 +-@deffnx {} BFD_RELOC_MIPS_TLS_TPREL64 +-@deffnx {} BFD_RELOC_MIPS_TLS_TPREL_HI16 +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_TPREL_HI16 +-@deffnx {} BFD_RELOC_MIPS_TLS_TPREL_LO16 +-@deffnx {} BFD_RELOC_MICROMIPS_TLS_TPREL_LO16 +-@deffnx {} BFD_RELOC_MIPS_EH +-MIPS ELF relocations. +-@end deffn +-@deffn {} BFD_RELOC_MIPS_COPY +-@deffnx {} BFD_RELOC_MIPS_JUMP_SLOT +-MIPS ELF relocations (VxWorks and PLT extensions). +-@end deffn +-@deffn {} BFD_RELOC_MOXIE_10_PCREL +-Moxie ELF relocations. +-@end deffn +-@deffn {} BFD_RELOC_FRV_LABEL16 +-@deffnx {} BFD_RELOC_FRV_LABEL24 +-@deffnx {} BFD_RELOC_FRV_LO16 +-@deffnx {} BFD_RELOC_FRV_HI16 +-@deffnx {} BFD_RELOC_FRV_GPREL12 +-@deffnx {} BFD_RELOC_FRV_GPRELU12 +-@deffnx {} BFD_RELOC_FRV_GPREL32 +-@deffnx {} BFD_RELOC_FRV_GPRELHI +-@deffnx {} BFD_RELOC_FRV_GPRELLO +-@deffnx {} BFD_RELOC_FRV_GOT12 +-@deffnx {} BFD_RELOC_FRV_GOTHI +-@deffnx {} BFD_RELOC_FRV_GOTLO +-@deffnx {} BFD_RELOC_FRV_FUNCDESC +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOT12 +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTHI +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTLO +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_VALUE +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTOFF12 +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTOFFHI +-@deffnx {} BFD_RELOC_FRV_FUNCDESC_GOTOFFLO +-@deffnx {} BFD_RELOC_FRV_GOTOFF12 +-@deffnx {} BFD_RELOC_FRV_GOTOFFHI +-@deffnx {} BFD_RELOC_FRV_GOTOFFLO +-@deffnx {} BFD_RELOC_FRV_GETTLSOFF +-@deffnx {} BFD_RELOC_FRV_TLSDESC_VALUE +-@deffnx {} BFD_RELOC_FRV_GOTTLSDESC12 +-@deffnx {} BFD_RELOC_FRV_GOTTLSDESCHI +-@deffnx {} BFD_RELOC_FRV_GOTTLSDESCLO +-@deffnx {} BFD_RELOC_FRV_TLSMOFF12 +-@deffnx {} BFD_RELOC_FRV_TLSMOFFHI +-@deffnx {} BFD_RELOC_FRV_TLSMOFFLO +-@deffnx {} BFD_RELOC_FRV_GOTTLSOFF12 +-@deffnx {} BFD_RELOC_FRV_GOTTLSOFFHI +-@deffnx {} BFD_RELOC_FRV_GOTTLSOFFLO +-@deffnx {} BFD_RELOC_FRV_TLSOFF +-@deffnx {} BFD_RELOC_FRV_TLSDESC_RELAX +-@deffnx {} BFD_RELOC_FRV_GETTLSOFF_RELAX +-@deffnx {} BFD_RELOC_FRV_TLSOFF_RELAX +-@deffnx {} BFD_RELOC_FRV_TLSMOFF +-Fujitsu Frv Relocations. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_GOTOFF24 +-This is a 24bit GOT-relative reloc for the mn10300. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_GOT32 +-This is a 32bit GOT-relative reloc for the mn10300, offset by two bytes +-in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_GOT24 +-This is a 24bit GOT-relative reloc for the mn10300, offset by two bytes +-in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_GOT16 +-This is a 16bit GOT-relative reloc for the mn10300, offset by two bytes +-in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_COPY +-Copy symbol at runtime. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_GLOB_DAT +-Create GOT entry. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_JMP_SLOT +-Create PLT entry. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_RELATIVE +-Adjust by program base. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_SYM_DIFF +-Together with another reloc targeted at the same location, +-allows for a value that is the difference of two symbols +-in the same section. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_ALIGN +-The addend of this reloc is an alignment power that must +-be honoured at the offset's location, regardless of linker +-relaxation. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_TLS_GD +-@deffnx {} BFD_RELOC_MN10300_TLS_LD +-@deffnx {} BFD_RELOC_MN10300_TLS_LDO +-@deffnx {} BFD_RELOC_MN10300_TLS_GOTIE +-@deffnx {} BFD_RELOC_MN10300_TLS_IE +-@deffnx {} BFD_RELOC_MN10300_TLS_LE +-@deffnx {} BFD_RELOC_MN10300_TLS_DTPMOD +-@deffnx {} BFD_RELOC_MN10300_TLS_DTPOFF +-@deffnx {} BFD_RELOC_MN10300_TLS_TPOFF +-Various TLS-related relocations. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_32_PCREL +-This is a 32bit pcrel reloc for the mn10300, offset by two bytes in the +-instruction. +-@end deffn +-@deffn {} BFD_RELOC_MN10300_16_PCREL +-This is a 16bit pcrel reloc for the mn10300, offset by two bytes in the +-instruction. +-@end deffn +-@deffn {} BFD_RELOC_386_GOT32 +-@deffnx {} BFD_RELOC_386_PLT32 +-@deffnx {} BFD_RELOC_386_COPY +-@deffnx {} BFD_RELOC_386_GLOB_DAT +-@deffnx {} BFD_RELOC_386_JUMP_SLOT +-@deffnx {} BFD_RELOC_386_RELATIVE +-@deffnx {} BFD_RELOC_386_GOTOFF +-@deffnx {} BFD_RELOC_386_GOTPC +-@deffnx {} BFD_RELOC_386_TLS_TPOFF +-@deffnx {} BFD_RELOC_386_TLS_IE +-@deffnx {} BFD_RELOC_386_TLS_GOTIE +-@deffnx {} BFD_RELOC_386_TLS_LE +-@deffnx {} BFD_RELOC_386_TLS_GD +-@deffnx {} BFD_RELOC_386_TLS_LDM +-@deffnx {} BFD_RELOC_386_TLS_LDO_32 +-@deffnx {} BFD_RELOC_386_TLS_IE_32 +-@deffnx {} BFD_RELOC_386_TLS_LE_32 +-@deffnx {} BFD_RELOC_386_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_386_TLS_DTPOFF32 +-@deffnx {} BFD_RELOC_386_TLS_TPOFF32 +-@deffnx {} BFD_RELOC_386_TLS_GOTDESC +-@deffnx {} BFD_RELOC_386_TLS_DESC_CALL +-@deffnx {} BFD_RELOC_386_TLS_DESC +-@deffnx {} BFD_RELOC_386_IRELATIVE +-i386/elf relocations +-@end deffn +-@deffn {} BFD_RELOC_X86_64_GOT32 +-@deffnx {} BFD_RELOC_X86_64_PLT32 +-@deffnx {} BFD_RELOC_X86_64_COPY +-@deffnx {} BFD_RELOC_X86_64_GLOB_DAT +-@deffnx {} BFD_RELOC_X86_64_JUMP_SLOT +-@deffnx {} BFD_RELOC_X86_64_RELATIVE +-@deffnx {} BFD_RELOC_X86_64_GOTPCREL +-@deffnx {} BFD_RELOC_X86_64_32S +-@deffnx {} BFD_RELOC_X86_64_DTPMOD64 +-@deffnx {} BFD_RELOC_X86_64_DTPOFF64 +-@deffnx {} BFD_RELOC_X86_64_TPOFF64 +-@deffnx {} BFD_RELOC_X86_64_TLSGD +-@deffnx {} BFD_RELOC_X86_64_TLSLD +-@deffnx {} BFD_RELOC_X86_64_DTPOFF32 +-@deffnx {} BFD_RELOC_X86_64_GOTTPOFF +-@deffnx {} BFD_RELOC_X86_64_TPOFF32 +-@deffnx {} BFD_RELOC_X86_64_GOTOFF64 +-@deffnx {} BFD_RELOC_X86_64_GOTPC32 +-@deffnx {} BFD_RELOC_X86_64_GOT64 +-@deffnx {} BFD_RELOC_X86_64_GOTPCREL64 +-@deffnx {} BFD_RELOC_X86_64_GOTPC64 +-@deffnx {} BFD_RELOC_X86_64_GOTPLT64 +-@deffnx {} BFD_RELOC_X86_64_PLTOFF64 +-@deffnx {} BFD_RELOC_X86_64_GOTPC32_TLSDESC +-@deffnx {} BFD_RELOC_X86_64_TLSDESC_CALL +-@deffnx {} BFD_RELOC_X86_64_TLSDESC +-@deffnx {} BFD_RELOC_X86_64_IRELATIVE +-@deffnx {} BFD_RELOC_X86_64_PC32_BND +-@deffnx {} BFD_RELOC_X86_64_PLT32_BND +-x86-64/elf relocations +-@end deffn +-@deffn {} BFD_RELOC_NS32K_IMM_8 +-@deffnx {} BFD_RELOC_NS32K_IMM_16 +-@deffnx {} BFD_RELOC_NS32K_IMM_32 +-@deffnx {} BFD_RELOC_NS32K_IMM_8_PCREL +-@deffnx {} BFD_RELOC_NS32K_IMM_16_PCREL +-@deffnx {} BFD_RELOC_NS32K_IMM_32_PCREL +-@deffnx {} BFD_RELOC_NS32K_DISP_8 +-@deffnx {} BFD_RELOC_NS32K_DISP_16 +-@deffnx {} BFD_RELOC_NS32K_DISP_32 +-@deffnx {} BFD_RELOC_NS32K_DISP_8_PCREL +-@deffnx {} BFD_RELOC_NS32K_DISP_16_PCREL +-@deffnx {} BFD_RELOC_NS32K_DISP_32_PCREL +-ns32k relocations +-@end deffn +-@deffn {} BFD_RELOC_PDP11_DISP_8_PCREL +-@deffnx {} BFD_RELOC_PDP11_DISP_6_PCREL +-PDP11 relocations +-@end deffn +-@deffn {} BFD_RELOC_PJ_CODE_HI16 +-@deffnx {} BFD_RELOC_PJ_CODE_LO16 +-@deffnx {} BFD_RELOC_PJ_CODE_DIR16 +-@deffnx {} BFD_RELOC_PJ_CODE_DIR32 +-@deffnx {} BFD_RELOC_PJ_CODE_REL16 +-@deffnx {} BFD_RELOC_PJ_CODE_REL32 +-Picojava relocs. Not all of these appear in object files. +-@end deffn +-@deffn {} BFD_RELOC_PPC_B26 +-@deffnx {} BFD_RELOC_PPC_BA26 +-@deffnx {} BFD_RELOC_PPC_TOC16 +-@deffnx {} BFD_RELOC_PPC_B16 +-@deffnx {} BFD_RELOC_PPC_B16_BRTAKEN +-@deffnx {} BFD_RELOC_PPC_B16_BRNTAKEN +-@deffnx {} BFD_RELOC_PPC_BA16 +-@deffnx {} BFD_RELOC_PPC_BA16_BRTAKEN +-@deffnx {} BFD_RELOC_PPC_BA16_BRNTAKEN +-@deffnx {} BFD_RELOC_PPC_COPY +-@deffnx {} BFD_RELOC_PPC_GLOB_DAT +-@deffnx {} BFD_RELOC_PPC_JMP_SLOT +-@deffnx {} BFD_RELOC_PPC_RELATIVE +-@deffnx {} BFD_RELOC_PPC_LOCAL24PC +-@deffnx {} BFD_RELOC_PPC_EMB_NADDR32 +-@deffnx {} BFD_RELOC_PPC_EMB_NADDR16 +-@deffnx {} BFD_RELOC_PPC_EMB_NADDR16_LO +-@deffnx {} BFD_RELOC_PPC_EMB_NADDR16_HI +-@deffnx {} BFD_RELOC_PPC_EMB_NADDR16_HA +-@deffnx {} BFD_RELOC_PPC_EMB_SDAI16 +-@deffnx {} BFD_RELOC_PPC_EMB_SDA2I16 +-@deffnx {} BFD_RELOC_PPC_EMB_SDA2REL +-@deffnx {} BFD_RELOC_PPC_EMB_SDA21 +-@deffnx {} BFD_RELOC_PPC_EMB_MRKREF +-@deffnx {} BFD_RELOC_PPC_EMB_RELSEC16 +-@deffnx {} BFD_RELOC_PPC_EMB_RELST_LO +-@deffnx {} BFD_RELOC_PPC_EMB_RELST_HI +-@deffnx {} BFD_RELOC_PPC_EMB_RELST_HA +-@deffnx {} BFD_RELOC_PPC_EMB_BIT_FLD +-@deffnx {} BFD_RELOC_PPC_EMB_RELSDA +-@deffnx {} BFD_RELOC_PPC_VLE_REL8 +-@deffnx {} BFD_RELOC_PPC_VLE_REL15 +-@deffnx {} BFD_RELOC_PPC_VLE_REL24 +-@deffnx {} BFD_RELOC_PPC_VLE_LO16A +-@deffnx {} BFD_RELOC_PPC_VLE_LO16D +-@deffnx {} BFD_RELOC_PPC_VLE_HI16A +-@deffnx {} BFD_RELOC_PPC_VLE_HI16D +-@deffnx {} BFD_RELOC_PPC_VLE_HA16A +-@deffnx {} BFD_RELOC_PPC_VLE_HA16D +-@deffnx {} BFD_RELOC_PPC_VLE_SDA21 +-@deffnx {} BFD_RELOC_PPC_VLE_SDA21_LO +-@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_LO16A +-@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_LO16D +-@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HI16A +-@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HI16D +-@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HA16A +-@deffnx {} BFD_RELOC_PPC_VLE_SDAREL_HA16D +-@deffnx {} BFD_RELOC_PPC64_HIGHER +-@deffnx {} BFD_RELOC_PPC64_HIGHER_S +-@deffnx {} BFD_RELOC_PPC64_HIGHEST +-@deffnx {} BFD_RELOC_PPC64_HIGHEST_S +-@deffnx {} BFD_RELOC_PPC64_TOC16_LO +-@deffnx {} BFD_RELOC_PPC64_TOC16_HI +-@deffnx {} BFD_RELOC_PPC64_TOC16_HA +-@deffnx {} BFD_RELOC_PPC64_TOC +-@deffnx {} BFD_RELOC_PPC64_PLTGOT16 +-@deffnx {} BFD_RELOC_PPC64_PLTGOT16_LO +-@deffnx {} BFD_RELOC_PPC64_PLTGOT16_HI +-@deffnx {} BFD_RELOC_PPC64_PLTGOT16_HA +-@deffnx {} BFD_RELOC_PPC64_ADDR16_DS +-@deffnx {} BFD_RELOC_PPC64_ADDR16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_GOT16_DS +-@deffnx {} BFD_RELOC_PPC64_GOT16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_PLT16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_SECTOFF_DS +-@deffnx {} BFD_RELOC_PPC64_SECTOFF_LO_DS +-@deffnx {} BFD_RELOC_PPC64_TOC16_DS +-@deffnx {} BFD_RELOC_PPC64_TOC16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_PLTGOT16_DS +-@deffnx {} BFD_RELOC_PPC64_PLTGOT16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_ADDR16_HIGH +-@deffnx {} BFD_RELOC_PPC64_ADDR16_HIGHA +-Power(rs6000) and PowerPC relocations. +-@end deffn +-@deffn {} BFD_RELOC_PPC_TLS +-@deffnx {} BFD_RELOC_PPC_TLSGD +-@deffnx {} BFD_RELOC_PPC_TLSLD +-@deffnx {} BFD_RELOC_PPC_DTPMOD +-@deffnx {} BFD_RELOC_PPC_TPREL16 +-@deffnx {} BFD_RELOC_PPC_TPREL16_LO +-@deffnx {} BFD_RELOC_PPC_TPREL16_HI +-@deffnx {} BFD_RELOC_PPC_TPREL16_HA +-@deffnx {} BFD_RELOC_PPC_TPREL +-@deffnx {} BFD_RELOC_PPC_DTPREL16 +-@deffnx {} BFD_RELOC_PPC_DTPREL16_LO +-@deffnx {} BFD_RELOC_PPC_DTPREL16_HI +-@deffnx {} BFD_RELOC_PPC_DTPREL16_HA +-@deffnx {} BFD_RELOC_PPC_DTPREL +-@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16 +-@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16_LO +-@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16_HI +-@deffnx {} BFD_RELOC_PPC_GOT_TLSGD16_HA +-@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16 +-@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16_LO +-@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16_HI +-@deffnx {} BFD_RELOC_PPC_GOT_TLSLD16_HA +-@deffnx {} BFD_RELOC_PPC_GOT_TPREL16 +-@deffnx {} BFD_RELOC_PPC_GOT_TPREL16_LO +-@deffnx {} BFD_RELOC_PPC_GOT_TPREL16_HI +-@deffnx {} BFD_RELOC_PPC_GOT_TPREL16_HA +-@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16 +-@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16_LO +-@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16_HI +-@deffnx {} BFD_RELOC_PPC_GOT_DTPREL16_HA +-@deffnx {} BFD_RELOC_PPC64_TPREL16_DS +-@deffnx {} BFD_RELOC_PPC64_TPREL16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHER +-@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHERA +-@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHEST +-@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHESTA +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_DS +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_LO_DS +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHER +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHERA +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHEST +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHESTA +-@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGH +-@deffnx {} BFD_RELOC_PPC64_TPREL16_HIGHA +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGH +-@deffnx {} BFD_RELOC_PPC64_DTPREL16_HIGHA +-PowerPC and PowerPC64 thread-local storage relocations. +-@end deffn +-@deffn {} BFD_RELOC_I370_D12 +-IBM 370/390 relocations +-@end deffn +-@deffn {} BFD_RELOC_CTOR +-The type of reloc used to build a constructor table - at the moment +-probably a 32 bit wide absolute relocation, but the target can choose. +-It generally does map to one of the other relocation types. +-@end deffn +-@deffn {} BFD_RELOC_ARM_PCREL_BRANCH +-ARM 26 bit pc-relative branch. The lowest two bits must be zero and are +-not stored in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_ARM_PCREL_BLX +-ARM 26 bit pc-relative branch. The lowest bit must be zero and is +-not stored in the instruction. The 2nd lowest bit comes from a 1 bit +-field in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_THUMB_PCREL_BLX +-Thumb 22 bit pc-relative branch. The lowest bit must be zero and is +-not stored in the instruction. The 2nd lowest bit comes from a 1 bit +-field in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_ARM_PCREL_CALL +-ARM 26-bit pc-relative branch for an unconditional BL or BLX instruction. +-@end deffn +-@deffn {} BFD_RELOC_ARM_PCREL_JUMP +-ARM 26-bit pc-relative branch for B or conditional BL instruction. +-@end deffn +-@deffn {} BFD_RELOC_THUMB_PCREL_BRANCH7 +-@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH9 +-@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH12 +-@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH20 +-@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH23 +-@deffnx {} BFD_RELOC_THUMB_PCREL_BRANCH25 +-Thumb 7-, 9-, 12-, 20-, 23-, and 25-bit pc-relative branches. +-The lowest bit must be zero and is not stored in the instruction. +-Note that the corresponding ELF R_ARM_THM_JUMPnn constant has an +-"nn" one smaller in all cases. Note further that BRANCH23 +-corresponds to R_ARM_THM_CALL. +-@end deffn +-@deffn {} BFD_RELOC_ARM_OFFSET_IMM +-12-bit immediate offset, used in ARM-format ldr and str instructions. +-@end deffn +-@deffn {} BFD_RELOC_ARM_THUMB_OFFSET +-5-bit immediate offset, used in Thumb-format ldr and str instructions. +-@end deffn +-@deffn {} BFD_RELOC_ARM_TARGET1 +-Pc-relative or absolute relocation depending on target. Used for +-entries in .init_array sections. +-@end deffn +-@deffn {} BFD_RELOC_ARM_ROSEGREL32 +-Read-only segment base relative address. +-@end deffn +-@deffn {} BFD_RELOC_ARM_SBREL32 +-Data segment base relative address. +-@end deffn +-@deffn {} BFD_RELOC_ARM_TARGET2 +-This reloc is used for references to RTTI data from exception handling +-tables. The actual definition depends on the target. It may be a +-pc-relative or some form of GOT-indirect relocation. +-@end deffn +-@deffn {} BFD_RELOC_ARM_PREL31 +-31-bit PC relative address. +-@end deffn +-@deffn {} BFD_RELOC_ARM_MOVW +-@deffnx {} BFD_RELOC_ARM_MOVT +-@deffnx {} BFD_RELOC_ARM_MOVW_PCREL +-@deffnx {} BFD_RELOC_ARM_MOVT_PCREL +-@deffnx {} BFD_RELOC_ARM_THUMB_MOVW +-@deffnx {} BFD_RELOC_ARM_THUMB_MOVT +-@deffnx {} BFD_RELOC_ARM_THUMB_MOVW_PCREL +-@deffnx {} BFD_RELOC_ARM_THUMB_MOVT_PCREL +-Low and High halfword relocations for MOVW and MOVT instructions. +-@end deffn +-@deffn {} BFD_RELOC_ARM_JUMP_SLOT +-@deffnx {} BFD_RELOC_ARM_GLOB_DAT +-@deffnx {} BFD_RELOC_ARM_GOT32 +-@deffnx {} BFD_RELOC_ARM_PLT32 +-@deffnx {} BFD_RELOC_ARM_RELATIVE +-@deffnx {} BFD_RELOC_ARM_GOTOFF +-@deffnx {} BFD_RELOC_ARM_GOTPC +-@deffnx {} BFD_RELOC_ARM_GOT_PREL +-Relocations for setting up GOTs and PLTs for shared libraries. +-@end deffn +-@deffn {} BFD_RELOC_ARM_TLS_GD32 +-@deffnx {} BFD_RELOC_ARM_TLS_LDO32 +-@deffnx {} BFD_RELOC_ARM_TLS_LDM32 +-@deffnx {} BFD_RELOC_ARM_TLS_DTPOFF32 +-@deffnx {} BFD_RELOC_ARM_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_ARM_TLS_TPOFF32 +-@deffnx {} BFD_RELOC_ARM_TLS_IE32 +-@deffnx {} BFD_RELOC_ARM_TLS_LE32 +-@deffnx {} BFD_RELOC_ARM_TLS_GOTDESC +-@deffnx {} BFD_RELOC_ARM_TLS_CALL +-@deffnx {} BFD_RELOC_ARM_THM_TLS_CALL +-@deffnx {} BFD_RELOC_ARM_TLS_DESCSEQ +-@deffnx {} BFD_RELOC_ARM_THM_TLS_DESCSEQ +-@deffnx {} BFD_RELOC_ARM_TLS_DESC +-ARM thread-local storage relocations. +-@end deffn +-@deffn {} BFD_RELOC_ARM_ALU_PC_G0_NC +-@deffnx {} BFD_RELOC_ARM_ALU_PC_G0 +-@deffnx {} BFD_RELOC_ARM_ALU_PC_G1_NC +-@deffnx {} BFD_RELOC_ARM_ALU_PC_G1 +-@deffnx {} BFD_RELOC_ARM_ALU_PC_G2 +-@deffnx {} BFD_RELOC_ARM_LDR_PC_G0 +-@deffnx {} BFD_RELOC_ARM_LDR_PC_G1 +-@deffnx {} BFD_RELOC_ARM_LDR_PC_G2 +-@deffnx {} BFD_RELOC_ARM_LDRS_PC_G0 +-@deffnx {} BFD_RELOC_ARM_LDRS_PC_G1 +-@deffnx {} BFD_RELOC_ARM_LDRS_PC_G2 +-@deffnx {} BFD_RELOC_ARM_LDC_PC_G0 +-@deffnx {} BFD_RELOC_ARM_LDC_PC_G1 +-@deffnx {} BFD_RELOC_ARM_LDC_PC_G2 +-@deffnx {} BFD_RELOC_ARM_ALU_SB_G0_NC +-@deffnx {} BFD_RELOC_ARM_ALU_SB_G0 +-@deffnx {} BFD_RELOC_ARM_ALU_SB_G1_NC +-@deffnx {} BFD_RELOC_ARM_ALU_SB_G1 +-@deffnx {} BFD_RELOC_ARM_ALU_SB_G2 +-@deffnx {} BFD_RELOC_ARM_LDR_SB_G0 +-@deffnx {} BFD_RELOC_ARM_LDR_SB_G1 +-@deffnx {} BFD_RELOC_ARM_LDR_SB_G2 +-@deffnx {} BFD_RELOC_ARM_LDRS_SB_G0 +-@deffnx {} BFD_RELOC_ARM_LDRS_SB_G1 +-@deffnx {} BFD_RELOC_ARM_LDRS_SB_G2 +-@deffnx {} BFD_RELOC_ARM_LDC_SB_G0 +-@deffnx {} BFD_RELOC_ARM_LDC_SB_G1 +-@deffnx {} BFD_RELOC_ARM_LDC_SB_G2 +-ARM group relocations. +-@end deffn +-@deffn {} BFD_RELOC_ARM_V4BX +-Annotation of BX instructions. +-@end deffn +-@deffn {} BFD_RELOC_ARM_IRELATIVE +-ARM support for STT_GNU_IFUNC. +-@end deffn +-@deffn {} BFD_RELOC_ARM_IMMEDIATE +-@deffnx {} BFD_RELOC_ARM_ADRL_IMMEDIATE +-@deffnx {} BFD_RELOC_ARM_T32_IMMEDIATE +-@deffnx {} BFD_RELOC_ARM_T32_ADD_IMM +-@deffnx {} BFD_RELOC_ARM_T32_IMM12 +-@deffnx {} BFD_RELOC_ARM_T32_ADD_PC12 +-@deffnx {} BFD_RELOC_ARM_SHIFT_IMM +-@deffnx {} BFD_RELOC_ARM_SMC +-@deffnx {} BFD_RELOC_ARM_HVC +-@deffnx {} BFD_RELOC_ARM_SWI +-@deffnx {} BFD_RELOC_ARM_MULTI +-@deffnx {} BFD_RELOC_ARM_CP_OFF_IMM +-@deffnx {} BFD_RELOC_ARM_CP_OFF_IMM_S2 +-@deffnx {} BFD_RELOC_ARM_T32_CP_OFF_IMM +-@deffnx {} BFD_RELOC_ARM_T32_CP_OFF_IMM_S2 +-@deffnx {} BFD_RELOC_ARM_ADR_IMM +-@deffnx {} BFD_RELOC_ARM_LDR_IMM +-@deffnx {} BFD_RELOC_ARM_LITERAL +-@deffnx {} BFD_RELOC_ARM_IN_POOL +-@deffnx {} BFD_RELOC_ARM_OFFSET_IMM8 +-@deffnx {} BFD_RELOC_ARM_T32_OFFSET_U8 +-@deffnx {} BFD_RELOC_ARM_T32_OFFSET_IMM +-@deffnx {} BFD_RELOC_ARM_HWLITERAL +-@deffnx {} BFD_RELOC_ARM_THUMB_ADD +-@deffnx {} BFD_RELOC_ARM_THUMB_IMM +-@deffnx {} BFD_RELOC_ARM_THUMB_SHIFT +-These relocs are only used within the ARM assembler. They are not +-(at present) written to any object files. +-@end deffn +-@deffn {} BFD_RELOC_SH_PCDISP8BY2 +-@deffnx {} BFD_RELOC_SH_PCDISP12BY2 +-@deffnx {} BFD_RELOC_SH_IMM3 +-@deffnx {} BFD_RELOC_SH_IMM3U +-@deffnx {} BFD_RELOC_SH_DISP12 +-@deffnx {} BFD_RELOC_SH_DISP12BY2 +-@deffnx {} BFD_RELOC_SH_DISP12BY4 +-@deffnx {} BFD_RELOC_SH_DISP12BY8 +-@deffnx {} BFD_RELOC_SH_DISP20 +-@deffnx {} BFD_RELOC_SH_DISP20BY8 +-@deffnx {} BFD_RELOC_SH_IMM4 +-@deffnx {} BFD_RELOC_SH_IMM4BY2 +-@deffnx {} BFD_RELOC_SH_IMM4BY4 +-@deffnx {} BFD_RELOC_SH_IMM8 +-@deffnx {} BFD_RELOC_SH_IMM8BY2 +-@deffnx {} BFD_RELOC_SH_IMM8BY4 +-@deffnx {} BFD_RELOC_SH_PCRELIMM8BY2 +-@deffnx {} BFD_RELOC_SH_PCRELIMM8BY4 +-@deffnx {} BFD_RELOC_SH_SWITCH16 +-@deffnx {} BFD_RELOC_SH_SWITCH32 +-@deffnx {} BFD_RELOC_SH_USES +-@deffnx {} BFD_RELOC_SH_COUNT +-@deffnx {} BFD_RELOC_SH_ALIGN +-@deffnx {} BFD_RELOC_SH_CODE +-@deffnx {} BFD_RELOC_SH_DATA +-@deffnx {} BFD_RELOC_SH_LABEL +-@deffnx {} BFD_RELOC_SH_LOOP_START +-@deffnx {} BFD_RELOC_SH_LOOP_END +-@deffnx {} BFD_RELOC_SH_COPY +-@deffnx {} BFD_RELOC_SH_GLOB_DAT +-@deffnx {} BFD_RELOC_SH_JMP_SLOT +-@deffnx {} BFD_RELOC_SH_RELATIVE +-@deffnx {} BFD_RELOC_SH_GOTPC +-@deffnx {} BFD_RELOC_SH_GOT_LOW16 +-@deffnx {} BFD_RELOC_SH_GOT_MEDLOW16 +-@deffnx {} BFD_RELOC_SH_GOT_MEDHI16 +-@deffnx {} BFD_RELOC_SH_GOT_HI16 +-@deffnx {} BFD_RELOC_SH_GOTPLT_LOW16 +-@deffnx {} BFD_RELOC_SH_GOTPLT_MEDLOW16 +-@deffnx {} BFD_RELOC_SH_GOTPLT_MEDHI16 +-@deffnx {} BFD_RELOC_SH_GOTPLT_HI16 +-@deffnx {} BFD_RELOC_SH_PLT_LOW16 +-@deffnx {} BFD_RELOC_SH_PLT_MEDLOW16 +-@deffnx {} BFD_RELOC_SH_PLT_MEDHI16 +-@deffnx {} BFD_RELOC_SH_PLT_HI16 +-@deffnx {} BFD_RELOC_SH_GOTOFF_LOW16 +-@deffnx {} BFD_RELOC_SH_GOTOFF_MEDLOW16 +-@deffnx {} BFD_RELOC_SH_GOTOFF_MEDHI16 +-@deffnx {} BFD_RELOC_SH_GOTOFF_HI16 +-@deffnx {} BFD_RELOC_SH_GOTPC_LOW16 +-@deffnx {} BFD_RELOC_SH_GOTPC_MEDLOW16 +-@deffnx {} BFD_RELOC_SH_GOTPC_MEDHI16 +-@deffnx {} BFD_RELOC_SH_GOTPC_HI16 +-@deffnx {} BFD_RELOC_SH_COPY64 +-@deffnx {} BFD_RELOC_SH_GLOB_DAT64 +-@deffnx {} BFD_RELOC_SH_JMP_SLOT64 +-@deffnx {} BFD_RELOC_SH_RELATIVE64 +-@deffnx {} BFD_RELOC_SH_GOT10BY4 +-@deffnx {} BFD_RELOC_SH_GOT10BY8 +-@deffnx {} BFD_RELOC_SH_GOTPLT10BY4 +-@deffnx {} BFD_RELOC_SH_GOTPLT10BY8 +-@deffnx {} BFD_RELOC_SH_GOTPLT32 +-@deffnx {} BFD_RELOC_SH_SHMEDIA_CODE +-@deffnx {} BFD_RELOC_SH_IMMU5 +-@deffnx {} BFD_RELOC_SH_IMMS6 +-@deffnx {} BFD_RELOC_SH_IMMS6BY32 +-@deffnx {} BFD_RELOC_SH_IMMU6 +-@deffnx {} BFD_RELOC_SH_IMMS10 +-@deffnx {} BFD_RELOC_SH_IMMS10BY2 +-@deffnx {} BFD_RELOC_SH_IMMS10BY4 +-@deffnx {} BFD_RELOC_SH_IMMS10BY8 +-@deffnx {} BFD_RELOC_SH_IMMS16 +-@deffnx {} BFD_RELOC_SH_IMMU16 +-@deffnx {} BFD_RELOC_SH_IMM_LOW16 +-@deffnx {} BFD_RELOC_SH_IMM_LOW16_PCREL +-@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16 +-@deffnx {} BFD_RELOC_SH_IMM_MEDLOW16_PCREL +-@deffnx {} BFD_RELOC_SH_IMM_MEDHI16 +-@deffnx {} BFD_RELOC_SH_IMM_MEDHI16_PCREL +-@deffnx {} BFD_RELOC_SH_IMM_HI16 +-@deffnx {} BFD_RELOC_SH_IMM_HI16_PCREL +-@deffnx {} BFD_RELOC_SH_PT_16 +-@deffnx {} BFD_RELOC_SH_TLS_GD_32 +-@deffnx {} BFD_RELOC_SH_TLS_LD_32 +-@deffnx {} BFD_RELOC_SH_TLS_LDO_32 +-@deffnx {} BFD_RELOC_SH_TLS_IE_32 +-@deffnx {} BFD_RELOC_SH_TLS_LE_32 +-@deffnx {} BFD_RELOC_SH_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_SH_TLS_DTPOFF32 +-@deffnx {} BFD_RELOC_SH_TLS_TPOFF32 +-@deffnx {} BFD_RELOC_SH_GOT20 +-@deffnx {} BFD_RELOC_SH_GOTOFF20 +-@deffnx {} BFD_RELOC_SH_GOTFUNCDESC +-@deffnx {} BFD_RELOC_SH_GOTFUNCDESC20 +-@deffnx {} BFD_RELOC_SH_GOTOFFFUNCDESC +-@deffnx {} BFD_RELOC_SH_GOTOFFFUNCDESC20 +-@deffnx {} BFD_RELOC_SH_FUNCDESC +-Renesas / SuperH SH relocs. Not all of these appear in object files. +-@end deffn +-@deffn {} BFD_RELOC_ARC_B22_PCREL +-ARC Cores relocs. +-ARC 22 bit pc-relative branch. The lowest two bits must be zero and are +-not stored in the instruction. The high 20 bits are installed in bits 26 +-through 7 of the instruction. +-@end deffn +-@deffn {} BFD_RELOC_ARC_B26 +-ARC 26 bit absolute branch. The lowest two bits must be zero and are not +-stored in the instruction. The high 24 bits are installed in bits 23 +-through 0. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_16_IMM +-ADI Blackfin 16 bit immediate absolute reloc. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_16_HIGH +-ADI Blackfin 16 bit immediate absolute reloc higher 16 bits. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_4_PCREL +-ADI Blackfin 'a' part of LSETUP. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_5_PCREL +-ADI Blackfin. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_16_LOW +-ADI Blackfin 16 bit immediate absolute reloc lower 16 bits. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_10_PCREL +-ADI Blackfin. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_11_PCREL +-ADI Blackfin 'b' part of LSETUP. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_12_PCREL_JUMP +-ADI Blackfin. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_12_PCREL_JUMP_S +-ADI Blackfin Short jump, pcrel. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_24_PCREL_CALL_X +-ADI Blackfin Call.x not implemented. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_24_PCREL_JUMP_L +-ADI Blackfin Long Jump pcrel. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_GOT17M4 +-@deffnx {} BFD_RELOC_BFIN_GOTHI +-@deffnx {} BFD_RELOC_BFIN_GOTLO +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOT17M4 +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTHI +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTLO +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_VALUE +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTOFF17M4 +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTOFFHI +-@deffnx {} BFD_RELOC_BFIN_FUNCDESC_GOTOFFLO +-@deffnx {} BFD_RELOC_BFIN_GOTOFF17M4 +-@deffnx {} BFD_RELOC_BFIN_GOTOFFHI +-@deffnx {} BFD_RELOC_BFIN_GOTOFFLO +-ADI Blackfin FD-PIC relocations. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_GOT +-ADI Blackfin GOT relocation. +-@end deffn +-@deffn {} BFD_RELOC_BFIN_PLTPC +-ADI Blackfin PLTPC relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_PUSH +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_CONST +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_ADD +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_SUB +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_MULT +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_DIV +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_MOD +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_LSHIFT +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_RSHIFT +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_AND +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_OR +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_XOR +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_LAND +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_LOR +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_LEN +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_NEG +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_COMP +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_PAGE +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_HWPAGE +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_ARELOC_BFIN_ADDR +-ADI Blackfin arithmetic relocation. +-@end deffn +-@deffn {} BFD_RELOC_D10V_10_PCREL_R +-Mitsubishi D10V relocs. +-This is a 10-bit reloc with the right 2 bits +-assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D10V_10_PCREL_L +-Mitsubishi D10V relocs. +-This is a 10-bit reloc with the right 2 bits +-assumed to be 0. This is the same as the previous reloc +-except it is in the left container, i.e., +-shifted left 15 bits. +-@end deffn +-@deffn {} BFD_RELOC_D10V_18 +-This is an 18-bit reloc with the right 2 bits +-assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D10V_18_PCREL +-This is an 18-bit reloc with the right 2 bits +-assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D30V_6 +-Mitsubishi D30V relocs. +-This is a 6-bit absolute reloc. +-@end deffn +-@deffn {} BFD_RELOC_D30V_9_PCREL +-This is a 6-bit pc-relative reloc with +-the right 3 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D30V_9_PCREL_R +-This is a 6-bit pc-relative reloc with +-the right 3 bits assumed to be 0. Same +-as the previous reloc but on the right side +-of the container. +-@end deffn +-@deffn {} BFD_RELOC_D30V_15 +-This is a 12-bit absolute reloc with the +-right 3 bitsassumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D30V_15_PCREL +-This is a 12-bit pc-relative reloc with +-the right 3 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D30V_15_PCREL_R +-This is a 12-bit pc-relative reloc with +-the right 3 bits assumed to be 0. Same +-as the previous reloc but on the right side +-of the container. +-@end deffn +-@deffn {} BFD_RELOC_D30V_21 +-This is an 18-bit absolute reloc with +-the right 3 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D30V_21_PCREL +-This is an 18-bit pc-relative reloc with +-the right 3 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_D30V_21_PCREL_R +-This is an 18-bit pc-relative reloc with +-the right 3 bits assumed to be 0. Same +-as the previous reloc but on the right side +-of the container. +-@end deffn +-@deffn {} BFD_RELOC_D30V_32 +-This is a 32-bit absolute reloc. +-@end deffn +-@deffn {} BFD_RELOC_D30V_32_PCREL +-This is a 32-bit pc-relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_DLX_HI16_S +-DLX relocs +-@end deffn +-@deffn {} BFD_RELOC_DLX_LO16 +-DLX relocs +-@end deffn +-@deffn {} BFD_RELOC_DLX_JMP26 +-DLX relocs +-@end deffn +-@deffn {} BFD_RELOC_M32C_HI8 +-@deffnx {} BFD_RELOC_M32C_RL_JUMP +-@deffnx {} BFD_RELOC_M32C_RL_1ADDR +-@deffnx {} BFD_RELOC_M32C_RL_2ADDR +-Renesas M16C/M32C Relocations. +-@end deffn +-@deffn {} BFD_RELOC_M32R_24 +-Renesas M32R (formerly Mitsubishi M32R) relocs. +-This is a 24 bit absolute address. +-@end deffn +-@deffn {} BFD_RELOC_M32R_10_PCREL +-This is a 10-bit pc-relative reloc with the right 2 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_M32R_18_PCREL +-This is an 18-bit reloc with the right 2 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_M32R_26_PCREL +-This is a 26-bit reloc with the right 2 bits assumed to be 0. +-@end deffn +-@deffn {} BFD_RELOC_M32R_HI16_ULO +-This is a 16-bit reloc containing the high 16 bits of an address +-used when the lower 16 bits are treated as unsigned. +-@end deffn +-@deffn {} BFD_RELOC_M32R_HI16_SLO +-This is a 16-bit reloc containing the high 16 bits of an address +-used when the lower 16 bits are treated as signed. +-@end deffn +-@deffn {} BFD_RELOC_M32R_LO16 +-This is a 16-bit reloc containing the lower 16 bits of an address. +-@end deffn +-@deffn {} BFD_RELOC_M32R_SDA16 +-This is a 16-bit reloc containing the small data area offset for use in +-add3, load, and store instructions. +-@end deffn +-@deffn {} BFD_RELOC_M32R_GOT24 +-@deffnx {} BFD_RELOC_M32R_26_PLTREL +-@deffnx {} BFD_RELOC_M32R_COPY +-@deffnx {} BFD_RELOC_M32R_GLOB_DAT +-@deffnx {} BFD_RELOC_M32R_JMP_SLOT +-@deffnx {} BFD_RELOC_M32R_RELATIVE +-@deffnx {} BFD_RELOC_M32R_GOTOFF +-@deffnx {} BFD_RELOC_M32R_GOTOFF_HI_ULO +-@deffnx {} BFD_RELOC_M32R_GOTOFF_HI_SLO +-@deffnx {} BFD_RELOC_M32R_GOTOFF_LO +-@deffnx {} BFD_RELOC_M32R_GOTPC24 +-@deffnx {} BFD_RELOC_M32R_GOT16_HI_ULO +-@deffnx {} BFD_RELOC_M32R_GOT16_HI_SLO +-@deffnx {} BFD_RELOC_M32R_GOT16_LO +-@deffnx {} BFD_RELOC_M32R_GOTPC_HI_ULO +-@deffnx {} BFD_RELOC_M32R_GOTPC_HI_SLO +-@deffnx {} BFD_RELOC_M32R_GOTPC_LO +-For PIC. +-@end deffn +-@deffn {} BFD_RELOC_V850_9_PCREL +-This is a 9-bit reloc +-@end deffn +-@deffn {} BFD_RELOC_V850_22_PCREL +-This is a 22-bit reloc +-@end deffn +-@deffn {} BFD_RELOC_V850_SDA_16_16_OFFSET +-This is a 16 bit offset from the short data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_SDA_15_16_OFFSET +-This is a 16 bit offset (of which only 15 bits are used) from the +-short data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_ZDA_16_16_OFFSET +-This is a 16 bit offset from the zero data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_ZDA_15_16_OFFSET +-This is a 16 bit offset (of which only 15 bits are used) from the +-zero data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_TDA_6_8_OFFSET +-This is an 8 bit offset (of which only 6 bits are used) from the +-tiny data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_TDA_7_8_OFFSET +-This is an 8bit offset (of which only 7 bits are used) from the tiny +-data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_TDA_7_7_OFFSET +-This is a 7 bit offset from the tiny data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_TDA_16_16_OFFSET +-This is a 16 bit offset from the tiny data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_TDA_4_5_OFFSET +-This is a 5 bit offset (of which only 4 bits are used) from the tiny +-data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_TDA_4_4_OFFSET +-This is a 4 bit offset from the tiny data area pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET +-This is a 16 bit offset from the short data area pointer, with the +-bits placed non-contiguously in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET +-This is a 16 bit offset from the zero data area pointer, with the +-bits placed non-contiguously in the instruction. +-@end deffn +-@deffn {} BFD_RELOC_V850_CALLT_6_7_OFFSET +-This is a 6 bit offset from the call table base pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_CALLT_16_16_OFFSET +-This is a 16 bit offset from the call table base pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_LONGCALL +-Used for relaxing indirect function calls. +-@end deffn +-@deffn {} BFD_RELOC_V850_LONGJUMP +-Used for relaxing indirect jumps. +-@end deffn +-@deffn {} BFD_RELOC_V850_ALIGN +-Used to maintain alignment whilst relaxing. +-@end deffn +-@deffn {} BFD_RELOC_V850_LO16_SPLIT_OFFSET +-This is a variation of BFD_RELOC_LO16 that can be used in v850e ld.bu +-instructions. +-@end deffn +-@deffn {} BFD_RELOC_V850_16_PCREL +-This is a 16-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_17_PCREL +-This is a 17-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_23 +-This is a 23-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_32_PCREL +-This is a 32-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_32_ABS +-This is a 32-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_16_SPLIT_OFFSET +-This is a 16-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_16_S1 +-This is a 16-bit reloc. +-@end deffn +-@deffn {} BFD_RELOC_V850_LO16_S1 +-Low 16 bits. 16 bit shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_V850_CALLT_15_16_OFFSET +-This is a 16 bit offset from the call table base pointer. +-@end deffn +-@deffn {} BFD_RELOC_V850_32_GOTPCREL +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_16_GOT +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_32_GOT +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_22_PLT_PCREL +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_32_PLT_PCREL +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_COPY +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_GLOB_DAT +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_JMP_SLOT +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_RELATIVE +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_16_GOTOFF +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_32_GOTOFF +-DSO relocations. +-@end deffn +-@deffn {} BFD_RELOC_V850_CODE +-start code. +-@end deffn +-@deffn {} BFD_RELOC_V850_DATA +-start data in text. +-@end deffn +-@deffn {} BFD_RELOC_TIC30_LDP +-This is a 8bit DP reloc for the tms320c30, where the most +-significant 8 bits of a 24 bit word are placed into the least +-significant 8 bits of the opcode. +-@end deffn +-@deffn {} BFD_RELOC_TIC54X_PARTLS7 +-This is a 7bit reloc for the tms320c54x, where the least +-significant 7 bits of a 16 bit word are placed into the least +-significant 7 bits of the opcode. +-@end deffn +-@deffn {} BFD_RELOC_TIC54X_PARTMS9 +-This is a 9bit DP reloc for the tms320c54x, where the most +-significant 9 bits of a 16 bit word are placed into the least +-significant 9 bits of the opcode. +-@end deffn +-@deffn {} BFD_RELOC_TIC54X_23 +-This is an extended address 23-bit reloc for the tms320c54x. +-@end deffn +-@deffn {} BFD_RELOC_TIC54X_16_OF_23 +-This is a 16-bit reloc for the tms320c54x, where the least +-significant 16 bits of a 23-bit extended address are placed into +-the opcode. +-@end deffn +-@deffn {} BFD_RELOC_TIC54X_MS7_OF_23 +-This is a reloc for the tms320c54x, where the most +-significant 7 bits of a 23-bit extended address are placed into +-the opcode. +-@end deffn +-@deffn {} BFD_RELOC_C6000_PCR_S21 +-@deffnx {} BFD_RELOC_C6000_PCR_S12 +-@deffnx {} BFD_RELOC_C6000_PCR_S10 +-@deffnx {} BFD_RELOC_C6000_PCR_S7 +-@deffnx {} BFD_RELOC_C6000_ABS_S16 +-@deffnx {} BFD_RELOC_C6000_ABS_L16 +-@deffnx {} BFD_RELOC_C6000_ABS_H16 +-@deffnx {} BFD_RELOC_C6000_SBR_U15_B +-@deffnx {} BFD_RELOC_C6000_SBR_U15_H +-@deffnx {} BFD_RELOC_C6000_SBR_U15_W +-@deffnx {} BFD_RELOC_C6000_SBR_S16 +-@deffnx {} BFD_RELOC_C6000_SBR_L16_B +-@deffnx {} BFD_RELOC_C6000_SBR_L16_H +-@deffnx {} BFD_RELOC_C6000_SBR_L16_W +-@deffnx {} BFD_RELOC_C6000_SBR_H16_B +-@deffnx {} BFD_RELOC_C6000_SBR_H16_H +-@deffnx {} BFD_RELOC_C6000_SBR_H16_W +-@deffnx {} BFD_RELOC_C6000_SBR_GOT_U15_W +-@deffnx {} BFD_RELOC_C6000_SBR_GOT_L16_W +-@deffnx {} BFD_RELOC_C6000_SBR_GOT_H16_W +-@deffnx {} BFD_RELOC_C6000_DSBT_INDEX +-@deffnx {} BFD_RELOC_C6000_PREL31 +-@deffnx {} BFD_RELOC_C6000_COPY +-@deffnx {} BFD_RELOC_C6000_JUMP_SLOT +-@deffnx {} BFD_RELOC_C6000_EHTYPE +-@deffnx {} BFD_RELOC_C6000_PCR_H16 +-@deffnx {} BFD_RELOC_C6000_PCR_L16 +-@deffnx {} BFD_RELOC_C6000_ALIGN +-@deffnx {} BFD_RELOC_C6000_FPHEAD +-@deffnx {} BFD_RELOC_C6000_NOCMP +-TMS320C6000 relocations. +-@end deffn +-@deffn {} BFD_RELOC_FR30_48 +-This is a 48 bit reloc for the FR30 that stores 32 bits. +-@end deffn +-@deffn {} BFD_RELOC_FR30_20 +-This is a 32 bit reloc for the FR30 that stores 20 bits split up into +-two sections. +-@end deffn +-@deffn {} BFD_RELOC_FR30_6_IN_4 +-This is a 16 bit reloc for the FR30 that stores a 6 bit word offset in +-4 bits. +-@end deffn +-@deffn {} BFD_RELOC_FR30_8_IN_8 +-This is a 16 bit reloc for the FR30 that stores an 8 bit byte offset +-into 8 bits. +-@end deffn +-@deffn {} BFD_RELOC_FR30_9_IN_8 +-This is a 16 bit reloc for the FR30 that stores a 9 bit short offset +-into 8 bits. +-@end deffn +-@deffn {} BFD_RELOC_FR30_10_IN_8 +-This is a 16 bit reloc for the FR30 that stores a 10 bit word offset +-into 8 bits. +-@end deffn +-@deffn {} BFD_RELOC_FR30_9_PCREL +-This is a 16 bit reloc for the FR30 that stores a 9 bit pc relative +-short offset into 8 bits. +-@end deffn +-@deffn {} BFD_RELOC_FR30_12_PCREL +-This is a 16 bit reloc for the FR30 that stores a 12 bit pc relative +-short offset into 11 bits. +-@end deffn +-@deffn {} BFD_RELOC_MCORE_PCREL_IMM8BY4 +-@deffnx {} BFD_RELOC_MCORE_PCREL_IMM11BY2 +-@deffnx {} BFD_RELOC_MCORE_PCREL_IMM4BY2 +-@deffnx {} BFD_RELOC_MCORE_PCREL_32 +-@deffnx {} BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2 +-@deffnx {} BFD_RELOC_MCORE_RVA +-Motorola Mcore relocations. +-@end deffn +-@deffn {} BFD_RELOC_MEP_8 +-@deffnx {} BFD_RELOC_MEP_16 +-@deffnx {} BFD_RELOC_MEP_32 +-@deffnx {} BFD_RELOC_MEP_PCREL8A2 +-@deffnx {} BFD_RELOC_MEP_PCREL12A2 +-@deffnx {} BFD_RELOC_MEP_PCREL17A2 +-@deffnx {} BFD_RELOC_MEP_PCREL24A2 +-@deffnx {} BFD_RELOC_MEP_PCABS24A2 +-@deffnx {} BFD_RELOC_MEP_LOW16 +-@deffnx {} BFD_RELOC_MEP_HI16U +-@deffnx {} BFD_RELOC_MEP_HI16S +-@deffnx {} BFD_RELOC_MEP_GPREL +-@deffnx {} BFD_RELOC_MEP_TPREL +-@deffnx {} BFD_RELOC_MEP_TPREL7 +-@deffnx {} BFD_RELOC_MEP_TPREL7A2 +-@deffnx {} BFD_RELOC_MEP_TPREL7A4 +-@deffnx {} BFD_RELOC_MEP_UIMM24 +-@deffnx {} BFD_RELOC_MEP_ADDR24A4 +-@deffnx {} BFD_RELOC_MEP_GNU_VTINHERIT +-@deffnx {} BFD_RELOC_MEP_GNU_VTENTRY +-Toshiba Media Processor Relocations. +-@end deffn +-@deffn {} BFD_RELOC_METAG_HIADDR16 +-@deffnx {} BFD_RELOC_METAG_LOADDR16 +-@deffnx {} BFD_RELOC_METAG_RELBRANCH +-@deffnx {} BFD_RELOC_METAG_GETSETOFF +-@deffnx {} BFD_RELOC_METAG_HIOG +-@deffnx {} BFD_RELOC_METAG_LOOG +-@deffnx {} BFD_RELOC_METAG_REL8 +-@deffnx {} BFD_RELOC_METAG_REL16 +-@deffnx {} BFD_RELOC_METAG_HI16_GOTOFF +-@deffnx {} BFD_RELOC_METAG_LO16_GOTOFF +-@deffnx {} BFD_RELOC_METAG_GETSET_GOTOFF +-@deffnx {} BFD_RELOC_METAG_GETSET_GOT +-@deffnx {} BFD_RELOC_METAG_HI16_GOTPC +-@deffnx {} BFD_RELOC_METAG_LO16_GOTPC +-@deffnx {} BFD_RELOC_METAG_HI16_PLT +-@deffnx {} BFD_RELOC_METAG_LO16_PLT +-@deffnx {} BFD_RELOC_METAG_RELBRANCH_PLT +-@deffnx {} BFD_RELOC_METAG_GOTOFF +-@deffnx {} BFD_RELOC_METAG_PLT +-@deffnx {} BFD_RELOC_METAG_COPY +-@deffnx {} BFD_RELOC_METAG_JMP_SLOT +-@deffnx {} BFD_RELOC_METAG_RELATIVE +-@deffnx {} BFD_RELOC_METAG_GLOB_DAT +-@deffnx {} BFD_RELOC_METAG_TLS_GD +-@deffnx {} BFD_RELOC_METAG_TLS_LDM +-@deffnx {} BFD_RELOC_METAG_TLS_LDO_HI16 +-@deffnx {} BFD_RELOC_METAG_TLS_LDO_LO16 +-@deffnx {} BFD_RELOC_METAG_TLS_LDO +-@deffnx {} BFD_RELOC_METAG_TLS_IE +-@deffnx {} BFD_RELOC_METAG_TLS_IENONPIC +-@deffnx {} BFD_RELOC_METAG_TLS_IENONPIC_HI16 +-@deffnx {} BFD_RELOC_METAG_TLS_IENONPIC_LO16 +-@deffnx {} BFD_RELOC_METAG_TLS_TPOFF +-@deffnx {} BFD_RELOC_METAG_TLS_DTPMOD +-@deffnx {} BFD_RELOC_METAG_TLS_DTPOFF +-@deffnx {} BFD_RELOC_METAG_TLS_LE +-@deffnx {} BFD_RELOC_METAG_TLS_LE_HI16 +-@deffnx {} BFD_RELOC_METAG_TLS_LE_LO16 +-Imagination Technologies Meta relocations. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_GETA +-@deffnx {} BFD_RELOC_MMIX_GETA_1 +-@deffnx {} BFD_RELOC_MMIX_GETA_2 +-@deffnx {} BFD_RELOC_MMIX_GETA_3 +-These are relocations for the GETA instruction. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_CBRANCH +-@deffnx {} BFD_RELOC_MMIX_CBRANCH_J +-@deffnx {} BFD_RELOC_MMIX_CBRANCH_1 +-@deffnx {} BFD_RELOC_MMIX_CBRANCH_2 +-@deffnx {} BFD_RELOC_MMIX_CBRANCH_3 +-These are relocations for a conditional branch instruction. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_PUSHJ +-@deffnx {} BFD_RELOC_MMIX_PUSHJ_1 +-@deffnx {} BFD_RELOC_MMIX_PUSHJ_2 +-@deffnx {} BFD_RELOC_MMIX_PUSHJ_3 +-@deffnx {} BFD_RELOC_MMIX_PUSHJ_STUBBABLE +-These are relocations for the PUSHJ instruction. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_JMP +-@deffnx {} BFD_RELOC_MMIX_JMP_1 +-@deffnx {} BFD_RELOC_MMIX_JMP_2 +-@deffnx {} BFD_RELOC_MMIX_JMP_3 +-These are relocations for the JMP instruction. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_ADDR19 +-This is a relocation for a relative address as in a GETA instruction or +-a branch. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_ADDR27 +-This is a relocation for a relative address as in a JMP instruction. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_REG_OR_BYTE +-This is a relocation for an instruction field that may be a general +-register or a value 0..255. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_REG +-This is a relocation for an instruction field that may be a general +-register. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_BASE_PLUS_OFFSET +-This is a relocation for two instruction fields holding a register and +-an offset, the equivalent of the relocation. +-@end deffn +-@deffn {} BFD_RELOC_MMIX_LOCAL +-This relocation is an assertion that the expression is not allocated as +-a global register. It does not modify contents. +-@end deffn +-@deffn {} BFD_RELOC_AVR_7_PCREL +-This is a 16 bit reloc for the AVR that stores 8 bit pc relative +-short offset into 7 bits. +-@end deffn +-@deffn {} BFD_RELOC_AVR_13_PCREL +-This is a 16 bit reloc for the AVR that stores 13 bit pc relative +-short offset into 12 bits. +-@end deffn +-@deffn {} BFD_RELOC_AVR_16_PM +-This is a 16 bit reloc for the AVR that stores 17 bit value (usually +-program memory address) into 16 bits. +-@end deffn +-@deffn {} BFD_RELOC_AVR_LO8_LDI +-This is a 16 bit reloc for the AVR that stores 8 bit value (usually +-data memory address) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HI8_LDI +-This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +-of data memory address) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HH8_LDI +-This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +-of program memory address) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_MS8_LDI +-This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +-of 32 bit value) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_LO8_LDI_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value +-(usually data memory address) into 8 bit immediate value of SUBI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HI8_LDI_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value +-(high 8 bit of data memory address) into 8 bit immediate value of +-SUBI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HH8_LDI_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value +-(most high 8 bit of program memory address) into 8 bit immediate value +-of LDI or SUBI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_MS8_LDI_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value (msb +-of 32 bit value) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_LO8_LDI_PM +-This is a 16 bit reloc for the AVR that stores 8 bit value (usually +-command address) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_LO8_LDI_GS +-This is a 16 bit reloc for the AVR that stores 8 bit value +-(command address) into 8 bit immediate value of LDI insn. If the address +-is beyond the 128k boundary, the linker inserts a jump stub for this reloc +-in the lower 128k. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HI8_LDI_PM +-This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +-of command address) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HI8_LDI_GS +-This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit +-of command address) into 8 bit immediate value of LDI insn. If the address +-is beyond the 128k boundary, the linker inserts a jump stub for this reloc +-below 128k. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HH8_LDI_PM +-This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit +-of command address) into 8 bit immediate value of LDI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_LO8_LDI_PM_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value +-(usually command address) into 8 bit immediate value of SUBI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HI8_LDI_PM_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value +-(high 8 bit of 16 bit command address) into 8 bit immediate value +-of SUBI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_HH8_LDI_PM_NEG +-This is a 16 bit reloc for the AVR that stores negated 8 bit value +-(high 6 bit of 22 bit command address) into 8 bit immediate +-value of SUBI insn. +-@end deffn +-@deffn {} BFD_RELOC_AVR_CALL +-This is a 32 bit reloc for the AVR that stores 23 bit value +-into 22 bits. +-@end deffn +-@deffn {} BFD_RELOC_AVR_LDI +-This is a 16 bit reloc for the AVR that stores all needed bits +-for absolute addressing with ldi with overflow check to linktime +-@end deffn +-@deffn {} BFD_RELOC_AVR_6 +-This is a 6 bit reloc for the AVR that stores offset for ldd/std +-instructions +-@end deffn +-@deffn {} BFD_RELOC_AVR_6_ADIW +-This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw +-instructions +-@end deffn +-@deffn {} BFD_RELOC_AVR_8_LO +-This is a 8 bit reloc for the AVR that stores bits 0..7 of a symbol +-in .byte lo8(symbol) +-@end deffn +-@deffn {} BFD_RELOC_AVR_8_HI +-This is a 8 bit reloc for the AVR that stores bits 8..15 of a symbol +-in .byte hi8(symbol) +-@end deffn +-@deffn {} BFD_RELOC_AVR_8_HLO +-This is a 8 bit reloc for the AVR that stores bits 16..23 of a symbol +-in .byte hlo8(symbol) +-@end deffn +-@deffn {} BFD_RELOC_RL78_NEG8 +-@deffnx {} BFD_RELOC_RL78_NEG16 +-@deffnx {} BFD_RELOC_RL78_NEG24 +-@deffnx {} BFD_RELOC_RL78_NEG32 +-@deffnx {} BFD_RELOC_RL78_16_OP +-@deffnx {} BFD_RELOC_RL78_24_OP +-@deffnx {} BFD_RELOC_RL78_32_OP +-@deffnx {} BFD_RELOC_RL78_8U +-@deffnx {} BFD_RELOC_RL78_16U +-@deffnx {} BFD_RELOC_RL78_24U +-@deffnx {} BFD_RELOC_RL78_DIR3U_PCREL +-@deffnx {} BFD_RELOC_RL78_DIFF +-@deffnx {} BFD_RELOC_RL78_GPRELB +-@deffnx {} BFD_RELOC_RL78_GPRELW +-@deffnx {} BFD_RELOC_RL78_GPRELL +-@deffnx {} BFD_RELOC_RL78_SYM +-@deffnx {} BFD_RELOC_RL78_OP_SUBTRACT +-@deffnx {} BFD_RELOC_RL78_OP_NEG +-@deffnx {} BFD_RELOC_RL78_OP_AND +-@deffnx {} BFD_RELOC_RL78_OP_SHRA +-@deffnx {} BFD_RELOC_RL78_ABS8 +-@deffnx {} BFD_RELOC_RL78_ABS16 +-@deffnx {} BFD_RELOC_RL78_ABS16_REV +-@deffnx {} BFD_RELOC_RL78_ABS32 +-@deffnx {} BFD_RELOC_RL78_ABS32_REV +-@deffnx {} BFD_RELOC_RL78_ABS16U +-@deffnx {} BFD_RELOC_RL78_ABS16UW +-@deffnx {} BFD_RELOC_RL78_ABS16UL +-@deffnx {} BFD_RELOC_RL78_RELAX +-@deffnx {} BFD_RELOC_RL78_HI16 +-@deffnx {} BFD_RELOC_RL78_HI8 +-@deffnx {} BFD_RELOC_RL78_LO16 +-@deffnx {} BFD_RELOC_RL78_CODE +-Renesas RL78 Relocations. +-@end deffn +-@deffn {} BFD_RELOC_RX_NEG8 +-@deffnx {} BFD_RELOC_RX_NEG16 +-@deffnx {} BFD_RELOC_RX_NEG24 +-@deffnx {} BFD_RELOC_RX_NEG32 +-@deffnx {} BFD_RELOC_RX_16_OP +-@deffnx {} BFD_RELOC_RX_24_OP +-@deffnx {} BFD_RELOC_RX_32_OP +-@deffnx {} BFD_RELOC_RX_8U +-@deffnx {} BFD_RELOC_RX_16U +-@deffnx {} BFD_RELOC_RX_24U +-@deffnx {} BFD_RELOC_RX_DIR3U_PCREL +-@deffnx {} BFD_RELOC_RX_DIFF +-@deffnx {} BFD_RELOC_RX_GPRELB +-@deffnx {} BFD_RELOC_RX_GPRELW +-@deffnx {} BFD_RELOC_RX_GPRELL +-@deffnx {} BFD_RELOC_RX_SYM +-@deffnx {} BFD_RELOC_RX_OP_SUBTRACT +-@deffnx {} BFD_RELOC_RX_OP_NEG +-@deffnx {} BFD_RELOC_RX_ABS8 +-@deffnx {} BFD_RELOC_RX_ABS16 +-@deffnx {} BFD_RELOC_RX_ABS16_REV +-@deffnx {} BFD_RELOC_RX_ABS32 +-@deffnx {} BFD_RELOC_RX_ABS32_REV +-@deffnx {} BFD_RELOC_RX_ABS16U +-@deffnx {} BFD_RELOC_RX_ABS16UW +-@deffnx {} BFD_RELOC_RX_ABS16UL +-@deffnx {} BFD_RELOC_RX_RELAX +-Renesas RX Relocations. +-@end deffn +-@deffn {} BFD_RELOC_390_12 +-Direct 12 bit. +-@end deffn +-@deffn {} BFD_RELOC_390_GOT12 +-12 bit GOT offset. +-@end deffn +-@deffn {} BFD_RELOC_390_PLT32 +-32 bit PC relative PLT address. +-@end deffn +-@deffn {} BFD_RELOC_390_COPY +-Copy symbol at runtime. +-@end deffn +-@deffn {} BFD_RELOC_390_GLOB_DAT +-Create GOT entry. +-@end deffn +-@deffn {} BFD_RELOC_390_JMP_SLOT +-Create PLT entry. +-@end deffn +-@deffn {} BFD_RELOC_390_RELATIVE +-Adjust by program base. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPC +-32 bit PC relative offset to GOT. +-@end deffn +-@deffn {} BFD_RELOC_390_GOT16 +-16 bit GOT offset. +-@end deffn +-@deffn {} BFD_RELOC_390_PC12DBL +-PC relative 12 bit shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PLT12DBL +-12 bit PC rel. PLT shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PC16DBL +-PC relative 16 bit shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PLT16DBL +-16 bit PC rel. PLT shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PC24DBL +-PC relative 24 bit shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PLT24DBL +-24 bit PC rel. PLT shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PC32DBL +-PC relative 32 bit shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_PLT32DBL +-32 bit PC rel. PLT shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPCDBL +-32 bit PC rel. GOT shifted by 1. +-@end deffn +-@deffn {} BFD_RELOC_390_GOT64 +-64 bit GOT offset. +-@end deffn +-@deffn {} BFD_RELOC_390_PLT64 +-64 bit PC relative PLT address. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTENT +-32 bit rel. offset to GOT entry. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTOFF64 +-64 bit offset to GOT. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPLT12 +-12-bit offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPLT16 +-16-bit offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPLT32 +-32-bit offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPLT64 +-64-bit offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_390_GOTPLTENT +-32-bit rel. offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_390_PLTOFF16 +-16-bit rel. offset from the GOT to a PLT entry. +-@end deffn +-@deffn {} BFD_RELOC_390_PLTOFF32 +-32-bit rel. offset from the GOT to a PLT entry. +-@end deffn +-@deffn {} BFD_RELOC_390_PLTOFF64 +-64-bit rel. offset from the GOT to a PLT entry. +-@end deffn +-@deffn {} BFD_RELOC_390_TLS_LOAD +-@deffnx {} BFD_RELOC_390_TLS_GDCALL +-@deffnx {} BFD_RELOC_390_TLS_LDCALL +-@deffnx {} BFD_RELOC_390_TLS_GD32 +-@deffnx {} BFD_RELOC_390_TLS_GD64 +-@deffnx {} BFD_RELOC_390_TLS_GOTIE12 +-@deffnx {} BFD_RELOC_390_TLS_GOTIE32 +-@deffnx {} BFD_RELOC_390_TLS_GOTIE64 +-@deffnx {} BFD_RELOC_390_TLS_LDM32 +-@deffnx {} BFD_RELOC_390_TLS_LDM64 +-@deffnx {} BFD_RELOC_390_TLS_IE32 +-@deffnx {} BFD_RELOC_390_TLS_IE64 +-@deffnx {} BFD_RELOC_390_TLS_IEENT +-@deffnx {} BFD_RELOC_390_TLS_LE32 +-@deffnx {} BFD_RELOC_390_TLS_LE64 +-@deffnx {} BFD_RELOC_390_TLS_LDO32 +-@deffnx {} BFD_RELOC_390_TLS_LDO64 +-@deffnx {} BFD_RELOC_390_TLS_DTPMOD +-@deffnx {} BFD_RELOC_390_TLS_DTPOFF +-@deffnx {} BFD_RELOC_390_TLS_TPOFF +-s390 tls relocations. +-@end deffn +-@deffn {} BFD_RELOC_390_20 +-@deffnx {} BFD_RELOC_390_GOT20 +-@deffnx {} BFD_RELOC_390_GOTPLT20 +-@deffnx {} BFD_RELOC_390_TLS_GOTIE20 +-Long displacement extension. +-@end deffn +-@deffn {} BFD_RELOC_390_IRELATIVE +-STT_GNU_IFUNC relocation. +-@end deffn +-@deffn {} BFD_RELOC_SCORE_GPREL15 +-Score relocations +-Low 16 bit for load/store +-@end deffn +-@deffn {} BFD_RELOC_SCORE_DUMMY2 +-@deffnx {} BFD_RELOC_SCORE_JMP +-This is a 24-bit reloc with the right 1 bit assumed to be 0 +-@end deffn +-@deffn {} BFD_RELOC_SCORE_BRANCH +-This is a 19-bit reloc with the right 1 bit assumed to be 0 +-@end deffn +-@deffn {} BFD_RELOC_SCORE_IMM30 +-This is a 32-bit reloc for 48-bit instructions. +-@end deffn +-@deffn {} BFD_RELOC_SCORE_IMM32 +-This is a 32-bit reloc for 48-bit instructions. +-@end deffn +-@deffn {} BFD_RELOC_SCORE16_JMP +-This is a 11-bit reloc with the right 1 bit assumed to be 0 +-@end deffn +-@deffn {} BFD_RELOC_SCORE16_BRANCH +-This is a 8-bit reloc with the right 1 bit assumed to be 0 +-@end deffn +-@deffn {} BFD_RELOC_SCORE_BCMP +-This is a 9-bit reloc with the right 1 bit assumed to be 0 +-@end deffn +-@deffn {} BFD_RELOC_SCORE_GOT15 +-@deffnx {} BFD_RELOC_SCORE_GOT_LO16 +-@deffnx {} BFD_RELOC_SCORE_CALL15 +-@deffnx {} BFD_RELOC_SCORE_DUMMY_HI16 +-Undocumented Score relocs +-@end deffn +-@deffn {} BFD_RELOC_IP2K_FR9 +-Scenix IP2K - 9-bit register number / data address +-@end deffn +-@deffn {} BFD_RELOC_IP2K_BANK +-Scenix IP2K - 4-bit register/data bank number +-@end deffn +-@deffn {} BFD_RELOC_IP2K_ADDR16CJP +-Scenix IP2K - low 13 bits of instruction word address +-@end deffn +-@deffn {} BFD_RELOC_IP2K_PAGE3 +-Scenix IP2K - high 3 bits of instruction word address +-@end deffn +-@deffn {} BFD_RELOC_IP2K_LO8DATA +-@deffnx {} BFD_RELOC_IP2K_HI8DATA +-@deffnx {} BFD_RELOC_IP2K_EX8DATA +-Scenix IP2K - ext/low/high 8 bits of data address +-@end deffn +-@deffn {} BFD_RELOC_IP2K_LO8INSN +-@deffnx {} BFD_RELOC_IP2K_HI8INSN +-Scenix IP2K - low/high 8 bits of instruction word address +-@end deffn +-@deffn {} BFD_RELOC_IP2K_PC_SKIP +-Scenix IP2K - even/odd PC modifier to modify snb pcl.0 +-@end deffn +-@deffn {} BFD_RELOC_IP2K_TEXT +-Scenix IP2K - 16 bit word address in text section. +-@end deffn +-@deffn {} BFD_RELOC_IP2K_FR_OFFSET +-Scenix IP2K - 7-bit sp or dp offset +-@end deffn +-@deffn {} BFD_RELOC_VPE4KMATH_DATA +-@deffnx {} BFD_RELOC_VPE4KMATH_INSN +-Scenix VPE4K coprocessor - data/insn-space addressing +-@end deffn +-@deffn {} BFD_RELOC_VTABLE_INHERIT +-@deffnx {} BFD_RELOC_VTABLE_ENTRY +-These two relocations are used by the linker to determine which of +-the entries in a C++ virtual function table are actually used. When +-the --gc-sections option is given, the linker will zero out the entries +-that are not used, so that the code for those functions need not be +-included in the output. +- +-VTABLE_INHERIT is a zero-space relocation used to describe to the +-linker the inheritance tree of a C++ virtual function table. The +-relocation's symbol should be the parent class' vtable, and the +-relocation should be located at the child vtable. +- +-VTABLE_ENTRY is a zero-space relocation that describes the use of a +-virtual function table entry. The reloc's symbol should refer to the +-table of the class mentioned in the code. Off of that base, an offset +-describes the entry that is being used. For Rela hosts, this offset +-is stored in the reloc's addend. For Rel hosts, we are forced to put +-this offset in the reloc's section offset. +-@end deffn +-@deffn {} BFD_RELOC_IA64_IMM14 +-@deffnx {} BFD_RELOC_IA64_IMM22 +-@deffnx {} BFD_RELOC_IA64_IMM64 +-@deffnx {} BFD_RELOC_IA64_DIR32MSB +-@deffnx {} BFD_RELOC_IA64_DIR32LSB +-@deffnx {} BFD_RELOC_IA64_DIR64MSB +-@deffnx {} BFD_RELOC_IA64_DIR64LSB +-@deffnx {} BFD_RELOC_IA64_GPREL22 +-@deffnx {} BFD_RELOC_IA64_GPREL64I +-@deffnx {} BFD_RELOC_IA64_GPREL32MSB +-@deffnx {} BFD_RELOC_IA64_GPREL32LSB +-@deffnx {} BFD_RELOC_IA64_GPREL64MSB +-@deffnx {} BFD_RELOC_IA64_GPREL64LSB +-@deffnx {} BFD_RELOC_IA64_LTOFF22 +-@deffnx {} BFD_RELOC_IA64_LTOFF64I +-@deffnx {} BFD_RELOC_IA64_PLTOFF22 +-@deffnx {} BFD_RELOC_IA64_PLTOFF64I +-@deffnx {} BFD_RELOC_IA64_PLTOFF64MSB +-@deffnx {} BFD_RELOC_IA64_PLTOFF64LSB +-@deffnx {} BFD_RELOC_IA64_FPTR64I +-@deffnx {} BFD_RELOC_IA64_FPTR32MSB +-@deffnx {} BFD_RELOC_IA64_FPTR32LSB +-@deffnx {} BFD_RELOC_IA64_FPTR64MSB +-@deffnx {} BFD_RELOC_IA64_FPTR64LSB +-@deffnx {} BFD_RELOC_IA64_PCREL21B +-@deffnx {} BFD_RELOC_IA64_PCREL21BI +-@deffnx {} BFD_RELOC_IA64_PCREL21M +-@deffnx {} BFD_RELOC_IA64_PCREL21F +-@deffnx {} BFD_RELOC_IA64_PCREL22 +-@deffnx {} BFD_RELOC_IA64_PCREL60B +-@deffnx {} BFD_RELOC_IA64_PCREL64I +-@deffnx {} BFD_RELOC_IA64_PCREL32MSB +-@deffnx {} BFD_RELOC_IA64_PCREL32LSB +-@deffnx {} BFD_RELOC_IA64_PCREL64MSB +-@deffnx {} BFD_RELOC_IA64_PCREL64LSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR22 +-@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR64I +-@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR32MSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR32LSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR64MSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_FPTR64LSB +-@deffnx {} BFD_RELOC_IA64_SEGREL32MSB +-@deffnx {} BFD_RELOC_IA64_SEGREL32LSB +-@deffnx {} BFD_RELOC_IA64_SEGREL64MSB +-@deffnx {} BFD_RELOC_IA64_SEGREL64LSB +-@deffnx {} BFD_RELOC_IA64_SECREL32MSB +-@deffnx {} BFD_RELOC_IA64_SECREL32LSB +-@deffnx {} BFD_RELOC_IA64_SECREL64MSB +-@deffnx {} BFD_RELOC_IA64_SECREL64LSB +-@deffnx {} BFD_RELOC_IA64_REL32MSB +-@deffnx {} BFD_RELOC_IA64_REL32LSB +-@deffnx {} BFD_RELOC_IA64_REL64MSB +-@deffnx {} BFD_RELOC_IA64_REL64LSB +-@deffnx {} BFD_RELOC_IA64_LTV32MSB +-@deffnx {} BFD_RELOC_IA64_LTV32LSB +-@deffnx {} BFD_RELOC_IA64_LTV64MSB +-@deffnx {} BFD_RELOC_IA64_LTV64LSB +-@deffnx {} BFD_RELOC_IA64_IPLTMSB +-@deffnx {} BFD_RELOC_IA64_IPLTLSB +-@deffnx {} BFD_RELOC_IA64_COPY +-@deffnx {} BFD_RELOC_IA64_LTOFF22X +-@deffnx {} BFD_RELOC_IA64_LDXMOV +-@deffnx {} BFD_RELOC_IA64_TPREL14 +-@deffnx {} BFD_RELOC_IA64_TPREL22 +-@deffnx {} BFD_RELOC_IA64_TPREL64I +-@deffnx {} BFD_RELOC_IA64_TPREL64MSB +-@deffnx {} BFD_RELOC_IA64_TPREL64LSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_TPREL22 +-@deffnx {} BFD_RELOC_IA64_DTPMOD64MSB +-@deffnx {} BFD_RELOC_IA64_DTPMOD64LSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_DTPMOD22 +-@deffnx {} BFD_RELOC_IA64_DTPREL14 +-@deffnx {} BFD_RELOC_IA64_DTPREL22 +-@deffnx {} BFD_RELOC_IA64_DTPREL64I +-@deffnx {} BFD_RELOC_IA64_DTPREL32MSB +-@deffnx {} BFD_RELOC_IA64_DTPREL32LSB +-@deffnx {} BFD_RELOC_IA64_DTPREL64MSB +-@deffnx {} BFD_RELOC_IA64_DTPREL64LSB +-@deffnx {} BFD_RELOC_IA64_LTOFF_DTPREL22 +-Intel IA64 Relocations. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_HI8 +-Motorola 68HC11 reloc. +-This is the 8 bit high part of an absolute address. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_LO8 +-Motorola 68HC11 reloc. +-This is the 8 bit low part of an absolute address. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_3B +-Motorola 68HC11 reloc. +-This is the 3 bit of a value. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_RL_JUMP +-Motorola 68HC11 reloc. +-This reloc marks the beginning of a jump/call instruction. +-It is used for linker relaxation to correctly identify beginning +-of instruction and change some branches to use PC-relative +-addressing mode. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_RL_GROUP +-Motorola 68HC11 reloc. +-This reloc marks a group of several instructions that gcc generates +-and for which the linker relaxation pass can modify and/or remove +-some of them. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_LO16 +-Motorola 68HC11 reloc. +-This is the 16-bit lower part of an address. It is used for 'call' +-instruction to specify the symbol address without any special +-transformation (due to memory bank window). +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_PAGE +-Motorola 68HC11 reloc. +-This is a 8-bit reloc that specifies the page number of an address. +-It is used by 'call' instruction to specify the page number of +-the symbol. +-@end deffn +-@deffn {} BFD_RELOC_M68HC11_24 +-Motorola 68HC11 reloc. +-This is a 24-bit reloc that represents the address with a 16-bit +-value and a 8-bit page number. The symbol address is transformed +-to follow the 16K memory bank of 68HC12 (seen as mapped in the window). +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_5B +-Motorola 68HC12 reloc. +-This is the 5 bits of a value. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_RL_JUMP +-Freescale XGATE reloc. +-This reloc marks the beginning of a bra/jal instruction. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_RL_GROUP +-Freescale XGATE reloc. +-This reloc marks a group of several instructions that gcc generates +-and for which the linker relaxation pass can modify and/or remove +-some of them. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_LO16 +-Freescale XGATE reloc. +-This is the 16-bit lower part of an address. It is used for the '16-bit' +-instructions. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_GPAGE +-Freescale XGATE reloc. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_24 +-Freescale XGATE reloc. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_PCREL_9 +-Freescale XGATE reloc. +-This is a 9-bit pc-relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_PCREL_10 +-Freescale XGATE reloc. +-This is a 10-bit pc-relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_IMM8_LO +-Freescale XGATE reloc. +-This is the 16-bit lower part of an address. It is used for the '16-bit' +-instructions. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_IMM8_HI +-Freescale XGATE reloc. +-This is the 16-bit higher part of an address. It is used for the '16-bit' +-instructions. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_IMM3 +-Freescale XGATE reloc. +-This is a 3-bit pc-relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_IMM4 +-Freescale XGATE reloc. +-This is a 4-bit pc-relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_XGATE_IMM5 +-Freescale XGATE reloc. +-This is a 5-bit pc-relative reloc. +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_9B +-Motorola 68HC12 reloc. +-This is the 9 bits of a value. +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_16B +-Motorola 68HC12 reloc. +-This is the 16 bits of a value. +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_9_PCREL +-Motorola 68HC12/XGATE reloc. +-This is a PCREL9 branch. +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_10_PCREL +-Motorola 68HC12/XGATE reloc. +-This is a PCREL10 branch. +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_LO8XG +-Motorola 68HC12/XGATE reloc. +-This is the 8 bit low part of an absolute address and immediately precedes +-a matching HI8XG part. +-@end deffn +-@deffn {} BFD_RELOC_M68HC12_HI8XG +-Motorola 68HC12/XGATE reloc. +-This is the 8 bit high part of an absolute address and immediately follows +-a matching LO8XG part. +-@end deffn +-@deffn {} BFD_RELOC_16C_NUM08 +-@deffnx {} BFD_RELOC_16C_NUM08_C +-@deffnx {} BFD_RELOC_16C_NUM16 +-@deffnx {} BFD_RELOC_16C_NUM16_C +-@deffnx {} BFD_RELOC_16C_NUM32 +-@deffnx {} BFD_RELOC_16C_NUM32_C +-@deffnx {} BFD_RELOC_16C_DISP04 +-@deffnx {} BFD_RELOC_16C_DISP04_C +-@deffnx {} BFD_RELOC_16C_DISP08 +-@deffnx {} BFD_RELOC_16C_DISP08_C +-@deffnx {} BFD_RELOC_16C_DISP16 +-@deffnx {} BFD_RELOC_16C_DISP16_C +-@deffnx {} BFD_RELOC_16C_DISP24 +-@deffnx {} BFD_RELOC_16C_DISP24_C +-@deffnx {} BFD_RELOC_16C_DISP24a +-@deffnx {} BFD_RELOC_16C_DISP24a_C +-@deffnx {} BFD_RELOC_16C_REG04 +-@deffnx {} BFD_RELOC_16C_REG04_C +-@deffnx {} BFD_RELOC_16C_REG04a +-@deffnx {} BFD_RELOC_16C_REG04a_C +-@deffnx {} BFD_RELOC_16C_REG14 +-@deffnx {} BFD_RELOC_16C_REG14_C +-@deffnx {} BFD_RELOC_16C_REG16 +-@deffnx {} BFD_RELOC_16C_REG16_C +-@deffnx {} BFD_RELOC_16C_REG20 +-@deffnx {} BFD_RELOC_16C_REG20_C +-@deffnx {} BFD_RELOC_16C_ABS20 +-@deffnx {} BFD_RELOC_16C_ABS20_C +-@deffnx {} BFD_RELOC_16C_ABS24 +-@deffnx {} BFD_RELOC_16C_ABS24_C +-@deffnx {} BFD_RELOC_16C_IMM04 +-@deffnx {} BFD_RELOC_16C_IMM04_C +-@deffnx {} BFD_RELOC_16C_IMM16 +-@deffnx {} BFD_RELOC_16C_IMM16_C +-@deffnx {} BFD_RELOC_16C_IMM20 +-@deffnx {} BFD_RELOC_16C_IMM20_C +-@deffnx {} BFD_RELOC_16C_IMM24 +-@deffnx {} BFD_RELOC_16C_IMM24_C +-@deffnx {} BFD_RELOC_16C_IMM32 +-@deffnx {} BFD_RELOC_16C_IMM32_C +-NS CR16C Relocations. +-@end deffn +-@deffn {} BFD_RELOC_CR16_NUM8 +-@deffnx {} BFD_RELOC_CR16_NUM16 +-@deffnx {} BFD_RELOC_CR16_NUM32 +-@deffnx {} BFD_RELOC_CR16_NUM32a +-@deffnx {} BFD_RELOC_CR16_REGREL0 +-@deffnx {} BFD_RELOC_CR16_REGREL4 +-@deffnx {} BFD_RELOC_CR16_REGREL4a +-@deffnx {} BFD_RELOC_CR16_REGREL14 +-@deffnx {} BFD_RELOC_CR16_REGREL14a +-@deffnx {} BFD_RELOC_CR16_REGREL16 +-@deffnx {} BFD_RELOC_CR16_REGREL20 +-@deffnx {} BFD_RELOC_CR16_REGREL20a +-@deffnx {} BFD_RELOC_CR16_ABS20 +-@deffnx {} BFD_RELOC_CR16_ABS24 +-@deffnx {} BFD_RELOC_CR16_IMM4 +-@deffnx {} BFD_RELOC_CR16_IMM8 +-@deffnx {} BFD_RELOC_CR16_IMM16 +-@deffnx {} BFD_RELOC_CR16_IMM20 +-@deffnx {} BFD_RELOC_CR16_IMM24 +-@deffnx {} BFD_RELOC_CR16_IMM32 +-@deffnx {} BFD_RELOC_CR16_IMM32a +-@deffnx {} BFD_RELOC_CR16_DISP4 +-@deffnx {} BFD_RELOC_CR16_DISP8 +-@deffnx {} BFD_RELOC_CR16_DISP16 +-@deffnx {} BFD_RELOC_CR16_DISP20 +-@deffnx {} BFD_RELOC_CR16_DISP24 +-@deffnx {} BFD_RELOC_CR16_DISP24a +-@deffnx {} BFD_RELOC_CR16_SWITCH8 +-@deffnx {} BFD_RELOC_CR16_SWITCH16 +-@deffnx {} BFD_RELOC_CR16_SWITCH32 +-@deffnx {} BFD_RELOC_CR16_GOT_REGREL20 +-@deffnx {} BFD_RELOC_CR16_GOTC_REGREL20 +-@deffnx {} BFD_RELOC_CR16_GLOB_DAT +-NS CR16 Relocations. +-@end deffn +-@deffn {} BFD_RELOC_CRX_REL4 +-@deffnx {} BFD_RELOC_CRX_REL8 +-@deffnx {} BFD_RELOC_CRX_REL8_CMP +-@deffnx {} BFD_RELOC_CRX_REL16 +-@deffnx {} BFD_RELOC_CRX_REL24 +-@deffnx {} BFD_RELOC_CRX_REL32 +-@deffnx {} BFD_RELOC_CRX_REGREL12 +-@deffnx {} BFD_RELOC_CRX_REGREL22 +-@deffnx {} BFD_RELOC_CRX_REGREL28 +-@deffnx {} BFD_RELOC_CRX_REGREL32 +-@deffnx {} BFD_RELOC_CRX_ABS16 +-@deffnx {} BFD_RELOC_CRX_ABS32 +-@deffnx {} BFD_RELOC_CRX_NUM8 +-@deffnx {} BFD_RELOC_CRX_NUM16 +-@deffnx {} BFD_RELOC_CRX_NUM32 +-@deffnx {} BFD_RELOC_CRX_IMM16 +-@deffnx {} BFD_RELOC_CRX_IMM32 +-@deffnx {} BFD_RELOC_CRX_SWITCH8 +-@deffnx {} BFD_RELOC_CRX_SWITCH16 +-@deffnx {} BFD_RELOC_CRX_SWITCH32 +-NS CRX Relocations. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_BDISP8 +-@deffnx {} BFD_RELOC_CRIS_UNSIGNED_5 +-@deffnx {} BFD_RELOC_CRIS_SIGNED_6 +-@deffnx {} BFD_RELOC_CRIS_UNSIGNED_6 +-@deffnx {} BFD_RELOC_CRIS_SIGNED_8 +-@deffnx {} BFD_RELOC_CRIS_UNSIGNED_8 +-@deffnx {} BFD_RELOC_CRIS_SIGNED_16 +-@deffnx {} BFD_RELOC_CRIS_UNSIGNED_16 +-@deffnx {} BFD_RELOC_CRIS_LAPCQ_OFFSET +-@deffnx {} BFD_RELOC_CRIS_UNSIGNED_4 +-These relocs are only used within the CRIS assembler. They are not +-(at present) written to any object files. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_COPY +-@deffnx {} BFD_RELOC_CRIS_GLOB_DAT +-@deffnx {} BFD_RELOC_CRIS_JUMP_SLOT +-@deffnx {} BFD_RELOC_CRIS_RELATIVE +-Relocs used in ELF shared libraries for CRIS. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_32_GOT +-32-bit offset to symbol-entry within GOT. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_16_GOT +-16-bit offset to symbol-entry within GOT. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_32_GOTPLT +-32-bit offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_16_GOTPLT +-16-bit offset to symbol-entry within GOT, with PLT handling. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_32_GOTREL +-32-bit offset to symbol, relative to GOT. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_32_PLT_GOTREL +-32-bit offset to symbol with PLT entry, relative to GOT. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_32_PLT_PCREL +-32-bit offset to symbol with PLT entry, relative to this relocation. +-@end deffn +-@deffn {} BFD_RELOC_CRIS_32_GOT_GD +-@deffnx {} BFD_RELOC_CRIS_16_GOT_GD +-@deffnx {} BFD_RELOC_CRIS_32_GD +-@deffnx {} BFD_RELOC_CRIS_DTP +-@deffnx {} BFD_RELOC_CRIS_32_DTPREL +-@deffnx {} BFD_RELOC_CRIS_16_DTPREL +-@deffnx {} BFD_RELOC_CRIS_32_GOT_TPREL +-@deffnx {} BFD_RELOC_CRIS_16_GOT_TPREL +-@deffnx {} BFD_RELOC_CRIS_32_TPREL +-@deffnx {} BFD_RELOC_CRIS_16_TPREL +-@deffnx {} BFD_RELOC_CRIS_DTPMOD +-@deffnx {} BFD_RELOC_CRIS_32_IE +-Relocs used in TLS code for CRIS. +-@end deffn +-@deffn {} BFD_RELOC_860_COPY +-@deffnx {} BFD_RELOC_860_GLOB_DAT +-@deffnx {} BFD_RELOC_860_JUMP_SLOT +-@deffnx {} BFD_RELOC_860_RELATIVE +-@deffnx {} BFD_RELOC_860_PC26 +-@deffnx {} BFD_RELOC_860_PLT26 +-@deffnx {} BFD_RELOC_860_PC16 +-@deffnx {} BFD_RELOC_860_LOW0 +-@deffnx {} BFD_RELOC_860_SPLIT0 +-@deffnx {} BFD_RELOC_860_LOW1 +-@deffnx {} BFD_RELOC_860_SPLIT1 +-@deffnx {} BFD_RELOC_860_LOW2 +-@deffnx {} BFD_RELOC_860_SPLIT2 +-@deffnx {} BFD_RELOC_860_LOW3 +-@deffnx {} BFD_RELOC_860_LOGOT0 +-@deffnx {} BFD_RELOC_860_SPGOT0 +-@deffnx {} BFD_RELOC_860_LOGOT1 +-@deffnx {} BFD_RELOC_860_SPGOT1 +-@deffnx {} BFD_RELOC_860_LOGOTOFF0 +-@deffnx {} BFD_RELOC_860_SPGOTOFF0 +-@deffnx {} BFD_RELOC_860_LOGOTOFF1 +-@deffnx {} BFD_RELOC_860_SPGOTOFF1 +-@deffnx {} BFD_RELOC_860_LOGOTOFF2 +-@deffnx {} BFD_RELOC_860_LOGOTOFF3 +-@deffnx {} BFD_RELOC_860_LOPC +-@deffnx {} BFD_RELOC_860_HIGHADJ +-@deffnx {} BFD_RELOC_860_HAGOT +-@deffnx {} BFD_RELOC_860_HAGOTOFF +-@deffnx {} BFD_RELOC_860_HAPC +-@deffnx {} BFD_RELOC_860_HIGH +-@deffnx {} BFD_RELOC_860_HIGOT +-@deffnx {} BFD_RELOC_860_HIGOTOFF +-Intel i860 Relocations. +-@end deffn +-@deffn {} BFD_RELOC_OPENRISC_ABS_26 +-@deffnx {} BFD_RELOC_OPENRISC_REL_26 +-OpenRISC Relocations. +-@end deffn +-@deffn {} BFD_RELOC_H8_DIR16A8 +-@deffnx {} BFD_RELOC_H8_DIR16R8 +-@deffnx {} BFD_RELOC_H8_DIR24A8 +-@deffnx {} BFD_RELOC_H8_DIR24R8 +-@deffnx {} BFD_RELOC_H8_DIR32A16 +-@deffnx {} BFD_RELOC_H8_DISP32A16 +-H8 elf Relocations. +-@end deffn +-@deffn {} BFD_RELOC_XSTORMY16_REL_12 +-@deffnx {} BFD_RELOC_XSTORMY16_12 +-@deffnx {} BFD_RELOC_XSTORMY16_24 +-@deffnx {} BFD_RELOC_XSTORMY16_FPTR16 +-Sony Xstormy16 Relocations. +-@end deffn +-@deffn {} BFD_RELOC_RELC +-Self-describing complex relocations. +-@end deffn +-@deffn {} BFD_RELOC_XC16X_PAG +-@deffnx {} BFD_RELOC_XC16X_POF +-@deffnx {} BFD_RELOC_XC16X_SEG +-@deffnx {} BFD_RELOC_XC16X_SOF +-Infineon Relocations. +-@end deffn +-@deffn {} BFD_RELOC_VAX_GLOB_DAT +-@deffnx {} BFD_RELOC_VAX_JMP_SLOT +-@deffnx {} BFD_RELOC_VAX_RELATIVE +-Relocations used by VAX ELF. +-@end deffn +-@deffn {} BFD_RELOC_MT_PC16 +-Morpho MT - 16 bit immediate relocation. +-@end deffn +-@deffn {} BFD_RELOC_MT_HI16 +-Morpho MT - Hi 16 bits of an address. +-@end deffn +-@deffn {} BFD_RELOC_MT_LO16 +-Morpho MT - Low 16 bits of an address. +-@end deffn +-@deffn {} BFD_RELOC_MT_GNU_VTINHERIT +-Morpho MT - Used to tell the linker which vtable entries are used. +-@end deffn +-@deffn {} BFD_RELOC_MT_GNU_VTENTRY +-Morpho MT - Used to tell the linker which vtable entries are used. +-@end deffn +-@deffn {} BFD_RELOC_MT_PCINSN8 +-Morpho MT - 8 bit immediate relocation. +-@end deffn +-@deffn {} BFD_RELOC_MSP430_10_PCREL +-@deffnx {} BFD_RELOC_MSP430_16_PCREL +-@deffnx {} BFD_RELOC_MSP430_16 +-@deffnx {} BFD_RELOC_MSP430_16_PCREL_BYTE +-@deffnx {} BFD_RELOC_MSP430_16_BYTE +-@deffnx {} BFD_RELOC_MSP430_2X_PCREL +-@deffnx {} BFD_RELOC_MSP430_RL_PCREL +-@deffnx {} BFD_RELOC_MSP430_ABS8 +-@deffnx {} BFD_RELOC_MSP430X_PCR20_EXT_SRC +-@deffnx {} BFD_RELOC_MSP430X_PCR20_EXT_DST +-@deffnx {} BFD_RELOC_MSP430X_PCR20_EXT_ODST +-@deffnx {} BFD_RELOC_MSP430X_ABS20_EXT_SRC +-@deffnx {} BFD_RELOC_MSP430X_ABS20_EXT_DST +-@deffnx {} BFD_RELOC_MSP430X_ABS20_EXT_ODST +-@deffnx {} BFD_RELOC_MSP430X_ABS20_ADR_SRC +-@deffnx {} BFD_RELOC_MSP430X_ABS20_ADR_DST +-@deffnx {} BFD_RELOC_MSP430X_PCR16 +-@deffnx {} BFD_RELOC_MSP430X_PCR20_CALL +-@deffnx {} BFD_RELOC_MSP430X_ABS16 +-@deffnx {} BFD_RELOC_MSP430_ABS_HI16 +-@deffnx {} BFD_RELOC_MSP430_PREL31 +-@deffnx {} BFD_RELOC_MSP430_SYM_DIFF +-msp430 specific relocation codes +-@end deffn +-@deffn {} BFD_RELOC_NIOS2_S16 +-@deffnx {} BFD_RELOC_NIOS2_U16 +-@deffnx {} BFD_RELOC_NIOS2_CALL26 +-@deffnx {} BFD_RELOC_NIOS2_IMM5 +-@deffnx {} BFD_RELOC_NIOS2_CACHE_OPX +-@deffnx {} BFD_RELOC_NIOS2_IMM6 +-@deffnx {} BFD_RELOC_NIOS2_IMM8 +-@deffnx {} BFD_RELOC_NIOS2_HI16 +-@deffnx {} BFD_RELOC_NIOS2_LO16 +-@deffnx {} BFD_RELOC_NIOS2_HIADJ16 +-@deffnx {} BFD_RELOC_NIOS2_GPREL +-@deffnx {} BFD_RELOC_NIOS2_UJMP +-@deffnx {} BFD_RELOC_NIOS2_CJMP +-@deffnx {} BFD_RELOC_NIOS2_CALLR +-@deffnx {} BFD_RELOC_NIOS2_ALIGN +-@deffnx {} BFD_RELOC_NIOS2_GOT16 +-@deffnx {} BFD_RELOC_NIOS2_CALL16 +-@deffnx {} BFD_RELOC_NIOS2_GOTOFF_LO +-@deffnx {} BFD_RELOC_NIOS2_GOTOFF_HA +-@deffnx {} BFD_RELOC_NIOS2_PCREL_LO +-@deffnx {} BFD_RELOC_NIOS2_PCREL_HA +-@deffnx {} BFD_RELOC_NIOS2_TLS_GD16 +-@deffnx {} BFD_RELOC_NIOS2_TLS_LDM16 +-@deffnx {} BFD_RELOC_NIOS2_TLS_LDO16 +-@deffnx {} BFD_RELOC_NIOS2_TLS_IE16 +-@deffnx {} BFD_RELOC_NIOS2_TLS_LE16 +-@deffnx {} BFD_RELOC_NIOS2_TLS_DTPMOD +-@deffnx {} BFD_RELOC_NIOS2_TLS_DTPREL +-@deffnx {} BFD_RELOC_NIOS2_TLS_TPREL +-@deffnx {} BFD_RELOC_NIOS2_COPY +-@deffnx {} BFD_RELOC_NIOS2_GLOB_DAT +-@deffnx {} BFD_RELOC_NIOS2_JUMP_SLOT +-@deffnx {} BFD_RELOC_NIOS2_RELATIVE +-@deffnx {} BFD_RELOC_NIOS2_GOTOFF +-Relocations used by the Altera Nios II core. +-@end deffn +-@deffn {} BFD_RELOC_IQ2000_OFFSET_16 +-@deffnx {} BFD_RELOC_IQ2000_OFFSET_21 +-@deffnx {} BFD_RELOC_IQ2000_UHI16 +-IQ2000 Relocations. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_RTLD +-Special Xtensa relocation used only by PLT entries in ELF shared +-objects to indicate that the runtime linker should set the value +-to one of its own internal functions or data structures. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_GLOB_DAT +-@deffnx {} BFD_RELOC_XTENSA_JMP_SLOT +-@deffnx {} BFD_RELOC_XTENSA_RELATIVE +-Xtensa relocations for ELF shared objects. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_PLT +-Xtensa relocation used in ELF object files for symbols that may require +-PLT entries. Otherwise, this is just a generic 32-bit relocation. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_DIFF8 +-@deffnx {} BFD_RELOC_XTENSA_DIFF16 +-@deffnx {} BFD_RELOC_XTENSA_DIFF32 +-Xtensa relocations to mark the difference of two local symbols. +-These are only needed to support linker relaxation and can be ignored +-when not relaxing. The field is set to the value of the difference +-assuming no relaxation. The relocation encodes the position of the +-first symbol so the linker can determine whether to adjust the field +-value. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_SLOT0_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT1_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT2_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT3_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT4_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT5_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT6_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT7_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT8_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT9_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT10_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT11_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT12_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT13_OP +-@deffnx {} BFD_RELOC_XTENSA_SLOT14_OP +-Generic Xtensa relocations for instruction operands. Only the slot +-number is encoded in the relocation. The relocation applies to the +-last PC-relative immediate operand, or if there are no PC-relative +-immediates, to the last immediate operand. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_SLOT0_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT1_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT2_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT3_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT4_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT5_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT6_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT7_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT8_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT9_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT10_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT11_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT12_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT13_ALT +-@deffnx {} BFD_RELOC_XTENSA_SLOT14_ALT +-Alternate Xtensa relocations. Only the slot is encoded in the +-relocation. The meaning of these relocations is opcode-specific. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_OP0 +-@deffnx {} BFD_RELOC_XTENSA_OP1 +-@deffnx {} BFD_RELOC_XTENSA_OP2 +-Xtensa relocations for backward compatibility. These have all been +-replaced by BFD_RELOC_XTENSA_SLOT0_OP. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_ASM_EXPAND +-Xtensa relocation to mark that the assembler expanded the +-instructions from an original target. The expansion size is +-encoded in the reloc size. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_ASM_SIMPLIFY +-Xtensa relocation to mark that the linker should simplify +-assembler-expanded instructions. This is commonly used +-internally by the linker after analysis of a +-BFD_RELOC_XTENSA_ASM_EXPAND. +-@end deffn +-@deffn {} BFD_RELOC_XTENSA_TLSDESC_FN +-@deffnx {} BFD_RELOC_XTENSA_TLSDESC_ARG +-@deffnx {} BFD_RELOC_XTENSA_TLS_DTPOFF +-@deffnx {} BFD_RELOC_XTENSA_TLS_TPOFF +-@deffnx {} BFD_RELOC_XTENSA_TLS_FUNC +-@deffnx {} BFD_RELOC_XTENSA_TLS_ARG +-@deffnx {} BFD_RELOC_XTENSA_TLS_CALL +-Xtensa TLS relocations. +-@end deffn +-@deffn {} BFD_RELOC_Z80_DISP8 +-8 bit signed offset in (ix+d) or (iy+d). +-@end deffn +-@deffn {} BFD_RELOC_Z8K_DISP7 +-DJNZ offset. +-@end deffn +-@deffn {} BFD_RELOC_Z8K_CALLR +-CALR offset. +-@end deffn +-@deffn {} BFD_RELOC_Z8K_IMM4L +-4 bit value. +-@end deffn +-@deffn {} BFD_RELOC_LM32_CALL +-@deffnx {} BFD_RELOC_LM32_BRANCH +-@deffnx {} BFD_RELOC_LM32_16_GOT +-@deffnx {} BFD_RELOC_LM32_GOTOFF_HI16 +-@deffnx {} BFD_RELOC_LM32_GOTOFF_LO16 +-@deffnx {} BFD_RELOC_LM32_COPY +-@deffnx {} BFD_RELOC_LM32_GLOB_DAT +-@deffnx {} BFD_RELOC_LM32_JMP_SLOT +-@deffnx {} BFD_RELOC_LM32_RELATIVE +-Lattice Mico32 relocations. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_SECTDIFF +-Difference between two section addreses. Must be followed by a +-BFD_RELOC_MACH_O_PAIR. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_LOCAL_SECTDIFF +-Like BFD_RELOC_MACH_O_SECTDIFF but with a local symbol. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_PAIR +-Pair of relocation. Contains the first symbol. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_BRANCH32 +-@deffnx {} BFD_RELOC_MACH_O_X86_64_BRANCH8 +-PCREL relocations. They are marked as branch to create PLT entry if +-required. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_GOT +-Used when referencing a GOT entry. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_GOT_LOAD +-Used when loading a GOT entry with movq. It is specially marked so that +-the linker could optimize the movq to a leaq if possible. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_SUBTRACTOR32 +-Symbol will be substracted. Must be followed by a BFD_RELOC_64. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_SUBTRACTOR64 +-Symbol will be substracted. Must be followed by a BFD_RELOC_64. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_PCREL32_1 +-Same as BFD_RELOC_32_PCREL but with an implicit -1 addend. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_PCREL32_2 +-Same as BFD_RELOC_32_PCREL but with an implicit -2 addend. +-@end deffn +-@deffn {} BFD_RELOC_MACH_O_X86_64_PCREL32_4 +-Same as BFD_RELOC_32_PCREL but with an implicit -4 addend. +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_LO +-This is a 32 bit reloc for the microblaze that stores the +-low 16 bits of a value +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_LO_PCREL +-This is a 32 bit pc-relative reloc for the microblaze that +-stores the low 16 bits of a value +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_ROSDA +-This is a 32 bit reloc for the microblaze that stores a +-value relative to the read-only small data area anchor +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_RWSDA +-This is a 32 bit reloc for the microblaze that stores a +-value relative to the read-write small data area anchor +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM +-This is a 32 bit reloc for the microblaze to handle +-expressions of the form "Symbol Op Symbol" +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_NONE +-This is a 64 bit reloc that stores the 32 bit pc relative +-value in two words (with an imm instruction). No relocation is +-done here - only used for relaxing +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_GOTPC +-This is a 64 bit reloc that stores the 32 bit pc relative +-value in two words (with an imm instruction). The relocation is +-PC-relative GOT offset +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_GOT +-This is a 64 bit reloc that stores the 32 bit pc relative +-value in two words (with an imm instruction). The relocation is +-GOT offset +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_PLT +-This is a 64 bit reloc that stores the 32 bit pc relative +-value in two words (with an imm instruction). The relocation is +-PC-relative offset into PLT +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_GOTOFF +-This is a 64 bit reloc that stores the 32 bit GOT relative +-value in two words (with an imm instruction). The relocation is +-relative offset from _GLOBAL_OFFSET_TABLE_ +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_GOTOFF +-This is a 32 bit reloc that stores the 32 bit GOT relative +-value in a word. The relocation is relative offset from +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_COPY +-This is used to tell the dynamic linker to copy the value out of +-the dynamic object into the runtime process image. +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_TLS +-Unused Reloc +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_TLSGD +-This is a 64 bit reloc that stores the 32 bit GOT relative value +-of the GOT TLS GD info entry in two words (with an imm instruction). The +-relocation is GOT offset. +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_TLSLD +-This is a 64 bit reloc that stores the 32 bit GOT relative value +-of the GOT TLS LD info entry in two words (with an imm instruction). The +-relocation is GOT offset. +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_TLSDTPMOD +-This is a 32 bit reloc that stores the Module ID to GOT(n). +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_32_TLSDTPREL +-This is a 32 bit reloc that stores TLS offset to GOT(n+1). +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_TLSDTPREL +-This is a 32 bit reloc for storing TLS offset to two words (uses imm +-instruction) +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL +-This is a 64 bit reloc that stores 32-bit thread pointer relative offset +-to two words (uses imm instruction). +-@end deffn +-@deffn {} BFD_RELOC_MICROBLAZE_64_TLSTPREL +-This is a 64 bit reloc that stores 32-bit thread pointer relative offset +-to two words (uses imm instruction). +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_RELOC_START +-AArch64 pseudo relocation code to mark the start of the AArch64 +-relocation enumerators. N.B. the order of the enumerators is +-important as several tables in the AArch64 bfd backend are indexed +-by these enumerators; make sure they are all synced. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_NONE +-AArch64 null relocation code. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_64 +-@deffnx {} BFD_RELOC_AARCH64_32 +-@deffnx {} BFD_RELOC_AARCH64_16 +-Basic absolute relocations of N bits. These are equivalent to +-BFD_RELOC_N and they were added to assist the indexing of the howto +-table. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_64_PCREL +-@deffnx {} BFD_RELOC_AARCH64_32_PCREL +-@deffnx {} BFD_RELOC_AARCH64_16_PCREL +-PC-relative relocations. These are equivalent to BFD_RELOC_N_PCREL +-and they were added to assist the indexing of the howto table. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G0 +-AArch64 MOV[NZK] instruction with most significant bits 0 to 15 +-of an unsigned address/value. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G0_NC +-AArch64 MOV[NZK] instruction with less significant bits 0 to 15 of +-an address/value. No overflow checking. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G1 +-AArch64 MOV[NZK] instruction with most significant bits 16 to 31 +-of an unsigned address/value. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G1_NC +-AArch64 MOV[NZK] instruction with less significant bits 16 to 31 +-of an address/value. No overflow checking. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G2 +-AArch64 MOV[NZK] instruction with most significant bits 32 to 47 +-of an unsigned address/value. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G2_NC +-AArch64 MOV[NZK] instruction with less significant bits 32 to 47 +-of an address/value. No overflow checking. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G3 +-AArch64 MOV[NZK] instruction with most signficant bits 48 to 64 +-of a signed or unsigned address/value. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G0_S +-AArch64 MOV[NZ] instruction with most significant bits 0 to 15 +-of a signed value. Changes instruction to MOVZ or MOVN depending on the +-value's sign. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G1_S +-AArch64 MOV[NZ] instruction with most significant bits 16 to 31 +-of a signed value. Changes instruction to MOVZ or MOVN depending on the +-value's sign. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_MOVW_G2_S +-AArch64 MOV[NZ] instruction with most significant bits 32 to 47 +-of a signed value. Changes instruction to MOVZ or MOVN depending on the +-value's sign. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LD_LO19_PCREL +-AArch64 Load Literal instruction, holding a 19 bit pc-relative word +-offset. The lowest two bits must be zero and are not stored in the +-instruction, giving a 21 bit signed byte offset. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_ADR_LO21_PCREL +-AArch64 ADR instruction, holding a simple 21 bit pc-relative byte offset. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_ADR_HI21_PCREL +-AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page +-offset, giving a 4KB aligned page base address. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_ADR_HI21_NC_PCREL +-AArch64 ADRP instruction, with bits 12 to 32 of a pc-relative page +-offset, giving a 4KB aligned page base address, but with no overflow +-checking. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_ADD_LO12 +-AArch64 ADD immediate instruction, holding bits 0 to 11 of the address. +-Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LDST8_LO12 +-AArch64 8-bit load/store instruction, holding bits 0 to 11 of the +-address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TSTBR14 +-AArch64 14 bit pc-relative test bit and branch. +-The lowest two bits must be zero and are not stored in the instruction, +-giving a 16 bit signed byte offset. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_BRANCH19 +-AArch64 19 bit pc-relative conditional branch and compare & branch. +-The lowest two bits must be zero and are not stored in the instruction, +-giving a 21 bit signed byte offset. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_JUMP26 +-AArch64 26 bit pc-relative unconditional branch. +-The lowest two bits must be zero and are not stored in the instruction, +-giving a 28 bit signed byte offset. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_CALL26 +-AArch64 26 bit pc-relative unconditional branch and link. +-The lowest two bits must be zero and are not stored in the instruction, +-giving a 28 bit signed byte offset. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LDST16_LO12 +-AArch64 16-bit load/store instruction, holding bits 0 to 11 of the +-address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LDST32_LO12 +-AArch64 32-bit load/store instruction, holding bits 0 to 11 of the +-address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LDST64_LO12 +-AArch64 64-bit load/store instruction, holding bits 0 to 11 of the +-address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LDST128_LO12 +-AArch64 128-bit load/store instruction, holding bits 0 to 11 of the +-address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_GOT_LD_PREL19 +-AArch64 Load Literal instruction, holding a 19 bit PC relative word +-offset of the global offset table entry for a symbol. The lowest two +-bits must be zero and are not stored in the instruction, giving a 21 +-bit signed byte offset. This relocation type requires signed overflow +-checking. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_ADR_GOT_PAGE +-Get to the page base of the global offset table entry for a symbol as +-part of an ADRP instruction using a 21 bit PC relative value.Used in +-conjunction with BFD_RELOC_AARCH64_LD64_GOT_LO12_NC. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LD64_GOT_LO12_NC +-Unsigned 12 bit byte offset for 64 bit load/store from the page of +-the GOT entry for this symbol. Used in conjunction with +-BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in LP64 ABI only. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LD32_GOT_LO12_NC +-Unsigned 12 bit byte offset for 32 bit load/store from the page of +-the GOT entry for this symbol. Used in conjunction with +-BFD_RELOC_AARCH64_ADR_GOTPAGE. Valid in ILP32 ABI only. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21 +-Get to the page base of the global offset table entry for a symbols +-tls_index structure as part of an adrp instruction using a 21 bit PC +-relative value. Used in conjunction with +-BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSGD_ADD_LO12_NC +-Unsigned 12 bit byte offset to global offset table entry for a symbols +-tls_index structure. Used in conjunction with +-BFD_RELOC_AARCH64_TLSGD_ADR_PAGE21. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G1 +-AArch64 TLS INITIAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC +-AArch64 TLS INITIAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 +-AArch64 TLS INITIAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC +-AArch64 TLS INITIAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC +-AArch64 TLS INITIAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_PREL19 +-AArch64 TLS INITIAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2 +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1 +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0 +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12 +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12 +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC +-AArch64 TLS LOCAL EXEC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD_PREL19 +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21 +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21 +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD64_LO12_NC +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD32_LO12_NC +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADD_LO12_NC +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_OFF_G1 +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_OFF_G0_NC +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_LDR +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_ADD +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_CALL +-AArch64 TLS DESC relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_COPY +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_GLOB_DAT +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_JUMP_SLOT +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_RELATIVE +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLS_DTPMOD +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLS_DTPREL +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLS_TPREL +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC +-AArch64 TLS relocation. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_IRELATIVE +-AArch64 support for STT_GNU_IFUNC. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_RELOC_END +-AArch64 pseudo relocation code to mark the end of the AArch64 +-relocation enumerators that have direct mapping to ELF reloc codes. +-There are a few more enumerators after this one; those are mainly +-used by the AArch64 assembler for the internal fixup or to select +-one of the above enumerators. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP +-AArch64 pseudo relocation code to be used internally by the AArch64 +-assembler and not (currently) written to any object files. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LDST_LO12 +-AArch64 unspecified load/store instruction, holding bits 0 to 11 of the +-address. Used in conjunction with BFD_RELOC_AARCH64_ADR_HI21_PCREL. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_LD_GOT_LO12_NC +-AArch64 pseudo relocation code to be used internally by the AArch64 +-assembler and not (currently) written to any object files. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC +-AArch64 pseudo relocation code to be used internally by the AArch64 +-assembler and not (currently) written to any object files. +-@end deffn +-@deffn {} BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC +-AArch64 pseudo relocation code to be used internally by the AArch64 +-assembler and not (currently) written to any object files. +-@end deffn +-@deffn {} BFD_RELOC_TILEPRO_COPY +-@deffnx {} BFD_RELOC_TILEPRO_GLOB_DAT +-@deffnx {} BFD_RELOC_TILEPRO_JMP_SLOT +-@deffnx {} BFD_RELOC_TILEPRO_RELATIVE +-@deffnx {} BFD_RELOC_TILEPRO_BROFF_X1 +-@deffnx {} BFD_RELOC_TILEPRO_JOFFLONG_X1 +-@deffnx {} BFD_RELOC_TILEPRO_JOFFLONG_X1_PLT +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_X0 +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y0 +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_X1 +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y1 +-@deffnx {} BFD_RELOC_TILEPRO_DEST_IMM8_X1 +-@deffnx {} BFD_RELOC_TILEPRO_MT_IMM15_X1 +-@deffnx {} BFD_RELOC_TILEPRO_MF_IMM15_X1 +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0 +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1 +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_LO_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_LO_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HI_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HI_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_HA_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_HA_PCREL +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_GOT_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_GOT_HA +-@deffnx {} BFD_RELOC_TILEPRO_MMSTART_X0 +-@deffnx {} BFD_RELOC_TILEPRO_MMEND_X0 +-@deffnx {} BFD_RELOC_TILEPRO_MMSTART_X1 +-@deffnx {} BFD_RELOC_TILEPRO_MMEND_X1 +-@deffnx {} BFD_RELOC_TILEPRO_SHAMT_X0 +-@deffnx {} BFD_RELOC_TILEPRO_SHAMT_X1 +-@deffnx {} BFD_RELOC_TILEPRO_SHAMT_Y0 +-@deffnx {} BFD_RELOC_TILEPRO_SHAMT_Y1 +-@deffnx {} BFD_RELOC_TILEPRO_TLS_GD_CALL +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_X0_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_X1_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y0_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEPRO_IMM8_Y1_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEPRO_TLS_IE_LOAD +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_GD_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_GD_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_IE_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_IE_HA +-@deffnx {} BFD_RELOC_TILEPRO_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_TILEPRO_TLS_DTPOFF32 +-@deffnx {} BFD_RELOC_TILEPRO_TLS_TPOFF32 +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_LO +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HI +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X0_TLS_LE_HA +-@deffnx {} BFD_RELOC_TILEPRO_IMM16_X1_TLS_LE_HA +-Tilera TILEPro Relocations. +-@end deffn +-@deffn {} BFD_RELOC_TILEGX_HW0 +-@deffnx {} BFD_RELOC_TILEGX_HW1 +-@deffnx {} BFD_RELOC_TILEGX_HW2 +-@deffnx {} BFD_RELOC_TILEGX_HW3 +-@deffnx {} BFD_RELOC_TILEGX_HW0_LAST +-@deffnx {} BFD_RELOC_TILEGX_HW1_LAST +-@deffnx {} BFD_RELOC_TILEGX_HW2_LAST +-@deffnx {} BFD_RELOC_TILEGX_COPY +-@deffnx {} BFD_RELOC_TILEGX_GLOB_DAT +-@deffnx {} BFD_RELOC_TILEGX_JMP_SLOT +-@deffnx {} BFD_RELOC_TILEGX_RELATIVE +-@deffnx {} BFD_RELOC_TILEGX_BROFF_X1 +-@deffnx {} BFD_RELOC_TILEGX_JUMPOFF_X1 +-@deffnx {} BFD_RELOC_TILEGX_JUMPOFF_X1_PLT +-@deffnx {} BFD_RELOC_TILEGX_IMM8_X0 +-@deffnx {} BFD_RELOC_TILEGX_IMM8_Y0 +-@deffnx {} BFD_RELOC_TILEGX_IMM8_X1 +-@deffnx {} BFD_RELOC_TILEGX_IMM8_Y1 +-@deffnx {} BFD_RELOC_TILEGX_DEST_IMM8_X1 +-@deffnx {} BFD_RELOC_TILEGX_MT_IMM14_X1 +-@deffnx {} BFD_RELOC_TILEGX_MF_IMM14_X1 +-@deffnx {} BFD_RELOC_TILEGX_MMSTART_X0 +-@deffnx {} BFD_RELOC_TILEGX_MMEND_X0 +-@deffnx {} BFD_RELOC_TILEGX_SHAMT_X0 +-@deffnx {} BFD_RELOC_TILEGX_SHAMT_X1 +-@deffnx {} BFD_RELOC_TILEGX_SHAMT_Y0 +-@deffnx {} BFD_RELOC_TILEGX_SHAMT_Y1 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW3 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW3 +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW3_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW3_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_LE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_LE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_LE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_LE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_LE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_LE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE +-@deffnx {} BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE +-@deffnx {} BFD_RELOC_TILEGX_TLS_DTPMOD64 +-@deffnx {} BFD_RELOC_TILEGX_TLS_DTPOFF64 +-@deffnx {} BFD_RELOC_TILEGX_TLS_TPOFF64 +-@deffnx {} BFD_RELOC_TILEGX_TLS_DTPMOD32 +-@deffnx {} BFD_RELOC_TILEGX_TLS_DTPOFF32 +-@deffnx {} BFD_RELOC_TILEGX_TLS_TPOFF32 +-@deffnx {} BFD_RELOC_TILEGX_TLS_GD_CALL +-@deffnx {} BFD_RELOC_TILEGX_IMM8_X0_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_X1_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_Y0_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_Y1_TLS_GD_ADD +-@deffnx {} BFD_RELOC_TILEGX_TLS_IE_LOAD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_X0_TLS_ADD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_X1_TLS_ADD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_Y0_TLS_ADD +-@deffnx {} BFD_RELOC_TILEGX_IMM8_Y1_TLS_ADD +-Tilera TILE-Gx Relocations. +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_SIMM8 +-Adapteva EPIPHANY - 8 bit signed pc-relative displacement +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_SIMM24 +-Adapteva EPIPHANY - 24 bit signed pc-relative displacement +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_HIGH +-Adapteva EPIPHANY - 16 most-significant bits of absolute address +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_LOW +-Adapteva EPIPHANY - 16 least-significant bits of absolute address +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_SIMM11 +-Adapteva EPIPHANY - 11 bit signed number - add/sub immediate +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_IMM11 +-Adapteva EPIPHANY - 11 bit sign-magnitude number (ld/st displacement) +-@end deffn +-@deffn {} BFD_RELOC_EPIPHANY_IMM8 +-Adapteva EPIPHANY - 8 bit immediate for 16 bit mov instruction. +-@end deffn +- +-@example +- +-typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; +-@end example +-@findex bfd_reloc_type_lookup +-@subsubsection @code{bfd_reloc_type_lookup} +-@strong{Synopsis} +-@example +-reloc_howto_type *bfd_reloc_type_lookup +- (bfd *abfd, bfd_reloc_code_real_type code); +-reloc_howto_type *bfd_reloc_name_lookup +- (bfd *abfd, const char *reloc_name); +-@end example +-@strong{Description}@* +-Return a pointer to a howto structure which, when +-invoked, will perform the relocation @var{code} on data from the +-architecture noted. +- +-@findex bfd_default_reloc_type_lookup +-@subsubsection @code{bfd_default_reloc_type_lookup} +-@strong{Synopsis} +-@example +-reloc_howto_type *bfd_default_reloc_type_lookup +- (bfd *abfd, bfd_reloc_code_real_type code); +-@end example +-@strong{Description}@* +-Provides a default relocation lookup routine for any architecture. +- +-@findex bfd_get_reloc_code_name +-@subsubsection @code{bfd_get_reloc_code_name} +-@strong{Synopsis} +-@example +-const char *bfd_get_reloc_code_name (bfd_reloc_code_real_type code); +-@end example +-@strong{Description}@* +-Provides a printable name for the supplied relocation code. +-Useful mainly for printing error messages. +- +-@findex bfd_generic_relax_section +-@subsubsection @code{bfd_generic_relax_section} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_relax_section +- (bfd *abfd, +- asection *section, +- struct bfd_link_info *, +- bfd_boolean *); +-@end example +-@strong{Description}@* +-Provides default handling for relaxing for back ends which +-don't do relaxing. +- +-@findex bfd_generic_gc_sections +-@subsubsection @code{bfd_generic_gc_sections} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_gc_sections +- (bfd *, struct bfd_link_info *); +-@end example +-@strong{Description}@* +-Provides default handling for relaxing for back ends which +-don't do section gc -- i.e., does nothing. +- +-@findex bfd_generic_lookup_section_flags +-@subsubsection @code{bfd_generic_lookup_section_flags} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_lookup_section_flags +- (struct bfd_link_info *, struct flag_info *, asection *); +-@end example +-@strong{Description}@* +-Provides default handling for section flags lookup +--- i.e., does nothing. +-Returns FALSE if the section should be omitted, otherwise TRUE. +- +-@findex bfd_generic_merge_sections +-@subsubsection @code{bfd_generic_merge_sections} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_merge_sections +- (bfd *, struct bfd_link_info *); +-@end example +-@strong{Description}@* +-Provides default handling for SEC_MERGE section merging for back ends +-which don't have SEC_MERGE support -- i.e., does nothing. +- +-@findex bfd_generic_get_relocated_section_contents +-@subsubsection @code{bfd_generic_get_relocated_section_contents} +-@strong{Synopsis} +-@example +-bfd_byte *bfd_generic_get_relocated_section_contents +- (bfd *abfd, +- struct bfd_link_info *link_info, +- struct bfd_link_order *link_order, +- bfd_byte *data, +- bfd_boolean relocatable, +- asymbol **symbols); +-@end example +-@strong{Description}@* +-Provides default handling of relocation effort for back ends +-which can't be bothered to do it efficiently. +- +diff -Nur binutils-2.24.orig/bfd/doc/section.texi binutils-2.24/bfd/doc/section.texi +--- binutils-2.24.orig/bfd/doc/section.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/section.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1035 +0,0 @@ +-@section Sections +-The raw data contained within a BFD is maintained through the +-section abstraction. A single BFD may have any number of +-sections. It keeps hold of them by pointing to the first; +-each one points to the next in the list. +- +-Sections are supported in BFD in @code{section.c}. +- +-@menu +-* Section Input:: +-* Section Output:: +-* typedef asection:: +-* section prototypes:: +-@end menu +- +-@node Section Input, Section Output, Sections, Sections +-@subsection Section input +-When a BFD is opened for reading, the section structures are +-created and attached to the BFD. +- +-Each section has a name which describes the section in the +-outside world---for example, @code{a.out} would contain at least +-three sections, called @code{.text}, @code{.data} and @code{.bss}. +- +-Names need not be unique; for example a COFF file may have several +-sections named @code{.data}. +- +-Sometimes a BFD will contain more than the ``natural'' number of +-sections. A back end may attach other sections containing +-constructor data, or an application may add a section (using +-@code{bfd_make_section}) to the sections attached to an already open +-BFD. For example, the linker creates an extra section +-@code{COMMON} for each input file's BFD to hold information about +-common storage. +- +-The raw data is not necessarily read in when +-the section descriptor is created. Some targets may leave the +-data in place until a @code{bfd_get_section_contents} call is +-made. Other back ends may read in all the data at once. For +-example, an S-record file has to be read once to determine the +-size of the data. An IEEE-695 file doesn't contain raw data in +-sections, but data and relocation expressions intermixed, so +-the data area has to be parsed to get out the data and +-relocations. +- +-@node Section Output, typedef asection, Section Input, Sections +-@subsection Section output +-To write a new object style BFD, the various sections to be +-written have to be created. They are attached to the BFD in +-the same way as input sections; data is written to the +-sections using @code{bfd_set_section_contents}. +- +-Any program that creates or combines sections (e.g., the assembler +-and linker) must use the @code{asection} fields @code{output_section} and +-@code{output_offset} to indicate the file sections to which each +-section must be written. (If the section is being created from +-scratch, @code{output_section} should probably point to the section +-itself and @code{output_offset} should probably be zero.) +- +-The data to be written comes from input sections attached +-(via @code{output_section} pointers) to +-the output sections. The output section structure can be +-considered a filter for the input section: the output section +-determines the vma of the output data and the name, but the +-input section determines the offset into the output section of +-the data to be written. +- +-E.g., to create a section "O", starting at 0x100, 0x123 long, +-containing two subsections, "A" at offset 0x0 (i.e., at vma +-0x100) and "B" at offset 0x20 (i.e., at vma 0x120) the @code{asection} +-structures would look like: +- +-@example +- section name "A" +- output_offset 0x00 +- size 0x20 +- output_section -----------> section name "O" +- | vma 0x100 +- section name "B" | size 0x123 +- output_offset 0x20 | +- size 0x103 | +- output_section --------| +-@end example +- +-@subsection Link orders +-The data within a section is stored in a @dfn{link_order}. +-These are much like the fixups in @code{gas}. The link_order +-abstraction allows a section to grow and shrink within itself. +- +-A link_order knows how big it is, and which is the next +-link_order and where the raw data for it is; it also points to +-a list of relocations which apply to it. +- +-The link_order is used by the linker to perform relaxing on +-final code. The compiler creates code which is as big as +-necessary to make it work without relaxing, and the user can +-select whether to relax. Sometimes relaxing takes a lot of +-time. The linker runs around the relocations to see if any +-are attached to data which can be shrunk, if so it does it on +-a link_order by link_order basis. +- +- +-@node typedef asection, section prototypes, Section Output, Sections +-@subsection typedef asection +-Here is the section structure: +- +- +-@example +- +-typedef struct bfd_section +-@{ +- /* The name of the section; the name isn't a copy, the pointer is +- the same as that passed to bfd_make_section. */ +- const char *name; +- +- /* A unique sequence number. */ +- int id; +- +- /* Which section in the bfd; 0..n-1 as sections are created in a bfd. */ +- int index; +- +- /* The next section in the list belonging to the BFD, or NULL. */ +- struct bfd_section *next; +- +- /* The previous section in the list belonging to the BFD, or NULL. */ +- struct bfd_section *prev; +- +- /* The field flags contains attributes of the section. Some +- flags are read in from the object file, and some are +- synthesized from other information. */ +- flagword flags; +- +-#define SEC_NO_FLAGS 0x000 +- +- /* Tells the OS to allocate space for this section when loading. +- This is clear for a section containing debug information only. */ +-#define SEC_ALLOC 0x001 +- +- /* Tells the OS to load the section from the file when loading. +- This is clear for a .bss section. */ +-#define SEC_LOAD 0x002 +- +- /* The section contains data still to be relocated, so there is +- some relocation information too. */ +-#define SEC_RELOC 0x004 +- +- /* A signal to the OS that the section contains read only data. */ +-#define SEC_READONLY 0x008 +- +- /* The section contains code only. */ +-#define SEC_CODE 0x010 +- +- /* The section contains data only. */ +-#define SEC_DATA 0x020 +- +- /* The section will reside in ROM. */ +-#define SEC_ROM 0x040 +- +- /* The section contains constructor information. This section +- type is used by the linker to create lists of constructors and +- destructors used by @code{g++}. When a back end sees a symbol +- which should be used in a constructor list, it creates a new +- section for the type of name (e.g., @code{__CTOR_LIST__}), attaches +- the symbol to it, and builds a relocation. To build the lists +- of constructors, all the linker has to do is catenate all the +- sections called @code{__CTOR_LIST__} and relocate the data +- contained within - exactly the operations it would peform on +- standard data. */ +-#define SEC_CONSTRUCTOR 0x080 +- +- /* The section has contents - a data section could be +- @code{SEC_ALLOC} | @code{SEC_HAS_CONTENTS}; a debug section could be +- @code{SEC_HAS_CONTENTS} */ +-#define SEC_HAS_CONTENTS 0x100 +- +- /* An instruction to the linker to not output the section +- even if it has information which would normally be written. */ +-#define SEC_NEVER_LOAD 0x200 +- +- /* The section contains thread local data. */ +-#define SEC_THREAD_LOCAL 0x400 +- +- /* The section has GOT references. This flag is only for the +- linker, and is currently only used by the elf32-hppa back end. +- It will be set if global offset table references were detected +- in this section, which indicate to the linker that the section +- contains PIC code, and must be handled specially when doing a +- static link. */ +-#define SEC_HAS_GOT_REF 0x800 +- +- /* The section contains common symbols (symbols may be defined +- multiple times, the value of a symbol is the amount of +- space it requires, and the largest symbol value is the one +- used). Most targets have exactly one of these (which we +- translate to bfd_com_section_ptr), but ECOFF has two. */ +-#define SEC_IS_COMMON 0x1000 +- +- /* The section contains only debugging information. For +- example, this is set for ELF .debug and .stab sections. +- strip tests this flag to see if a section can be +- discarded. */ +-#define SEC_DEBUGGING 0x2000 +- +- /* The contents of this section are held in memory pointed to +- by the contents field. This is checked by bfd_get_section_contents, +- and the data is retrieved from memory if appropriate. */ +-#define SEC_IN_MEMORY 0x4000 +- +- /* The contents of this section are to be excluded by the +- linker for executable and shared objects unless those +- objects are to be further relocated. */ +-#define SEC_EXCLUDE 0x8000 +- +- /* The contents of this section are to be sorted based on the sum of +- the symbol and addend values specified by the associated relocation +- entries. Entries without associated relocation entries will be +- appended to the end of the section in an unspecified order. */ +-#define SEC_SORT_ENTRIES 0x10000 +- +- /* When linking, duplicate sections of the same name should be +- discarded, rather than being combined into a single section as +- is usually done. This is similar to how common symbols are +- handled. See SEC_LINK_DUPLICATES below. */ +-#define SEC_LINK_ONCE 0x20000 +- +- /* If SEC_LINK_ONCE is set, this bitfield describes how the linker +- should handle duplicate sections. */ +-#define SEC_LINK_DUPLICATES 0xc0000 +- +- /* This value for SEC_LINK_DUPLICATES means that duplicate +- sections with the same name should simply be discarded. */ +-#define SEC_LINK_DUPLICATES_DISCARD 0x0 +- +- /* This value for SEC_LINK_DUPLICATES means that the linker +- should warn if there are any duplicate sections, although +- it should still only link one copy. */ +-#define SEC_LINK_DUPLICATES_ONE_ONLY 0x40000 +- +- /* This value for SEC_LINK_DUPLICATES means that the linker +- should warn if any duplicate sections are a different size. */ +-#define SEC_LINK_DUPLICATES_SAME_SIZE 0x80000 +- +- /* This value for SEC_LINK_DUPLICATES means that the linker +- should warn if any duplicate sections contain different +- contents. */ +-#define SEC_LINK_DUPLICATES_SAME_CONTENTS \ +- (SEC_LINK_DUPLICATES_ONE_ONLY | SEC_LINK_DUPLICATES_SAME_SIZE) +- +- /* This section was created by the linker as part of dynamic +- relocation or other arcane processing. It is skipped when +- going through the first-pass output, trusting that someone +- else up the line will take care of it later. */ +-#define SEC_LINKER_CREATED 0x100000 +- +- /* This section should not be subject to garbage collection. +- Also set to inform the linker that this section should not be +- listed in the link map as discarded. */ +-#define SEC_KEEP 0x200000 +- +- /* This section contains "short" data, and should be placed +- "near" the GP. */ +-#define SEC_SMALL_DATA 0x400000 +- +- /* Attempt to merge identical entities in the section. +- Entity size is given in the entsize field. */ +-#define SEC_MERGE 0x800000 +- +- /* If given with SEC_MERGE, entities to merge are zero terminated +- strings where entsize specifies character size instead of fixed +- size entries. */ +-#define SEC_STRINGS 0x1000000 +- +- /* This section contains data about section groups. */ +-#define SEC_GROUP 0x2000000 +- +- /* The section is a COFF shared library section. This flag is +- only for the linker. If this type of section appears in +- the input file, the linker must copy it to the output file +- without changing the vma or size. FIXME: Although this +- was originally intended to be general, it really is COFF +- specific (and the flag was renamed to indicate this). It +- might be cleaner to have some more general mechanism to +- allow the back end to control what the linker does with +- sections. */ +-#define SEC_COFF_SHARED_LIBRARY 0x4000000 +- +- /* This input section should be copied to output in reverse order +- as an array of pointers. This is for ELF linker internal use +- only. */ +-#define SEC_ELF_REVERSE_COPY 0x4000000 +- +- /* This section contains data which may be shared with other +- executables or shared objects. This is for COFF only. */ +-#define SEC_COFF_SHARED 0x8000000 +- +- /* When a section with this flag is being linked, then if the size of +- the input section is less than a page, it should not cross a page +- boundary. If the size of the input section is one page or more, +- it should be aligned on a page boundary. This is for TI +- TMS320C54X only. */ +-#define SEC_TIC54X_BLOCK 0x10000000 +- +- /* Conditionally link this section; do not link if there are no +- references found to any symbol in the section. This is for TI +- TMS320C54X only. */ +-#define SEC_TIC54X_CLINK 0x20000000 +- +- /* Indicate that section has the no read flag set. This happens +- when memory read flag isn't set. */ +-#define SEC_COFF_NOREAD 0x40000000 +- +- /* End of section flags. */ +- +- /* Some internal packed boolean fields. */ +- +- /* See the vma field. */ +- unsigned int user_set_vma : 1; +- +- /* A mark flag used by some of the linker backends. */ +- unsigned int linker_mark : 1; +- +- /* Another mark flag used by some of the linker backends. Set for +- output sections that have an input section. */ +- unsigned int linker_has_input : 1; +- +- /* Mark flag used by some linker backends for garbage collection. */ +- unsigned int gc_mark : 1; +- +- /* Section compression status. */ +- unsigned int compress_status : 2; +-#define COMPRESS_SECTION_NONE 0 +-#define COMPRESS_SECTION_DONE 1 +-#define DECOMPRESS_SECTION_SIZED 2 +- +- /* The following flags are used by the ELF linker. */ +- +- /* Mark sections which have been allocated to segments. */ +- unsigned int segment_mark : 1; +- +- /* Type of sec_info information. */ +- unsigned int sec_info_type:3; +-#define SEC_INFO_TYPE_NONE 0 +-#define SEC_INFO_TYPE_STABS 1 +-#define SEC_INFO_TYPE_MERGE 2 +-#define SEC_INFO_TYPE_EH_FRAME 3 +-#define SEC_INFO_TYPE_JUST_SYMS 4 +- +- /* Nonzero if this section uses RELA relocations, rather than REL. */ +- unsigned int use_rela_p:1; +- +- /* Bits used by various backends. The generic code doesn't touch +- these fields. */ +- +- unsigned int sec_flg0:1; +- unsigned int sec_flg1:1; +- unsigned int sec_flg2:1; +- unsigned int sec_flg3:1; +- unsigned int sec_flg4:1; +- unsigned int sec_flg5:1; +- +- /* End of internal packed boolean fields. */ +- +- /* The virtual memory address of the section - where it will be +- at run time. The symbols are relocated against this. The +- user_set_vma flag is maintained by bfd; if it's not set, the +- backend can assign addresses (for example, in @code{a.out}, where +- the default address for @code{.data} is dependent on the specific +- target and various flags). */ +- bfd_vma vma; +- +- /* The load address of the section - where it would be in a +- rom image; really only used for writing section header +- information. */ +- bfd_vma lma; +- +- /* The size of the section in octets, as it will be output. +- Contains a value even if the section has no contents (e.g., the +- size of @code{.bss}). */ +- bfd_size_type size; +- +- /* For input sections, the original size on disk of the section, in +- octets. This field should be set for any section whose size is +- changed by linker relaxation. It is required for sections where +- the linker relaxation scheme doesn't cache altered section and +- reloc contents (stabs, eh_frame, SEC_MERGE, some coff relaxing +- targets), and thus the original size needs to be kept to read the +- section multiple times. For output sections, rawsize holds the +- section size calculated on a previous linker relaxation pass. */ +- bfd_size_type rawsize; +- +- /* The compressed size of the section in octets. */ +- bfd_size_type compressed_size; +- +- /* Relaxation table. */ +- struct relax_table *relax; +- +- /* Count of used relaxation table entries. */ +- int relax_count; +- +- +- /* If this section is going to be output, then this value is the +- offset in *bytes* into the output section of the first byte in the +- input section (byte ==> smallest addressable unit on the +- target). In most cases, if this was going to start at the +- 100th octet (8-bit quantity) in the output section, this value +- would be 100. However, if the target byte size is 16 bits +- (bfd_octets_per_byte is "2"), this value would be 50. */ +- bfd_vma output_offset; +- +- /* The output section through which to map on output. */ +- struct bfd_section *output_section; +- +- /* The alignment requirement of the section, as an exponent of 2 - +- e.g., 3 aligns to 2^3 (or 8). */ +- unsigned int alignment_power; +- +- /* If an input section, a pointer to a vector of relocation +- records for the data in this section. */ +- struct reloc_cache_entry *relocation; +- +- /* If an output section, a pointer to a vector of pointers to +- relocation records for the data in this section. */ +- struct reloc_cache_entry **orelocation; +- +- /* The number of relocation records in one of the above. */ +- unsigned reloc_count; +- +- /* Information below is back end specific - and not always used +- or updated. */ +- +- /* File position of section data. */ +- file_ptr filepos; +- +- /* File position of relocation info. */ +- file_ptr rel_filepos; +- +- /* File position of line data. */ +- file_ptr line_filepos; +- +- /* Pointer to data for applications. */ +- void *userdata; +- +- /* If the SEC_IN_MEMORY flag is set, this points to the actual +- contents. */ +- unsigned char *contents; +- +- /* Attached line number information. */ +- alent *lineno; +- +- /* Number of line number records. */ +- unsigned int lineno_count; +- +- /* Entity size for merging purposes. */ +- unsigned int entsize; +- +- /* Points to the kept section if this section is a link-once section, +- and is discarded. */ +- struct bfd_section *kept_section; +- +- /* When a section is being output, this value changes as more +- linenumbers are written out. */ +- file_ptr moving_line_filepos; +- +- /* What the section number is in the target world. */ +- int target_index; +- +- void *used_by_bfd; +- +- /* If this is a constructor section then here is a list of the +- relocations created to relocate items within it. */ +- struct relent_chain *constructor_chain; +- +- /* The BFD which owns the section. */ +- bfd *owner; +- +- /* A symbol which points at this section only. */ +- struct bfd_symbol *symbol; +- struct bfd_symbol **symbol_ptr_ptr; +- +- /* Early in the link process, map_head and map_tail are used to build +- a list of input sections attached to an output section. Later, +- output sections use these fields for a list of bfd_link_order +- structs. */ +- union @{ +- struct bfd_link_order *link_order; +- struct bfd_section *s; +- @} map_head, map_tail; +-@} asection; +- +-/* Relax table contains information about instructions which can +- be removed by relaxation -- replacing a long address with a +- short address. */ +-struct relax_table @{ +- /* Address where bytes may be deleted. */ +- bfd_vma addr; +- +- /* Number of bytes to be deleted. */ +- int size; +-@}; +- +-/* These sections are global, and are managed by BFD. The application +- and target back end are not permitted to change the values in +- these sections. */ +-extern asection _bfd_std_section[4]; +- +-#define BFD_ABS_SECTION_NAME "*ABS*" +-#define BFD_UND_SECTION_NAME "*UND*" +-#define BFD_COM_SECTION_NAME "*COM*" +-#define BFD_IND_SECTION_NAME "*IND*" +- +-/* Pointer to the common section. */ +-#define bfd_com_section_ptr (&_bfd_std_section[0]) +-/* Pointer to the undefined section. */ +-#define bfd_und_section_ptr (&_bfd_std_section[1]) +-/* Pointer to the absolute section. */ +-#define bfd_abs_section_ptr (&_bfd_std_section[2]) +-/* Pointer to the indirect section. */ +-#define bfd_ind_section_ptr (&_bfd_std_section[3]) +- +-#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) +-#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) +-#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) +- +-#define bfd_is_const_section(SEC) \ +- ( ((SEC) == bfd_abs_section_ptr) \ +- || ((SEC) == bfd_und_section_ptr) \ +- || ((SEC) == bfd_com_section_ptr) \ +- || ((SEC) == bfd_ind_section_ptr)) +- +-/* Macros to handle insertion and deletion of a bfd's sections. These +- only handle the list pointers, ie. do not adjust section_count, +- target_index etc. */ +-#define bfd_section_list_remove(ABFD, S) \ +- do \ +- @{ \ +- asection *_s = S; \ +- asection *_next = _s->next; \ +- asection *_prev = _s->prev; \ +- if (_prev) \ +- _prev->next = _next; \ +- else \ +- (ABFD)->sections = _next; \ +- if (_next) \ +- _next->prev = _prev; \ +- else \ +- (ABFD)->section_last = _prev; \ +- @} \ +- while (0) +-#define bfd_section_list_append(ABFD, S) \ +- do \ +- @{ \ +- asection *_s = S; \ +- bfd *_abfd = ABFD; \ +- _s->next = NULL; \ +- if (_abfd->section_last) \ +- @{ \ +- _s->prev = _abfd->section_last; \ +- _abfd->section_last->next = _s; \ +- @} \ +- else \ +- @{ \ +- _s->prev = NULL; \ +- _abfd->sections = _s; \ +- @} \ +- _abfd->section_last = _s; \ +- @} \ +- while (0) +-#define bfd_section_list_prepend(ABFD, S) \ +- do \ +- @{ \ +- asection *_s = S; \ +- bfd *_abfd = ABFD; \ +- _s->prev = NULL; \ +- if (_abfd->sections) \ +- @{ \ +- _s->next = _abfd->sections; \ +- _abfd->sections->prev = _s; \ +- @} \ +- else \ +- @{ \ +- _s->next = NULL; \ +- _abfd->section_last = _s; \ +- @} \ +- _abfd->sections = _s; \ +- @} \ +- while (0) +-#define bfd_section_list_insert_after(ABFD, A, S) \ +- do \ +- @{ \ +- asection *_a = A; \ +- asection *_s = S; \ +- asection *_next = _a->next; \ +- _s->next = _next; \ +- _s->prev = _a; \ +- _a->next = _s; \ +- if (_next) \ +- _next->prev = _s; \ +- else \ +- (ABFD)->section_last = _s; \ +- @} \ +- while (0) +-#define bfd_section_list_insert_before(ABFD, B, S) \ +- do \ +- @{ \ +- asection *_b = B; \ +- asection *_s = S; \ +- asection *_prev = _b->prev; \ +- _s->prev = _prev; \ +- _s->next = _b; \ +- _b->prev = _s; \ +- if (_prev) \ +- _prev->next = _s; \ +- else \ +- (ABFD)->sections = _s; \ +- @} \ +- while (0) +-#define bfd_section_removed_from_list(ABFD, S) \ +- ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) +- +-#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ +- /* name, id, index, next, prev, flags, user_set_vma, */ \ +- @{ NAME, IDX, 0, NULL, NULL, FLAGS, 0, \ +- \ +- /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \ +- 0, 0, 1, 0, \ +- \ +- /* segment_mark, sec_info_type, use_rela_p, */ \ +- 0, 0, 0, \ +- \ +- /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \ +- 0, 0, 0, 0, 0, 0, \ +- \ +- /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ \ +- 0, 0, 0, 0, 0, 0, 0, \ +- \ +- /* output_offset, output_section, alignment_power, */ \ +- 0, &SEC, 0, \ +- \ +- /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ +- NULL, NULL, 0, 0, 0, \ +- \ +- /* line_filepos, userdata, contents, lineno, lineno_count, */ \ +- 0, NULL, NULL, NULL, 0, \ +- \ +- /* entsize, kept_section, moving_line_filepos, */ \ +- 0, NULL, 0, \ +- \ +- /* target_index, used_by_bfd, constructor_chain, owner, */ \ +- 0, NULL, NULL, NULL, \ +- \ +- /* symbol, symbol_ptr_ptr, */ \ +- (struct bfd_symbol *) SYM, &SEC.symbol, \ +- \ +- /* map_head, map_tail */ \ +- @{ NULL @}, @{ NULL @} \ +- @} +- +-@end example +- +-@node section prototypes, , typedef asection, Sections +-@subsection Section prototypes +-These are the functions exported by the section handling part of BFD. +- +-@findex bfd_section_list_clear +-@subsubsection @code{bfd_section_list_clear} +-@strong{Synopsis} +-@example +-void bfd_section_list_clear (bfd *); +-@end example +-@strong{Description}@* +-Clears the section list, and also resets the section count and +-hash table entries. +- +-@findex bfd_get_section_by_name +-@subsubsection @code{bfd_get_section_by_name} +-@strong{Synopsis} +-@example +-asection *bfd_get_section_by_name (bfd *abfd, const char *name); +-@end example +-@strong{Description}@* +-Return the most recently created section attached to @var{abfd} +-named @var{name}. Return NULL if no such section exists. +- +-@findex bfd_get_next_section_by_name +-@subsubsection @code{bfd_get_next_section_by_name} +-@strong{Synopsis} +-@example +-asection *bfd_get_next_section_by_name (asection *sec); +-@end example +-@strong{Description}@* +-Given @var{sec} is a section returned by @code{bfd_get_section_by_name}, +-return the next most recently created section attached to the same +-BFD with the same name. Return NULL if no such section exists. +- +-@findex bfd_get_linker_section +-@subsubsection @code{bfd_get_linker_section} +-@strong{Synopsis} +-@example +-asection *bfd_get_linker_section (bfd *abfd, const char *name); +-@end example +-@strong{Description}@* +-Return the linker created section attached to @var{abfd} +-named @var{name}. Return NULL if no such section exists. +- +-@findex bfd_get_section_by_name_if +-@subsubsection @code{bfd_get_section_by_name_if} +-@strong{Synopsis} +-@example +-asection *bfd_get_section_by_name_if +- (bfd *abfd, +- const char *name, +- bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), +- void *obj); +-@end example +-@strong{Description}@* +-Call the provided function @var{func} for each section +-attached to the BFD @var{abfd} whose name matches @var{name}, +-passing @var{obj} as an argument. The function will be called +-as if by +- +-@example +- func (abfd, the_section, obj); +-@end example +- +-It returns the first section for which @var{func} returns true, +-otherwise @code{NULL}. +- +-@findex bfd_get_unique_section_name +-@subsubsection @code{bfd_get_unique_section_name} +-@strong{Synopsis} +-@example +-char *bfd_get_unique_section_name +- (bfd *abfd, const char *templat, int *count); +-@end example +-@strong{Description}@* +-Invent a section name that is unique in @var{abfd} by tacking +-a dot and a digit suffix onto the original @var{templat}. If +-@var{count} is non-NULL, then it specifies the first number +-tried as a suffix to generate a unique name. The value +-pointed to by @var{count} will be incremented in this case. +- +-@findex bfd_make_section_old_way +-@subsubsection @code{bfd_make_section_old_way} +-@strong{Synopsis} +-@example +-asection *bfd_make_section_old_way (bfd *abfd, const char *name); +-@end example +-@strong{Description}@* +-Create a new empty section called @var{name} +-and attach it to the end of the chain of sections for the +-BFD @var{abfd}. An attempt to create a section with a name which +-is already in use returns its pointer without changing the +-section chain. +- +-It has the funny name since this is the way it used to be +-before it was rewritten.... +- +-Possible errors are: +-@itemize @bullet +- +-@item +-@code{bfd_error_invalid_operation} - +-If output has already started for this BFD. +-@item +-@code{bfd_error_no_memory} - +-If memory allocation fails. +-@end itemize +- +-@findex bfd_make_section_anyway_with_flags +-@subsubsection @code{bfd_make_section_anyway_with_flags} +-@strong{Synopsis} +-@example +-asection *bfd_make_section_anyway_with_flags +- (bfd *abfd, const char *name, flagword flags); +-@end example +-@strong{Description}@* +-Create a new empty section called @var{name} and attach it to the end of +-the chain of sections for @var{abfd}. Create a new section even if there +-is already a section with that name. Also set the attributes of the +-new section to the value @var{flags}. +- +-Return @code{NULL} and set @code{bfd_error} on error; possible errors are: +-@itemize @bullet +- +-@item +-@code{bfd_error_invalid_operation} - If output has already started for @var{abfd}. +-@item +-@code{bfd_error_no_memory} - If memory allocation fails. +-@end itemize +- +-@findex bfd_make_section_anyway +-@subsubsection @code{bfd_make_section_anyway} +-@strong{Synopsis} +-@example +-asection *bfd_make_section_anyway (bfd *abfd, const char *name); +-@end example +-@strong{Description}@* +-Create a new empty section called @var{name} and attach it to the end of +-the chain of sections for @var{abfd}. Create a new section even if there +-is already a section with that name. +- +-Return @code{NULL} and set @code{bfd_error} on error; possible errors are: +-@itemize @bullet +- +-@item +-@code{bfd_error_invalid_operation} - If output has already started for @var{abfd}. +-@item +-@code{bfd_error_no_memory} - If memory allocation fails. +-@end itemize +- +-@findex bfd_make_section_with_flags +-@subsubsection @code{bfd_make_section_with_flags} +-@strong{Synopsis} +-@example +-asection *bfd_make_section_with_flags +- (bfd *, const char *name, flagword flags); +-@end example +-@strong{Description}@* +-Like @code{bfd_make_section_anyway}, but return @code{NULL} (without calling +-bfd_set_error ()) without changing the section chain if there is already a +-section named @var{name}. Also set the attributes of the new section to +-the value @var{flags}. If there is an error, return @code{NULL} and set +-@code{bfd_error}. +- +-@findex bfd_make_section +-@subsubsection @code{bfd_make_section} +-@strong{Synopsis} +-@example +-asection *bfd_make_section (bfd *, const char *name); +-@end example +-@strong{Description}@* +-Like @code{bfd_make_section_anyway}, but return @code{NULL} (without calling +-bfd_set_error ()) without changing the section chain if there is already a +-section named @var{name}. If there is an error, return @code{NULL} and set +-@code{bfd_error}. +- +-@findex bfd_set_section_flags +-@subsubsection @code{bfd_set_section_flags} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_section_flags +- (bfd *abfd, asection *sec, flagword flags); +-@end example +-@strong{Description}@* +-Set the attributes of the section @var{sec} in the BFD +-@var{abfd} to the value @var{flags}. Return @code{TRUE} on success, +-@code{FALSE} on error. Possible error returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_invalid_operation} - +-The section cannot have one or more of the attributes +-requested. For example, a .bss section in @code{a.out} may not +-have the @code{SEC_HAS_CONTENTS} field set. +-@end itemize +- +-@findex bfd_rename_section +-@subsubsection @code{bfd_rename_section} +-@strong{Synopsis} +-@example +-void bfd_rename_section +- (bfd *abfd, asection *sec, const char *newname); +-@end example +-@strong{Description}@* +-Rename section @var{sec} in @var{abfd} to @var{newname}. +- +-@findex bfd_map_over_sections +-@subsubsection @code{bfd_map_over_sections} +-@strong{Synopsis} +-@example +-void bfd_map_over_sections +- (bfd *abfd, +- void (*func) (bfd *abfd, asection *sect, void *obj), +- void *obj); +-@end example +-@strong{Description}@* +-Call the provided function @var{func} for each section +-attached to the BFD @var{abfd}, passing @var{obj} as an +-argument. The function will be called as if by +- +-@example +- func (abfd, the_section, obj); +-@end example +- +-This is the preferred method for iterating over sections; an +-alternative would be to use a loop: +- +-@example +- asection *p; +- for (p = abfd->sections; p != NULL; p = p->next) +- func (abfd, p, ...) +-@end example +- +-@findex bfd_sections_find_if +-@subsubsection @code{bfd_sections_find_if} +-@strong{Synopsis} +-@example +-asection *bfd_sections_find_if +- (bfd *abfd, +- bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), +- void *obj); +-@end example +-@strong{Description}@* +-Call the provided function @var{operation} for each section +-attached to the BFD @var{abfd}, passing @var{obj} as an +-argument. The function will be called as if by +- +-@example +- operation (abfd, the_section, obj); +-@end example +- +-It returns the first section for which @var{operation} returns true. +- +-@findex bfd_set_section_size +-@subsubsection @code{bfd_set_section_size} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_section_size +- (bfd *abfd, asection *sec, bfd_size_type val); +-@end example +-@strong{Description}@* +-Set @var{sec} to the size @var{val}. If the operation is +-ok, then @code{TRUE} is returned, else @code{FALSE}. +- +-Possible error returns: +-@itemize @bullet +- +-@item +-@code{bfd_error_invalid_operation} - +-Writing has started to the BFD, so setting the size is invalid. +-@end itemize +- +-@findex bfd_set_section_contents +-@subsubsection @code{bfd_set_section_contents} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_section_contents +- (bfd *abfd, asection *section, const void *data, +- file_ptr offset, bfd_size_type count); +-@end example +-@strong{Description}@* +-Sets the contents of the section @var{section} in BFD +-@var{abfd} to the data starting in memory at @var{data}. The +-data is written to the output section starting at offset +-@var{offset} for @var{count} octets. +- +-Normally @code{TRUE} is returned, else @code{FALSE}. Possible error +-returns are: +-@itemize @bullet +- +-@item +-@code{bfd_error_no_contents} - +-The output section does not have the @code{SEC_HAS_CONTENTS} +-attribute, so nothing can be written to it. +-@item +-and some more too +-@end itemize +-This routine is front end to the back end function +-@code{_bfd_set_section_contents}. +- +-@findex bfd_get_section_contents +-@subsubsection @code{bfd_get_section_contents} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_get_section_contents +- (bfd *abfd, asection *section, void *location, file_ptr offset, +- bfd_size_type count); +-@end example +-@strong{Description}@* +-Read data from @var{section} in BFD @var{abfd} +-into memory starting at @var{location}. The data is read at an +-offset of @var{offset} from the start of the input section, +-and is read for @var{count} bytes. +- +-If the contents of a constructor with the @code{SEC_CONSTRUCTOR} +-flag set are requested or if the section does not have the +-@code{SEC_HAS_CONTENTS} flag set, then the @var{location} is filled +-with zeroes. If no errors occur, @code{TRUE} is returned, else +-@code{FALSE}. +- +-@findex bfd_malloc_and_get_section +-@subsubsection @code{bfd_malloc_and_get_section} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_malloc_and_get_section +- (bfd *abfd, asection *section, bfd_byte **buf); +-@end example +-@strong{Description}@* +-Read all data from @var{section} in BFD @var{abfd} +-into a buffer, *@var{buf}, malloc'd by this function. +- +-@findex bfd_copy_private_section_data +-@subsubsection @code{bfd_copy_private_section_data} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_copy_private_section_data +- (bfd *ibfd, asection *isec, bfd *obfd, asection *osec); +-@end example +-@strong{Description}@* +-Copy private section information from @var{isec} in the BFD +-@var{ibfd} to the section @var{osec} in the BFD @var{obfd}. +-Return @code{TRUE} on success, @code{FALSE} on error. Possible error +-returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_no_memory} - +-Not enough memory exists to create private data for @var{osec}. +-@end itemize +-@example +-#define bfd_copy_private_section_data(ibfd, isection, obfd, osection) \ +- BFD_SEND (obfd, _bfd_copy_private_section_data, \ +- (ibfd, isection, obfd, osection)) +-@end example +- +-@findex bfd_generic_is_group_section +-@subsubsection @code{bfd_generic_is_group_section} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); +-@end example +-@strong{Description}@* +-Returns TRUE if @var{sec} is a member of a group. +- +-@findex bfd_generic_discard_group +-@subsubsection @code{bfd_generic_discard_group} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group); +-@end example +-@strong{Description}@* +-Remove all members of @var{group} from the output. +- +diff -Nur binutils-2.24.orig/bfd/doc/syms.texi binutils-2.24/bfd/doc/syms.texi +--- binutils-2.24.orig/bfd/doc/syms.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/syms.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,480 +0,0 @@ +-@section Symbols +-BFD tries to maintain as much symbol information as it can when +-it moves information from file to file. BFD passes information +-to applications though the @code{asymbol} structure. When the +-application requests the symbol table, BFD reads the table in +-the native form and translates parts of it into the internal +-format. To maintain more than the information passed to +-applications, some targets keep some information ``behind the +-scenes'' in a structure only the particular back end knows +-about. For example, the coff back end keeps the original +-symbol table structure as well as the canonical structure when +-a BFD is read in. On output, the coff back end can reconstruct +-the output symbol table so that no information is lost, even +-information unique to coff which BFD doesn't know or +-understand. If a coff symbol table were read, but were written +-through an a.out back end, all the coff specific information +-would be lost. The symbol table of a BFD +-is not necessarily read in until a canonicalize request is +-made. Then the BFD back end fills in a table provided by the +-application with pointers to the canonical information. To +-output symbols, the application provides BFD with a table of +-pointers to pointers to @code{asymbol}s. This allows applications +-like the linker to output a symbol as it was read, since the ``behind +-the scenes'' information will be still available. +-@menu +-* Reading Symbols:: +-* Writing Symbols:: +-* Mini Symbols:: +-* typedef asymbol:: +-* symbol handling functions:: +-@end menu +- +-@node Reading Symbols, Writing Symbols, Symbols, Symbols +-@subsection Reading symbols +-There are two stages to reading a symbol table from a BFD: +-allocating storage, and the actual reading process. This is an +-excerpt from an application which reads the symbol table: +- +-@example +- long storage_needed; +- asymbol **symbol_table; +- long number_of_symbols; +- long i; +- +- storage_needed = bfd_get_symtab_upper_bound (abfd); +- +- if (storage_needed < 0) +- FAIL +- +- if (storage_needed == 0) +- return; +- +- symbol_table = xmalloc (storage_needed); +- ... +- number_of_symbols = +- bfd_canonicalize_symtab (abfd, symbol_table); +- +- if (number_of_symbols < 0) +- FAIL +- +- for (i = 0; i < number_of_symbols; i++) +- process_symbol (symbol_table[i]); +-@end example +- +-All storage for the symbols themselves is in an objalloc +-connected to the BFD; it is freed when the BFD is closed. +- +-@node Writing Symbols, Mini Symbols, Reading Symbols, Symbols +-@subsection Writing symbols +-Writing of a symbol table is automatic when a BFD open for +-writing is closed. The application attaches a vector of +-pointers to pointers to symbols to the BFD being written, and +-fills in the symbol count. The close and cleanup code reads +-through the table provided and performs all the necessary +-operations. The BFD output code must always be provided with an +-``owned'' symbol: one which has come from another BFD, or one +-which has been created using @code{bfd_make_empty_symbol}. Here is an +-example showing the creation of a symbol table with only one element: +- +-@example +- #include "sysdep.h" +- #include "bfd.h" +- int main (void) +- @{ +- bfd *abfd; +- asymbol *ptrs[2]; +- asymbol *new; +- +- abfd = bfd_openw ("foo","a.out-sunos-big"); +- bfd_set_format (abfd, bfd_object); +- new = bfd_make_empty_symbol (abfd); +- new->name = "dummy_symbol"; +- new->section = bfd_make_section_old_way (abfd, ".text"); +- new->flags = BSF_GLOBAL; +- new->value = 0x12345; +- +- ptrs[0] = new; +- ptrs[1] = 0; +- +- bfd_set_symtab (abfd, ptrs, 1); +- bfd_close (abfd); +- return 0; +- @} +- +- ./makesym +- nm foo +- 00012345 A dummy_symbol +-@end example +- +-Many formats cannot represent arbitrary symbol information; for +-instance, the @code{a.out} object format does not allow an +-arbitrary number of sections. A symbol pointing to a section +-which is not one of @code{.text}, @code{.data} or @code{.bss} cannot +-be described. +- +-@node Mini Symbols, typedef asymbol, Writing Symbols, Symbols +-@subsection Mini Symbols +-Mini symbols provide read-only access to the symbol table. +-They use less memory space, but require more time to access. +-They can be useful for tools like nm or objdump, which may +-have to handle symbol tables of extremely large executables. +- +-The @code{bfd_read_minisymbols} function will read the symbols +-into memory in an internal form. It will return a @code{void *} +-pointer to a block of memory, a symbol count, and the size of +-each symbol. The pointer is allocated using @code{malloc}, and +-should be freed by the caller when it is no longer needed. +- +-The function @code{bfd_minisymbol_to_symbol} will take a pointer +-to a minisymbol, and a pointer to a structure returned by +-@code{bfd_make_empty_symbol}, and return a @code{asymbol} structure. +-The return value may or may not be the same as the value from +-@code{bfd_make_empty_symbol} which was passed in. +- +- +-@node typedef asymbol, symbol handling functions, Mini Symbols, Symbols +-@subsection typedef asymbol +-An @code{asymbol} has the form: +- +- +-@example +- +-typedef struct bfd_symbol +-@{ +- /* A pointer to the BFD which owns the symbol. This information +- is necessary so that a back end can work out what additional +- information (invisible to the application writer) is carried +- with the symbol. +- +- This field is *almost* redundant, since you can use section->owner +- instead, except that some symbols point to the global sections +- bfd_@{abs,com,und@}_section. This could be fixed by making +- these globals be per-bfd (or per-target-flavor). FIXME. */ +- struct bfd *the_bfd; /* Use bfd_asymbol_bfd(sym) to access this field. */ +- +- /* The text of the symbol. The name is left alone, and not copied; the +- application may not alter it. */ +- const char *name; +- +- /* The value of the symbol. This really should be a union of a +- numeric value with a pointer, since some flags indicate that +- a pointer to another symbol is stored here. */ +- symvalue value; +- +- /* Attributes of a symbol. */ +-#define BSF_NO_FLAGS 0x00 +- +- /* The symbol has local scope; @code{static} in @code{C}. The value +- is the offset into the section of the data. */ +-#define BSF_LOCAL (1 << 0) +- +- /* The symbol has global scope; initialized data in @code{C}. The +- value is the offset into the section of the data. */ +-#define BSF_GLOBAL (1 << 1) +- +- /* The symbol has global scope and is exported. The value is +- the offset into the section of the data. */ +-#define BSF_EXPORT BSF_GLOBAL /* No real difference. */ +- +- /* A normal C symbol would be one of: +- @code{BSF_LOCAL}, @code{BSF_COMMON}, @code{BSF_UNDEFINED} or +- @code{BSF_GLOBAL}. */ +- +- /* The symbol is a debugging record. The value has an arbitrary +- meaning, unless BSF_DEBUGGING_RELOC is also set. */ +-#define BSF_DEBUGGING (1 << 2) +- +- /* The symbol denotes a function entry point. Used in ELF, +- perhaps others someday. */ +-#define BSF_FUNCTION (1 << 3) +- +- /* Used by the linker. */ +-#define BSF_KEEP (1 << 5) +-#define BSF_KEEP_G (1 << 6) +- +- /* A weak global symbol, overridable without warnings by +- a regular global symbol of the same name. */ +-#define BSF_WEAK (1 << 7) +- +- /* This symbol was created to point to a section, e.g. ELF's +- STT_SECTION symbols. */ +-#define BSF_SECTION_SYM (1 << 8) +- +- /* The symbol used to be a common symbol, but now it is +- allocated. */ +-#define BSF_OLD_COMMON (1 << 9) +- +- /* In some files the type of a symbol sometimes alters its +- location in an output file - ie in coff a @code{ISFCN} symbol +- which is also @code{C_EXT} symbol appears where it was +- declared and not at the end of a section. This bit is set +- by the target BFD part to convey this information. */ +-#define BSF_NOT_AT_END (1 << 10) +- +- /* Signal that the symbol is the label of constructor section. */ +-#define BSF_CONSTRUCTOR (1 << 11) +- +- /* Signal that the symbol is a warning symbol. The name is a +- warning. The name of the next symbol is the one to warn about; +- if a reference is made to a symbol with the same name as the next +- symbol, a warning is issued by the linker. */ +-#define BSF_WARNING (1 << 12) +- +- /* Signal that the symbol is indirect. This symbol is an indirect +- pointer to the symbol with the same name as the next symbol. */ +-#define BSF_INDIRECT (1 << 13) +- +- /* BSF_FILE marks symbols that contain a file name. This is used +- for ELF STT_FILE symbols. */ +-#define BSF_FILE (1 << 14) +- +- /* Symbol is from dynamic linking information. */ +-#define BSF_DYNAMIC (1 << 15) +- +- /* The symbol denotes a data object. Used in ELF, and perhaps +- others someday. */ +-#define BSF_OBJECT (1 << 16) +- +- /* This symbol is a debugging symbol. The value is the offset +- into the section of the data. BSF_DEBUGGING should be set +- as well. */ +-#define BSF_DEBUGGING_RELOC (1 << 17) +- +- /* This symbol is thread local. Used in ELF. */ +-#define BSF_THREAD_LOCAL (1 << 18) +- +- /* This symbol represents a complex relocation expression, +- with the expression tree serialized in the symbol name. */ +-#define BSF_RELC (1 << 19) +- +- /* This symbol represents a signed complex relocation expression, +- with the expression tree serialized in the symbol name. */ +-#define BSF_SRELC (1 << 20) +- +- /* This symbol was created by bfd_get_synthetic_symtab. */ +-#define BSF_SYNTHETIC (1 << 21) +- +- /* This symbol is an indirect code object. Unrelated to BSF_INDIRECT. +- The dynamic linker will compute the value of this symbol by +- calling the function that it points to. BSF_FUNCTION must +- also be also set. */ +-#define BSF_GNU_INDIRECT_FUNCTION (1 << 22) +- /* This symbol is a globally unique data object. The dynamic linker +- will make sure that in the entire process there is just one symbol +- with this name and type in use. BSF_OBJECT must also be set. */ +-#define BSF_GNU_UNIQUE (1 << 23) +- +- flagword flags; +- +- /* A pointer to the section to which this symbol is +- relative. This will always be non NULL, there are special +- sections for undefined and absolute symbols. */ +- struct bfd_section *section; +- +- /* Back end special data. */ +- union +- @{ +- void *p; +- bfd_vma i; +- @} +- udata; +-@} +-asymbol; +- +-@end example +- +-@node symbol handling functions, , typedef asymbol, Symbols +-@subsection Symbol handling functions +- +- +-@findex bfd_get_symtab_upper_bound +-@subsubsection @code{bfd_get_symtab_upper_bound} +-@strong{Description}@* +-Return the number of bytes required to store a vector of pointers +-to @code{asymbols} for all the symbols in the BFD @var{abfd}, +-including a terminal NULL pointer. If there are no symbols in +-the BFD, then return 0. If an error occurs, return -1. +-@example +-#define bfd_get_symtab_upper_bound(abfd) \ +- BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd)) +- +-@end example +- +-@findex bfd_is_local_label +-@subsubsection @code{bfd_is_local_label} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_is_local_label (bfd *abfd, asymbol *sym); +-@end example +-@strong{Description}@* +-Return TRUE if the given symbol @var{sym} in the BFD @var{abfd} is +-a compiler generated local label, else return FALSE. +- +-@findex bfd_is_local_label_name +-@subsubsection @code{bfd_is_local_label_name} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_is_local_label_name (bfd *abfd, const char *name); +-@end example +-@strong{Description}@* +-Return TRUE if a symbol with the name @var{name} in the BFD +-@var{abfd} is a compiler generated local label, else return +-FALSE. This just checks whether the name has the form of a +-local label. +-@example +-#define bfd_is_local_label_name(abfd, name) \ +- BFD_SEND (abfd, _bfd_is_local_label_name, (abfd, name)) +- +-@end example +- +-@findex bfd_is_target_special_symbol +-@subsubsection @code{bfd_is_target_special_symbol} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_is_target_special_symbol (bfd *abfd, asymbol *sym); +-@end example +-@strong{Description}@* +-Return TRUE iff a symbol @var{sym} in the BFD @var{abfd} is something +-special to the particular target represented by the BFD. Such symbols +-should normally not be mentioned to the user. +-@example +-#define bfd_is_target_special_symbol(abfd, sym) \ +- BFD_SEND (abfd, _bfd_is_target_special_symbol, (abfd, sym)) +- +-@end example +- +-@findex bfd_canonicalize_symtab +-@subsubsection @code{bfd_canonicalize_symtab} +-@strong{Description}@* +-Read the symbols from the BFD @var{abfd}, and fills in +-the vector @var{location} with pointers to the symbols and +-a trailing NULL. +-Return the actual number of symbol pointers, not +-including the NULL. +-@example +-#define bfd_canonicalize_symtab(abfd, location) \ +- BFD_SEND (abfd, _bfd_canonicalize_symtab, (abfd, location)) +- +-@end example +- +-@findex bfd_set_symtab +-@subsubsection @code{bfd_set_symtab} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_symtab +- (bfd *abfd, asymbol **location, unsigned int count); +-@end example +-@strong{Description}@* +-Arrange that when the output BFD @var{abfd} is closed, +-the table @var{location} of @var{count} pointers to symbols +-will be written. +- +-@findex bfd_print_symbol_vandf +-@subsubsection @code{bfd_print_symbol_vandf} +-@strong{Synopsis} +-@example +-void bfd_print_symbol_vandf (bfd *abfd, void *file, asymbol *symbol); +-@end example +-@strong{Description}@* +-Print the value and flags of the @var{symbol} supplied to the +-stream @var{file}. +- +-@findex bfd_make_empty_symbol +-@subsubsection @code{bfd_make_empty_symbol} +-@strong{Description}@* +-Create a new @code{asymbol} structure for the BFD @var{abfd} +-and return a pointer to it. +- +-This routine is necessary because each back end has private +-information surrounding the @code{asymbol}. Building your own +-@code{asymbol} and pointing to it will not create the private +-information, and will cause problems later on. +-@example +-#define bfd_make_empty_symbol(abfd) \ +- BFD_SEND (abfd, _bfd_make_empty_symbol, (abfd)) +- +-@end example +- +-@findex _bfd_generic_make_empty_symbol +-@subsubsection @code{_bfd_generic_make_empty_symbol} +-@strong{Synopsis} +-@example +-asymbol *_bfd_generic_make_empty_symbol (bfd *); +-@end example +-@strong{Description}@* +-Create a new @code{asymbol} structure for the BFD @var{abfd} +-and return a pointer to it. Used by core file routines, +-binary back-end and anywhere else where no private info +-is needed. +- +-@findex bfd_make_debug_symbol +-@subsubsection @code{bfd_make_debug_symbol} +-@strong{Description}@* +-Create a new @code{asymbol} structure for the BFD @var{abfd}, +-to be used as a debugging symbol. Further details of its use have +-yet to be worked out. +-@example +-#define bfd_make_debug_symbol(abfd,ptr,size) \ +- BFD_SEND (abfd, _bfd_make_debug_symbol, (abfd, ptr, size)) +- +-@end example +- +-@findex bfd_decode_symclass +-@subsubsection @code{bfd_decode_symclass} +-@strong{Description}@* +-Return a character corresponding to the symbol +-class of @var{symbol}, or '?' for an unknown class. +- +-@strong{Synopsis} +-@example +-int bfd_decode_symclass (asymbol *symbol); +-@end example +-@findex bfd_is_undefined_symclass +-@subsubsection @code{bfd_is_undefined_symclass} +-@strong{Description}@* +-Returns non-zero if the class symbol returned by +-bfd_decode_symclass represents an undefined symbol. +-Returns zero otherwise. +- +-@strong{Synopsis} +-@example +-bfd_boolean bfd_is_undefined_symclass (int symclass); +-@end example +-@findex bfd_symbol_info +-@subsubsection @code{bfd_symbol_info} +-@strong{Description}@* +-Fill in the basic info about symbol that nm needs. +-Additional info may be added by the back-ends after +-calling this function. +- +-@strong{Synopsis} +-@example +-void bfd_symbol_info (asymbol *symbol, symbol_info *ret); +-@end example +-@findex bfd_copy_private_symbol_data +-@subsubsection @code{bfd_copy_private_symbol_data} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_copy_private_symbol_data +- (bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym); +-@end example +-@strong{Description}@* +-Copy private symbol information from @var{isym} in the BFD +-@var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}. +-Return @code{TRUE} on success, @code{FALSE} on error. Possible error +-returns are: +- +-@itemize @bullet +- +-@item +-@code{bfd_error_no_memory} - +-Not enough memory exists to create private data for @var{osec}. +-@end itemize +-@example +-#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \ +- BFD_SEND (obfd, _bfd_copy_private_symbol_data, \ +- (ibfd, isymbol, obfd, osymbol)) +- +-@end example +- +diff -Nur binutils-2.24.orig/bfd/doc/targets.texi binutils-2.24/bfd/doc/targets.texi +--- binutils-2.24.orig/bfd/doc/targets.texi 2013-11-18 09:49:27.000000000 +0100 ++++ binutils-2.24/bfd/doc/targets.texi 1970-01-01 01:00:00.000000000 +0100 +@@ -1,621 +0,0 @@ +-@section Targets +- +- +-@strong{Description}@* +-Each port of BFD to a different machine requires the creation +-of a target back end. All the back end provides to the root +-part of BFD is a structure containing pointers to functions +-which perform certain low level operations on files. BFD +-translates the applications's requests through a pointer into +-calls to the back end routines. +- +-When a file is opened with @code{bfd_openr}, its format and +-target are unknown. BFD uses various mechanisms to determine +-how to interpret the file. The operations performed are: +- +-@itemize @bullet +- +-@item +-Create a BFD by calling the internal routine +-@code{_bfd_new_bfd}, then call @code{bfd_find_target} with the +-target string supplied to @code{bfd_openr} and the new BFD pointer. +- +-@item +-If a null target string was provided to @code{bfd_find_target}, +-look up the environment variable @code{GNUTARGET} and use +-that as the target string. +- +-@item +-If the target string is still @code{NULL}, or the target string is +-@code{default}, then use the first item in the target vector +-as the target type, and set @code{target_defaulted} in the BFD to +-cause @code{bfd_check_format} to loop through all the targets. +-@xref{bfd_target}. @xref{Formats}. +- +-@item +-Otherwise, inspect the elements in the target vector +-one by one, until a match on target name is found. When found, +-use it. +- +-@item +-Otherwise return the error @code{bfd_error_invalid_target} to +-@code{bfd_openr}. +- +-@item +-@code{bfd_openr} attempts to open the file using +-@code{bfd_open_file}, and returns the BFD. +-@end itemize +-Once the BFD has been opened and the target selected, the file +-format may be determined. This is done by calling +-@code{bfd_check_format} on the BFD with a suggested format. +-If @code{target_defaulted} has been set, each possible target +-type is tried to see if it recognizes the specified format. +-@code{bfd_check_format} returns @code{TRUE} when the caller guesses right. +-@menu +-* bfd_target:: +-@end menu +- +-@node bfd_target, , Targets, Targets +- +-@subsection bfd_target +- +- +-@strong{Description}@* +-This structure contains everything that BFD knows about a +-target. It includes things like its byte order, name, and which +-routines to call to do various operations. +- +-Every BFD points to a target structure with its @code{xvec} +-member. +- +-The macros below are used to dispatch to functions through the +-@code{bfd_target} vector. They are used in a number of macros further +-down in @file{bfd.h}, and are also used when calling various +-routines by hand inside the BFD implementation. The @var{arglist} +-argument must be parenthesized; it contains all the arguments +-to the called function. +- +-They make the documentation (more) unpleasant to read, so if +-someone wants to fix this and not break the above, please do. +-@example +-#define BFD_SEND(bfd, message, arglist) \ +- ((*((bfd)->xvec->message)) arglist) +- +-#ifdef DEBUG_BFD_SEND +-#undef BFD_SEND +-#define BFD_SEND(bfd, message, arglist) \ +- (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ +- ((*((bfd)->xvec->message)) arglist) : \ +- (bfd_assert (__FILE__,__LINE__), NULL)) +-#endif +-@end example +-For operations which index on the BFD format: +-@example +-#define BFD_SEND_FMT(bfd, message, arglist) \ +- (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) +- +-#ifdef DEBUG_BFD_SEND +-#undef BFD_SEND_FMT +-#define BFD_SEND_FMT(bfd, message, arglist) \ +- (((bfd) && (bfd)->xvec && (bfd)->xvec->message) ? \ +- (((bfd)->xvec->message[(int) ((bfd)->format)]) arglist) : \ +- (bfd_assert (__FILE__,__LINE__), NULL)) +-#endif +- +-@end example +-This is the structure which defines the type of BFD this is. The +-@code{xvec} member of the struct @code{bfd} itself points here. Each +-module that implements access to a different target under BFD, +-defines one of these. +- +-FIXME, these names should be rationalised with the names of +-the entry points which call them. Too bad we can't have one +-macro to define them both! +-@example +-enum bfd_flavour +-@{ +- bfd_target_unknown_flavour, +- bfd_target_aout_flavour, +- bfd_target_coff_flavour, +- bfd_target_ecoff_flavour, +- bfd_target_xcoff_flavour, +- bfd_target_elf_flavour, +- bfd_target_ieee_flavour, +- bfd_target_nlm_flavour, +- bfd_target_oasys_flavour, +- bfd_target_tekhex_flavour, +- bfd_target_srec_flavour, +- bfd_target_verilog_flavour, +- bfd_target_ihex_flavour, +- bfd_target_som_flavour, +- bfd_target_os9k_flavour, +- bfd_target_versados_flavour, +- bfd_target_msdos_flavour, +- bfd_target_ovax_flavour, +- bfd_target_evax_flavour, +- bfd_target_mmo_flavour, +- bfd_target_mach_o_flavour, +- bfd_target_pef_flavour, +- bfd_target_pef_xlib_flavour, +- bfd_target_sym_flavour +-@}; +- +-enum bfd_endian @{ BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN @}; +- +-/* Forward declaration. */ +-typedef struct bfd_link_info _bfd_link_info; +- +-/* Forward declaration. */ +-typedef struct flag_info flag_info; +- +-typedef struct bfd_target +-@{ +- /* Identifies the kind of target, e.g., SunOS4, Ultrix, etc. */ +- char *name; +- +- /* The "flavour" of a back end is a general indication about +- the contents of a file. */ +- enum bfd_flavour flavour; +- +- /* The order of bytes within the data area of a file. */ +- enum bfd_endian byteorder; +- +- /* The order of bytes within the header parts of a file. */ +- enum bfd_endian header_byteorder; +- +- /* A mask of all the flags which an executable may have set - +- from the set @code{BFD_NO_FLAGS}, @code{HAS_RELOC}, ...@code{D_PAGED}. */ +- flagword object_flags; +- +- /* A mask of all the flags which a section may have set - from +- the set @code{SEC_NO_FLAGS}, @code{SEC_ALLOC}, ...@code{SET_NEVER_LOAD}. */ +- flagword section_flags; +- +- /* The character normally found at the front of a symbol. +- (if any), perhaps `_'. */ +- char symbol_leading_char; +- +- /* The pad character for file names within an archive header. */ +- char ar_pad_char; +- +- /* The maximum number of characters in an archive header. */ +- unsigned char ar_max_namelen; +- +- /* How well this target matches, used to select between various +- possible targets when more than one target matches. */ +- unsigned char match_priority; +- +- /* Entries for byte swapping for data. These are different from the +- other entry points, since they don't take a BFD as the first argument. +- Certain other handlers could do the same. */ +- bfd_uint64_t (*bfd_getx64) (const void *); +- bfd_int64_t (*bfd_getx_signed_64) (const void *); +- void (*bfd_putx64) (bfd_uint64_t, void *); +- bfd_vma (*bfd_getx32) (const void *); +- bfd_signed_vma (*bfd_getx_signed_32) (const void *); +- void (*bfd_putx32) (bfd_vma, void *); +- bfd_vma (*bfd_getx16) (const void *); +- bfd_signed_vma (*bfd_getx_signed_16) (const void *); +- void (*bfd_putx16) (bfd_vma, void *); +- +- /* Byte swapping for the headers. */ +- bfd_uint64_t (*bfd_h_getx64) (const void *); +- bfd_int64_t (*bfd_h_getx_signed_64) (const void *); +- void (*bfd_h_putx64) (bfd_uint64_t, void *); +- bfd_vma (*bfd_h_getx32) (const void *); +- bfd_signed_vma (*bfd_h_getx_signed_32) (const void *); +- void (*bfd_h_putx32) (bfd_vma, void *); +- bfd_vma (*bfd_h_getx16) (const void *); +- bfd_signed_vma (*bfd_h_getx_signed_16) (const void *); +- void (*bfd_h_putx16) (bfd_vma, void *); +- +- /* Format dependent routines: these are vectors of entry points +- within the target vector structure, one for each format to check. */ +- +- /* Check the format of a file being read. Return a @code{bfd_target *} or zero. */ +- const struct bfd_target *(*_bfd_check_format[bfd_type_end]) (bfd *); +- +- /* Set the format of a file being written. */ +- bfd_boolean (*_bfd_set_format[bfd_type_end]) (bfd *); +- +- /* Write cached information into a file being written, at @code{bfd_close}. */ +- bfd_boolean (*_bfd_write_contents[bfd_type_end]) (bfd *); +- +-@end example +-The general target vector. These vectors are initialized using the +-BFD_JUMP_TABLE macros. +-@example +- +- /* Generic entry points. */ +-#define BFD_JUMP_TABLE_GENERIC(NAME) \ +- NAME##_close_and_cleanup, \ +- NAME##_bfd_free_cached_info, \ +- NAME##_new_section_hook, \ +- NAME##_get_section_contents, \ +- NAME##_get_section_contents_in_window +- +- /* Called when the BFD is being closed to do any necessary cleanup. */ +- bfd_boolean (*_close_and_cleanup) (bfd *); +- /* Ask the BFD to free all cached information. */ +- bfd_boolean (*_bfd_free_cached_info) (bfd *); +- /* Called when a new section is created. */ +- bfd_boolean (*_new_section_hook) (bfd *, sec_ptr); +- /* Read the contents of a section. */ +- bfd_boolean (*_bfd_get_section_contents) +- (bfd *, sec_ptr, void *, file_ptr, bfd_size_type); +- bfd_boolean (*_bfd_get_section_contents_in_window) +- (bfd *, sec_ptr, bfd_window *, file_ptr, bfd_size_type); +- +- /* Entry points to copy private data. */ +-#define BFD_JUMP_TABLE_COPY(NAME) \ +- NAME##_bfd_copy_private_bfd_data, \ +- NAME##_bfd_merge_private_bfd_data, \ +- _bfd_generic_init_private_section_data, \ +- NAME##_bfd_copy_private_section_data, \ +- NAME##_bfd_copy_private_symbol_data, \ +- NAME##_bfd_copy_private_header_data, \ +- NAME##_bfd_set_private_flags, \ +- NAME##_bfd_print_private_bfd_data +- +- /* Called to copy BFD general private data from one object file +- to another. */ +- bfd_boolean (*_bfd_copy_private_bfd_data) (bfd *, bfd *); +- /* Called to merge BFD general private data from one object file +- to a common output file when linking. */ +- bfd_boolean (*_bfd_merge_private_bfd_data) (bfd *, bfd *); +- /* Called to initialize BFD private section data from one object file +- to another. */ +-#define bfd_init_private_section_data(ibfd, isec, obfd, osec, link_info) \ +- BFD_SEND (obfd, _bfd_init_private_section_data, (ibfd, isec, obfd, osec, link_info)) +- bfd_boolean (*_bfd_init_private_section_data) +- (bfd *, sec_ptr, bfd *, sec_ptr, struct bfd_link_info *); +- /* Called to copy BFD private section data from one object file +- to another. */ +- bfd_boolean (*_bfd_copy_private_section_data) +- (bfd *, sec_ptr, bfd *, sec_ptr); +- /* Called to copy BFD private symbol data from one symbol +- to another. */ +- bfd_boolean (*_bfd_copy_private_symbol_data) +- (bfd *, asymbol *, bfd *, asymbol *); +- /* Called to copy BFD private header data from one object file +- to another. */ +- bfd_boolean (*_bfd_copy_private_header_data) +- (bfd *, bfd *); +- /* Called to set private backend flags. */ +- bfd_boolean (*_bfd_set_private_flags) (bfd *, flagword); +- +- /* Called to print private BFD data. */ +- bfd_boolean (*_bfd_print_private_bfd_data) (bfd *, void *); +- +- /* Core file entry points. */ +-#define BFD_JUMP_TABLE_CORE(NAME) \ +- NAME##_core_file_failing_command, \ +- NAME##_core_file_failing_signal, \ +- NAME##_core_file_matches_executable_p, \ +- NAME##_core_file_pid +- +- char * (*_core_file_failing_command) (bfd *); +- int (*_core_file_failing_signal) (bfd *); +- bfd_boolean (*_core_file_matches_executable_p) (bfd *, bfd *); +- int (*_core_file_pid) (bfd *); +- +- /* Archive entry points. */ +-#define BFD_JUMP_TABLE_ARCHIVE(NAME) \ +- NAME##_slurp_armap, \ +- NAME##_slurp_extended_name_table, \ +- NAME##_construct_extended_name_table, \ +- NAME##_truncate_arname, \ +- NAME##_write_armap, \ +- NAME##_read_ar_hdr, \ +- NAME##_write_ar_hdr, \ +- NAME##_openr_next_archived_file, \ +- NAME##_get_elt_at_index, \ +- NAME##_generic_stat_arch_elt, \ +- NAME##_update_armap_timestamp +- +- bfd_boolean (*_bfd_slurp_armap) (bfd *); +- bfd_boolean (*_bfd_slurp_extended_name_table) (bfd *); +- bfd_boolean (*_bfd_construct_extended_name_table) +- (bfd *, char **, bfd_size_type *, const char **); +- void (*_bfd_truncate_arname) (bfd *, const char *, char *); +- bfd_boolean (*write_armap) +- (bfd *, unsigned int, struct orl *, unsigned int, int); +- void * (*_bfd_read_ar_hdr_fn) (bfd *); +- bfd_boolean (*_bfd_write_ar_hdr_fn) (bfd *, bfd *); +- bfd * (*openr_next_archived_file) (bfd *, bfd *); +-#define bfd_get_elt_at_index(b,i) BFD_SEND (b, _bfd_get_elt_at_index, (b,i)) +- bfd * (*_bfd_get_elt_at_index) (bfd *, symindex); +- int (*_bfd_stat_arch_elt) (bfd *, struct stat *); +- bfd_boolean (*_bfd_update_armap_timestamp) (bfd *); +- +- /* Entry points used for symbols. */ +-#define BFD_JUMP_TABLE_SYMBOLS(NAME) \ +- NAME##_get_symtab_upper_bound, \ +- NAME##_canonicalize_symtab, \ +- NAME##_make_empty_symbol, \ +- NAME##_print_symbol, \ +- NAME##_get_symbol_info, \ +- NAME##_bfd_is_local_label_name, \ +- NAME##_bfd_is_target_special_symbol, \ +- NAME##_get_lineno, \ +- NAME##_find_nearest_line, \ +- _bfd_generic_find_nearest_line_discriminator, \ +- _bfd_generic_find_line, \ +- NAME##_find_inliner_info, \ +- NAME##_bfd_make_debug_symbol, \ +- NAME##_read_minisymbols, \ +- NAME##_minisymbol_to_symbol +- +- long (*_bfd_get_symtab_upper_bound) (bfd *); +- long (*_bfd_canonicalize_symtab) +- (bfd *, struct bfd_symbol **); +- struct bfd_symbol * +- (*_bfd_make_empty_symbol) (bfd *); +- void (*_bfd_print_symbol) +- (bfd *, void *, struct bfd_symbol *, bfd_print_symbol_type); +-#define bfd_print_symbol(b,p,s,e) BFD_SEND (b, _bfd_print_symbol, (b,p,s,e)) +- void (*_bfd_get_symbol_info) +- (bfd *, struct bfd_symbol *, symbol_info *); +-#define bfd_get_symbol_info(b,p,e) BFD_SEND (b, _bfd_get_symbol_info, (b,p,e)) +- bfd_boolean (*_bfd_is_local_label_name) (bfd *, const char *); +- bfd_boolean (*_bfd_is_target_special_symbol) (bfd *, asymbol *); +- alent * (*_get_lineno) (bfd *, struct bfd_symbol *); +- bfd_boolean (*_bfd_find_nearest_line) +- (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, +- const char **, const char **, unsigned int *); +- bfd_boolean (*_bfd_find_nearest_line_discriminator) +- (bfd *, struct bfd_section *, struct bfd_symbol **, bfd_vma, +- const char **, const char **, unsigned int *, unsigned int *); +- bfd_boolean (*_bfd_find_line) +- (bfd *, struct bfd_symbol **, struct bfd_symbol *, +- const char **, unsigned int *); +- bfd_boolean (*_bfd_find_inliner_info) +- (bfd *, const char **, const char **, unsigned int *); +- /* Back-door to allow format-aware applications to create debug symbols +- while using BFD for everything else. Currently used by the assembler +- when creating COFF files. */ +- asymbol * (*_bfd_make_debug_symbol) +- (bfd *, void *, unsigned long size); +-#define bfd_read_minisymbols(b, d, m, s) \ +- BFD_SEND (b, _read_minisymbols, (b, d, m, s)) +- long (*_read_minisymbols) +- (bfd *, bfd_boolean, void **, unsigned int *); +-#define bfd_minisymbol_to_symbol(b, d, m, f) \ +- BFD_SEND (b, _minisymbol_to_symbol, (b, d, m, f)) +- asymbol * (*_minisymbol_to_symbol) +- (bfd *, bfd_boolean, const void *, asymbol *); +- +- /* Routines for relocs. */ +-#define BFD_JUMP_TABLE_RELOCS(NAME) \ +- NAME##_get_reloc_upper_bound, \ +- NAME##_canonicalize_reloc, \ +- NAME##_bfd_reloc_type_lookup, \ +- NAME##_bfd_reloc_name_lookup +- +- long (*_get_reloc_upper_bound) (bfd *, sec_ptr); +- long (*_bfd_canonicalize_reloc) +- (bfd *, sec_ptr, arelent **, struct bfd_symbol **); +- /* See documentation on reloc types. */ +- reloc_howto_type * +- (*reloc_type_lookup) (bfd *, bfd_reloc_code_real_type); +- reloc_howto_type * +- (*reloc_name_lookup) (bfd *, const char *); +- +- +- /* Routines used when writing an object file. */ +-#define BFD_JUMP_TABLE_WRITE(NAME) \ +- NAME##_set_arch_mach, \ +- NAME##_set_section_contents +- +- bfd_boolean (*_bfd_set_arch_mach) +- (bfd *, enum bfd_architecture, unsigned long); +- bfd_boolean (*_bfd_set_section_contents) +- (bfd *, sec_ptr, const void *, file_ptr, bfd_size_type); +- +- /* Routines used by the linker. */ +-#define BFD_JUMP_TABLE_LINK(NAME) \ +- NAME##_sizeof_headers, \ +- NAME##_bfd_get_relocated_section_contents, \ +- NAME##_bfd_relax_section, \ +- NAME##_bfd_link_hash_table_create, \ +- NAME##_bfd_link_hash_table_free, \ +- NAME##_bfd_link_add_symbols, \ +- NAME##_bfd_link_just_syms, \ +- NAME##_bfd_copy_link_hash_symbol_type, \ +- NAME##_bfd_final_link, \ +- NAME##_bfd_link_split_section, \ +- NAME##_bfd_gc_sections, \ +- NAME##_bfd_lookup_section_flags, \ +- NAME##_bfd_merge_sections, \ +- NAME##_bfd_is_group_section, \ +- NAME##_bfd_discard_group, \ +- NAME##_section_already_linked, \ +- NAME##_bfd_define_common_symbol +- +- int (*_bfd_sizeof_headers) (bfd *, struct bfd_link_info *); +- bfd_byte * (*_bfd_get_relocated_section_contents) +- (bfd *, struct bfd_link_info *, struct bfd_link_order *, +- bfd_byte *, bfd_boolean, struct bfd_symbol **); +- +- bfd_boolean (*_bfd_relax_section) +- (bfd *, struct bfd_section *, struct bfd_link_info *, bfd_boolean *); +- +- /* Create a hash table for the linker. Different backends store +- different information in this table. */ +- struct bfd_link_hash_table * +- (*_bfd_link_hash_table_create) (bfd *); +- +- /* Release the memory associated with the linker hash table. */ +- void (*_bfd_link_hash_table_free) (struct bfd_link_hash_table *); +- +- /* Add symbols from this object file into the hash table. */ +- bfd_boolean (*_bfd_link_add_symbols) (bfd *, struct bfd_link_info *); +- +- /* Indicate that we are only retrieving symbol values from this section. */ +- void (*_bfd_link_just_syms) (asection *, struct bfd_link_info *); +- +- /* Copy the symbol type of a linker hash table entry. */ +-#define bfd_copy_link_hash_symbol_type(b, t, f) \ +- BFD_SEND (b, _bfd_copy_link_hash_symbol_type, (b, t, f)) +- void (*_bfd_copy_link_hash_symbol_type) +- (bfd *, struct bfd_link_hash_entry *, struct bfd_link_hash_entry *); +- +- /* Do a link based on the link_order structures attached to each +- section of the BFD. */ +- bfd_boolean (*_bfd_final_link) (bfd *, struct bfd_link_info *); +- +- /* Should this section be split up into smaller pieces during linking. */ +- bfd_boolean (*_bfd_link_split_section) (bfd *, struct bfd_section *); +- +- /* Remove sections that are not referenced from the output. */ +- bfd_boolean (*_bfd_gc_sections) (bfd *, struct bfd_link_info *); +- +- /* Sets the bitmask of allowed and disallowed section flags. */ +- bfd_boolean (*_bfd_lookup_section_flags) (struct bfd_link_info *, +- struct flag_info *, +- asection *); +- +- /* Attempt to merge SEC_MERGE sections. */ +- bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *); +- +- /* Is this section a member of a group? */ +- bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *); +- +- /* Discard members of a group. */ +- bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *); +- +- /* Check if SEC has been already linked during a reloceatable or +- final link. */ +- bfd_boolean (*_section_already_linked) (bfd *, asection *, +- struct bfd_link_info *); +- +- /* Define a common symbol. */ +- bfd_boolean (*_bfd_define_common_symbol) (bfd *, struct bfd_link_info *, +- struct bfd_link_hash_entry *); +- +- /* Routines to handle dynamic symbols and relocs. */ +-#define BFD_JUMP_TABLE_DYNAMIC(NAME) \ +- NAME##_get_dynamic_symtab_upper_bound, \ +- NAME##_canonicalize_dynamic_symtab, \ +- NAME##_get_synthetic_symtab, \ +- NAME##_get_dynamic_reloc_upper_bound, \ +- NAME##_canonicalize_dynamic_reloc +- +- /* Get the amount of memory required to hold the dynamic symbols. */ +- long (*_bfd_get_dynamic_symtab_upper_bound) (bfd *); +- /* Read in the dynamic symbols. */ +- long (*_bfd_canonicalize_dynamic_symtab) +- (bfd *, struct bfd_symbol **); +- /* Create synthetized symbols. */ +- long (*_bfd_get_synthetic_symtab) +- (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, +- struct bfd_symbol **); +- /* Get the amount of memory required to hold the dynamic relocs. */ +- long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); +- /* Read in the dynamic relocs. */ +- long (*_bfd_canonicalize_dynamic_reloc) +- (bfd *, arelent **, struct bfd_symbol **); +- +-@end example +-A pointer to an alternative bfd_target in case the current one is not +-satisfactory. This can happen when the target cpu supports both big +-and little endian code, and target chosen by the linker has the wrong +-endianness. The function open_output() in ld/ldlang.c uses this field +-to find an alternative output format that is suitable. +-@example +- /* Opposite endian version of this target. */ +- const struct bfd_target * alternative_target; +- +- /* Data for use by back-end routines, which isn't +- generic enough to belong in this structure. */ +- const void *backend_data; +- +-@} bfd_target; +- +-@end example +- +-@findex bfd_set_default_target +-@subsubsection @code{bfd_set_default_target} +-@strong{Synopsis} +-@example +-bfd_boolean bfd_set_default_target (const char *name); +-@end example +-@strong{Description}@* +-Set the default target vector to use when recognizing a BFD. +-This takes the name of the target, which may be a BFD target +-name or a configuration triplet. +- +-@findex bfd_find_target +-@subsubsection @code{bfd_find_target} +-@strong{Synopsis} +-@example +-const bfd_target *bfd_find_target (const char *target_name, bfd *abfd); +-@end example +-@strong{Description}@* +-Return a pointer to the transfer vector for the object target +-named @var{target_name}. If @var{target_name} is @code{NULL}, +-choose the one in the environment variable @code{GNUTARGET}; if +-that is null or not defined, then choose the first entry in the +-target list. Passing in the string "default" or setting the +-environment variable to "default" will cause the first entry in +-the target list to be returned, and "target_defaulted" will be +-set in the BFD if @var{abfd} isn't @code{NULL}. This causes +-@code{bfd_check_format} to loop over all the targets to find the +-one that matches the file being read. +- +-@findex bfd_get_target_info +-@subsubsection @code{bfd_get_target_info} +-@strong{Synopsis} +-@example +-const bfd_target *bfd_get_target_info (const char *target_name, +- bfd *abfd, +- bfd_boolean *is_bigendian, +- int *underscoring, +- const char **def_target_arch); +-@end example +-@strong{Description}@* +-Return a pointer to the transfer vector for the object target +-named @var{target_name}. If @var{target_name} is @code{NULL}, +-choose the one in the environment variable @code{GNUTARGET}; if +-that is null or not defined, then choose the first entry in the +-target list. Passing in the string "default" or setting the +-environment variable to "default" will cause the first entry in +-the target list to be returned, and "target_defaulted" will be +-set in the BFD if @var{abfd} isn't @code{NULL}. This causes +-@code{bfd_check_format} to loop over all the targets to find the +-one that matches the file being read. +-If @var{is_bigendian} is not @code{NULL}, then set this value to target's +-endian mode. True for big-endian, FALSE for little-endian or for +-invalid target. +-If @var{underscoring} is not @code{NULL}, then set this value to target's +-underscoring mode. Zero for none-underscoring, -1 for invalid target, +-else the value of target vector's symbol underscoring. +-If @var{def_target_arch} is not @code{NULL}, then set it to the architecture +-string specified by the target_name. +- +-@findex bfd_target_list +-@subsubsection @code{bfd_target_list} +-@strong{Synopsis} +-@example +-const char ** bfd_target_list (void); +-@end example +-@strong{Description}@* +-Return a freshly malloced NULL-terminated +-vector of the names of all the valid BFD targets. Do not +-modify the names. +- +-@findex bfd_seach_for_target +-@subsubsection @code{bfd_seach_for_target} +-@strong{Synopsis} +-@example +-const bfd_target *bfd_search_for_target +- (int (*search_func) (const bfd_target *, void *), +- void *); +-@end example +-@strong{Description}@* +-Return a pointer to the first transfer vector in the list of +-transfer vectors maintained by BFD that produces a non-zero +-result when passed to the function @var{search_func}. The +-parameter @var{data} is passed, unexamined, to the search +-function. +- +diff -Nur binutils-2.24.orig/bfd/elf-bfd.h binutils-2.24/bfd/elf-bfd.h +--- binutils-2.24.orig/bfd/elf-bfd.h 2013-11-08 11:13:48.000000000 +0100 ++++ binutils-2.24/bfd/elf-bfd.h 2016-04-10 20:30:46.000000000 +0200 +@@ -419,6 +419,7 @@ + MICROBLAZE_ELF_DATA, + MIPS_ELF_DATA, + MN10300_ELF_DATA, ++ NDS32_ELF_DATA, + NIOS2_ELF_DATA, + PPC32_ELF_DATA, + PPC64_ELF_DATA, +diff -Nur binutils-2.24.orig/bfd/elf32-nds32.c binutils-2.24/bfd/elf32-nds32.c +--- binutils-2.24.orig/bfd/elf32-nds32.c 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/bfd/elf32-nds32.c 2016-04-10 20:32:10.000000000 +0200 +@@ -0,0 +1,20276 @@ ++/* NDS32-specific support for 32-bit ELF. ++ Copyright (C) 2012-2013 Free Software Foundation, Inc. ++ Contributed by Andes Technology Corporation. ++ ++ 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 3 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.*/ ++ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfd_stdint.h" ++#include "bfdlink.h" ++#include "libbfd.h" ++#include "elf-bfd.h" ++#include "libiberty.h" ++#include "bfd_stdint.h" ++#include "elf/nds32.h" ++#include "opcode/nds32.h" ++#include "elf32-nds32.h" ++#include "opcode/cgen.h" ++#include "../opcodes/nds32-opc.h" ++ ++/* Relocation HOWTO functions. */ ++static bfd_reloc_status_type nds32_elf_ignore_reloc ++ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); ++static bfd_reloc_status_type nds32_elf_9_pcrel_reloc ++ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); ++static bfd_reloc_status_type nds32_elf_hi20_reloc ++ (bfd *, arelent *, asymbol *, void *, ++ asection *, bfd *, char **); ++static bfd_reloc_status_type nds32_elf_lo12_reloc ++ (bfd *, arelent *, asymbol *, void *, ++ asection *, bfd *, char **); ++static bfd_reloc_status_type nds32_elf_generic_reloc ++ (bfd *, arelent *, asymbol *, void *, ++ asection *, bfd *, char **); ++static bfd_reloc_status_type nds32_elf_sda15_reloc ++ (bfd *, arelent *, asymbol *, void *, ++ asection *, bfd *, char **); ++ ++/* Helper functions for HOWTO. */ ++static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc ++ (bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma, ++ asection *, bfd_vma, bfd_vma); ++static void nds32_elf_relocate_hi20 ++ (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); ++static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup ++ (enum elf_nds32_reloc_type); ++static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup ++ (bfd *, bfd_reloc_code_real_type); ++ ++/* Target hooks. */ ++static void nds32_info_to_howto_rel ++ (bfd *, arelent *, Elf_Internal_Rela *dst); ++static void nds32_info_to_howto ++ (bfd *, arelent *, Elf_Internal_Rela *dst); ++static bfd_boolean nds32_elf_add_symbol_hook ++ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **, ++ flagword *, asection **, bfd_vma *); ++static bfd_boolean nds32_elf_relocate_section ++ (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, ++ Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); ++static bfd_boolean nds32_elf_object_p (bfd *); ++static void nds32_elf_final_write_processing (bfd *, bfd_boolean); ++static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword); ++static bfd_boolean nds32_elf_merge_private_bfd_data (bfd *, bfd *); ++static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *); ++static bfd_boolean nds32_elf_gc_sweep_hook ++ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); ++static bfd_boolean nds32_elf_check_relocs ++ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); ++static asection *nds32_elf_gc_mark_hook ++ (asection *, struct bfd_link_info *, Elf_Internal_Rela *, ++ struct elf_link_hash_entry *, Elf_Internal_Sym *); ++static bfd_boolean nds32_elf_adjust_dynamic_symbol ++ (struct bfd_link_info *, struct elf_link_hash_entry *); ++static bfd_boolean nds32_elf_size_dynamic_sections ++ (bfd *, struct bfd_link_info *); ++static bfd_boolean nds32_elf_create_dynamic_sections ++ (bfd *, struct bfd_link_info *); ++static bfd_boolean nds32_elf_finish_dynamic_sections ++ (bfd *, struct bfd_link_info *info); ++static bfd_boolean nds32_elf_finish_dynamic_symbol ++ (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, ++ Elf_Internal_Sym *); ++static bfd_boolean nds32_elf_mkobject (bfd *); ++ ++/* Nds32 helper functions. */ ++static bfd_reloc_status_type nds32_elf_final_sda_base ++ (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean); ++static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *); ++static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *); ++static Elf_Internal_Rela *find_relocs_at_address ++ (Elf_Internal_Rela *, Elf_Internal_Rela *, ++ Elf_Internal_Rela *, enum elf_nds32_reloc_type); ++static bfd_vma calculate_memory_address ++(bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *); ++static int nds32_get_section_contents (bfd *, asection *, ++ bfd_byte **, bfd_boolean); ++static int nds32_elf_ex9_init (void); ++static bfd_boolean nds32_elf_ex9_build_hash_table ++(bfd *, asection *, struct bfd_link_info *); ++static bfd_boolean nds32_elf_ex9_itb_base (struct bfd_link_info *); ++static void nds32_elf_ex9_import_table (struct bfd_link_info *); ++static void nds32_elf_ex9_finish (struct bfd_link_info *); ++static void nds32_elf_ex9_reloc_jmp (struct bfd_link_info *); ++static void nds32_elf_get_insn_with_reg ++ (Elf_Internal_Rela *, uint32_t, uint32_t *); ++static int nds32_get_local_syms (bfd *, asection *ATTRIBUTE_UNUSED, ++ Elf_Internal_Sym **); ++static bfd_boolean nds32_elf_ex9_replace_instruction ++ (struct bfd_link_info *, bfd *, asection *); ++static int nds32_elf_ifc_init (void); ++static bfd_boolean nds32_elf_ifc_calc (struct bfd_link_info *, bfd *, ++ asection *); ++static void nds32_elf_ifc_cse_algo (struct bfd_link_info *); ++static bfd_boolean nds32_elf_ifc_finish (struct bfd_link_info *); ++static bfd_boolean nds32_elf_ifc_replace (struct bfd_link_info *); ++static bfd_boolean nds32_elf_ifc_trace_code (struct bfd_link_info *, ++ bfd *,asection *); ++static bfd_boolean nds32_elf_ifc_reloc (void); ++static bfd_boolean nds32_relax_fp_as_gp ++ (struct bfd_link_info *link_info, bfd *abfd, asection *sec, ++ Elf_Internal_Rela *internal_relocs, Elf_Internal_Rela *irelend, ++ Elf_Internal_Sym *isymbuf); ++static bfd_boolean nds32_fag_remove_unused_fpbase ++ (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend); ++static bfd_byte* ++nds32_elf_get_relocated_section_contents (bfd *abfd, ++ struct bfd_link_info *link_info, ++ struct bfd_link_order *link_order, ++ bfd_byte *data, ++ bfd_boolean relocatable, ++ asymbol **symbols); ++static void nds32_elf_ict_hash_init (void); ++static void nds32_elf_ict_relocate (struct bfd_link_info *); ++static asection* ++nds32_elf_get_target_section (struct bfd_link_info *, char *); ++ ++enum ++{ ++ MACH_V1 = bfd_mach_n1h, ++ MACH_V2 = bfd_mach_n1h_v2, ++ MACH_V3 = bfd_mach_n1h_v3, ++ MACH_V3M = bfd_mach_n1h_v3m, ++}; ++ ++#define MIN(a, b) ((a) > (b) ? (b) : (a)) ++#define MAX(a, b) ((a) > (b) ? (a) : (b)) ++ ++/* True if insn is 4byte. */ ++#define INSN_32BIT(insn) ((((insn) & 0x80000000) == 0 ? (TRUE) : (FALSE))) ++ ++/* The name of the dynamic interpreter. This is put in the .interp ++ section. */ ++#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1" ++ ++/**/ ++#define NDS32_GUARD_SEC_P(flags) ((flags) & SEC_ALLOC \ ++ && (flags) & SEC_LOAD \ ++ && (flags) & SEC_READONLY) ++ ++/* The nop opcode we use. */ ++#define NDS32_NOP32 0x40000009 ++#define NDS32_NOP16 0x9200 ++ ++/* The size in bytes of an entry in the procedure linkage table. */ ++#define PLT_ENTRY_SIZE 24 ++#define PLT_HEADER_SIZE 24 ++ ++/* The first entry in a procedure linkage table are reserved, ++ and the initial contents are unimportant (we zero them out). ++ Subsequent entries look like this. */ ++#define PLT0_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(.got+4) */ ++#define PLT0_ENTRY_WORD1 0x58f78000 /* ori r15, r25, LO12(.got+4) */ ++#define PLT0_ENTRY_WORD2 0x05178000 /* lwi r17, [r15+0] */ ++#define PLT0_ENTRY_WORD3 0x04f78001 /* lwi r15, [r15+4] */ ++#define PLT0_ENTRY_WORD4 0x4a003c00 /* jr r15 */ ++ ++/* $ta is change to $r15 (from $r25). */ ++#define PLT0_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[1]@GOT) */ ++#define PLT0_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[1]@GOT) */ ++#define PLT0_PIC_ENTRY_WORD2 0x40f7f400 /* add r15, gp, r15 */ ++#define PLT0_PIC_ENTRY_WORD3 0x05178000 /* lwi r17, [r15+0] */ ++#define PLT0_PIC_ENTRY_WORD4 0x04f78001 /* lwi r15, [r15+4] */ ++#define PLT0_PIC_ENTRY_WORD5 0x4a003c00 /* jr r15 */ ++ ++#define PLT_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(&got[n+3]) */ ++#define PLT_ENTRY_WORD1 0x04f78000 /* lwi r15, r15, LO12(&got[n+3]) */ ++#define PLT_ENTRY_WORD2 0x4a003c00 /* jr r15 */ ++#define PLT_ENTRY_WORD3 0x45000000 /* movi r16, sizeof(RELA) * n */ ++#define PLT_ENTRY_WORD4 0x48000000 /* j .plt0. */ ++ ++#define PLT_PIC_ENTRY_WORD0 0x46f00000 /* sethi r15, HI20(got[n+3]@GOT) */ ++#define PLT_PIC_ENTRY_WORD1 0x58f78000 /* ori r15, r15, LO12(got[n+3]@GOT) */ ++#define PLT_PIC_ENTRY_WORD2 0x38febc02 /* lw r15, [gp+r15] */ ++#define PLT_PIC_ENTRY_WORD3 0x4a003c00 /* jr r15 */ ++#define PLT_PIC_ENTRY_WORD4 0x45000000 /* movi r16, sizeof(RELA) * n */ ++#define PLT_PIC_ENTRY_WORD5 0x48000000 /* j .plt0 */ ++ ++/* These are macros used to get the relocation accurate value. */ ++#define ACCURATE_8BIT_S1 (0x100) ++#define ACCURATE_U9BIT_S1 (0x400) ++#define ACCURATE_12BIT_S1 (0x2000) ++#define ACCURATE_14BIT_S1 (0x4000) ++#define ACCURATE_19BIT (0x40000) ++ ++/* These are macros used to get the relocation conservative value. */ ++#define CONSERVATIVE_8BIT_S1 (0x100 - 4) ++#define CONSERVATIVE_14BIT_S1 (0x4000 - 4) ++#define CONSERVATIVE_16BIT_S1 (0x10000 - 4) ++#define CONSERVATIVE_24BIT_S1 (0x1000000 - 4) ++/* These must be more conservative because the address may be in ++ different segment. */ ++#define CONSERVATIVE_15BIT (0x4000 - 0x1000) ++#define CONSERVATIVE_15BIT_S1 (0x8000 - 0x1000) ++#define CONSERVATIVE_15BIT_S2 (0x10000 - 0x1000) ++#define CONSERVATIVE_19BIT (0x40000 - 0x1000) ++#define CONSERVATIVE_20BIT (0x80000 - 0x1000) ++ ++#define NDS32_ICT_SECTION ".nds32.ict" ++ ++/* Size of small data/bss sections, used to calculate SDA_BASE. */ ++static long got_size = 0; ++static int is_SDA_BASE_set = 0; ++static int is_ITB_BASE_set = 0; ++ ++/* Convert ELF-VER in eflags to string for debugging purpose. */ ++static const char *const nds32_elfver_strtab[] = { ++ "ELF-1.2", ++ "ELF-1.3", ++ "ELF-1.4", ++}; ++ ++/* The nds32 linker needs to keep track of the number of relocs that it ++ decides to copy in check_relocs for each symbol. This is so that ++ it can discard PC relative relocs if it doesn't need them when ++ linking with -Bsymbolic. We store the information in a field ++ extending the regular ELF linker hash table. */ ++ ++/* This structure keeps track of the number of PC relative relocs we ++ have copied for a given symbol. */ ++ ++struct elf_nds32_pcrel_relocs_copied ++{ ++ /* Next section. */ ++ struct elf_nds32_pcrel_relocs_copied *next; ++ /* A section in dynobj. */ ++ asection *section; ++ /* Number of relocs copied in this section. */ ++ bfd_size_type count; ++}; ++ ++/* The sh linker needs to keep track of the number of relocs that it ++ decides to copy as dynamic relocs in check_relocs for each symbol. ++ This is so that it can later discard them if they are found to be ++ unnecessary. We store the information in a field extending the ++ regular ELF linker hash table. */ ++ ++struct elf_nds32_dyn_relocs ++{ ++ struct elf_nds32_dyn_relocs *next; ++ ++ /* The input section of the reloc. */ ++ asection *sec; ++ ++ /* Total number of relocs copied for the input section. */ ++ bfd_size_type count; ++ ++ /* Number of pc-relative relocs copied for the input section. */ ++ bfd_size_type pc_count; ++}; ++ ++/* Nds32 ELF linker hash entry. */ ++ ++enum elf_nds32_tls_type ++{ ++ GOT_UNKNOWN = (0), ++ GOT_NORMAL = (1 << 0), ++ GOT_TLS_LE = (1 << 1), ++ GOT_TLS_IE = (1 << 2), ++ GOT_TLS_IEGP = (1 << 3), ++ GOT_TLS_LD = (1 << 4), ++ GOT_TLS_GD = (1 << 5), ++ GOT_TLS_DESC = (1 << 6), ++}; ++ ++struct elf_nds32_link_hash_entry ++{ ++ struct elf_link_hash_entry root; ++ ++ /* Track dynamic relocs copied for this symbol. */ ++ struct elf_nds32_dyn_relocs *dyn_relocs; ++ ++ /* For checking relocation type. */ ++ enum elf_nds32_tls_type tls_type; ++ ++ int offset_to_gp; ++ ++ /* For saving function attribute indirect_call and entry address. */ ++ bfd_boolean indirect_call; ++}; ++ ++/* Get the nds32 ELF linker hash table from a link_info structure. */ ++ ++#define FP_BASE_NAME "_FP_BASE_" ++static int check_start_export_sym = 0; ++static size_t ex9_relax_size = 0; /* Save ex9 predicted reducing size. */ ++static asection *ex9_section = NULL; ++/* File for exporting indirect call table. */ ++static FILE *ict_file = NULL; ++static bfd_boolean ignore_indirect_call = FALSE; ++ ++/* Rom-patch symbol hash table. */ ++struct elf_nds32_ict_hash_entry ++{ ++ struct bfd_hash_entry root; ++ struct elf_link_hash_entry *h; ++ unsigned int order; ++}; ++ ++/* Rom-patch hash table. */ ++static struct bfd_hash_table indirect_call_table; ++ ++/* Table to save initial crc table. */ ++static unsigned short byte_crc_table[256]; ++static unsigned short byte_inv_crc_table[256]; ++ ++/* The offset for executable tls relaxation. */ ++#define TP_OFFSET 0x0 ++ ++typedef struct ++{ ++ int min_id; ++ int max_id; ++ int count; ++ int bias; ++ int init; ++} elf32_nds32_relax_group_t; ++ ++struct elf_nds32_obj_tdata ++{ ++ struct elf_obj_tdata root; ++ ++ /* tls_type for each local got entry. */ ++ char *local_got_tls_type; ++ ++ unsigned int hdr_size; ++ ++ /* GOTPLT entries for TLS descriptors. */ ++ bfd_vma *local_tlsdesc_gotent; ++ ++ int* offset_to_gp; ++ ++ /* for R_NDS32_RELAX_GROUP handling. */ ++ elf32_nds32_relax_group_t relax_group; ++}; ++ ++#define elf_nds32_tdata(bfd) \ ++ ((struct elf_nds32_obj_tdata *) (bfd)->tdata.any) ++ ++#define elf32_nds32_local_got_tls_type(bfd) \ ++ (elf_nds32_tdata (bfd)->local_got_tls_type) ++ ++#define elf32_nds32_local_gp_offset(bfd) \ ++ (elf_nds32_tdata (bfd)->offset_to_gp) ++ ++#define elf32_nds32_relax_group_ptr(bfd) \ ++ &(elf_nds32_tdata (bfd)->relax_group) ++ ++#define elf32_nds32_hash_entry(ent) ((struct elf_nds32_link_hash_entry *)(ent)) ++ ++bfd_boolean ++nds32_elf_mkobject (bfd *abfd) ++{ ++ return bfd_elf_allocate_object (abfd, sizeof (struct elf_nds32_obj_tdata), ++ NDS32_ELF_DATA); ++} ++ ++ ++/* Relocations used for relocation. */ ++/* NOTE! ++ the index order must be the same with elf_nds32_reloc_type in ++ include/elf/nds32.h ++ */ ++#define HOWTO2(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ ++ [C] = HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) ++ ++static reloc_howto_type nds32_elf_howto_table[] = { ++ /* This reloc does nothing. */ ++ HOWTO2 (R_NDS32_NONE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_NONE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 16 bit absolute relocation. */ ++ HOWTO2 (R_NDS32_16, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ nds32_elf_generic_reloc,/* special_function */ ++ "R_NDS32_16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 32 bit absolute relocation. */ ++ HOWTO2 (R_NDS32_32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ nds32_elf_generic_reloc,/* special_function */ ++ "R_NDS32_32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 20 bit address. */ ++ HOWTO2 (R_NDS32_20, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_unsigned,/* complain_on_overflow */ ++ nds32_elf_generic_reloc,/* special_function */ ++ "R_NDS32_20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xfffff, /* src_mask */ ++ 0xfffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* An PC Relative 9-bit relocation, shifted by 2. ++ This reloc is complicated because relocations are relative to pc & -4. ++ i.e. branches in the right insn slot use the address of the left insn ++ slot for pc. */ ++ /* ??? It's not clear whether this should have partial_inplace set or not. ++ Branch relaxing in the assembler can store the addend in the insn, ++ and if bfd_install_relocation gets called the addend may get added ++ again. */ ++ HOWTO2 (R_NDS32_9_PCREL, /* type */ ++ 1, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ nds32_elf_9_pcrel_reloc,/* special_function */ ++ "R_NDS32_9_PCREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xff, /* src_mask */ ++ 0xff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative 15 bit relocation, right shifted by 1. */ ++ HOWTO2 (R_NDS32_15_PCREL, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 14, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_15_PCREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x3fff, /* src_mask */ ++ 0x3fff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative 17 bit relocation, right shifted by 1. */ ++ HOWTO2 (R_NDS32_17_PCREL, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_17_PCREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative 25 bit relocation, right shifted by 1. */ ++ /* ??? It's not clear whether this should have partial_inplace set or not. ++ Branch relaxing in the assembler can store the addend in the insn, ++ and if bfd_install_relocation gets called the addend may get added ++ again. */ ++ HOWTO2 (R_NDS32_25_PCREL, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 24, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_25_PCREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffff, /* src_mask */ ++ 0xffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* High 20 bits of address when lower 12 is or'd in. */ ++ HOWTO2 (R_NDS32_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_hi20_reloc, /* special_function */ ++ "R_NDS32_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S3, /* type */ ++ 3, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 9, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_lo12_reloc, /* special_function */ ++ "R_NDS32_LO12S3", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000001ff, /* src_mask */ ++ 0x000001ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S2, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 10, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_lo12_reloc, /* special_function */ ++ "R_NDS32_LO12S2", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000003ff, /* src_mask */ ++ 0x000003ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S1, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 11, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_lo12_reloc, /* special_function */ ++ "R_NDS32_LO12S1", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000007ff, /* src_mask */ ++ 0x000007ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S0, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_lo12_reloc, /* special_function */ ++ "R_NDS32_LO12S0", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA15S3, /* type */ ++ 3, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ nds32_elf_sda15_reloc, /* special_function */ ++ "R_NDS32_SDA15S3", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA15S2, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ nds32_elf_sda15_reloc, /* special_function */ ++ "R_NDS32_SDA15S2", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA15S1, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ nds32_elf_sda15_reloc, /* special_function */ ++ "R_NDS32_SDA15S1", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA15S0, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ nds32_elf_sda15_reloc, /* special_function */ ++ "R_NDS32_SDA15S0", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* GNU extension to record C++ vtable hierarchy */ ++ HOWTO2 (R_NDS32_GNU_VTINHERIT,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ NULL, /* special_function */ ++ "R_NDS32_GNU_VTINHERIT",/* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* GNU extension to record C++ vtable member usage */ ++ HOWTO2 (R_NDS32_GNU_VTENTRY, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ _bfd_elf_rel_vtable_reloc_fn,/* special_function */ ++ "R_NDS32_GNU_VTENTRY", /* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 16 bit absolute relocation. */ ++ HOWTO2 (R_NDS32_16_RELA, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_16_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 32 bit absolute relocation. */ ++ HOWTO2 (R_NDS32_32_RELA, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_32_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 20 bit address. */ ++ HOWTO2 (R_NDS32_20_RELA, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_20_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xfffff, /* src_mask */ ++ 0xfffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_9_PCREL_RELA, /* type */ ++ 1, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_9_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xff, /* src_mask */ ++ 0xff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative 15 bit relocation, right shifted by 1. */ ++ HOWTO2 (R_NDS32_15_PCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 14, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_15_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x3fff, /* src_mask */ ++ 0x3fff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative 17 bit relocation, right shifted by 1. */ ++ HOWTO2 (R_NDS32_17_PCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_17_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative 25 bit relocation, right shifted by 2. */ ++ HOWTO2 (R_NDS32_25_PCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 24, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_25_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffff, /* src_mask */ ++ 0xffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* High 20 bits of address when lower 16 is or'd in. */ ++ HOWTO2 (R_NDS32_HI20_RELA, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_HI20_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S3_RELA, /* type */ ++ 3, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 9, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S3_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000001ff, /* src_mask */ ++ 0x000001ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S2_RELA, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 10, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S2_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000003ff, /* src_mask */ ++ 0x000003ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S1_RELA, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 11, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S1_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000007ff, /* src_mask */ ++ 0x000007ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S0_RELA, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S0_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA15S3_RELA, /* type */ ++ 3, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA15S3_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA15S2_RELA, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA15S2_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_SDA15S1_RELA, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA15S1_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_SDA15S0_RELA, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA15S0_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* GNU extension to record C++ vtable hierarchy */ ++ HOWTO2 (R_NDS32_RELA_GNU_VTINHERIT,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ NULL, /* special_function */ ++ "R_NDS32_RELA_GNU_VTINHERIT",/* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* GNU extension to record C++ vtable member usage */ ++ HOWTO2 (R_NDS32_RELA_GNU_VTENTRY,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ _bfd_elf_rel_vtable_reloc_fn,/* special_function */ ++ "R_NDS32_RELA_GNU_VTENTRY",/* name */ ++ FALSE, /* partial_inplace */ ++ 0, /* src_mask */ ++ 0, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_20, but referring to the GOT table entry for ++ the symbol. */ ++ HOWTO2 (R_NDS32_GOT20, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xfffff, /* src_mask */ ++ 0xfffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_PCREL, but referring to the procedure linkage table ++ entry for the symbol. */ ++ HOWTO2 (R_NDS32_25_PLTREL, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 24, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_25_PLTREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffff, /* src_mask */ ++ 0xffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* This is used only by the dynamic linker. The symbol should exist ++ both in the object being run and in some shared library. The ++ dynamic linker copies the data addressed by the symbol from the ++ shared library into the object, because the object being ++ run has to have the data at some particular address. */ ++ HOWTO2 (R_NDS32_COPY, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_COPY", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_20, but used when setting global offset table ++ entries. */ ++ HOWTO2 (R_NDS32_GLOB_DAT, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GLOB_DAT", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Marks a procedure linkage table entry for a symbol. */ ++ HOWTO2 (R_NDS32_JMP_SLOT, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_JMP_SLOT", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Used only by the dynamic linker. When the object is run, this ++ longword is set to the load address of the object, plus the ++ addend. */ ++ HOWTO2 (R_NDS32_RELATIVE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_RELATIVE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_GOTOFF, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTOFF", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xfffff, /* src_mask */ ++ 0xfffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* An PC Relative 20-bit relocation used when setting PIC offset ++ table register. */ ++ HOWTO2 (R_NDS32_GOTPC20, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTPC20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xfffff, /* src_mask */ ++ 0xfffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_HI20, but referring to the GOT table entry for ++ the symbol. */ ++ HOWTO2 (R_NDS32_GOT_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOT_LO12, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT_LO12", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* An PC Relative relocation used when setting PIC offset table register. ++ Like R_NDS32_HI20, but referring to the GOT table entry for ++ the symbol. */ ++ HOWTO2 (R_NDS32_GOTPC_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTPC_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOTPC_LO12, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTPC_LO12", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_GOTOFF_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTOFF_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOTOFF_LO12, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTOFF_LO12", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Alignment hint for relaxable instruction. This is used with ++ R_NDS32_LABEL as a pair. Relax this instruction from 4 bytes to 2 ++ in order to make next label aligned on word boundary. */ ++ HOWTO2 (R_NDS32_INSN16, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_INSN16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Alignment hint for label. */ ++ HOWTO2 (R_NDS32_LABEL, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LABEL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for unconditional call sequence */ ++ HOWTO2 (R_NDS32_LONGCALL1, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGCALL1", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional call sequence. */ ++ HOWTO2 (R_NDS32_LONGCALL2, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGCALL2", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional call sequence. */ ++ HOWTO2 (R_NDS32_LONGCALL3, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGCALL3", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for unconditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP1, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP1", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP2, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP2", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP3, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP3", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for load/store sequence. */ ++ HOWTO2 (R_NDS32_LOADSTORE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LOADSTORE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for load/store sequence. */ ++ HOWTO2 (R_NDS32_9_FIXED_RELA, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_9_FIXED_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000000ff, /* src_mask */ ++ 0x000000ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for load/store sequence. */ ++ HOWTO2 (R_NDS32_15_FIXED_RELA,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_15_FIXED_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00003fff, /* src_mask */ ++ 0x00003fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for load/store sequence. */ ++ HOWTO2 (R_NDS32_17_FIXED_RELA,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_17_FIXED_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for load/store sequence. */ ++ HOWTO2 (R_NDS32_25_FIXED_RELA,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_25_FIXED_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00ffffff, /* src_mask */ ++ 0x00ffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* High 20 bits of PLT symbol offset relative to PC. */ ++ HOWTO2 (R_NDS32_PLTREL_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLTREL_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Low 12 bits of PLT symbol offset relative to PC. */ ++ HOWTO2 (R_NDS32_PLTREL_LO12, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLTREL_LO12", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* High 20 bits of PLT symbol offset relative to GOT (GP). */ ++ HOWTO2 (R_NDS32_PLT_GOTREL_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLT_GOTREL_HI20",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Low 12 bits of PLT symbol offset relative to GOT (GP). */ ++ HOWTO2 (R_NDS32_PLT_GOTREL_LO12,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLT_GOTREL_LO12",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 12 bits offset. */ ++ HOWTO2 (R_NDS32_SDA12S2_DP_RELA,/* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA12S2_DP_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 12 bits offset. */ ++ HOWTO2 (R_NDS32_SDA12S2_SP_RELA,/* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA12S2_SP_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* Lower 12 bits of address. */ ++ ++ HOWTO2 (R_NDS32_LO12S2_DP_RELA, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 10, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S2_DP_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000003ff, /* src_mask */ ++ 0x000003ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Lower 12 bits of address. */ ++ HOWTO2 (R_NDS32_LO12S2_SP_RELA,/* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 10, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S2_SP_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000003ff, /* src_mask */ ++ 0x000003ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* Lower 12 bits of address. Special identity for or case. */ ++ HOWTO2 (R_NDS32_LO12S0_ORI_RELA,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_LO12S0_ORI_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* Small data area 19 bits offset. */ ++ HOWTO2 (R_NDS32_SDA16S3_RELA, /* type */ ++ 3, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA16S3_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Small data area 15 bits offset. */ ++ HOWTO2 (R_NDS32_SDA17S2_RELA, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 17, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA17S2_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0001ffff, /* src_mask */ ++ 0x0001ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_SDA18S1_RELA, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 18, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA18S1_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0003ffff, /* src_mask */ ++ 0x0003ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_SDA19S0_RELA, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 19, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA19S0_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0007ffff, /* src_mask */ ++ 0x0007ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_DWARF2_OP1_RELA,/* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DWARF2_OP1_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xff, /* src_mask */ ++ 0xff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_DWARF2_OP2_RELA,/* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DWARF2_OP2_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_DWARF2_LEB_RELA,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DWARF2_LEB_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_UPDATE_TA_RELA,/* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_UPDATE_TA_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* Like R_NDS32_PCREL, but referring to the procedure linkage table ++ entry for the symbol. */ ++ HOWTO2 (R_NDS32_9_PLTREL, /* type */ ++ 1, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_9_PLTREL", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xff, /* src_mask */ ++ 0xff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ /* Low 20 bits of PLT symbol offset relative to GOT (GP). */ ++ HOWTO2 (R_NDS32_PLT_GOTREL_LO20,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLT_GOTREL_LO20",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* low 15 bits of PLT symbol offset relative to GOT (GP) */ ++ HOWTO2 (R_NDS32_PLT_GOTREL_LO15,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLT_GOTREL_LO15",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* Low 19 bits of PLT symbol offset relative to GOT (GP). */ ++ HOWTO2 (R_NDS32_PLT_GOTREL_LO19,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 19, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_PLT_GOTREL_LO19",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0007ffff, /* src_mask */ ++ 0x0007ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOT_LO15, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT_LO15", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOT_LO19, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 19, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT_LO19", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x0007ffff, /* src_mask */ ++ 0x0007ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOTOFF_LO15, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTOFF_LO15", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_GOTOFF_LO19, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 19, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOTOFF_LO19", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x0007ffff, /* src_mask */ ++ 0x0007ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* GOT 15 bits offset. */ ++ HOWTO2 (R_NDS32_GOT15S2_RELA, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT15S2_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00007fff, /* src_mask */ ++ 0x00007fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* GOT 17 bits offset. */ ++ HOWTO2 (R_NDS32_GOT17S2_RELA, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 17, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_GOT17S2_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0001ffff, /* src_mask */ ++ 0x0001ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* A 5 bit address. */ ++ HOWTO2 (R_NDS32_5_RELA, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 5, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_5_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x1f, /* src_mask */ ++ 0x1f, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_10_UPCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 9, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_unsigned,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_10_UPCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x1ff, /* src_mask */ ++ 0x1ff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_SDA_FP7U2_RELA,/* type */ ++ 2, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 7, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_unsigned,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SDA_FP7U2_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0000007f, /* src_mask */ ++ 0x0000007f, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_WORD_9_PCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_WORD_9_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xff, /* src_mask */ ++ 0xff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_25_ABS_RELA, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 24, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_25_ABS_RELA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffff, /* src_mask */ ++ 0xffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A relative 17 bit relocation for ifc, right shifted by 1. */ ++ HOWTO2 (R_NDS32_17IFC_PCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_17IFC_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffff, /* src_mask */ ++ 0xffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* A relative unsigned 10 bit relocation for ifc, right shifted by 1. */ ++ HOWTO2 (R_NDS32_10IFCU_PCREL_RELA,/* type */ ++ 1, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 9, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_unsigned,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_10IFCU_PCREL_RELA",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x1ff, /* src_mask */ ++ 0x1ff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* Relax hint for unconditional call sequence */ ++ HOWTO2 (R_NDS32_LONGCALL4, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGCALL4", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional call sequence. */ ++ HOWTO2 (R_NDS32_LONGCALL5, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGCALL5", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional call sequence. */ ++ HOWTO2 (R_NDS32_LONGCALL6, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGCALL6", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for unconditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP4, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP4", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP5, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP5", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP6, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP6", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Relax hint for conditional branch sequence. */ ++ HOWTO2 (R_NDS32_LONGJUMP7, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_LONGJUMP7", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Check sum value for security. */ ++ HOWTO2 (R_NDS32_SECURITY_16, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 5, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_SECURITY_16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x1fffe0, /* src_mask */ ++ 0x1fffe0, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++ ++ /* TLS LE TP offset relocation */ ++ HOWTO2 (R_NDS32_TLS_TPOFF, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_TPOFF", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_HI20, but referring to the TLS LE entry for the symbol. */ ++ HOWTO2 (R_NDS32_TLS_LE_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_LE_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_TLS_LE_LO12, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_LE_LO12", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* A 20 bit address. */ ++ HOWTO2 (R_NDS32_TLS_LE_20, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_LE_20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xfffff, /* src_mask */ ++ 0xfffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_TLS_LE_15S0, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_LE_15S0", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x7fff, /* src_mask */ ++ 0x7fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_TLS_LE_15S1, /* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_LE_15S1", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x7fff, /* src_mask */ ++ 0x7fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_TLS_LE_15S2, /* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 15, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_LE_15S2", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x7fff, /* src_mask */ ++ 0x7fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_HI20, but referring to the TLS IE entry for the symbol. */ ++ HOWTO2 (R_NDS32_TLS_IE_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_IE_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_TLS_IE_LO12, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_IE_LO12", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO2 (R_NDS32_TLS_IE_LO12S2,/* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 10, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_IE_LO12S2",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000003ff, /* src_mask */ ++ 0x000003ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Like R_NDS32_HI20, but referring to the TLS IE (PIE) entry for the symbol. */ ++ HOWTO2 (R_NDS32_TLS_IEGP_HI20,/* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_IEGP_HI20",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_TLS_IEGP_LO12,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_IEGP_LO12",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO2 (R_NDS32_TLS_IEGP_LO12S2,/* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 10, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_IEGP_LO12S2",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000003ff, /* src_mask */ ++ 0x000003ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS description relocation */ ++ HOWTO2 (R_NDS32_TLS_DESC, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_hi20_reloc, /* special_function */ ++ "R_NDS32_TLS_DESC_HI20",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description offset high part. */ ++ HOWTO2 (R_NDS32_TLS_DESC_HI20,/* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_hi20_reloc, /* special_function */ ++ "R_NDS32_TLS_DESC_HI20",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* TLS GD/LD description offset low part. */ ++ HOWTO2 (R_NDS32_TLS_DESC_LO12,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_lo12_reloc, /* special_function */ ++ "R_NDS32_TLS_DESC_LO12",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description offset set (movi). */ ++ HOWTO2 (R_NDS32_TLS_DESC_20, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_DESC_20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description offset set (lwi.gp). */ ++ HOWTO2 (R_NDS32_TLS_DESC_SDA17S2,/* type */ ++ 2, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 17, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_TLS_DESC_SDA17S2",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x0001ffff, /* src_mask */ ++ 0x0001ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* Jump-patch table relocations. */ ++ /* High 20 bits of jump-patch table address. */ ++ HOWTO2 (R_NDS32_ICT_HI20, /* type */ ++ 12, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 20, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_ICT_HI20", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000fffff, /* src_mask */ ++ 0x000fffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* Lower 12 bits of jump-patch table address. */ ++ HOWTO2 (R_NDS32_ICT_LO12,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 12, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_ICT_LO12",/* name */ ++ FALSE, /* partial_inplace */ ++ 0x00000fff, /* src_mask */ ++ 0x00000fff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ /* A relative 25 bit relocation, right shifted by 2. */ ++ HOWTO2 (R_NDS32_ICT_25PC,/* type */ ++ 1, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 24, /* bitsize */ ++ TRUE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_signed,/* complain_on_overflow */ ++ bfd_elf_generic_reloc, /* special_function */ ++ "R_NDS32_ICT_25PC",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffff, /* src_mask */ ++ 0xffffff, /* dst_mask */ ++ TRUE), /* pcrel_offset */ ++}; ++ ++/* Relocations used for relaxation. */ ++#define HOWTO3(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ ++ [C-R_NDS32_RELAX_ENTRY] = HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) ++ ++static reloc_howto_type nds32_elf_relax_howto_table[] = { ++ HOWTO3 (R_NDS32_RELAX_ENTRY, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_RELAX_ENTRY", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_GOT_SUFF, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_GOT_SUFF", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_GOTOFF_SUFF, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_bitfield,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_GOTOFF_SUFF", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_PLT_GOT_SUFF, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_PLT_GOT_SUFF",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_MULCALL_SUFF, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_MULCALL_SUFF",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_PTR, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_PTR", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_PTR_COUNT, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_PTR_COUNT", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_PTR_RESOLVED, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_PTR_RESOLVED",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_PLTBLOCK, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_PLTBLOCK", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_RELAX_REGION_BEGIN,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_RELAX_REGION_BEGIN",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_RELAX_REGION_END,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_RELAX_REGION_END",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_MINUEND, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_MINUEND", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_SUBTRAHEND, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_SUBTRAHEND", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_DIFF8, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 8, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DIFF8", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x000000ff, /* src_mask */ ++ 0x000000ff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_DIFF16, /* type */ ++ 0, /* rightshift */ ++ 1, /* size (0 = byte, 1 = short, 2 = long) */ ++ 16, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DIFF16", /* name */ ++ FALSE, /* partial_inplace */ ++ 0x0000ffff, /* src_mask */ ++ 0x0000ffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_DIFF32, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DIFF32", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_DIFF_ULEB128, /* type */ ++ 0, /* rightshift */ ++ 0, /* size (0 = byte, 1 = short, 2 = long) */ ++ 0, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DIFF_ULEB128",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_DATA, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_DATA", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_TRAN, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TRAN", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_EMPTY, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_EMPTY", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO3 (R_NDS32_TLS_LE_ADD, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_LE_ADD", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ HOWTO3 (R_NDS32_TLS_LE_LS, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_LE_LS", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ HOWTO3 (R_NDS32_TLS_IEGP_LW, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_IEGP_LW", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description address base addition. */ ++ HOWTO3 (R_NDS32_TLS_DESC_ADD, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_DESC_ADD",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description function load. */ ++ HOWTO3 (R_NDS32_TLS_DESC_FUNC,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_DESC_FUNC",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS DESC resolve function call. */ ++ HOWTO3 (R_NDS32_TLS_DESC_CALL,/* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_DESC_CALL",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS DESC variable access. */ ++ HOWTO3 (R_NDS32_TLS_DESC_MEM, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_TLS_DESC_MEM",/* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description mark (@tlsdec). */ ++ HOWTO3 (R_NDS32_RELAX_REMOVE, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_REMOVE", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++ ++ /* TLS GD/LD description mark (@tlsdec). */ ++ HOWTO3 (R_NDS32_RELAX_GROUP, /* type */ ++ 0, /* rightshift */ ++ 2, /* size (0 = byte, 1 = short, 2 = long) */ ++ 32, /* bitsize */ ++ FALSE, /* pc_relative */ ++ 0, /* bitpos */ ++ complain_overflow_dont,/* complain_on_overflow */ ++ nds32_elf_ignore_reloc,/* special_function */ ++ "R_NDS32_GROUP", /* name */ ++ FALSE, /* partial_inplace */ ++ 0xffffffff, /* src_mask */ ++ 0xffffffff, /* dst_mask */ ++ FALSE), /* pcrel_offset */ ++}; ++ ++ ++static unsigned long dl_tlsdesc_lazy_trampoline[] = ++{ ++ 0x46200000, /* sethi $r2,#0x0 */ ++ 0x58210000, /* ori $r2,$r2,#0x0 */ ++ 0x40217400, /* add $r2,$r2,$gp */ ++ 0x04210000, /* lwi $r2,[$r2+#0x0] */ ++ 0x46300000, /* sethi $r3,#0x0 */ ++ 0x58318000, /* ori $r3,$r3,#0x0 */ ++ 0x4031f400, /* add $r3,$r3,$gp */ ++ 0x4a000800, /* jr $r2 */ ++}; ++ ++/* === code === */ ++ ++static void ++nds32_put_trampoline (void *contents, const unsigned long *template, ++ unsigned count) ++{ ++ unsigned ix; ++ ++ for (ix = 0; ix != count; ix++) ++ { ++ unsigned long insn = template[ix]; ++ bfd_putb32 (insn, (char *) contents + ix * 4); ++ } ++} ++ ++/* nds32_insertion_sort sorts an array with nmemb elements of size size. ++ This prototype is the same as qsort (). */ ++ ++void ++nds32_insertion_sort (void *base, size_t nmemb, size_t size, ++ int (*compar) (const void *lhs, const void *rhs)) ++{ ++ char *ptr = (char *) base; ++ int i, j; ++ char *tmp = alloca (size); ++ ++ /* If i is less than j, i is inserted before j. ++ ++ |---- j ----- i --------------| ++ \ / \ / ++ sorted unsorted ++ */ ++ ++ for (i = 1; i < (int) nmemb; i++) ++ { ++ for (j = (i - 1); j >= 0; j--) ++ if (compar (ptr + i * size, ptr + j * size) >= 0) ++ break; ++ ++ j++; ++ ++ if (i == j) ++ continue; /* i is in order. */ ++ ++ memcpy (tmp, ptr + i * size, size); ++ memmove (ptr + (j + 1) * size, ptr + j * size, (i - j) * size); ++ memcpy (ptr + j * size, tmp, size); ++ } ++} ++ ++/* Sort relocation by r_offset. ++ ++ We didn't use qsort () in stdlib, because quick-sort is not a stable sorting ++ algorithm. Relocations at the same r_offset must keep their order. ++ For example, RELAX_ENTRY must be the very first relocation entry. ++ ++ Currently, this function implements insertion-sort. ++ ++ FIXME: If we already sort them in assembler, why bother sort them ++ here again? */ ++ ++static int ++compar_reloc (const void *lhs, const void *rhs) ++{ ++ const Elf_Internal_Rela *l = (const Elf_Internal_Rela *) lhs; ++ const Elf_Internal_Rela *r = (const Elf_Internal_Rela *) rhs; ++ ++ if (l->r_offset > r->r_offset) ++ return 1; ++ else if (l->r_offset == r->r_offset) ++ return 0; ++ else ++ return -1; ++} ++ ++/* Functions listed below are only used for old relocs. ++ nds32_elf_9_pcrel_reloc ++ nds32_elf_do_9_pcrel_reloc ++ nds32_elf_hi20_reloc ++ nds32_elf_relocate_hi20 ++ nds32_elf_lo12_reloc ++ nds32_elf_sda15_reloc ++ nds32_elf_generic_reloc */ ++ ++/* Handle the R_NDS32_9_PCREL & R_NDS32_9_PCREL_RELA reloc. */ ++ ++static bfd_reloc_status_type ++nds32_elf_9_pcrel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, ++ void *data, asection *input_section, bfd *output_bfd, ++ char **error_message ATTRIBUTE_UNUSED) ++{ ++ /* This part is from bfd_elf_generic_reloc. */ ++ if (output_bfd != (bfd *) NULL ++ && (symbol->flags & BSF_SECTION_SYM) == 0 ++ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ if (output_bfd != NULL) ++ { ++ /* FIXME: See bfd_perform_relocation. Is this right? */ ++ return bfd_reloc_continue; ++ } ++ ++ return nds32_elf_do_9_pcrel_reloc (abfd, reloc_entry->howto, ++ input_section, ++ data, reloc_entry->address, ++ symbol->section, ++ (symbol->value ++ + symbol->section->output_section->vma ++ + symbol->section->output_offset), ++ reloc_entry->addend); ++} ++ ++/* Utility to actually perform an R_NDS32_9_PCREL reloc. */ ++#define N_ONES(n) (((((bfd_vma) 1 << ((n) - 1)) - 1) << 1) | 1) ++ ++static bfd_reloc_status_type ++nds32_elf_do_9_pcrel_reloc (bfd *abfd, reloc_howto_type *howto, ++ asection *input_section, bfd_byte *data, ++ bfd_vma offset, ++ asection *symbol_section ATTRIBUTE_UNUSED, ++ bfd_vma symbol_value, bfd_vma addend) ++{ ++ bfd_signed_vma relocation; ++ unsigned short x; ++ bfd_reloc_status_type status; ++ ++ /* Sanity check the address (offset in section). */ ++ if (offset > bfd_get_section_limit (abfd, input_section)) ++ return bfd_reloc_outofrange; ++ ++ relocation = symbol_value + addend; ++ /* Make it pc relative. */ ++ relocation -= (input_section->output_section->vma ++ + input_section->output_offset); ++ /* These jumps mask off the lower two bits of the current address ++ before doing pcrel calculations. */ ++ relocation -= (offset & -(bfd_vma) 2); ++ ++ if (relocation < -ACCURATE_8BIT_S1 || relocation >= ACCURATE_8BIT_S1) ++ status = bfd_reloc_overflow; ++ else ++ status = bfd_reloc_ok; ++ ++ x = bfd_getb16 (data + offset); ++ ++ relocation >>= howto->rightshift; ++ relocation <<= howto->bitpos; ++ x = (x & ~howto->dst_mask) ++ | (((x & howto->src_mask) + relocation) & howto->dst_mask); ++ ++ bfd_putb16 ((bfd_vma) x, data + offset); ++ ++ return status; ++} ++ ++/* Handle the R_NDS32_HI20_[SU]LO relocs. ++ HI20_SLO is for the add3 and load/store with displacement instructions. ++ HI20 is for the or3 instruction. ++ For R_NDS32_HI20_SLO, the lower 16 bits are sign extended when added to ++ the high 16 bytes so if the lower 16 bits are negative (bit 15 == 1) then ++ we must add one to the high 16 bytes (which will get subtracted off when ++ the low 16 bits are added). ++ These relocs have to be done in combination with an R_NDS32_LO12 reloc ++ because there is a carry from the LO12 to the HI20. Here we just save ++ the information we need; we do the actual relocation when we see the LO12. ++ This code is copied from the elf32-mips.c. We also support an arbitrary ++ number of HI20 relocs to be associated with a single LO12 reloc. The ++ assembler sorts the relocs to ensure each HI20 immediately precedes its ++ LO12. However if there are multiple copies, the assembler may not find ++ the real LO12 so it picks the first one it finds. */ ++ ++struct nds32_hi20 ++{ ++ struct nds32_hi20 *next; ++ bfd_byte *addr; ++ bfd_vma addend; ++}; ++ ++static struct nds32_hi20 *nds32_hi20_list; ++ ++static bfd_reloc_status_type ++nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, ++ asymbol *symbol, void *data, asection *input_section, ++ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) ++{ ++ bfd_reloc_status_type ret; ++ bfd_vma relocation; ++ struct nds32_hi20 *n; ++ ++ /* This part is from bfd_elf_generic_reloc. ++ If we're relocating, and this an external symbol, we don't want ++ to change anything. */ ++ if (output_bfd != (bfd *) NULL ++ && (symbol->flags & BSF_SECTION_SYM) == 0 && reloc_entry->addend == 0) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ /* Sanity check the address (offset in section). */ ++ if (reloc_entry->address > bfd_get_section_limit (abfd, input_section)) ++ return bfd_reloc_outofrange; ++ ++ ret = bfd_reloc_ok; ++ if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL) ++ ret = bfd_reloc_undefined; ++ ++ if (bfd_is_com_section (symbol->section)) ++ relocation = 0; ++ else ++ relocation = symbol->value; ++ ++ relocation += symbol->section->output_section->vma; ++ relocation += symbol->section->output_offset; ++ relocation += reloc_entry->addend; ++ ++ /* Save the information, and let LO12 do the actual relocation. */ ++ n = (struct nds32_hi20 *) bfd_malloc ((bfd_size_type) sizeof *n); ++ if (n == NULL) ++ return bfd_reloc_outofrange; ++ ++ n->addr = (bfd_byte *) data + reloc_entry->address; ++ n->addend = relocation; ++ n->next = nds32_hi20_list; ++ nds32_hi20_list = n; ++ ++ if (output_bfd != (bfd *) NULL) ++ reloc_entry->address += input_section->output_offset; ++ ++ return ret; ++} ++ ++/* Handle an NDS32 ELF HI20 reloc. */ ++ ++static void ++nds32_elf_relocate_hi20 (bfd *input_bfd ATTRIBUTE_UNUSED, ++ int type ATTRIBUTE_UNUSED, Elf_Internal_Rela *relhi, ++ Elf_Internal_Rela *rello, bfd_byte *contents, ++ bfd_vma addend) ++{ ++ unsigned long insn; ++ bfd_vma addlo; ++ ++ insn = bfd_getb32 (contents + relhi->r_offset); ++ ++ addlo = bfd_getb32 (contents + rello->r_offset); ++ addlo &= 0xfff; ++ ++ addend += ((insn & 0xfffff) << 20) + addlo; ++ ++ insn = (insn & 0xfff00000) | ((addend >> 12) & 0xfffff); ++ bfd_putb32 (insn, contents + relhi->r_offset); ++} ++ ++/* Do an R_NDS32_LO12 relocation. This is a straightforward 12 bit ++ inplace relocation; this function exists in order to do the ++ R_NDS32_HI20_[SU]LO relocation described above. */ ++ ++static bfd_reloc_status_type ++nds32_elf_lo12_reloc (bfd *input_bfd, arelent *reloc_entry, asymbol *symbol, ++ void *data, asection *input_section, bfd *output_bfd, ++ char **error_message) ++{ ++ /* This part is from bfd_elf_generic_reloc. ++ If we're relocating, and this an external symbol, we don't want ++ to change anything. */ ++ if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 ++ && reloc_entry->addend == 0) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ if (nds32_hi20_list != NULL) ++ { ++ struct nds32_hi20 *l; ++ ++ l = nds32_hi20_list; ++ while (l != NULL) ++ { ++ unsigned long insn; ++ unsigned long val; ++ unsigned long vallo; ++ struct nds32_hi20 *next; ++ ++ /* Do the HI20 relocation. Note that we actually don't need ++ to know anything about the LO12 itself, except where to ++ find the low 12 bits of the addend needed by the LO12. */ ++ insn = bfd_getb32 (l->addr); ++ vallo = bfd_getb32 ((bfd_byte *) data + reloc_entry->address); ++ vallo &= 0xfff; ++ switch (reloc_entry->howto->type) ++ { ++ case R_NDS32_LO12S3: ++ vallo <<= 3; ++ break; ++ ++ case R_NDS32_LO12S2: ++ vallo <<= 2; ++ break; ++ ++ case R_NDS32_LO12S1: ++ vallo <<= 1; ++ break; ++ ++ case R_NDS32_LO12S0: ++ vallo <<= 0; ++ break; ++ } ++ ++ val = ((insn & 0xfffff) << 12) + vallo; ++ val += l->addend; ++ ++ insn = (insn & ~(bfd_vma) 0xfffff) | ((val >> 12) & 0xfffff); ++ bfd_putb32 ((bfd_vma) insn, l->addr); ++ ++ next = l->next; ++ free (l); ++ l = next; ++ } ++ ++ nds32_hi20_list = NULL; ++ } ++ ++ /* Now do the LO12 reloc in the usual way. ++ ??? It would be nice to call bfd_elf_generic_reloc here, ++ but we have partial_inplace set. bfd_elf_generic_reloc will ++ pass the handling back to bfd_install_relocation which will install ++ a section relative addend which is wrong. */ ++ return nds32_elf_generic_reloc (input_bfd, reloc_entry, symbol, data, ++ input_section, output_bfd, error_message); ++} ++ ++/* Do generic partial_inplace relocation. ++ This is a local replacement for bfd_elf_generic_reloc. */ ++ ++static bfd_reloc_status_type ++nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry, ++ asymbol *symbol, void *data, asection *input_section, ++ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) ++{ ++ bfd_reloc_status_type ret; ++ bfd_vma relocation; ++ bfd_byte *inplace_address; ++ ++ /* This part is from bfd_elf_generic_reloc. ++ If we're relocating, and this an external symbol, we don't want ++ to change anything. */ ++ if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 ++ && reloc_entry->addend == 0) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ /* Now do the reloc in the usual way. ++ ??? It would be nice to call bfd_elf_generic_reloc here, ++ but we have partial_inplace set. bfd_elf_generic_reloc will ++ pass the handling back to bfd_install_relocation which will install ++ a section relative addend which is wrong. */ ++ ++ /* Sanity check the address (offset in section). */ ++ if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section)) ++ return bfd_reloc_outofrange; ++ ++ ret = bfd_reloc_ok; ++ if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL) ++ ret = bfd_reloc_undefined; ++ ++ if (bfd_is_com_section (symbol->section) || output_bfd != (bfd *) NULL) ++ relocation = 0; ++ else ++ relocation = symbol->value; ++ ++ /* Only do this for a final link. */ ++ if (output_bfd == (bfd *) NULL) ++ { ++ relocation += symbol->section->output_section->vma; ++ relocation += symbol->section->output_offset; ++ } ++ ++ relocation += reloc_entry->addend; ++ switch (reloc_entry->howto->type) ++ { ++ case R_NDS32_LO12S3: ++ relocation >>= 3; ++ break; ++ ++ case R_NDS32_LO12S2: ++ relocation >>= 2; ++ break; ++ ++ case R_NDS32_LO12S1: ++ relocation >>= 1; ++ break; ++ ++ case R_NDS32_LO12S0: ++ default: ++ relocation >>= 0; ++ break; ++ } ++ ++ inplace_address = (bfd_byte *) data + reloc_entry->address; ++ ++#define DOIT(x) \ ++ x = ((x & ~reloc_entry->howto->dst_mask) | \ ++ (((x & reloc_entry->howto->src_mask) + relocation) & \ ++ reloc_entry->howto->dst_mask)) ++ ++ switch (reloc_entry->howto->size) ++ { ++ case 1: ++ { ++ short x = bfd_getb16 (inplace_address); ++ ++ DOIT (x); ++ bfd_putb16 ((bfd_vma) x, inplace_address); ++ } ++ break; ++ case 2: ++ { ++ unsigned long x = bfd_getb32 (inplace_address); ++ ++ DOIT (x); ++ bfd_putb32 ((bfd_vma) x, inplace_address); ++ } ++ break; ++ default: ++ BFD_ASSERT (0); ++ } ++ ++ if (output_bfd != (bfd *) NULL) ++ reloc_entry->address += input_section->output_offset; ++ ++ return ret; ++} ++ ++/* Handle the R_NDS32_SDA15 reloc. ++ This reloc is used to compute the address of objects in the small data area ++ and to perform loads and stores from that area. ++ The lower 15 bits are sign extended and added to the register specified ++ in the instruction, which is assumed to point to _SDA_BASE_. ++ ++ Since the lower 15 bits offset is left-shifted 0, 1 or 2 bits depending on ++ the access size, this must be taken care of. */ ++ ++static bfd_reloc_status_type ++nds32_elf_sda15_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, ++ asymbol *symbol, void *data ATTRIBUTE_UNUSED, ++ asection *input_section, bfd *output_bfd, ++ char **error_message ATTRIBUTE_UNUSED) ++{ ++ /* This part is from bfd_elf_generic_reloc. */ ++ if (output_bfd != (bfd *) NULL ++ && (symbol->flags & BSF_SECTION_SYM) == 0 ++ && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0)) ++ { ++ reloc_entry->address += input_section->output_offset; ++ return bfd_reloc_ok; ++ } ++ ++ if (output_bfd != NULL) ++ { ++ /* FIXME: See bfd_perform_relocation. Is this right? */ ++ return bfd_reloc_continue; ++ } ++ ++ /* FIXME: not sure what to do here yet. But then again, the linker ++ may never call us. */ ++ abort (); ++} ++ ++/* nds32_elf_ignore_reloc is the special function for ++ relocation types which don't need to be relocated ++ like relaxation relocation types. ++ This function simply return bfd_reloc_ok when it is ++ invoked. */ ++ ++static bfd_reloc_status_type ++nds32_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry, ++ asymbol *symbol ATTRIBUTE_UNUSED, ++ void *data ATTRIBUTE_UNUSED, asection *input_section, ++ bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) ++{ ++ if (output_bfd != NULL) ++ reloc_entry->address += input_section->output_offset; ++ ++ return bfd_reloc_ok; ++} ++ ++ ++/* Map BFD reloc types to NDS32 ELF reloc types. */ ++ ++struct nds32_reloc_map_entry ++{ ++ bfd_reloc_code_real_type bfd_reloc_val; ++ unsigned char elf_reloc_val; ++}; ++ ++static const struct nds32_reloc_map_entry nds32_reloc_map[] = { ++ {BFD_RELOC_NONE, R_NDS32_NONE}, ++ {BFD_RELOC_16, R_NDS32_16_RELA}, ++ {BFD_RELOC_32, R_NDS32_32_RELA}, ++ {BFD_RELOC_NDS32_20, R_NDS32_20_RELA}, ++ {BFD_RELOC_NDS32_5, R_NDS32_5_RELA}, ++ {BFD_RELOC_NDS32_9_PCREL, R_NDS32_9_PCREL_RELA}, ++ {BFD_RELOC_NDS32_WORD_9_PCREL, R_NDS32_WORD_9_PCREL_RELA}, ++ {BFD_RELOC_NDS32_15_PCREL, R_NDS32_15_PCREL_RELA}, ++ {BFD_RELOC_NDS32_17_PCREL, R_NDS32_17_PCREL_RELA}, ++ {BFD_RELOC_NDS32_25_PCREL, R_NDS32_25_PCREL_RELA}, ++ {BFD_RELOC_NDS32_10_UPCREL, R_NDS32_10_UPCREL_RELA}, ++ {BFD_RELOC_NDS32_HI20, R_NDS32_HI20_RELA}, ++ {BFD_RELOC_NDS32_LO12S3, R_NDS32_LO12S3_RELA}, ++ {BFD_RELOC_NDS32_LO12S2, R_NDS32_LO12S2_RELA}, ++ {BFD_RELOC_NDS32_LO12S1, R_NDS32_LO12S1_RELA}, ++ {BFD_RELOC_NDS32_LO12S0, R_NDS32_LO12S0_RELA}, ++ {BFD_RELOC_NDS32_LO12S0_ORI, R_NDS32_LO12S0_ORI_RELA}, ++ {BFD_RELOC_NDS32_SDA15S3, R_NDS32_SDA15S3_RELA}, ++ {BFD_RELOC_NDS32_SDA15S2, R_NDS32_SDA15S2_RELA}, ++ {BFD_RELOC_NDS32_SDA15S1, R_NDS32_SDA15S1_RELA}, ++ {BFD_RELOC_NDS32_SDA15S0, R_NDS32_SDA15S0_RELA}, ++ {BFD_RELOC_VTABLE_INHERIT, R_NDS32_RELA_GNU_VTINHERIT}, ++ {BFD_RELOC_VTABLE_ENTRY, R_NDS32_RELA_GNU_VTENTRY}, ++ ++ {BFD_RELOC_NDS32_GOT20, R_NDS32_GOT20}, ++ {BFD_RELOC_NDS32_9_PLTREL, R_NDS32_9_PLTREL}, ++ {BFD_RELOC_NDS32_25_PLTREL, R_NDS32_25_PLTREL}, ++ {BFD_RELOC_NDS32_COPY, R_NDS32_COPY}, ++ {BFD_RELOC_NDS32_GLOB_DAT, R_NDS32_GLOB_DAT}, ++ {BFD_RELOC_NDS32_JMP_SLOT, R_NDS32_JMP_SLOT}, ++ {BFD_RELOC_NDS32_RELATIVE, R_NDS32_RELATIVE}, ++ {BFD_RELOC_NDS32_GOTOFF, R_NDS32_GOTOFF}, ++ {BFD_RELOC_NDS32_GOTPC20, R_NDS32_GOTPC20}, ++ {BFD_RELOC_NDS32_GOT_HI20, R_NDS32_GOT_HI20}, ++ {BFD_RELOC_NDS32_GOT_LO12, R_NDS32_GOT_LO12}, ++ {BFD_RELOC_NDS32_GOT_LO15, R_NDS32_GOT_LO15}, ++ {BFD_RELOC_NDS32_GOT_LO19, R_NDS32_GOT_LO19}, ++ {BFD_RELOC_NDS32_GOTPC_HI20, R_NDS32_GOTPC_HI20}, ++ {BFD_RELOC_NDS32_GOTPC_LO12, R_NDS32_GOTPC_LO12}, ++ {BFD_RELOC_NDS32_GOTOFF_HI20, R_NDS32_GOTOFF_HI20}, ++ {BFD_RELOC_NDS32_GOTOFF_LO12, R_NDS32_GOTOFF_LO12}, ++ {BFD_RELOC_NDS32_GOTOFF_LO15, R_NDS32_GOTOFF_LO15}, ++ {BFD_RELOC_NDS32_GOTOFF_LO19, R_NDS32_GOTOFF_LO19}, ++ {BFD_RELOC_NDS32_INSN16, R_NDS32_INSN16}, ++ {BFD_RELOC_NDS32_LABEL, R_NDS32_LABEL}, ++ {BFD_RELOC_NDS32_LONGCALL1, R_NDS32_LONGCALL1}, ++ {BFD_RELOC_NDS32_LONGCALL2, R_NDS32_LONGCALL2}, ++ {BFD_RELOC_NDS32_LONGCALL3, R_NDS32_LONGCALL3}, ++ {BFD_RELOC_NDS32_LONGCALL4, R_NDS32_LONGCALL4}, ++ {BFD_RELOC_NDS32_LONGCALL5, R_NDS32_LONGCALL5}, ++ {BFD_RELOC_NDS32_LONGCALL6, R_NDS32_LONGCALL6}, ++ {BFD_RELOC_NDS32_LONGJUMP1, R_NDS32_LONGJUMP1}, ++ {BFD_RELOC_NDS32_LONGJUMP2, R_NDS32_LONGJUMP2}, ++ {BFD_RELOC_NDS32_LONGJUMP3, R_NDS32_LONGJUMP3}, ++ {BFD_RELOC_NDS32_LONGJUMP4, R_NDS32_LONGJUMP4}, ++ {BFD_RELOC_NDS32_LONGJUMP5, R_NDS32_LONGJUMP5}, ++ {BFD_RELOC_NDS32_LONGJUMP6, R_NDS32_LONGJUMP6}, ++ {BFD_RELOC_NDS32_LONGJUMP7, R_NDS32_LONGJUMP7}, ++ {BFD_RELOC_NDS32_SECURITY_16, R_NDS32_SECURITY_16}, ++ {BFD_RELOC_NDS32_LOADSTORE, R_NDS32_LOADSTORE}, ++ {BFD_RELOC_NDS32_9_FIXED, R_NDS32_9_FIXED_RELA}, ++ {BFD_RELOC_NDS32_15_FIXED, R_NDS32_15_FIXED_RELA}, ++ {BFD_RELOC_NDS32_17_FIXED, R_NDS32_17_FIXED_RELA}, ++ {BFD_RELOC_NDS32_25_FIXED, R_NDS32_25_FIXED_RELA}, ++ {BFD_RELOC_NDS32_PLTREL_HI20, R_NDS32_PLTREL_HI20}, ++ {BFD_RELOC_NDS32_PLTREL_LO12, R_NDS32_PLTREL_LO12}, ++ {BFD_RELOC_NDS32_PLT_GOTREL_HI20, R_NDS32_PLT_GOTREL_HI20}, ++ {BFD_RELOC_NDS32_PLT_GOTREL_LO12, R_NDS32_PLT_GOTREL_LO12}, ++ {BFD_RELOC_NDS32_PLT_GOTREL_LO15, R_NDS32_PLT_GOTREL_LO15}, ++ {BFD_RELOC_NDS32_PLT_GOTREL_LO19, R_NDS32_PLT_GOTREL_LO19}, ++ {BFD_RELOC_NDS32_PLT_GOTREL_LO20, R_NDS32_PLT_GOTREL_LO20}, ++ {BFD_RELOC_NDS32_SDA12S2_DP, R_NDS32_SDA12S2_DP_RELA}, ++ {BFD_RELOC_NDS32_SDA12S2_SP, R_NDS32_SDA12S2_SP_RELA}, ++ {BFD_RELOC_NDS32_LO12S2_DP, R_NDS32_LO12S2_DP_RELA}, ++ {BFD_RELOC_NDS32_LO12S2_SP, R_NDS32_LO12S2_SP_RELA}, ++ {BFD_RELOC_NDS32_SDA16S3, R_NDS32_SDA16S3_RELA}, ++ {BFD_RELOC_NDS32_SDA17S2, R_NDS32_SDA17S2_RELA}, ++ {BFD_RELOC_NDS32_SDA18S1, R_NDS32_SDA18S1_RELA}, ++ {BFD_RELOC_NDS32_SDA19S0, R_NDS32_SDA19S0_RELA}, ++ {BFD_RELOC_NDS32_SDA_FP7U2_RELA, R_NDS32_SDA_FP7U2_RELA}, ++ {BFD_RELOC_NDS32_DWARF2_OP1, R_NDS32_DWARF2_OP1_RELA}, ++ {BFD_RELOC_NDS32_DWARF2_OP2, R_NDS32_DWARF2_OP2_RELA}, ++ {BFD_RELOC_NDS32_DWARF2_LEB, R_NDS32_DWARF2_LEB_RELA}, ++ {BFD_RELOC_NDS32_UPDATE_TA, R_NDS32_UPDATE_TA_RELA}, ++ {BFD_RELOC_NDS32_GOT_SUFF, R_NDS32_GOT_SUFF}, ++ {BFD_RELOC_NDS32_GOTOFF_SUFF, R_NDS32_GOTOFF_SUFF}, ++ {BFD_RELOC_NDS32_GOT15S2, R_NDS32_GOT15S2_RELA}, ++ {BFD_RELOC_NDS32_GOT17S2, R_NDS32_GOT17S2_RELA}, ++ {BFD_RELOC_NDS32_PTR, R_NDS32_PTR}, ++ {BFD_RELOC_NDS32_PTR_COUNT, R_NDS32_PTR_COUNT}, ++ {BFD_RELOC_NDS32_PLT_GOT_SUFF, R_NDS32_PLT_GOT_SUFF}, ++ {BFD_RELOC_NDS32_PTR_RESOLVED, R_NDS32_PTR_RESOLVED}, ++ {BFD_RELOC_NDS32_RELAX_ENTRY, R_NDS32_RELAX_ENTRY}, ++ {BFD_RELOC_NDS32_MULCALL_SUFF, R_NDS32_MULCALL_SUFF}, ++ {BFD_RELOC_NDS32_PLTBLOCK, R_NDS32_PLTBLOCK}, ++ {BFD_RELOC_NDS32_RELAX_REGION_BEGIN, R_NDS32_RELAX_REGION_BEGIN}, ++ {BFD_RELOC_NDS32_RELAX_REGION_END, R_NDS32_RELAX_REGION_END}, ++ {BFD_RELOC_NDS32_MINUEND, R_NDS32_MINUEND}, ++ {BFD_RELOC_NDS32_SUBTRAHEND, R_NDS32_SUBTRAHEND}, ++ {BFD_RELOC_NDS32_EMPTY, R_NDS32_EMPTY}, ++ ++ {BFD_RELOC_NDS32_DIFF8, R_NDS32_DIFF8}, ++ {BFD_RELOC_NDS32_DIFF16, R_NDS32_DIFF16}, ++ {BFD_RELOC_NDS32_DIFF32, R_NDS32_DIFF32}, ++ {BFD_RELOC_NDS32_DIFF_ULEB128, R_NDS32_DIFF_ULEB128}, ++ {BFD_RELOC_NDS32_25_ABS, R_NDS32_25_ABS_RELA}, ++ {BFD_RELOC_NDS32_DATA, R_NDS32_DATA}, ++ {BFD_RELOC_NDS32_TRAN, R_NDS32_TRAN}, ++ {BFD_RELOC_NDS32_17IFC_PCREL, R_NDS32_17IFC_PCREL_RELA}, ++ {BFD_RELOC_NDS32_10IFCU_PCREL, R_NDS32_10IFCU_PCREL_RELA}, ++ {BFD_RELOC_NDS32_TLS_LE_HI20, R_NDS32_TLS_LE_HI20}, ++ {BFD_RELOC_NDS32_TLS_LE_LO12, R_NDS32_TLS_LE_LO12}, ++ {BFD_RELOC_NDS32_TLS_LE_ADD, R_NDS32_TLS_LE_ADD}, ++ {BFD_RELOC_NDS32_TLS_LE_LS, R_NDS32_TLS_LE_LS}, ++ {BFD_RELOC_NDS32_TLS_IE_HI20, R_NDS32_TLS_IE_HI20}, ++ {BFD_RELOC_NDS32_TLS_IE_LO12S2, R_NDS32_TLS_IE_LO12S2}, ++ {BFD_RELOC_NDS32_TLS_LE_20, R_NDS32_TLS_LE_20}, ++ {BFD_RELOC_NDS32_TLS_LE_15S0, R_NDS32_TLS_LE_15S0}, ++ {BFD_RELOC_NDS32_TLS_LE_15S1, R_NDS32_TLS_LE_15S1}, ++ {BFD_RELOC_NDS32_TLS_LE_15S2, R_NDS32_TLS_LE_15S2}, ++ ++ {BFD_RELOC_NDS32_TLS_DESC, R_NDS32_TLS_DESC}, ++ {BFD_RELOC_NDS32_TLS_DESC_HI20, R_NDS32_TLS_DESC_HI20}, ++ {BFD_RELOC_NDS32_TLS_DESC_LO12, R_NDS32_TLS_DESC_LO12}, ++ {BFD_RELOC_NDS32_TLS_DESC_ADD, R_NDS32_TLS_DESC_ADD}, ++ {BFD_RELOC_NDS32_TLS_DESC_FUNC, R_NDS32_TLS_DESC_FUNC}, ++ {BFD_RELOC_NDS32_TLS_DESC_CALL, R_NDS32_TLS_DESC_CALL}, ++ {BFD_RELOC_NDS32_TLS_DESC_MEM, R_NDS32_TLS_DESC_MEM}, ++ {BFD_RELOC_NDS32_TLS_DESC_20, R_NDS32_TLS_DESC_20}, ++ {BFD_RELOC_NDS32_TLS_DESC_SDA17S2, R_NDS32_TLS_DESC_SDA17S2}, ++ {BFD_RELOC_NDS32_TLS_IE_LO12, R_NDS32_TLS_IE_LO12}, ++ {BFD_RELOC_NDS32_TLS_IEGP_HI20, R_NDS32_TLS_IEGP_HI20}, ++ {BFD_RELOC_NDS32_TLS_IEGP_LO12, R_NDS32_TLS_IEGP_LO12}, ++ {BFD_RELOC_NDS32_TLS_IEGP_LO12S2, R_NDS32_TLS_IEGP_LO12S2}, ++ {BFD_RELOC_NDS32_TLS_IEGP_LW, R_NDS32_TLS_IEGP_LW}, ++ ++ {BFD_RELOC_NDS32_REMOVE, R_NDS32_RELAX_REMOVE}, ++ {BFD_RELOC_NDS32_GROUP, R_NDS32_RELAX_GROUP}, ++ ++ {BFD_RELOC_NDS32_ICT_HI20, R_NDS32_ICT_HI20}, ++ {BFD_RELOC_NDS32_ICT_LO12, R_NDS32_ICT_LO12}, ++ {BFD_RELOC_NDS32_ICT_25PC, R_NDS32_ICT_25PC}, ++}; ++ ++/* Patch tag. */ ++ ++/* Reserve space for COUNT dynamic relocations in relocation selection ++ SRELOC. */ ++ ++static inline void ++elf32_nds32_allocate_dynrelocs (struct bfd_link_info *info, asection *sreloc, ++ bfd_size_type count) ++{ ++ BFD_ASSERT (elf_hash_table (info)->dynamic_sections_created); ++ if (sreloc == NULL) ++ abort (); ++ sreloc->size += sizeof (Elf32_External_Rela) * count; ++} ++ ++static reloc_howto_type * ++bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ const char *r_name) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE (nds32_elf_howto_table); i++) ++ if (nds32_elf_howto_table[i].name != NULL ++ && strcasecmp (nds32_elf_howto_table[i].name, r_name) == 0) ++ return &nds32_elf_howto_table[i]; ++ ++ for (i = 0; i < ARRAY_SIZE (nds32_elf_relax_howto_table); i++) ++ if (nds32_elf_relax_howto_table[i].name != NULL ++ && strcasecmp (nds32_elf_relax_howto_table[i].name, r_name) == 0) ++ return &nds32_elf_relax_howto_table[i]; ++ ++ return NULL; ++} ++ ++static reloc_howto_type * ++bfd_elf32_bfd_reloc_type_table_lookup (enum elf_nds32_reloc_type code) ++{ ++ if (code < R_NDS32_RELAX_ENTRY) ++ { ++ BFD_ASSERT (code < ARRAY_SIZE (nds32_elf_howto_table)); ++ return &nds32_elf_howto_table[code]; ++ } ++ else ++ { ++ if ((size_t) (code - R_NDS32_RELAX_ENTRY) >= ++ ARRAY_SIZE (nds32_elf_relax_howto_table)) ++ { ++ int i = code; ++ i += 1; ++ } ++ ++ BFD_ASSERT ((size_t) (code - R_NDS32_RELAX_ENTRY) ++ < ARRAY_SIZE (nds32_elf_relax_howto_table)); ++ return &nds32_elf_relax_howto_table[code - R_NDS32_RELAX_ENTRY]; ++ } ++} ++ ++static reloc_howto_type * ++bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, ++ bfd_reloc_code_real_type code) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE (nds32_reloc_map); i++) ++ { ++ if (nds32_reloc_map[i].bfd_reloc_val == code) ++ return bfd_elf32_bfd_reloc_type_table_lookup ++ (nds32_reloc_map[i].elf_reloc_val); ++ } ++ ++ return NULL; ++} ++ ++/* Set the howto pointer for an NDS32 ELF reloc. */ ++ ++static void ++nds32_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, ++ Elf_Internal_Rela *dst) ++{ ++ enum elf_nds32_reloc_type r_type; ++ ++ r_type = ELF32_R_TYPE (dst->r_info); ++ BFD_ASSERT (ELF32_R_TYPE (dst->r_info) <= R_NDS32_GNU_VTENTRY); ++ cache_ptr->howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type); ++} ++ ++static void ++nds32_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr, ++ Elf_Internal_Rela *dst) ++{ ++ BFD_ASSERT ((ELF32_R_TYPE (dst->r_info) == R_NDS32_NONE) ++ || ((ELF32_R_TYPE (dst->r_info) > R_NDS32_GNU_VTENTRY) ++ && (ELF32_R_TYPE (dst->r_info) < R_NDS32_max))); ++ cache_ptr->howto = ++ bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (dst->r_info)); ++} ++ ++/* Support for core dump NOTE sections. ++ Reference to include/linux/elfcore.h in Linux. */ ++ ++static bfd_boolean ++nds32_elf_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) ++{ ++ int offset; ++ size_t size; ++ ++ switch (note->descsz) ++ { ++ case 0x114: ++ /* Linux/NDS32 32-bit, ABI1 */ ++ ++ /* pr_cursig */ ++ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); ++ ++ /* pr_pid */ ++ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24); ++ ++ /* pr_reg */ ++ offset = 72; ++ size = 200; ++ break; ++ ++ case 0xfc: ++ /* Linux/NDS32 32-bit */ ++ ++ /* pr_cursig */ ++ elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12); ++ ++ /* pr_pid */ ++ elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 24); ++ ++ /* pr_reg */ ++ offset = 72; ++ size = 176; ++ break; ++ ++ default: ++ return FALSE; ++ } ++ ++ /* Make a ".reg" section. */ ++ return _bfd_elfcore_make_pseudosection (abfd, ".reg", ++ size, note->descpos + offset); ++} ++ ++static bfd_boolean ++nds32_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) ++{ ++ switch (note->descsz) ++ { ++ case 124: ++ /* Linux/NDS32 */ ++ ++ /* __kernel_uid_t, __kernel_gid_t are short on NDS32 platform. */ ++ elf_tdata (abfd)->core->program = ++ _bfd_elfcore_strndup (abfd, note->descdata + 28, 16); ++ elf_tdata (abfd)->core->command = ++ _bfd_elfcore_strndup (abfd, note->descdata + 44, 80); ++ ++ default: ++ return FALSE; ++ } ++ ++ /* Note that for some reason, a spurious space is tacked ++ onto the end of the args in some (at least one anyway) ++ implementations, so strip it off if it exists. */ ++ { ++ char *command = elf_tdata (abfd)->core->command; ++ int n = strlen (command); ++ ++ if (0 < n && command[n - 1] == ' ') ++ command[n - 1] = '\0'; ++ } ++ ++ return TRUE; ++} ++ ++/* Hook called by the linker routine which adds symbols from an object ++ file. We must handle the special NDS32 section numbers here. ++ We also keep watching for whether we need to create the sdata special ++ linker sections. */ ++ ++static bfd_boolean ++nds32_elf_add_symbol_hook (bfd *abfd, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ Elf_Internal_Sym *sym, ++ const char **namep ATTRIBUTE_UNUSED, ++ flagword *flagsp ATTRIBUTE_UNUSED, ++ asection **secp, bfd_vma *valp) ++{ ++ switch (sym->st_shndx) ++ { ++ case SHN_COMMON: ++ /* Common symbols less than the GP size are automatically ++ treated as SHN_MIPS_SCOMMON symbols. */ ++ if (sym->st_size > elf_gp_size (abfd) ++ || ELF_ST_TYPE (sym->st_info) == STT_TLS) ++ break; ++ ++ /* st_value is the alignemnt constraint. ++ That might be its actual size if it is an array or structure. */ ++ switch (sym->st_value) ++ { ++ case 1: ++ *secp = bfd_make_section_old_way (abfd, ".scommon_b"); ++ break; ++ case 2: ++ *secp = bfd_make_section_old_way (abfd, ".scommon_h"); ++ break; ++ case 4: ++ *secp = bfd_make_section_old_way (abfd, ".scommon_w"); ++ break; ++ case 8: ++ *secp = bfd_make_section_old_way (abfd, ".scommon_d"); ++ break; ++ default: ++ return TRUE; ++ } ++ ++ (*secp)->flags |= SEC_IS_COMMON; ++ *valp = sym->st_size; ++ break; ++ } ++ ++ return TRUE; ++} ++ ++ ++/* This function can figure out the best location for a base register to access ++ data relative to this base register ++ INPUT: ++ sda_d0: size of first DOUBLE WORD data section ++ sda_w0: size of first WORD data section ++ sda_h0: size of first HALF WORD data section ++ sda_b : size of BYTE data section ++ sda_hi: size of second HALF WORD data section ++ sda_w1: size of second WORD data section ++ sda_d1: size of second DOUBLE WORD data section ++ OUTPUT: ++ offset (always positive) from the beginning of sda_d0 if OK ++ a negative error value if fail ++ NOTE: ++ these 7 sections have to be located back to back if exist ++ a pass in 0 value for non-existing section */ ++ ++/* Due to the interpretation of simm15 field of load/store depending on ++ data accessing size, the organization of base register relative data shall ++ like the following figure ++ ------------------------------------------- ++ | DOUBLE WORD sized data (range +/- 128K) ++ ------------------------------------------- ++ | WORD sized data (range +/- 64K) ++ ------------------------------------------- ++ | HALF WORD sized data (range +/- 32K) ++ ------------------------------------------- ++ | BYTE sized data (range +/- 16K) ++ ------------------------------------------- ++ | HALF WORD sized data (range +/- 32K) ++ ------------------------------------------- ++ | WORD sized data (range +/- 64K) ++ ------------------------------------------- ++ | DOUBLE WORD sized data (range +/- 128K) ++ ------------------------------------------- ++ Its base register shall be set to access these data freely. */ ++ ++/* We have to figure out the SDA_BASE value, so that we can adjust the ++ symbol value correctly. We look up the symbol _SDA_BASE_ in the output ++ BFD. If we can't find it, we're stuck. We cache it in the ELF ++ target data. We don't need to adjust the symbol value for an ++ external symbol if we are producing relocatable output. */ ++ ++static asection *sda_rela_sec = NULL; ++ ++#define SDA_SECTION_NUM 10 ++ ++static bfd_reloc_status_type ++nds32_elf_final_sda_base (bfd *output_bfd, struct bfd_link_info *info, ++ bfd_vma *psb, bfd_boolean add_symbol) ++{ ++ int relax_fp_as_gp; ++ struct elf_nds32_link_hash_table *table; ++ struct bfd_link_hash_entry *h, *h2; ++ long unsigned int total = 0; ++ asection *first = NULL, *final = NULL, *temp; ++ bfd_vma sda_base = 0; ++ ++ h = bfd_link_hash_lookup (info->hash, "_SDA_BASE_", FALSE, FALSE, TRUE); ++ if (!h || (h->type != bfd_link_hash_defined && h->type != bfd_link_hash_defweak)) ++ { ++ /* The first section must be 4-byte aligned to promise _SDA_BASE_ being ++ 4 byte-aligned. Therefore, it has to set the first section ".data" ++ 4 byte-aligned. */ ++ static const char sec_name[SDA_SECTION_NUM][10] = { ++ ".data", ".got", ".sdata_d", ".sdata_w", ".sdata_h", ".sdata_b", ++ ".sbss_b", ".sbss_h", ".sbss_w", ".sbss_d" ++ }; ++ size_t i = 0; ++ ++ if (output_bfd->sections == NULL) ++ { ++ *psb = elf_gp (output_bfd); ++ return bfd_reloc_ok; ++ } ++ ++ /* Get the first and final section. */ ++ while (i < ARRAY_SIZE (sec_name)) ++ { ++ temp = bfd_get_section_by_name (output_bfd, sec_name[i]); ++ if (temp && !first && (temp->size != 0 || temp->rawsize != 0)) ++ first = temp; ++ if (temp && (temp->size != 0 || temp->rawsize != 0)) ++ final = temp; ++ ++ /* Summarize the sections in order to check if joining .bss. */ ++ if (temp && temp->size != 0) ++ total += temp->size; ++ else if (temp && temp->rawsize != 0) ++ total += temp->rawsize; ++ ++ i++; ++ } ++ ++ /* Check .bss size. */ ++ temp = bfd_get_section_by_name (output_bfd, ".bss"); ++ if (temp) ++ { ++ if (temp->size != 0) ++ total += temp->size; ++ else if (temp->rawsize != 0) ++ total += temp->rawsize; ++ ++ if (total < 0x80000) ++ { ++ if (!first && (temp->size != 0 || temp->rawsize != 0)) ++ first = temp; ++ if ((temp->size != 0 || temp->rawsize != 0)) ++ final = temp; ++ } ++ } ++ ++ if (first && final) ++ { ++ /* The middle of data region. */ ++ sda_base = final->vma / 2 + final->rawsize / 2 + first->vma / 2; ++ ++ /* Find the section sda_base located. */ ++ i = 0; ++ while (i < ARRAY_SIZE (sec_name)) ++ { ++ final = bfd_get_section_by_name (output_bfd, sec_name[i]); ++ if (final && (final->size != 0 || final->rawsize != 0) ++ && sda_base >= final->vma) ++ { ++ first = final; ++ i++; ++ } ++ else ++ break; ++ } ++ } ++ else ++ { ++ /* If there is not any default data section in output bfd, try to find ++ the first data section. If no data section be found, just simplily ++ choose the first output section. */ ++ temp = output_bfd->sections; ++ while (temp) ++ { ++ if (temp->flags & SEC_ALLOC ++ && (((temp->flags & SEC_DATA) ++ && ((temp->flags & SEC_READONLY) == 0)) ++ || (temp->flags & SEC_LOAD) == 0) ++ && (temp->size != 0 || temp->rawsize != 0)) ++ { ++ if (!first) ++ first = temp; ++ final = temp; ++ } ++ temp = temp->next; ++ } ++ ++ /* There is no data or bss section. */ ++ if (!first || (first->size == 0 && first->rawsize == 0)) ++ { ++ first = output_bfd->sections; ++ while (first && first->size == 0 && first->rawsize == 0) ++ first = first->next; ++ } ++ ++ /* There is no concrete section. */ ++ if (!first) ++ { ++ *psb = elf_gp (output_bfd); ++ return bfd_reloc_ok; ++ } ++ ++ if (final && (final->vma + final->rawsize - first->vma) <= 0x4000) ++ sda_base = final->vma / 2 + final->rawsize / 2 + first->vma / 2; ++ else ++ sda_base = first->vma + 0x2000; ++ } ++ ++ sda_base -= first->vma; ++ sda_base = sda_base & (~7); ++ ++ if (!_bfd_generic_link_add_one_symbol ++ (info, output_bfd, "_SDA_BASE_", BSF_GLOBAL | BSF_WEAK, first, ++ (bfd_vma) sda_base, (const char *) NULL, FALSE, ++ get_elf_backend_data (output_bfd)->collect, &h)) ++ return FALSE; ++ ++ sda_rela_sec = first; ++ ++ } ++ ++ /* Set _FP_BASE_ to _SDA_BASE_. */ ++ table = nds32_elf_hash_table (info); ++ relax_fp_as_gp = table->relax_fp_as_gp; ++ h2 = bfd_link_hash_lookup (info->hash, FP_BASE_NAME, FALSE, FALSE, FALSE); ++ /* _SDA_BASE_ is difined in linker script. */ ++ if (!first) ++ { ++ first = h->u.def.section; ++ sda_base = h->u.def.value; ++ } ++ ++ if (relax_fp_as_gp && h2 ++ && (h2->type == bfd_link_hash_undefweak ++ || h2->type == bfd_link_hash_undefined)) ++ { ++ /* Define a weak FP_BASE_NAME here to prevent the undefined symbol. ++ And set FP equal to SDA_BASE to do relaxation for ++ la $fp, _FP_BASE_. */ ++ if (!_bfd_generic_link_add_one_symbol ++ (info, output_bfd, FP_BASE_NAME, BSF_GLOBAL | BSF_WEAK, ++ first, sda_base, (const char *) NULL, ++ FALSE, get_elf_backend_data (output_bfd)->collect, &h2)) ++ return FALSE; ++ } ++ ++ if (add_symbol == TRUE) ++ { ++ if (h) ++ { ++ /* Now set gp. */ ++ elf_gp (output_bfd) = (h->u.def.value ++ + h->u.def.section->output_section->vma ++ + h->u.def.section->output_offset); ++ } ++ else ++ { ++ (*_bfd_error_handler) (_("error: Can't find symbol: _SDA_BASE_.")); ++ return bfd_reloc_dangerous; ++ } ++ } ++ ++ *psb = h->u.def.value + h->u.def.section->output_section->vma ++ + h->u.def.section->output_offset; ++ return bfd_reloc_ok; ++} ++ ++ ++/* Return size of a PLT entry. */ ++#define elf_nds32_sizeof_plt(info) PLT_ENTRY_SIZE ++ ++ ++/* Create an entry in an nds32 ELF linker hash table. */ ++ ++static struct bfd_hash_entry * ++nds32_elf_link_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ struct elf_nds32_link_hash_entry *ret; ++ ++ ret = (struct elf_nds32_link_hash_entry *) entry; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (ret == NULL) ++ ret = (struct elf_nds32_link_hash_entry *) ++ bfd_hash_allocate (table, sizeof (struct elf_nds32_link_hash_entry)); ++ ++ if (ret == NULL) ++ return (struct bfd_hash_entry *) ret; ++ ++ /* Call the allocation method of the superclass. */ ++ ret = (struct elf_nds32_link_hash_entry *) ++ _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, table, string); ++ ++ if (ret != NULL) ++ { ++ struct elf_nds32_link_hash_entry *eh; ++ ++ eh = (struct elf_nds32_link_hash_entry *) ret; ++ eh->dyn_relocs = NULL; ++ eh->tls_type = GOT_UNKNOWN; ++ eh->offset_to_gp = 0; ++ eh->indirect_call = FALSE; ++ } ++ ++ return (struct bfd_hash_entry *) ret; ++} ++ ++/* Create an nds32 ELF linker hash table. */ ++ ++static struct bfd_link_hash_table * ++nds32_elf_link_hash_table_create (bfd *abfd) ++{ ++ struct elf_nds32_link_hash_table *ret; ++ ++ bfd_size_type amt = sizeof (struct elf_nds32_link_hash_table); ++ ++ ret = (struct elf_nds32_link_hash_table *) bfd_zmalloc (amt); ++ if (ret == NULL) ++ return NULL; ++ ++ /* patch tag. */ ++ if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, ++ nds32_elf_link_hash_newfunc, ++ sizeof (struct elf_nds32_link_hash_entry), ++ NDS32_ELF_DATA)) ++ { ++ free (ret); ++ return NULL; ++ } ++ ++ ret->sdynbss = NULL; ++ ret->srelbss = NULL; ++ ret->sym_ld_script = NULL; ++ ret->ex9_export_file = NULL; ++ ret->ex9_import_file = NULL; ++ ++ return &ret->root.root; ++} ++ ++/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up ++ shortcuts to them in our hash table. */ ++ ++static bfd_boolean ++create_got_section (bfd *dynobj, struct bfd_link_info *info) ++{ ++ struct elf_link_hash_table *ehtab; ++ ++ if (!_bfd_elf_create_got_section (dynobj, info)) ++ return FALSE; ++ ++ ehtab = elf_hash_table (info); ++ ehtab->sgot = bfd_get_section_by_name (dynobj, ".got"); ++ ehtab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt"); ++ if (!ehtab->sgot || !ehtab->sgotplt) ++ abort (); ++ ++ /* _bfd_elf_create_got_section will create it for us. */ ++ ehtab->srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); ++ if (ehtab->srelgot == NULL ++ || !bfd_set_section_flags (dynobj, ehtab->srelgot, ++ (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS ++ | SEC_IN_MEMORY | SEC_LINKER_CREATED ++ | SEC_READONLY)) ++ || !bfd_set_section_alignment (dynobj, ehtab->srelgot, 2)) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++/* Create dynamic sections when linking against a dynamic object. */ ++ ++static bfd_boolean ++nds32_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) ++{ ++ struct elf_link_hash_table *ehtab; ++ struct elf_nds32_link_hash_table *htab; ++ flagword flags, pltflags; ++ register asection *s; ++ const struct elf_backend_data *bed; ++ int ptralign = 2; /* 32-bit */ ++ const char *secname; ++ char *relname; ++ flagword secflags; ++ asection *sec; ++ ++ bed = get_elf_backend_data (abfd); ++ ehtab = elf_hash_table (info); ++ htab = nds32_elf_hash_table (info); ++ ++ /* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and ++ .rel[a].bss sections. */ ++ ++ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY ++ | SEC_LINKER_CREATED); ++ ++ pltflags = flags; ++ pltflags |= SEC_CODE; ++ if (bed->plt_not_loaded) ++ pltflags &= ~(SEC_LOAD | SEC_HAS_CONTENTS); ++ if (bed->plt_readonly) ++ pltflags |= SEC_READONLY; ++ ++ s = bfd_make_section (abfd, ".plt"); ++ ehtab->splt = s; ++ if (s == NULL ++ || !bfd_set_section_flags (abfd, s, pltflags) ++ || !bfd_set_section_alignment (abfd, s, bed->plt_alignment)) ++ return FALSE; ++ ++ if (bed->want_plt_sym) ++ { ++ /* Define the symbol _PROCEDURE_LINKAGE_TABLE_ at the start of the ++ .plt section. */ ++ struct bfd_link_hash_entry *bh = NULL; ++ struct elf_link_hash_entry *h; ++ ++ if (!(_bfd_generic_link_add_one_symbol ++ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, ++ (bfd_vma) 0, (const char *) NULL, FALSE, ++ get_elf_backend_data (abfd)->collect, &bh))) ++ return FALSE; ++ ++ h = (struct elf_link_hash_entry *) bh; ++ h->def_regular = 1; ++ h->type = STT_OBJECT; ++ ++ if (info->shared && !bfd_elf_link_record_dynamic_symbol (info, h)) ++ return FALSE; ++ } ++ ++ s = bfd_make_section (abfd, ++ bed->default_use_rela_p ? ".rela.plt" : ".rel.plt"); ++ ehtab->srelplt = s; ++ if (s == NULL ++ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY) ++ || !bfd_set_section_alignment (abfd, s, ptralign)) ++ return FALSE; ++ ++ if (ehtab->sgot == NULL && !create_got_section (abfd, info)) ++ return FALSE; ++ ++ for (sec = abfd->sections; sec; sec = sec->next) ++ { ++ secflags = bfd_get_section_flags (abfd, sec); ++ if ((secflags & (SEC_DATA | SEC_LINKER_CREATED)) ++ || ((secflags & SEC_HAS_CONTENTS) != SEC_HAS_CONTENTS)) ++ continue; ++ secname = bfd_get_section_name (abfd, sec); ++ relname = (char *) bfd_malloc ((bfd_size_type) strlen (secname) + 6); ++ strcpy (relname, ".rela"); ++ strcat (relname, secname); ++ if (bfd_get_section_by_name (abfd, secname)) ++ continue; ++ s = bfd_make_section (abfd, relname); ++ if (s == NULL ++ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY) ++ || !bfd_set_section_alignment (abfd, s, ptralign)) ++ return FALSE; ++ } ++ ++ if (bed->want_dynbss) ++ { ++ /* The .dynbss section is a place to put symbols which are defined ++ by dynamic objects, are referenced by regular objects, and are ++ not functions. We must allocate space for them in the process ++ image and use a R_*_COPY reloc to tell the dynamic linker to ++ initialize them at run time. The linker script puts the .dynbss ++ section into the .bss section of the final image. */ ++ s = bfd_make_section (abfd, ".dynbss"); ++ htab->sdynbss = s; ++ if (s == NULL ++ || !bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED)) ++ return FALSE; ++ /* The .rel[a].bss section holds copy relocs. This section is not ++ normally needed. We need to create it here, though, so that the ++ linker will map it to an output section. We can't just create it ++ only if we need it, because we will not know whether we need it ++ until we have seen all the input files, and the first time the ++ main linker code calls BFD after examining all the input files ++ (size_dynamic_sections) the input sections have already been ++ mapped to the output sections. If the section turns out not to ++ be needed, we can discard it later. We will never need this ++ section when generating a shared object, since they do not use ++ copy relocs. */ ++ if (!info->shared) ++ { ++ s = bfd_make_section (abfd, (bed->default_use_rela_p ++ ? ".rela.bss" : ".rel.bss")); ++ htab->srelbss = s; ++ if (s == NULL ++ || !bfd_set_section_flags (abfd, s, flags | SEC_READONLY) ++ || !bfd_set_section_alignment (abfd, s, ptralign)) ++ return FALSE; ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Copy the extra info we tack onto an elf_link_hash_entry. */ ++static void ++nds32_elf_copy_indirect_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *dir, ++ struct elf_link_hash_entry *ind) ++{ ++ struct elf_nds32_link_hash_entry *edir, *eind; ++ ++ edir = (struct elf_nds32_link_hash_entry *) dir; ++ eind = (struct elf_nds32_link_hash_entry *) ind; ++ ++ if (eind->dyn_relocs != NULL) ++ { ++ if (edir->dyn_relocs != NULL) ++ { ++ struct elf_nds32_dyn_relocs **pp; ++ struct elf_nds32_dyn_relocs *p; ++ ++ if (ind->root.type == bfd_link_hash_indirect) ++ abort (); ++ ++ /* Add reloc counts against the weak sym to the strong sym ++ list. Merge any entries against the same section. */ ++ for (pp = &eind->dyn_relocs; (p = *pp) != NULL;) ++ { ++ struct elf_nds32_dyn_relocs *q; ++ ++ for (q = edir->dyn_relocs; q != NULL; q = q->next) ++ if (q->sec == p->sec) ++ { ++ q->pc_count += p->pc_count; ++ q->count += p->count; ++ *pp = p->next; ++ break; ++ } ++ if (q == NULL) ++ pp = &p->next; ++ } ++ *pp = edir->dyn_relocs; ++ } ++ ++ edir->dyn_relocs = eind->dyn_relocs; ++ eind->dyn_relocs = NULL; ++ } ++ ++ if (ind->root.type == bfd_link_hash_indirect) ++ { ++ if (dir->got.refcount <= 0) ++ { ++ edir->tls_type = eind->tls_type; ++ eind->tls_type = GOT_UNKNOWN; ++ } ++ } ++ ++ _bfd_elf_link_hash_copy_indirect (info, dir, ind); ++} ++ ++ ++/* Adjust a symbol defined by a dynamic object and referenced by a ++ regular object. The current definition is in some section of the ++ dynamic object, but we're not including those sections. We have to ++ change the definition to something the rest of the link can ++ understand. */ ++ ++static bfd_boolean ++nds32_elf_adjust_dynamic_symbol (struct bfd_link_info *info, ++ struct elf_link_hash_entry *h) ++{ ++ struct elf_nds32_link_hash_table *htab; ++ struct elf_nds32_link_hash_entry *eh; ++ struct elf_nds32_dyn_relocs *p; ++ bfd *dynobj; ++ asection *s; ++ unsigned int power_of_two; ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ ++ /* Make sure we know what is going on here. */ ++ BFD_ASSERT (dynobj != NULL ++ && (h->needs_plt ++ || h->u.weakdef != NULL ++ || (h->def_dynamic && h->ref_regular && !h->def_regular))); ++ ++ ++ /* If this is a function, put it in the procedure linkage table. We ++ will fill in the contents of the procedure linkage table later, ++ when we know the address of the .got section. */ ++ if (h->type == STT_FUNC || h->needs_plt) ++ { ++ if (!info->shared ++ && !h->def_dynamic ++ && !h->ref_dynamic ++ && h->root.type != bfd_link_hash_undefweak ++ && h->root.type != bfd_link_hash_undefined) ++ { ++ /* This case can occur if we saw a PLT reloc in an input ++ file, but the symbol was never referred to by a dynamic ++ object. In such a case, we don't actually need to build ++ a procedure linkage table, and we can just do a PCREL ++ reloc instead. */ ++ h->plt.offset = (bfd_vma) - 1; ++ h->needs_plt = 0; ++ } ++ ++ return TRUE; ++ } ++ else ++ h->plt.offset = (bfd_vma) - 1; ++ ++ /* If this is a weak symbol, and there is a real definition, the ++ processor independent code will have arranged for us to see the ++ real definition first, and we can just use the same value. */ ++ if (h->u.weakdef != NULL) ++ { ++ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined ++ || h->u.weakdef->root.type == bfd_link_hash_defweak); ++ h->root.u.def.section = h->u.weakdef->root.u.def.section; ++ h->root.u.def.value = h->u.weakdef->root.u.def.value; ++ return TRUE; ++ } ++ ++ /* This is a reference to a symbol defined by a dynamic object which ++ is not a function. */ ++ ++ /* If we are creating a shared library, we must presume that the ++ only references to the symbol are via the global offset table. ++ For such cases we need not do anything here; the relocations will ++ be handled correctly by relocate_section. */ ++ if (info->shared) ++ return TRUE; ++ ++ /* If there are no references to this symbol that do not use the ++ GOT, we don't need to generate a copy reloc. */ ++ if (!h->non_got_ref) ++ return TRUE; ++ ++ /* If -z nocopyreloc was given, we won't generate them either. */ ++ if (info->nocopyreloc) ++ { ++ h->non_got_ref = 0; ++ return TRUE; ++ } ++ ++ eh = (struct elf_nds32_link_hash_entry *) h; ++ for (p = eh->dyn_relocs; p != NULL; p = p->next) ++ { ++ s = p->sec->output_section; ++ if (s != NULL && (s->flags & (SEC_READONLY | SEC_HAS_CONTENTS)) != 0) ++ break; ++ } ++ ++ /* If we didn't find any dynamic relocs in sections which needs the ++ copy reloc, then we'll be keeping the dynamic relocs and avoiding ++ the copy reloc. */ ++ if (p == NULL) ++ { ++ h->non_got_ref = 0; ++ return TRUE; ++ } ++ ++ /* We must allocate the symbol in our .dynbss section, which will ++ become part of the .bss section of the executable. There will be ++ an entry for this symbol in the .dynsym section. The dynamic ++ object will contain position independent code, so all references ++ from the dynamic object to this symbol will go through the global ++ offset table. The dynamic linker will use the .dynsym entry to ++ determine the address it must put in the global offset table, so ++ both the dynamic object and the regular object will refer to the ++ same memory location for the variable. */ ++ ++ htab = nds32_elf_hash_table (info); ++ s = htab->sdynbss; ++ BFD_ASSERT (s != NULL); ++ ++ /* We must generate a R_NDS32_COPY reloc to tell the dynamic linker ++ to copy the initial value out of the dynamic object and into the ++ runtime process image. We need to remember the offset into the ++ .rela.bss section we are going to use. */ ++ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0) ++ { ++ asection *srel; ++ ++ srel = htab->srelbss; ++ BFD_ASSERT (srel != NULL); ++ srel->size += sizeof (Elf32_External_Rela); ++ h->needs_copy = 1; ++ } ++ ++ /* We need to figure out the alignment required for this symbol. I ++ have no idea how ELF linkers handle this. */ ++ power_of_two = bfd_log2 (h->size); ++ if (power_of_two > 3) ++ power_of_two = 3; ++ ++ /* Apply the required alignment. */ ++ s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two)); ++ if (power_of_two > bfd_get_section_alignment (dynobj, s)) ++ { ++ if (!bfd_set_section_alignment (dynobj, s, power_of_two)) ++ return FALSE; ++ } ++ ++ /* Define the symbol as being at this point in the section. */ ++ h->root.u.def.section = s; ++ h->root.u.def.value = s->size; ++ ++ /* Increment the section size to make room for the symbol. */ ++ s->size += h->size; ++ ++ return TRUE; ++} ++ ++/* Allocate space in .plt, .got and associated reloc sections for ++ dynamic relocs. */ ++ ++static bfd_boolean ++allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) ++{ ++ struct bfd_link_info *info; ++ struct elf_link_hash_table *ehtab; ++ struct elf_nds32_link_hash_table *htab; ++ struct elf_nds32_link_hash_entry *eh; ++ struct elf_nds32_dyn_relocs *p; ++ ++ if (h->root.type == bfd_link_hash_indirect) ++ return TRUE; ++ ++ /* When warning symbols are created, they **replace** the "real" ++ entry in the hash table, thus we never get to see the real ++ symbol in a hash traversal. So look at it now. */ ++ if (h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ eh = (struct elf_nds32_link_hash_entry *) h; ++ ++ info = (struct bfd_link_info *) inf; ++ ehtab = elf_hash_table (info); ++ htab = nds32_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ if ((htab->root.dynamic_sections_created || h->type == STT_GNU_IFUNC) ++ && h->plt.refcount > 0 ++ && !(info->pie && h->def_regular)) ++ { ++ /* Make sure this symbol is output as a dynamic symbol. ++ Undefined weak syms won't yet be marked as dynamic. */ ++ if (h->dynindx == -1 && !h->forced_local) ++ { ++ if (!bfd_elf_link_record_dynamic_symbol (info, h)) ++ return FALSE; ++ } ++ ++ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) ++ { ++ asection *s = ehtab->splt; ++ ++ /* If this is the first .plt entry, make room for the special ++ first entry. */ ++ if (s->size == 0) ++ s->size += PLT_ENTRY_SIZE; ++ ++ h->plt.offset = s->size; ++ ++ /* If this symbol is not defined in a regular file, and we are ++ not generating a shared library, then set the symbol to this ++ location in the .plt. This is required to make function ++ pointers compare as equal between the normal executable and ++ the shared library. */ ++ if (!info->shared && !h->def_regular) ++ { ++ h->root.u.def.section = s; ++ h->root.u.def.value = h->plt.offset; ++ } ++ ++ /* Make room for this entry. */ ++ s->size += PLT_ENTRY_SIZE; ++ ++ /* We also need to make an entry in the .got.plt section, which ++ will be placed in the .got section by the linker script. */ ++ ehtab->sgotplt->size += 4; ++ ++ /* We also need to make an entry in the .rel.plt section. */ ++ ehtab->srelplt->size += sizeof (Elf32_External_Rela); ++ htab->next_tls_desc_index++; ++ } ++ else ++ { ++ h->plt.offset = (bfd_vma) - 1; ++ h->needs_plt = 0; ++ } ++ } ++ else ++ { ++ h->plt.offset = (bfd_vma) - 1; ++ h->needs_plt = 0; ++ } ++ ++ if (h->got.refcount > 0) ++ { ++ asection *sgot; ++ bfd_boolean dyn; ++ int tls_type = elf32_nds32_hash_entry (h)->tls_type; ++ ++ /* Make sure this symbol is output as a dynamic symbol. ++ Undefined weak syms won't yet be marked as dynamic. */ ++ if (h->dynindx == -1 && !h->forced_local) ++ { ++ if (!bfd_elf_link_record_dynamic_symbol (info, h)) ++ return FALSE; ++ } ++ ++ sgot = elf_hash_table (info)->sgot; ++ h->got.offset = sgot->size; ++ ++ if (tls_type == GOT_UNKNOWN) ++ abort (); ++ ++ /* Non-TLS symbols, and TLS_IE need one GOT slot. */ ++ if (tls_type & (GOT_NORMAL | GOT_TLS_IE | GOT_TLS_IEGP)) ++ sgot->size += 4; ++ else ++ { ++ /* TLS_DESC, TLS_GD, and TLS_LD need 2 consecutive GOT slots. */ ++ if (tls_type & GOT_TLS_DESC) ++ sgot->size += 8; ++ } ++ ++ dyn = htab->root.dynamic_sections_created; ++ ++ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)) ++ { ++ if (tls_type == GOT_TLS_DESC) ++ { ++ /* TLS_DESC needs a relocation slot within .rela.plt. */ ++ htab->num_tls_desc++; ++ ehtab->srelplt->size += sizeof (Elf32_External_Rela); ++ htab->tls_trampoline = -1; ++ } ++ else ++ { ++ /* other relocations need a relocation slot within .rela.got. */ ++ ehtab->srelgot->size += sizeof (Elf32_External_Rela); ++ } ++ } ++ } ++ else ++ h->got.offset = (bfd_vma) -1; ++ ++ if (eh->dyn_relocs == NULL) ++ return TRUE; ++ ++ /* In the shared -Bsymbolic case, discard space allocated for ++ dynamic pc-relative relocs against symbols which turn out to be ++ defined in regular objects. For the normal shared case, discard ++ space for pc-relative relocs that have become local due to symbol ++ visibility changes. */ ++ ++ if (info->shared) ++ { ++ if (h->def_regular && (h->forced_local || info->symbolic)) ++ { ++ struct elf_nds32_dyn_relocs **pp; ++ ++ for (pp = &eh->dyn_relocs; (p = *pp) != NULL;) ++ { ++ p->count -= p->pc_count; ++ p->pc_count = 0; ++ if (p->count == 0) ++ *pp = p->next; ++ else ++ pp = &p->next; ++ } ++ } ++ } ++ else ++ { ++ /* For the non-shared case, discard space for relocs against ++ symbols which turn out to need copy relocs or are not dynamic. */ ++ ++ if (!h->non_got_ref ++ && ((h->def_dynamic ++ && !h->def_regular) ++ || (htab->root.dynamic_sections_created ++ && (h->root.type == bfd_link_hash_undefweak ++ || h->root.type == bfd_link_hash_undefined)))) ++ { ++ /* Make sure this symbol is output as a dynamic symbol. ++ Undefined weak syms won't yet be marked as dynamic. */ ++ if (h->dynindx == -1 && !h->forced_local) ++ { ++ if (!bfd_elf_link_record_dynamic_symbol (info, h)) ++ return FALSE; ++ } ++ ++ /* If that succeeded, we know we'll be keeping all the ++ relocs. */ ++ if (h->dynindx != -1) ++ goto keep; ++ } ++ ++ eh->dyn_relocs = NULL; ++ ++keep:; ++ } ++ ++ /* Finally, allocate space. */ ++ for (p = eh->dyn_relocs; p != NULL; p = p->next) ++ { ++ asection *sreloc = elf_section_data (p->sec)->sreloc; ++ sreloc->size += p->count * sizeof (Elf32_External_Rela); ++ } ++ ++ return TRUE; ++} ++ ++/* Add relocation REL to the end of relocation section SRELOC. */ ++ ++static void ++elf32_nds32_add_dynreloc (bfd *output_bfd, ++ struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ asection *sreloc, Elf_Internal_Rela *rel) ++{ ++ bfd_byte *loc; ++ if (sreloc == NULL) ++ abort (); ++ ++ loc = sreloc->contents; ++ loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela); ++ if (sreloc->reloc_count * sizeof (Elf32_External_Rela) > sreloc->size) ++ abort (); ++ ++ bfd_elf32_swap_reloca_out (output_bfd, rel, loc); ++} ++ ++/* Find any dynamic relocs that apply to read-only sections. */ ++ ++static bfd_boolean ++readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) ++{ ++ struct elf_nds32_link_hash_entry *eh; ++ struct elf_nds32_dyn_relocs *p; ++ ++ if (h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ eh = (struct elf_nds32_link_hash_entry *) h; ++ for (p = eh->dyn_relocs; p != NULL; p = p->next) ++ { ++ asection *s = p->sec->output_section; ++ ++ if (s != NULL && (s->flags & SEC_READONLY) != 0) ++ { ++ struct bfd_link_info *info = (struct bfd_link_info *) inf; ++ ++ info->flags |= DF_TEXTREL; ++ ++ /* Not an error, just cut short the traversal. */ ++ return FALSE; ++ } ++ } ++ return TRUE; ++} ++ ++/* Set the sizes of the dynamic sections. */ ++ ++static bfd_boolean ++nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info) ++{ ++ bfd *dynobj; ++ asection *s; ++ bfd_boolean plt; ++ bfd_boolean relocs; ++ bfd *ibfd; ++ struct elf_nds32_link_hash_table *htab; ++ ++ htab = nds32_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ BFD_ASSERT (dynobj != NULL); ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ { ++ /* Set the contents of the .interp section to the interpreter. */ ++ if (info->executable) ++ { ++ s = bfd_get_section_by_name (dynobj, ".interp"); ++ BFD_ASSERT (s != NULL); ++ s->size = sizeof ELF_DYNAMIC_INTERPRETER; ++ s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER; ++ } ++ } ++ ++ /* Set up .got offsets for local syms, and space for local dynamic ++ relocs. */ ++ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next) ++ { ++ bfd_signed_vma *local_got; ++ bfd_signed_vma *end_local_got; ++ bfd_size_type locsymcount; ++ Elf_Internal_Shdr *symtab_hdr; ++ asection *sgot; ++ char *local_tls_type; ++ unsigned long symndx; ++ bfd_vma *local_tlsdesc_gotent; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) ++ continue; ++ ++ for (s = ibfd->sections; s != NULL; s = s->next) ++ { ++ struct elf_nds32_dyn_relocs *p; ++ ++ for (p = ((struct elf_nds32_dyn_relocs *) ++ elf_section_data (s)->local_dynrel); ++ p != NULL; p = p->next) ++ { ++ if (!bfd_is_abs_section (p->sec) ++ && bfd_is_abs_section (p->sec->output_section)) ++ { ++ /* Input section has been discarded, either because ++ it is a copy of a linkonce section or due to ++ linker script /DISCARD/, so we'll be discarding ++ the relocs too. */ ++ } ++ else if (p->count != 0) ++ { ++ asection *sreloc = elf_section_data (p->sec)->sreloc; ++ sreloc->size += p->count * sizeof (Elf32_External_Rela); ++ if ((p->sec->output_section->flags & SEC_READONLY) != 0) ++ info->flags |= DF_TEXTREL; ++ } ++ } ++ } ++ ++ local_got = elf_local_got_refcounts (ibfd); ++ if (!local_got) ++ continue; ++ ++ symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; ++ locsymcount = symtab_hdr->sh_info; ++ end_local_got = local_got + locsymcount; ++ sgot = elf_hash_table (info)->sgot; ++ local_tls_type = elf32_nds32_local_got_tls_type (ibfd); ++ local_tlsdesc_gotent = elf32_nds32_local_tlsdesc_gotent (ibfd); ++ for (symndx = 0; local_got < end_local_got; ++ ++local_got, ++local_tls_type, ++local_tlsdesc_gotent, ++symndx) ++ { ++ if (*local_got > 0) ++ { ++ int num_of_got_entry_needed = 0; ++ *local_got = sgot->size; ++ *local_tlsdesc_gotent = sgot->size; ++ ++ /* TLS_NORMAL, and TLS_IE need one slot in .got. */ ++ if (*local_tls_type & (GOT_NORMAL | GOT_TLS_IE | GOT_TLS_IEGP)) ++ num_of_got_entry_needed = 1; ++ /* TLS_GD, TLS_LD, and TLS_DESC need an 8-byte structure in the GOT. */ ++ else if (*local_tls_type & GOT_TLS_DESC) ++ num_of_got_entry_needed = 2; ++ ++ sgot->size += (num_of_got_entry_needed << 2); ++ ++ /* non-relax-able TLS_DESCs need a slot in .rela.plt. ++ others need a slot in .rela.got. */ ++ if (*local_tls_type == GOT_TLS_DESC) ++ { ++ if (info->shared) ++ { ++ htab->num_tls_desc++; ++ htab->root.srelplt->size += sizeof (Elf32_External_Rela); ++ htab->tls_trampoline = -1; ++ } ++ else ++ { ++ /* TLS_DESC -> TLS_LE */ ++ } ++ } ++ else ++ { ++ htab->root.srelgot->size += sizeof (Elf32_External_Rela); ++ } ++ } ++ else ++ { ++ *local_got = (bfd_vma) -1; ++ *local_tlsdesc_gotent = (bfd_vma) -1; ++ } ++ } ++ } ++ ++ /* Allocate global sym .plt and .got entries, and space for global ++ sym dynamic relocs. */ ++ elf_link_hash_traverse (&htab->root, allocate_dynrelocs, (void *) info); ++ ++ /* For every jump slot reserved in the sgotplt, reloc_count is ++ incremented. However, when we reserve space for TLS descriptors, ++ it's not incremented, so in order to compute the space reserved ++ for them, it suffices to multiply the reloc count by the jump ++ slot size. */ ++ if (htab->root.srelplt) ++ htab->sgotplt_jump_table_size = elf32_nds32_compute_jump_table_size (htab); ++ ++ if (htab->tls_trampoline) ++ { ++ htab->tls_trampoline = htab->root.splt->size; ++ ++ /* If we're not using lazy TLS relocations, don't generate the ++ PLT and GOT entries they require. */ ++ if (!(info->flags & DF_BIND_NOW)) ++ { ++ htab->dt_tlsdesc_got = htab->root.sgot->size; ++ htab->root.sgot->size += 4; ++ ++ htab->dt_tlsdesc_plt = htab->root.splt->size; ++ htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline); ++ } ++ } ++ ++ /* We now have determined the sizes of the various dynamic sections. ++ Allocate memory for them. */ ++ /* The check_relocs and adjust_dynamic_symbol entry points have ++ determined the sizes of the various dynamic sections. Allocate ++ memory for them. */ ++ plt = FALSE; ++ relocs = FALSE; ++ for (s = dynobj->sections; s != NULL; s = s->next) ++ { ++ if ((s->flags & SEC_LINKER_CREATED) == 0) ++ continue; ++ ++ if (s == htab->root.splt) ++ { ++ /* Strip this section if we don't need it; see the ++ comment below. */ ++ plt = s->size != 0; ++ } ++ else if (s == elf_hash_table (info)->sgot) ++ { ++ got_size += s->size; ++ } ++ else if (s == elf_hash_table (info)->sgotplt) ++ { ++ got_size += s->size; ++ } ++ else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0) ++ { ++ if (s->size != 0 && s != elf_hash_table (info)->srelplt) ++ relocs = TRUE; ++ ++ /* We use the reloc_count field as a counter if we need ++ to copy relocs into the output file. */ ++ s->reloc_count = 0; ++ } ++ else ++ { ++ /* It's not one of our sections, so don't allocate space. */ ++ continue; ++ } ++ ++ if (s->size == 0) ++ { ++ /* If we don't need this section, strip it from the ++ output file. This is mostly to handle .rela.bss and ++ .rela.plt. We must create both sections in ++ create_dynamic_sections, because they must be created ++ before the linker maps input sections to output ++ sections. The linker does that before ++ adjust_dynamic_symbol is called, and it is that ++ function which decides whether anything needs to go ++ into these sections. */ ++ s->flags |= SEC_EXCLUDE; ++ continue; ++ } ++ ++ /* Allocate memory for the section contents. We use bfd_zalloc ++ here in case unused entries are not reclaimed before the ++ section's contents are written out. This should not happen, ++ but this way if it does, we get a R_NDS32_NONE reloc instead ++ of garbage. */ ++ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size); ++ if (s->contents == NULL) ++ return FALSE; ++ } ++ ++ ++ if (htab->root.dynamic_sections_created) ++ { ++ /* Add some entries to the .dynamic section. We fill in the ++ values later, in nds32_elf_finish_dynamic_sections, but we ++ must add the entries now so that we get the correct size for ++ the .dynamic section. The DT_DEBUG entry is filled in by the ++ dynamic linker and used by the debugger. */ ++#define add_dynamic_entry(TAG, VAL) _bfd_elf_add_dynamic_entry (info, TAG, VAL) ++ ++ if (info->executable) ++ { ++ if (!add_dynamic_entry (DT_DEBUG, 0)) ++ return FALSE; ++ } ++ ++ if (elf_hash_table (info)->splt->size != 0) ++ { ++ if (!add_dynamic_entry (DT_PLTGOT, 0) ++ || !add_dynamic_entry (DT_PLTRELSZ, 0) ++ || !add_dynamic_entry (DT_PLTREL, DT_RELA) ++ || !add_dynamic_entry (DT_JMPREL, 0)) ++ return FALSE; ++ } ++ ++ if (plt) ++ { ++ if (htab->dt_tlsdesc_plt ++ && (!add_dynamic_entry (DT_TLSDESC_PLT, 0) ++ || !add_dynamic_entry (DT_TLSDESC_GOT, 0))) ++ return FALSE; ++ } ++ ++ if (relocs) ++ { ++ if (!add_dynamic_entry (DT_RELA, 0) ++ || !add_dynamic_entry (DT_RELASZ, 0) ++ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela))) ++ return FALSE; ++ ++ /* If any dynamic relocs apply to a read-only section, ++ then we need a DT_TEXTREL entry. */ ++ if ((info->flags & DF_TEXTREL) == 0) ++ elf_link_hash_traverse (&htab->root, readonly_dynrelocs, ++ (void *) info); ++ ++ if ((info->flags & DF_TEXTREL) != 0) ++ { ++ if (!add_dynamic_entry (DT_TEXTREL, 0)) ++ return FALSE; ++ } ++ } ++ } ++#undef add_dynamic_entry ++ ++ return TRUE; ++} ++ ++static bfd_reloc_status_type ++nds32_relocate_contents (reloc_howto_type *howto, bfd *input_bfd, ++ bfd_vma relocation, bfd_byte *location) ++{ ++ int size; ++ bfd_vma x = 0; ++ bfd_reloc_status_type flag; ++ unsigned int rightshift = howto->rightshift; ++ unsigned int bitpos = howto->bitpos; ++ ++ /* If the size is negative, negate RELOCATION. This isn't very ++ general. */ ++ if (howto->size < 0) ++ relocation = -relocation; ++ ++ /* Get the value we are going to relocate. */ ++ size = bfd_get_reloc_size (howto); ++ switch (size) ++ { ++ default: ++ case 0: ++ case 1: ++ case 8: ++ abort (); ++ break; ++ case 2: ++ x = bfd_getb16 (location); ++ break; ++ case 4: ++ x = bfd_getb32 (location); ++ break; ++ } ++ ++ /* Check for overflow. FIXME: We may drop bits during the addition ++ which we don't check for. We must either check at every single ++ operation, which would be tedious, or we must do the computations ++ in a type larger than bfd_vma, which would be inefficient. */ ++ flag = bfd_reloc_ok; ++ if (howto->complain_on_overflow != complain_overflow_dont) ++ { ++ bfd_vma addrmask, fieldmask, signmask, ss; ++ bfd_vma a, b, sum; ++ ++ /* Get the values to be added together. For signed and unsigned ++ relocations, we assume that all values should be truncated to ++ the size of an address. For bitfields, all the bits matter. ++ See also bfd_check_overflow. */ ++ fieldmask = N_ONES (howto->bitsize); ++ signmask = ~fieldmask; ++ addrmask = N_ONES (bfd_arch_bits_per_address (input_bfd)) | fieldmask; ++ a = (relocation & addrmask) >> rightshift; ++ b = (x & howto->src_mask & addrmask) >> bitpos; ++ ++ switch (howto->complain_on_overflow) ++ { ++ case complain_overflow_signed: ++ /* If any sign bits are set, all sign bits must be set. ++ That is, A must be a valid negative address after ++ shifting. */ ++ signmask = ~(fieldmask >> 1); ++ /* Fall through. */ ++ ++ case complain_overflow_bitfield: ++ /* Much like the signed check, but for a field one bit ++ wider. We allow a bitfield to represent numbers in the ++ range -2**n to 2**n-1, where n is the number of bits in the ++ field. Note that when bfd_vma is 32 bits, a 32-bit reloc ++ can't overflow, which is exactly what we want. */ ++ ss = a & signmask; ++ if (ss != 0 && ss != ((addrmask >> rightshift) & signmask)) ++ flag = bfd_reloc_overflow; ++ ++ /* We only need this next bit of code if the sign bit of B ++ is below the sign bit of A. This would only happen if ++ SRC_MASK had fewer bits than BITSIZE. Note that if ++ SRC_MASK has more bits than BITSIZE, we can get into ++ trouble; we would need to verify that B is in range, as ++ we do for A above. */ ++ ss = ((~howto->src_mask) >> 1) & howto->src_mask; ++ ss >>= bitpos; ++ ++ /* Set all the bits above the sign bit. */ ++ b = (b ^ ss) - ss; ++ ++ /* Now we can do the addition. */ ++ sum = a + b; ++ ++ /* See if the result has the correct sign. Bits above the ++ sign bit are junk now; ignore them. If the sum is ++ positive, make sure we did not have all negative inputs; ++ if the sum is negative, make sure we did not have all ++ positive inputs. The test below looks only at the sign ++ bits, and it really just ++ SIGN (A) == SIGN (B) && SIGN (A) != SIGN (SUM) ++ ++ We mask with addrmask here to explicitly allow an address ++ wrap-around. The Linux kernel relies on it, and it is ++ the only way to write assembler code which can run when ++ loaded at a location 0x80000000 away from the location at ++ which it is linked. */ ++ if (((~(a ^ b)) & (a ^ sum)) & signmask & addrmask) ++ flag = bfd_reloc_overflow; ++ ++ break; ++ ++ case complain_overflow_unsigned: ++ /* Checking for an unsigned overflow is relatively easy: ++ trim the addresses and add, and trim the result as well. ++ Overflow is normally indicated when the result does not ++ fit in the field. However, we also need to consider the ++ case when, e.g., fieldmask is 0x7fffffff or smaller, an ++ input is 0x80000000, and bfd_vma is only 32 bits; then we ++ will get sum == 0, but there is an overflow, since the ++ inputs did not fit in the field. Instead of doing a ++ separate test, we can check for this by or-ing in the ++ operands when testing for the sum overflowing its final ++ field. */ ++ sum = (a + b) & addrmask; ++ if ((a | b | sum) & signmask) ++ flag = bfd_reloc_overflow; ++ break; ++ ++ default: ++ abort (); ++ } ++ } ++ ++ /* Put RELOCATION in the right bits. */ ++ relocation >>= (bfd_vma) rightshift; ++ relocation <<= (bfd_vma) bitpos; ++ ++ /* Add RELOCATION to the right bits of X. */ ++ /* FIXME : 090616 ++ Because the relaxation may generate duplicate relocation at one address, ++ an addition to immediate in the instruction may cause the relocation added ++ several times. ++ This bug should be fixed in assembler, but a check is also needed here. */ ++ if (howto->partial_inplace) ++ x = ((x & ~howto->dst_mask) ++ | (((x & howto->src_mask) + relocation) & howto->dst_mask)); ++ else ++ x = ((x & ~howto->dst_mask) | ((relocation) & howto->dst_mask)); ++ ++ ++ /* Put the relocated value back in the object file. */ ++ switch (size) ++ { ++ default: ++ case 0: ++ case 1: ++ case 8: ++ abort (); ++ break; ++ case 2: ++ bfd_putb16 (x, location); ++ break; ++ case 4: ++ bfd_putb32 (x, location); ++ break; ++ } ++ ++ return flag; ++} ++ ++static bfd_reloc_status_type ++nds32_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd, ++ asection *input_section, bfd_byte *contents, ++ bfd_vma address, bfd_vma value, bfd_vma addend) ++{ ++ bfd_vma relocation; ++ ++ /* Sanity check the address. */ ++ if (address > bfd_get_section_limit (input_bfd, input_section)) ++ return bfd_reloc_outofrange; ++ ++ /* This function assumes that we are dealing with a basic relocation ++ against a symbol. We want to compute the value of the symbol to ++ relocate to. This is just VALUE, the value of the symbol, plus ++ ADDEND, any addend associated with the reloc. */ ++ relocation = value + addend; ++ ++ /* If the relocation is PC relative, we want to set RELOCATION to ++ the distance between the symbol (currently in RELOCATION) and the ++ location we are relocating. Some targets (e.g., i386-aout) ++ arrange for the contents of the section to be the negative of the ++ offset of the location within the section; for such targets ++ pcrel_offset is FALSE. Other targets (e.g., m88kbcs or ELF) ++ simply leave the contents of the section as zero; for such ++ targets pcrel_offset is TRUE. If pcrel_offset is FALSE we do not ++ need to subtract out the offset of the location within the ++ section (which is just ADDRESS). */ ++ if (howto->pc_relative) ++ { ++ relocation -= (input_section->output_section->vma ++ + input_section->output_offset); ++ if (howto->pcrel_offset) ++ relocation -= address; ++ } ++ ++ return nds32_relocate_contents (howto, input_bfd, relocation, ++ contents + address); ++} ++ ++static bfd_boolean ++nds32_elf_output_symbol_hook (struct bfd_link_info *info, ++ const char *name, ++ Elf_Internal_Sym *elfsym ATTRIBUTE_UNUSED, ++ asection *input_sec, ++ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) ++{ ++ const char *source; ++ FILE *sym_ld_script = NULL; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (info); ++ sym_ld_script = table->sym_ld_script; ++ if (!sym_ld_script) ++ return TRUE; ++ ++ if (!h || !name || *name == '\0') ++ return TRUE; ++ ++ if (input_sec->flags & SEC_EXCLUDE) ++ return TRUE; ++ ++ if (!check_start_export_sym) ++ { ++ fprintf (sym_ld_script, "SECTIONS\n{\n"); ++ check_start_export_sym = 1; ++ } ++ ++ if (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ { ++ if (!h->root.u.def.section->output_section) ++ return TRUE; ++ ++ if (bfd_is_const_section (input_sec)) ++ source = input_sec->name; ++ else ++ source = input_sec->owner->filename; ++ ++ fprintf (sym_ld_script, "\t%s = 0x%08lx;\t /* %s */\n", ++ h->root.root.string, ++ (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset), source); ++ } ++ ++ return TRUE; ++} ++ ++/* Relocate an NDS32/D ELF section. ++ There is some attempt to make this function usable for many architectures, ++ both for RELA and REL type relocs, if only to serve as a learning tool. ++ ++ The RELOCATE_SECTION function is called by the new ELF backend linker ++ to handle the relocations for a section. ++ ++ The relocs are always passed as Rela structures; if the section ++ actually uses Rel structures, the r_addend field will always be ++ zero. ++ ++ This function is responsible for adjust the section contents as ++ necessary, and (if using Rela relocs and generating a ++ relocatable output file) adjusting the reloc addend as ++ necessary. ++ ++ This function does not have to worry about setting the reloc ++ address or the reloc symbol index. ++ ++ LOCAL_SYMS is a pointer to the swapped in local symbols. ++ ++ LOCAL_SECTIONS is an array giving the section in the input file ++ corresponding to the st_shndx field of each local symbol. ++ ++ The global hash table entry for the global symbols can be found ++ via elf_sym_hashes (input_bfd). ++ ++ When generating relocatable output, this function must handle ++ STB_LOCAL/STT_SECTION symbols specially. The output symbol is ++ going to be the section symbol corresponding to the output ++ section, which means that the addend must be adjusted ++ accordingly. */ ++ ++/* Return the base VMA address which should be subtracted from real addresses ++ when resolving @dtpoff relocation. ++ This is PT_TLS segment p_vaddr. */ ++ ++/* Return the relocation value for @tpoff relocation ++ if STT_TLS virtual address is ADDRESS. */ ++ ++/* Return the relocation value for @gottpoff relocation ++ if STT_TLS virtual address is ADDRESS. */ ++static bfd_vma ++gottpoff (struct bfd_link_info *info, bfd_vma address) ++{ ++ bfd_vma tp_base; ++ bfd_vma tp_offset; ++ ++ /* If tls_sec is NULL, we should have signalled an error already. */ ++ if (elf_hash_table (info)->tls_sec == NULL) ++ return 0; ++ ++ tp_base = elf_hash_table (info)->tls_sec->vma; ++ tp_offset = address - tp_base; ++ ++ return tp_offset; ++} ++ ++#define POLY 0x755b /* crc = (0x10000 | POLY) >> 1 = 0xbaad. */ ++#define INV_POLY 0xb55d ++ ++/* Initial the crc table value. */ ++ ++static void ++nds32_precompute_byte_crc_table (void) ++{ ++ int i; ++ int j; ++ unsigned short r; ++ r = 0; ++ for (i = 0; i < 0x100; ++i) ++ { ++ r = i << 8; ++ for (j = 7; j >= 0; --j) ++ { ++ unsigned short p = (r & 0x8000) ? POLY : 0; ++ r = (r << 1) ^ p; ++ } ++ byte_crc_table[i] = r; ++ } ++} ++ ++static void ++nds32_precompute_byte_inv_crc_table (void) ++{ ++ int i; ++ int j; ++ unsigned short r; ++ r = 0; ++ for (i = 0; i < 0x100; ++i) ++ { ++ r = i << 8; ++ for (j = 7; j >= 0; --j) ++ { ++ unsigned short p = (r & 0x8000) ? INV_POLY : 0; ++ r = (r << 1) ^ p; ++ } ++ byte_inv_crc_table[i] = r; ++ } ++} ++ ++/* Perform the crc computation. */ ++ ++static void ++nds32_crc_compute (bfd_byte *ptr, unsigned int size, unsigned short *sum) ++{ ++ unsigned char b; ++ ++ if (size == 2) ++ { ++ b = *ptr++ ^ (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ b = *ptr++ ^ (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ b = (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ b = (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ } ++ else ++ { ++ b = *ptr++ ^ (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ b = *ptr++ ^ (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ b = *ptr++ ^ (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ b = *ptr++ ^ (*sum >> 8); ++ *sum = (0xffff & (*sum << 8)) ^ byte_crc_table[b]; ++ } ++} ++ ++static void ++nds32_crc_final (int num, unsigned short *sum) ++{ ++ int i, tmp, r = 0; ++ unsigned short crc, inv_crc = 0; ++ ++ crc = *sum; ++ /* Reverse it. */ ++ for (i = 0; i < 16; ++i) ++ { ++ tmp = crc & 0x1; ++ inv_crc = (inv_crc << 1) | tmp; ++ crc = crc >> 1; ++ } ++ ++ for (i = 0; i < num + 2; ++i) ++ { ++ if (i == 0) ++ tmp = (inv_crc >> 8) ^ (r >> 8); ++ else if (i == 1) ++ tmp = (inv_crc & 0xff) ^ (r >> 8); ++ else ++ tmp = (r >> 8); ++ r = (0xffff & (r << 8)) ^ byte_inv_crc_table[tmp]; ++ } ++ crc = r; ++ inv_crc = 0; ++ ++ for (i = 0; i < 16; ++i) ++ { ++ tmp = crc & 0x1; ++ inv_crc = (inv_crc << 1) | tmp; ++ crc = crc >> 1; ++ } ++ ++ *sum = inv_crc; ++} ++ ++/* Traverse the security region and get the crc. */ ++ ++static bfd_vma ++nds32_elf_crc_relocation (Elf_Internal_Rela *start_rel, ++ Elf_Internal_Rela *end_rel, ++ Elf_Internal_Rela *irelend, ++ bfd_byte *contents) ++{ ++ static bfd_boolean init = FALSE; ++ bfd_byte *location; ++ bfd_vma address; ++ bfd_vma x; ++ unsigned short sum = 0; ++ int num = 0; ++ static bfd_byte *ex9_contents = NULL; ++ Elf_Internal_Rela *irel; ++ bfd_boolean ex_final = FALSE; ++ ++ if (init == FALSE) ++ { ++ nds32_precompute_byte_crc_table (); ++ nds32_precompute_byte_inv_crc_table (); ++ init = TRUE; ++ if (ex9_section) ++ nds32_get_section_contents (ex9_section->owner, ex9_section, ++ &ex9_contents, TRUE); ++ } ++ ++ /* Check the final instruction is isps or not. */ ++ irel = end_rel; ++ while (irel < irelend && irel->r_offset == end_rel->r_offset) ++ { ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SECURITY_16 ++ && irel->r_addend == NDS32_SECURITY_RESTART) ++ { ++ ex_final = TRUE; ++ break; ++ } ++ irel++; ++ } ++ ++ ++ /* It doesn't have to add crc itself. */ ++ ++ for (address = start_rel->r_offset + 4; address <= end_rel->r_offset;) ++ { ++ /* Don't check the next crc itself. */ ++ if (address == end_rel->r_offset && ex_final) ++ break; ++ ++ num += 4; ++ location = contents + address; ++ x = bfd_getb32 (location); ++ if (INSN_32BIT (x)) ++ { ++ /* 4byte instruction. */ ++ nds32_crc_compute (location, 4, &sum); ++ address += 4; ++ } ++ else ++ { ++ /* 2byte instruction. */ ++ /* Ex9 has to fetch table instruction. */ ++ if (((x >> 16) & 0xfe00) == INSN_EX9_IT_1 && ((x >> 16) & 0x1e0)) ++ { ++ if (!ex9_contents) ++ (*_bfd_error_handler) (_("SIG error: Can't get ex9 contents.")); ++ nds32_crc_compute (ex9_contents + ((x >> 16) & 0x1ff) * 4, ++ 4, &sum); ++ } ++ else if (((x >> 16) & 0xffe0) == INSN_EX9_IT_2) ++ { ++ if (!ex9_contents) ++ (*_bfd_error_handler) (_("SIG error: Can't get ex9 contents.")); ++ nds32_crc_compute (ex9_contents + ((x >> 16) & 0x1f) * 4, ++ 4, &sum); ++ } ++ else ++ nds32_crc_compute (location, 2, &sum); ++ address += 2; ++ } ++ } ++ ++ nds32_crc_final (num, &sum); ++ ++ return sum; ++} ++ ++/* Move all SECURITY_16 to the final one for each instruction. */ ++ ++static void ++nds32_elf_crc_adjust_reloc (Elf_Internal_Rela *relocs, ++ Elf_Internal_Rela *relend) ++{ ++ Elf_Internal_Rela *rel, *crc_rel = NULL; ++ Elf_Internal_Rela rel_temp; ++ ++ for (rel = relocs; rel < relend; rel++) ++ { ++ if (crc_rel && crc_rel->r_offset == rel->r_offset) ++ { ++ memcpy (&rel_temp, rel, sizeof (Elf_Internal_Rela)); ++ memcpy (rel, crc_rel, sizeof (Elf_Internal_Rela)); ++ memcpy (crc_rel, &rel_temp, sizeof (Elf_Internal_Rela)); ++ crc_rel = rel; ++ } ++ else if (ELF32_R_TYPE (rel->r_info) == R_NDS32_SECURITY_16) ++ { ++ crc_rel = rel; ++ continue; ++ } ++ } ++} ++ ++static bfd_boolean ++patch_tls_desc_to_ie (bfd_byte *contents, Elf_Internal_Rela *rel, bfd *ibfd) ++{ ++ /* TLS_GD/TLS_LD model #1 ++ 46 00 00 00 sethi $r0,#0x0 ++ 58 00 00 00 ori $r0,$r0,#0x0 ++ 40 00 74 00 add $r0,$r0,$gp ++ 04 10 00 00 lwi $r1,[$r0+#0x0] ++ 4b e0 04 01 jral $lp,$r1 */ ++ ++ /* TLS_GD/TLS_LD model #2 ++ 46 00 00 00 sethi $r0,#0x0 ++ 58 00 00 00 ori $r0,$r0,#0x0 ++ 38 10 74 02 lw $r1,[$r0+($gp<<#0x0)] <= TODO: not necessary $r1 register allocation ++ 40 00 74 00 add $r0,$r0,$gp ++ 4b e0 04 01 jral $lp,$r1 */ ++ ++ /* TLS_IE model (non-PIC) ++ 46 00 00 00 sethi $r0,#0x0 ++ 04 00 00 00 lwi $r0,[$r0+#0x0] ++ 38 00 64 02 lw $r0,[$r0+($r25<<#0x0)] */ ++ ++ /* TLS_IE model (PIC) ++ 46 00 00 00 sethi $r0,#0x0 ++ 58 00 00 00 ori $r0,$r0,#0x0 ++ 38 00 74 02 lw $r0,[$r0+($gp<<#0x0)] ++ 38 00 64 02 lw $r0,[$r0+($r25<<#0x0)] */ ++ ++ /* TLS_GD_TO_IE model ++ 46 00 00 00 sethi $r0,#0x0 ++ 58 00 00 00 ori $r0,$r0,#0x0 ++ 40 00 74 00 add $r0,$rM,$gp ++ 04 00 00 01 lwi $r0,[$r0+#0x4] ++ 40 00 64 00 add $r0,$r0,$r25 */ ++ ++ bfd_boolean rz = FALSE; ++ ++ typedef struct ++ { ++ uint32_t opcode; ++ uint32_t mask; ++ } pat_t; ++ ++ uint32_t patch[3] = ++ { ++ 0x40007400, /* add $r0,$rM,$gp */ ++ 0x04000001, /* lwi $r0,[$r0+#0x4] */ ++ 0x40006400, /* add $r0,$r0,$r25 */ ++ }; ++ ++ pat_t mode0[3] = ++ { ++ { 0x40000000, 0xfe0003ff }, ++ { 0x04000000, 0xfe000000 }, ++ { 0x4be00001, 0xffff83ff }, ++ }; ++ ++ pat_t mode1[3] = ++ { ++ { 0x38007402, 0xfe007fff }, ++ { 0x40007400, 0xfe007fff }, ++ { 0x4be00001, 0xffff83ff }, ++ }; ++ ++ unsigned char *p = contents + rel->r_offset; ++ ++ uint32_t insn; ++ uint32_t regidx = 0; ++ insn = bfd_getb32 (p); ++ if (INSN_SETHI == (0xfe0fffffu & insn)) ++ { ++ regidx = 0x1f & (insn >> 20); ++ p += 4; ++ } ++ ++ insn = bfd_getb32 (p); ++ if (INSN_ORI == (0xfe007fffu & insn)) ++ { ++ regidx = 0x1f & (insn >> 20); ++ p += 4; ++ } ++ ++ if (patch[2] == bfd_getb32 (p + 8)) /* character instruction */ ++ { ++ /* already patched? */ ++ if ((patch[0] == (0xfff07fffu & bfd_getb32 (p + 0))) && ++ (patch[1] == bfd_getb32 (p + 4))) ++ rz = TRUE; ++ } ++ else if (mode0[0].opcode == (mode0[0].mask & bfd_getb32 (p + 0))) ++ { ++ if ((mode0[1].opcode == (mode0[1].mask & bfd_getb32 (p + 4))) && ++ (mode0[2].opcode == (mode0[2].mask & bfd_getb32 (p + 8)))) ++ { ++ bfd_putb32 (patch[0] | (regidx << 15), p + 0); ++ bfd_putb32 (patch[1], p + 4); ++ bfd_putb32 (patch[2], p + 8); ++ rz = TRUE; ++ } ++ } ++ else if (mode1[0].opcode == (mode1[0].mask & bfd_getb32 (p + 0))) ++ { ++ if ((mode1[1].opcode == (mode1[1].mask & bfd_getb32 (p + 4))) && ++ (mode1[2].opcode == (mode1[2].mask & bfd_getb32 (p + 8)))) ++ { ++ bfd_putb32 (patch[0] | (regidx << 15), p + 0); ++ bfd_putb32 (patch[1], p + 4); ++ bfd_putb32 (patch[2], p + 8); ++ rz = TRUE; ++ } ++ } ++ ++ if (!rz) ++ { ++ printf ("%s: %s @ 0x%08x\n", __func__, ibfd->filename, ++ (int) rel->r_offset); ++ BFD_ASSERT(0); /* unsupported pattern */ ++ } ++ ++ return rz; ++} ++ ++static enum elf_nds32_tls_type ++get_tls_type (enum elf_nds32_reloc_type r_type, struct elf_link_hash_entry *h); ++ ++static unsigned int ++ones32 (register unsigned int x) ++{ ++ /* 32-bit recursive reduction using SWAR... ++ but first step is mapping 2-bit values ++ into sum of 2 1-bit values in sneaky way. */ ++ x -= ((x >> 1) & 0x55555555); ++ x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); ++ x = (((x >> 4) + x) & 0x0f0f0f0f); ++ x += (x >> 8); ++ x += (x >> 16); ++ return (x & 0x0000003f); ++} ++ ++/* ++static unsigned int ++fls (register unsigned int x) ++{ ++ return ffs (x & (-x)); ++} ++*/ ++ ++#define nds32_elf_local_tlsdesc_gotent(bfd) \ ++ (elf_nds32_tdata (bfd)->local_tlsdesc_gotent) ++ ++static bfd_boolean ++nds32_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info, bfd *input_bfd, ++ asection *input_section, bfd_byte *contents, ++ Elf_Internal_Rela *relocs, ++ Elf_Internal_Sym *local_syms, ++ asection **local_sections) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ struct elf_link_hash_entry **sym_hashes; ++ Elf_Internal_Rela *rel, *relend; ++ bfd_boolean ret = TRUE; /* Assume success. */ ++ int align = 0; ++ bfd_reloc_status_type r; ++ const char *errmsg = NULL; ++ bfd_vma gp; ++ struct elf_link_hash_table *ehtab; ++ struct elf_nds32_link_hash_table *htab; ++ bfd *dynobj; ++ bfd_vma *local_got_offsets; ++ asection *sgot, *splt, *sreloc; ++ bfd_vma high_address; ++ struct elf_nds32_link_hash_table *table; ++ int eliminate_gc_relocs; ++ bfd_vma fpbase_addr; ++ Elf_Internal_Rela *crc_rel = NULL; ++ ++ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; ++ sym_hashes = elf_sym_hashes (input_bfd); ++ ehtab = elf_hash_table (info); ++ htab = nds32_elf_hash_table (info); ++ high_address = bfd_get_section_limit (input_bfd, input_section); ++ ++ dynobj = htab->root.dynobj; ++ local_got_offsets = elf_local_got_offsets (input_bfd); ++ ++ sgot = ehtab->sgot; ++ splt = ehtab->splt; ++ sreloc = NULL; ++ ++ rel = relocs; ++ relend = relocs + input_section->reloc_count; ++ ++ table = nds32_elf_hash_table (info); ++ eliminate_gc_relocs = table->eliminate_gc_relocs; ++ ++ /* explain _SDA_BASE_ */ ++ /* By this time, we can adjust the value of _SDA_BASE_. */ ++ if ((!info->relocatable)) ++ { ++ is_SDA_BASE_set = 1; ++ r = nds32_elf_final_sda_base (output_bfd, info, &gp, TRUE); ++ if (r != bfd_reloc_ok) ++ return FALSE; ++ } ++ ++#ifdef NDS32_LINUX_TOOLCHAIN ++ /* Do TLS model conversion once at first. */ ++ nds32_elf_unify_tls_model (input_bfd, input_section, contents, info); ++#endif ++ ++ if (is_ITB_BASE_set == 0) ++ { ++ /* Set the _ITB_BASE_. */ ++ if (!nds32_elf_ex9_itb_base (info)) ++ { ++ (*_bfd_error_handler) (_("%B: error: Cannot set _ITB_BASE_"), ++ output_bfd); ++ bfd_set_error (bfd_error_bad_value); ++ } ++ } ++ ++ if (table->target_optimize & NDS32_RELAX_IFC_ON) ++ if (!nds32_elf_ifc_reloc ()) ++ (*_bfd_error_handler) (_("error: IFC relocation error.")); ++ ++ /* Relocation for .ex9.itable. */ ++ if ((table->target_optimize & NDS32_RELAX_EX9_ON) ++ || (table->ex9_import_file && table->update_ex9_table)) ++ nds32_elf_ex9_reloc_jmp (info); ++ ++ if (indirect_call_table.count > 0) ++ nds32_elf_ict_relocate (info); ++ ++ /* Use gp as fp to prevent truncated fit. Because in relaxation time ++ the fp value is set as gp, and it has be reverted for instruction ++ setting fp. */ ++ fpbase_addr = elf_gp (output_bfd); ++ ++ /* Move all SECURITY_16 to the final one for each instruction. */ ++ nds32_elf_crc_adjust_reloc (relocs, relend); ++ ++ /* Deal with (dynamic) relocations. */ ++ for (rel = relocs; rel < relend; rel++) ++ { ++ enum elf_nds32_reloc_type r_type; ++ reloc_howto_type *howto = NULL; ++ unsigned long r_symndx; ++ struct elf_link_hash_entry *h = NULL; ++ struct bfd_link_hash_entry *h2; ++ Elf_Internal_Sym *sym = NULL; ++ asection *sec; ++ bfd_vma relocation; ++ struct elf_nds32_ict_hash_entry *entry; ++ bfd_vma relocation_sym = 0xdeadbeef; ++ Elf_Internal_Rela *lorel; ++ bfd_vma off; ++ ++ /* We can't modify r_addend here as elf_link_input_bfd has an assert to ++ ensure it's zero (we use REL relocs, not RELA). Therefore this ++ should be assigning zero to `addend', but for clarity we use ++ `r_addend'. */ ++ ++ bfd_vma addend = rel->r_addend; ++ bfd_vma offset = rel->r_offset; ++ ++ r_type = ELF32_R_TYPE (rel->r_info); ++ if (r_type >= R_NDS32_max) ++ { ++ (*_bfd_error_handler) (_("%B: error: unknown relocation type %d."), ++ input_bfd, r_type); ++ bfd_set_error (bfd_error_bad_value); ++ ret = FALSE; ++ continue; ++ } ++ ++ if (r_type == R_NDS32_GNU_VTENTRY ++ || r_type == R_NDS32_GNU_VTINHERIT ++ || r_type == R_NDS32_NONE ++ || r_type == R_NDS32_RELA_GNU_VTENTRY ++ || r_type == R_NDS32_RELA_GNU_VTINHERIT ++ || (r_type >= R_NDS32_INSN16 && r_type <= R_NDS32_25_FIXED_RELA) ++ || r_type == R_NDS32_DATA ++ || r_type == R_NDS32_TRAN ++ || (r_type >= R_NDS32_LONGCALL4 && r_type <= R_NDS32_LONGJUMP7)) ++ continue; ++ ++ /* Save security beginning. */ ++ if (r_type == R_NDS32_SECURITY_16 && crc_rel == NULL) ++ { ++ crc_rel = rel; ++ continue; ++ } ++ ++ /* If we enter the fp-as-gp region. Resolve the address of best fp-base. */ ++ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_BEGIN ++ && (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ { ++ int dist; ++ ++ /* Distance to relocation of best fp-base is encoded in R_SYM. */ ++ dist = rel->r_addend >> 16; ++ fpbase_addr = calculate_memory_address (input_bfd, rel + dist, ++ local_syms, symtab_hdr); ++ } ++ else if (ELF32_R_TYPE (rel->r_info) == R_NDS32_RELAX_REGION_END ++ && (rel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ { ++ fpbase_addr = elf_gp (output_bfd); ++ } ++ ++ if (((r_type >= R_NDS32_DWARF2_OP1_RELA ++ && r_type <= R_NDS32_DWARF2_LEB_RELA) || r_type >= R_NDS32_RELAX_ENTRY) ++ && !info->relocatable) ++ continue; ++ ++ howto = bfd_elf32_bfd_reloc_type_table_lookup (r_type); ++ r_symndx = ELF32_R_SYM (rel->r_info); ++ ++ /* This is a final link. */ ++ sym = NULL; ++ sec = NULL; ++ h = NULL; ++ ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Local symbol. */ ++ sym = local_syms + r_symndx; ++ sec = local_sections[r_symndx]; ++ ++ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); ++ addend = rel->r_addend; ++ ++ /* keep symbol location for static TLS_IE GOT entry */ ++ relocation_sym = relocation; ++ } ++ else ++ { ++ /* External symbol. */ ++ bfd_boolean warned, unresolved_reloc; ++ int symndx = r_symndx - symtab_hdr->sh_info; ++ ++ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, ++ r_symndx, symtab_hdr, sym_hashes, h, sec, ++ relocation, unresolved_reloc, warned); ++ ++ /* keep symbol location for static TLS_IE GOT entry */ ++ relocation_sym = relocation; ++ ++ /* la $fp, _FP_BASE_ is per-function (region). ++ Handle it specially. */ ++ switch ((int) r_type) ++ { ++ case R_NDS32_SDA19S0_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ case R_NDS32_20_RELA: ++ if (strcmp (elf_sym_hashes (input_bfd)[symndx]->root.root.string, ++ FP_BASE_NAME) == 0) ++ { ++ relocation = fpbase_addr; ++ break; ++ } ++ } ++ } ++ ++ if (info->relocatable) ++ { ++ /* This is a relocatable link. We don't have to change ++ anything, unless the reloc is against a section symbol, ++ in which case we have to adjust according to where the ++ section symbol winds up in the output section. */ ++ if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION) ++ rel->r_addend += sec->output_offset + sym->st_value; ++ ++ continue; ++ } ++ ++ /* Sanity check the address. */ ++ if (offset > high_address) ++ { ++ r = bfd_reloc_outofrange; ++ goto check_reloc; ++ } ++ ++ if ((r_type >= R_NDS32_DWARF2_OP1_RELA ++ && r_type <= R_NDS32_DWARF2_LEB_RELA) ++ || r_type >= R_NDS32_RELAX_ENTRY) ++ continue; ++ ++ switch ((int) r_type) ++ { ++ case R_NDS32_GOTOFF: ++ /* Relocation is relative to the start of the global offset ++ table (for ld24 rx, #uimm24), e.g. access at label + addend ++ ++ ld24 rx. #label@GOTOFF + addend ++ sub rx, r12. */ ++ case R_NDS32_GOTOFF_HI20: ++ case R_NDS32_GOTOFF_LO12: ++ case R_NDS32_GOTOFF_LO15: ++ case R_NDS32_GOTOFF_LO19: ++ BFD_ASSERT (sgot != NULL); ++ ++ relocation -= elf_gp (output_bfd); ++ break; ++ ++ case R_NDS32_9_PLTREL: ++ case R_NDS32_25_PLTREL: ++ /* Relocation is to the entry for this symbol in the ++ procedure linkage table. */ ++ ++ /* The native assembler will generate a 25_PLTREL reloc ++ for a local symbol if you assemble a call from one ++ section to another when using -K pic. */ ++ if (h == NULL) ++ break; ++ ++ if (h->forced_local) ++ break; ++ ++ /* We didn't make a PLT entry for this symbol. This ++ happens when statically linking PIC code, or when ++ using -Bsymbolic. */ ++ if (h->plt.offset == (bfd_vma) - 1) ++ break; ++ ++ relocation = (splt->output_section->vma ++ + splt->output_offset + h->plt.offset); ++ break; ++ ++ case R_NDS32_PLT_GOTREL_HI20: ++ case R_NDS32_PLT_GOTREL_LO12: ++ case R_NDS32_PLT_GOTREL_LO15: ++ case R_NDS32_PLT_GOTREL_LO19: ++ case R_NDS32_PLT_GOTREL_LO20: ++ if (h == NULL ++ || h->forced_local ++ || h->plt.offset == (bfd_vma) -1 ++ || (info->pie && h->def_regular)) ++ { ++ /* TODO: find better checking to optimize PIE PLT relocations. */ ++ /* We didn't make a PLT entry for this symbol. This ++ happens when statically linking PIC code, or when ++ using -Bsymbolic. */ ++ if (h) ++ h->plt.offset = (bfd_vma) -1; /* cancel PLT trampoline. */ ++ relocation -= elf_gp(output_bfd); ++ break; ++ } ++ ++ relocation = (splt->output_section->vma ++ + splt->output_offset + h->plt.offset); ++ ++ relocation -= elf_gp (output_bfd); ++ break; ++ ++ case R_NDS32_PLTREL_HI20: ++ case R_NDS32_PLTREL_LO12: ++ ++ /* Relocation is to the entry for this symbol in the ++ procedure linkage table. */ ++ ++ /* The native assembler will generate a 25_PLTREL reloc ++ for a local symbol if you assemble a call from one ++ section to another when using -K pic. */ ++ if (h == NULL) ++ break; ++ ++ if (h->forced_local) ++ break; ++ ++ if (h->plt.offset == (bfd_vma) - 1) ++ /* We didn't make a PLT entry for this symbol. This ++ happens when statically linking PIC code, or when ++ using -Bsymbolic. */ ++ break; ++ ++ if (splt == NULL) ++ break; ++ ++ relocation = (splt->output_section->vma ++ + splt->output_offset ++ + h->plt.offset + 4) ++ - (input_section->output_section->vma ++ + input_section->output_offset ++ + rel->r_offset); ++ ++ break; ++ ++ case R_NDS32_GOTPC20: ++ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation ++ ld24 rx,#_GLOBAL_OFFSET_TABLE_ */ ++ relocation = elf_gp (output_bfd); ++ break; ++ ++ case R_NDS32_GOTPC_HI20: ++ case R_NDS32_GOTPC_LO12: ++ /* .got(_GLOBAL_OFFSET_TABLE_) - pc relocation ++ bl .+4 ++ seth rx,#high(_GLOBAL_OFFSET_TABLE_) ++ or3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) ++ or ++ bl .+4 ++ seth rx,#shigh(_GLOBAL_OFFSET_TABLE_) ++ add3 rx,rx,#low(_GLOBAL_OFFSET_TABLE_ +4) */ ++ relocation = elf_gp (output_bfd); ++ relocation -= (input_section->output_section->vma ++ + input_section->output_offset + rel->r_offset); ++ break; ++ ++ case R_NDS32_GOT20: ++ /* Fall through. */ ++ case R_NDS32_GOT_HI20: ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOT_LO15: ++ case R_NDS32_GOT_LO19: ++ /* Relocation is to the entry for this symbol in the global ++ offset table. */ ++ BFD_ASSERT (sgot != NULL); ++ ++ if (h != NULL) /* External symbol */ ++ { ++ bfd_boolean dyn; ++ ++ off = h->got.offset; ++ BFD_ASSERT (off != (bfd_vma) - 1); ++ dyn = htab->root.dynamic_sections_created; ++ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) ++ || (info->shared ++ && (info->symbolic ++ || h->dynindx == -1 ++ || h->forced_local) && h->def_regular)) ++ { ++ /* This is actually a static link, or it is a ++ -Bsymbolic link and the symbol is defined ++ locally, or the symbol was forced to be local ++ because of a version file. We must initialize ++ this entry in the global offset table. Since the ++ offset must always be a multiple of 4, we use the ++ least significant bit to record whether we have ++ initialized it already. ++ ++ When doing a dynamic link, we create a .rela.got ++ relocation entry to initialize the value. This ++ is done in the finish_dynamic_symbol routine. */ ++ if ((off & 1) != 0) /* clear LSB */ ++ off &= ~1; ++ else ++ { ++ bfd_put_32 (output_bfd, relocation, sgot->contents + off); ++ h->got.offset |= 1; /* mark initialized */ ++ } ++ } ++ relocation = sgot->output_section->vma + sgot->output_offset + off ++ - elf_gp (output_bfd); ++ } ++ else /* Local symbol */ ++ { ++ bfd_byte *loc; ++ ++ BFD_ASSERT (local_got_offsets != NULL ++ && local_got_offsets[r_symndx] != (bfd_vma) - 1); ++ ++ off = local_got_offsets[r_symndx]; ++ ++ /* The offset must always be a multiple of 4. We use ++ the least significant bit to record whether we have ++ already processed this entry. */ ++ if ((off & 1) != 0) /* clear LSB */ ++ off &= ~1; ++ else ++ { ++ bfd_put_32 (output_bfd, relocation, sgot->contents + off); ++ ++ if (info->shared) ++ { ++ asection *srelgot; ++ Elf_Internal_Rela outrel; ++ ++ /* We need to generate a R_NDS32_RELATIVE reloc ++ for the dynamic linker. */ ++ srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); ++ BFD_ASSERT (srelgot != NULL); ++ ++ outrel.r_offset = (elf_gp (output_bfd) ++ + sgot->output_offset + off); ++ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); ++ outrel.r_addend = relocation; ++ loc = srelgot->contents; ++ loc += ++ srelgot->reloc_count * sizeof (Elf32_External_Rela); ++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); ++ ++srelgot->reloc_count; ++ } ++ local_got_offsets[r_symndx] |= 1; ++ } ++ relocation = sgot->output_section->vma + sgot->output_offset + off ++ - elf_gp (output_bfd); ++ } ++ ++ break; ++ ++ case R_NDS32_25_PCREL_RELA: ++ case R_NDS32_HI20_RELA: ++ case R_NDS32_LO12S0_RELA: ++ /* Merge normal and indirect call functions. */ ++ if (!ignore_indirect_call && h ++ && elf32_nds32_hash_entry (h)->indirect_call) ++ { ++ (*_bfd_error_handler) ++ (_("%B: Warning: there are mixed" ++ " indirect call function \'%s\'\n"), ++ input_bfd, h->root.root.string); ++ ++ entry = (struct elf_nds32_ict_hash_entry*) ++ bfd_hash_lookup (&indirect_call_table, h->root.root.string, ++ FALSE, FALSE); ++ if (!entry) ++ { ++ (*_bfd_error_handler) ++ (_("%B %A: internal error indirect call relocation " ++ "0x%lx without hash.\n"), ++ input_bfd, sec, rel->r_offset); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ h2 = bfd_link_hash_lookup (info->hash, ++ "_INDIRECT_CALL_TABLE_BASE_", ++ FALSE, FALSE, FALSE); ++ relocation = ((h2->u.def.value ++ + h2->u.def.section->output_section->vma ++ + h2->u.def.section->output_offset) ++ + (entry->order * 4)); ++ break; ++ } ++ ++ /* Fall through. */ ++ case R_NDS32_16_RELA: ++ case R_NDS32_20_RELA: ++ case R_NDS32_5_RELA: ++ case R_NDS32_32_RELA: ++ case R_NDS32_9_PCREL_RELA: ++ case R_NDS32_WORD_9_PCREL_RELA: ++ case R_NDS32_10_UPCREL_RELA: ++ case R_NDS32_15_PCREL_RELA: ++ case R_NDS32_17_PCREL_RELA: ++ case R_NDS32_LO12S3_RELA: ++ case R_NDS32_LO12S2_RELA: ++ case R_NDS32_LO12S2_DP_RELA: ++ case R_NDS32_LO12S2_SP_RELA: ++ case R_NDS32_LO12S1_RELA: ++ case R_NDS32_LO12S0_ORI_RELA: ++ if (info->shared && r_symndx != 0 ++ && (input_section->flags & SEC_ALLOC) != 0 ++ && (eliminate_gc_relocs == 0 ++ || (sec && (sec->flags & SEC_EXCLUDE) == 0)) ++ && ((r_type != R_NDS32_9_PCREL_RELA ++ && r_type != R_NDS32_WORD_9_PCREL_RELA ++ && r_type != R_NDS32_10_UPCREL_RELA ++ && r_type != R_NDS32_15_PCREL_RELA ++ && r_type != R_NDS32_17_PCREL_RELA ++ && r_type != R_NDS32_25_PCREL_RELA ++ && !(r_type == R_NDS32_32_RELA ++ && strcmp (input_section->name, ".eh_frame") == 0)) ++ || (h != NULL && h->dynindx != -1 ++ && (!info->symbolic || !h->def_regular)))) ++ { ++ Elf_Internal_Rela outrel; ++ bfd_boolean skip, relocate; ++ bfd_byte *loc; ++ ++ /* When generating a shared object, these relocations ++ are copied into the output file to be resolved at run ++ time. */ ++ ++ if (sreloc == NULL) ++ { ++ const char *name; ++ ++ name = bfd_elf_string_from_elf_section ++ (input_bfd, elf_elfheader (input_bfd)->e_shstrndx, ++ elf_section_data (input_section)->rela.hdr->sh_name); ++ if (name == NULL) ++ return FALSE; ++ ++ BFD_ASSERT (strncmp (name, ".rela", 5) == 0 ++ && strcmp (bfd_get_section_name (input_bfd, ++ input_section), ++ name + 5) == 0); ++ ++ sreloc = bfd_get_section_by_name (dynobj, name); ++ BFD_ASSERT (sreloc != NULL); ++ } ++ ++ skip = FALSE; ++ relocate = FALSE; ++ ++ outrel.r_offset = _bfd_elf_section_offset (output_bfd, ++ info, ++ input_section, ++ rel->r_offset); ++ if (outrel.r_offset == (bfd_vma) - 1) ++ skip = TRUE; ++ else if (outrel.r_offset == (bfd_vma) - 2) ++ skip = TRUE, relocate = TRUE; ++ outrel.r_offset += (input_section->output_section->vma ++ + input_section->output_offset); ++ ++ if (skip) ++ memset (&outrel, 0, sizeof outrel); ++ else if (r_type == R_NDS32_17_PCREL_RELA ++ || r_type == R_NDS32_15_PCREL_RELA ++ || r_type == R_NDS32_25_PCREL_RELA) ++ { ++ BFD_ASSERT (h != NULL && h->dynindx != -1); ++ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); ++ outrel.r_addend = rel->r_addend; ++ } ++ else ++ { ++ /* h->dynindx may be -1 if this symbol was marked to ++ become local. */ ++ if (h == NULL ++ || ((info->symbolic || h->dynindx == -1) ++ && h->def_regular) ++ || (info->pie && h->def_regular)) ++ { ++ relocate = TRUE; ++ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); ++ outrel.r_addend = relocation + rel->r_addend; ++ if (h) ++ h->plt.offset = (bfd_vma) -1; /* cancel PLT trampoline. */ ++ } ++ else ++ { ++ if (h->dynindx == -1) ++ { ++ (*_bfd_error_handler) ++ (_("%B: relocation %s against `%s' can not be used when" ++ "making a shared object; recompile with -fPIC"), ++ input_bfd, nds32_elf_howto_table[r_type].name, h->root.root.string); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ outrel.r_info = ELF32_R_INFO (h->dynindx, r_type); ++ outrel.r_addend = rel->r_addend; ++ } ++ } ++ ++ loc = sreloc->contents; ++ loc += sreloc->reloc_count * sizeof (Elf32_External_Rela); ++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); ++ ++sreloc->reloc_count; ++ ++ /* If this reloc is against an external symbol, we do ++ not want to fiddle with the addend. Otherwise, we ++ need to include the symbol value so that it becomes ++ an addend for the dynamic reloc. */ ++ if (!relocate) ++ continue; ++ } ++ break; ++ ++ case R_NDS32_25_ABS_RELA: ++ if (info->shared) ++ { ++ (*_bfd_error_handler) ++ (_("%s: warning: cannot deal R_NDS32_25_ABS_RELA in shared mode."), ++ bfd_get_filename (input_bfd)); ++ return FALSE; ++ } ++ break; ++ ++ case R_NDS32_9_PCREL: ++ r = nds32_elf_do_9_pcrel_reloc (input_bfd, howto, input_section, ++ contents, offset, ++ sec, relocation, addend); ++ goto check_reloc; ++ ++ case R_NDS32_HI20: ++ /* We allow an arbitrary number of HI20 relocs before the ++ LO12 reloc. This permits GCC to emit the HI and LO relocs ++ itself. */ ++ for (lorel = rel + 1; ++ (lorel < relend ++ && ELF32_R_TYPE (lorel->r_info) == R_NDS32_HI20); lorel++) ++ continue; ++ if (lorel < relend ++ && (ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S3 ++ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S2 ++ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S1 ++ || ELF32_R_TYPE (lorel->r_info) == R_NDS32_LO12S0)) ++ { ++ nds32_elf_relocate_hi20 (input_bfd, r_type, rel, lorel, ++ contents, relocation + addend); ++ r = bfd_reloc_ok; ++ } ++ else ++ r = _bfd_final_link_relocate (howto, input_bfd, input_section, ++ contents, offset, relocation, ++ addend); ++ ++ goto check_reloc; ++ ++ case R_NDS32_GOT17S2_RELA: ++ case R_NDS32_GOT15S2_RELA: ++ BFD_ASSERT (sgot != NULL); ++ ++ if (h != NULL) ++ { ++ bfd_boolean dyn; ++ ++ off = h->got.offset; ++ BFD_ASSERT (off != (bfd_vma) - 1); ++ ++ dyn = htab->root.dynamic_sections_created; ++ if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL ++ (dyn, info->shared, h) || (info->shared ++ && (info->symbolic ++ || h->dynindx == -1 ++ || h->forced_local) ++ && h->def_regular)) ++ { ++ /* This is actually a static link, or it is a ++ -Bsymbolic link and the symbol is defined ++ locally, or the symbol was forced to be local ++ because of a version file. We must initialize ++ this entry in the global offset table. Since the ++ offset must always be a multiple of 4, we use the ++ least significant bit to record whether we have ++ initialized it already. ++ ++ When doing a dynamic link, we create a .rela.got ++ relocation entry to initialize the value. This ++ is done in the finish_dynamic_symbol routine. */ ++ if ((off & 1) != 0) ++ off &= ~1; ++ else ++ { ++ bfd_put_32 (output_bfd, relocation, ++ sgot->contents + off); ++ h->got.offset |= 1; ++ } ++ } ++ } ++ else ++ { ++ bfd_byte *loc; ++ ++ BFD_ASSERT (local_got_offsets != NULL ++ && local_got_offsets[r_symndx] != (bfd_vma) - 1); ++ ++ off = local_got_offsets[r_symndx]; ++ ++ /* The offset must always be a multiple of 4. We use ++ the least significant bit to record whether we have ++ already processed this entry. */ ++ if ((off & 1) != 0) ++ off &= ~1; ++ else ++ { ++ bfd_put_32 (output_bfd, relocation, sgot->contents + off); ++ ++ if (info->shared) ++ { ++ asection *srelgot; ++ Elf_Internal_Rela outrel; ++ ++ /* We need to generate a R_NDS32_RELATIVE reloc ++ for the dynamic linker. */ ++ srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); ++ BFD_ASSERT (srelgot != NULL); ++ ++ outrel.r_offset = (elf_gp (output_bfd) ++ + sgot->output_offset + off); ++ outrel.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); ++ outrel.r_addend = relocation; ++ loc = srelgot->contents; ++ loc += ++ srelgot->reloc_count * sizeof (Elf32_External_Rela); ++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); ++ ++srelgot->reloc_count; ++ } ++ local_got_offsets[r_symndx] |= 1; ++ } ++ } ++ relocation = sgot->output_section->vma + sgot->output_offset + off ++ - elf_gp (output_bfd); ++ ++ if (relocation & align) ++ { ++ /* Incorrect alignment. */ ++ (*_bfd_error_handler) ++ (_("%B: warning: unaligned access to GOT entry."), input_bfd); ++ ret = FALSE; ++ r = bfd_reloc_dangerous; ++ goto check_reloc; ++ } ++ break; ++ ++ case R_NDS32_SDA16S3_RELA: ++ case R_NDS32_SDA15S3_RELA: ++ case R_NDS32_SDA15S3: ++ align = 0x7; ++ goto handle_sda; ++ ++ case R_NDS32_SDA17S2_RELA: ++ case R_NDS32_SDA15S2_RELA: ++ case R_NDS32_SDA12S2_SP_RELA: ++ case R_NDS32_SDA12S2_DP_RELA: ++ case R_NDS32_SDA15S2: ++ case R_NDS32_SDA_FP7U2_RELA: ++ align = 0x3; ++ goto handle_sda; ++ ++ case R_NDS32_SDA18S1_RELA: ++ case R_NDS32_SDA15S1_RELA: ++ case R_NDS32_SDA15S1: ++ align = 0x1; ++ goto handle_sda; ++ ++ case R_NDS32_SDA19S0_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ case R_NDS32_SDA15S0: ++ align = 0x0; ++handle_sda: ++ BFD_ASSERT (sec != NULL); ++ ++ /* If the symbol is in the abs section, the out_bfd will be null. ++ This happens when the relocation has a symbol@GOTOFF. */ ++ r = nds32_elf_final_sda_base (output_bfd, info, &gp, FALSE); ++ if (r != bfd_reloc_ok) ++ { ++ (*_bfd_error_handler) ++ (_("%B: warning: relocate SDA_BASE failed."), input_bfd); ++ ret = FALSE; ++ goto check_reloc; ++ } ++ ++ /* At this point `relocation' contains the object's ++ address. */ ++ if (r_type == R_NDS32_SDA_FP7U2_RELA) ++ { ++ relocation -= fpbase_addr; ++ } ++ else ++ relocation -= gp; ++ /* Now it contains the offset from _SDA_BASE_. */ ++ ++ /* Make sure alignment is correct. */ ++ ++ if (relocation & align) ++ { ++ /* Incorrect alignment. */ ++ (*_bfd_error_handler) ++ (_("%B(%A): warning: unaligned small data access of type %d."), ++ input_bfd, input_section, r_type); ++ ret = FALSE; ++ goto check_reloc; ++ } ++ ++ break; ++ case R_NDS32_17IFC_PCREL_RELA: ++ case R_NDS32_10IFCU_PCREL_RELA: ++ /* do nothing */ ++ break; ++ ++ case R_NDS32_TLS_LE_HI20: ++ case R_NDS32_TLS_LE_LO12: ++ case R_NDS32_TLS_LE_20: ++ case R_NDS32_TLS_LE_15S0: ++ case R_NDS32_TLS_LE_15S1: ++ case R_NDS32_TLS_LE_15S2: ++ if (elf_hash_table (info)->tls_sec != NULL) ++ relocation -= (elf_hash_table (info)->tls_sec->vma + TP_OFFSET); ++ break; ++ case R_NDS32_TLS_IE_HI20: ++ case R_NDS32_TLS_IE_LO12S2: ++ case R_NDS32_TLS_DESC_HI20: ++ case R_NDS32_TLS_DESC_LO12: ++ case R_NDS32_TLS_IE_LO12: ++ case R_NDS32_TLS_IEGP_HI20: ++ case R_NDS32_TLS_IEGP_LO12: ++ case R_NDS32_TLS_IEGP_LO12S2: ++ { ++ /* Relocation is to the entry for this symbol in the global ++ offset table. */ ++ enum elf_nds32_tls_type tls_type, org_tls_type, eff_tls_type; ++ asection *srelgot; ++ Elf_Internal_Rela outrel; ++ bfd_byte *loc; ++ int indx = 0; ++ ++ eff_tls_type = org_tls_type = get_tls_type (r_type, h); ++ ++ BFD_ASSERT (sgot != NULL); ++ if (h != NULL) ++ { ++ bfd_boolean dyn; ++ ++ off = h->got.offset; ++ BFD_ASSERT (off != (bfd_vma) -1); ++ dyn = htab->root.dynamic_sections_created; ++ tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type; ++ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) ++ && (!info->shared ++ || !SYMBOL_REFERENCES_LOCAL (info, h))) ++ indx = h->dynindx; ++ } ++ else ++ { ++ BFD_ASSERT (local_got_offsets != NULL ++ && local_got_offsets[r_symndx] != (bfd_vma) - 1); ++ ++ off = local_got_offsets[r_symndx]; ++ tls_type = elf32_nds32_local_got_tls_type (input_bfd)[r_symndx]; ++ } ++ ++ relocation = sgot->output_section->vma + sgot->output_offset + off; ++ ++ if (1 < ones32 (tls_type)) ++ { ++ eff_tls_type = 1 << (fls (tls_type) - 1); ++ /* TLS model shall be handled in nds32_elf_unify_tls_model () */ ++ ++ /* TLS model X -> LE is not implement yet! ++ * workaround here! */ ++ if (eff_tls_type == GOT_TLS_LE) ++ { ++ eff_tls_type = 1 << (fls (tls_type ^ eff_tls_type) - 1); ++ } ++ } ++ ++ /* The offset must always be a multiple of 4. We use ++ the least significant bit to record whether we have ++ already processed this entry. */ ++ bfd_boolean need_relocs = FALSE; ++ srelgot = ehtab->srelgot; ++ if ((info->shared || indx != 0) ++ && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT ++ || h->root.type != bfd_link_hash_undefweak)) ++ { ++ need_relocs = TRUE; ++ BFD_ASSERT (srelgot != NULL); ++ } ++ ++ if (off & 1) ++ { ++ off &= ~1; ++ relocation &= ~1; ++ ++ if (eff_tls_type & GOT_TLS_DESC) ++ { ++ relocation -= elf_gp (output_bfd); ++ if ((R_NDS32_TLS_DESC_HI20 == r_type) && (!need_relocs)) ++ { ++ /* TLS model shall be converted */ ++ BFD_ASSERT(0); ++ } ++ } ++ else if (eff_tls_type & GOT_TLS_IEGP) ++ { ++ relocation -= elf_gp (output_bfd); ++ } ++ } ++ else ++ { ++ if ((eff_tls_type & GOT_TLS_LE) && (tls_type ^ eff_tls_type)) ++ { ++ /* TLS model workaround shall be applied */ ++ BFD_ASSERT(0); ++ } ++ else if (eff_tls_type & (GOT_TLS_IE | GOT_TLS_IEGP)) ++ { ++ if (eff_tls_type & GOT_TLS_IEGP) ++ relocation -= elf_gp(output_bfd); ++ ++ if (need_relocs) ++ { ++ if (indx == 0) ++ outrel.r_addend = gottpoff (info, relocation_sym); ++ else ++ outrel.r_addend = 0; ++ outrel.r_offset = (sgot->output_section->vma ++ + sgot->output_offset + off); ++ outrel.r_info = ELF32_R_INFO (indx, R_NDS32_TLS_TPOFF); ++ ++ elf32_nds32_add_dynreloc (output_bfd, info, srelgot, ++ &outrel); ++ } ++ else ++ { ++ bfd_put_32 (output_bfd, gottpoff (info, relocation_sym), ++ sgot->contents + off); ++ } ++ } ++ else if (eff_tls_type & GOT_TLS_DESC) ++ { ++ relocation -= elf_gp (output_bfd); ++ if (need_relocs) ++ { ++ asection *srelplt; ++ srelplt = ehtab->srelplt; ++ ++ if (indx == 0) ++ outrel.r_addend = gottpoff (info, relocation_sym); ++ else ++ outrel.r_addend = 0; ++ outrel.r_offset = (sgot->output_section->vma ++ + sgot->output_offset + off); ++ outrel.r_info = ELF32_R_INFO (indx, R_NDS32_TLS_DESC); ++ ++ loc = srelplt->contents; ++ loc += htab->next_tls_desc_index++ * sizeof (Elf32_External_Rela); ++ BFD_ASSERT (loc + sizeof (Elf32_External_Rela) ++ <= srelplt->contents + srelplt->size); ++ ++ bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc); ++ } ++ else ++ { ++ /* feed me! */ ++ bfd_put_32 (output_bfd, 0xdeadbeef, ++ sgot->contents + off); ++ bfd_put_32 (output_bfd, gottpoff (info, relocation_sym), ++ sgot->contents + off + 4); ++ patch_tls_desc_to_ie (contents, rel, input_bfd); ++ BFD_ASSERT(0); ++ } ++ } ++ else ++ { ++ /* TLS model workaround shall be applied */ ++ BFD_ASSERT(0); ++ } ++ ++ if (h != NULL) ++ h->got.offset |= 1; ++ else ++ local_got_offsets[r_symndx] |= 1; ++ } ++ } ++ break; ++ ++ case R_NDS32_SECURITY_16: ++ relocation = nds32_elf_crc_relocation (crc_rel, rel, relend, ++ contents); ++ crc_rel->r_addend = NDS32_SECURITY_NONE; ++ r = nds32_elf_final_link_relocate (howto, input_bfd, ++ input_section, contents, ++ crc_rel->r_offset, relocation, ++ crc_rel->r_addend); ++ crc_rel = NULL; ++ goto check_reloc; ++ break; ++ /* DON'T fall through. */ ++ case R_NDS32_ICT_HI20: ++ case R_NDS32_ICT_LO12: ++ case R_NDS32_ICT_25PC: ++ if (!ignore_indirect_call) ++ { ++ entry = (struct elf_nds32_ict_hash_entry*) ++ bfd_hash_lookup (&indirect_call_table, h->root.root.string, ++ FALSE, FALSE); ++ if (!entry) ++ { ++ (*_bfd_error_handler) ++ (_("%B %A: internal error indirect call relocation " ++ "0x%lx without hash.\n"), ++ input_bfd, sec, rel->r_offset); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ h2 = bfd_link_hash_lookup (info->hash, ++ "_INDIRECT_CALL_TABLE_BASE_", ++ FALSE, FALSE, FALSE); ++ relocation = ((h2->u.def.value ++ + h2->u.def.section->output_section->vma ++ + h2->u.def.section->output_offset) ++ + (entry->order * 4)); ++ } ++ break; ++ /* DON'T fall through. */ ++ ++ default: ++ /* OLD_NDS32_RELOC. */ ++ ++ r = _bfd_final_link_relocate (howto, input_bfd, input_section, ++ contents, offset, relocation, addend); ++ goto check_reloc; ++ } ++ ++ switch ((int) r_type) ++ { ++ case R_NDS32_20_RELA: ++ case R_NDS32_5_RELA: ++ case R_NDS32_9_PCREL_RELA: ++ case R_NDS32_WORD_9_PCREL_RELA: ++ case R_NDS32_10_UPCREL_RELA: ++ case R_NDS32_15_PCREL_RELA: ++ case R_NDS32_17_PCREL_RELA: ++ case R_NDS32_25_PCREL_RELA: ++ case R_NDS32_25_ABS_RELA: ++ case R_NDS32_HI20_RELA: ++ case R_NDS32_LO12S3_RELA: ++ case R_NDS32_LO12S2_RELA: ++ case R_NDS32_LO12S2_DP_RELA: ++ case R_NDS32_LO12S2_SP_RELA: ++ case R_NDS32_LO12S1_RELA: ++ case R_NDS32_LO12S0_RELA: ++ case R_NDS32_LO12S0_ORI_RELA: ++ case R_NDS32_SDA16S3_RELA: ++ case R_NDS32_SDA17S2_RELA: ++ case R_NDS32_SDA18S1_RELA: ++ case R_NDS32_SDA19S0_RELA: ++ case R_NDS32_SDA15S3_RELA: ++ case R_NDS32_SDA15S2_RELA: ++ case R_NDS32_SDA12S2_DP_RELA: ++ case R_NDS32_SDA12S2_SP_RELA: ++ case R_NDS32_SDA15S1_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ case R_NDS32_SDA_FP7U2_RELA: ++ case R_NDS32_9_PLTREL: ++ case R_NDS32_25_PLTREL: ++ case R_NDS32_GOT20: ++ case R_NDS32_GOT_HI20: ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOT_LO15: ++ case R_NDS32_GOT_LO19: ++ case R_NDS32_GOT15S2_RELA: ++ case R_NDS32_GOT17S2_RELA: ++ case R_NDS32_GOTPC20: ++ case R_NDS32_GOTPC_HI20: ++ case R_NDS32_GOTPC_LO12: ++ case R_NDS32_GOTOFF: ++ case R_NDS32_GOTOFF_HI20: ++ case R_NDS32_GOTOFF_LO12: ++ case R_NDS32_GOTOFF_LO15: ++ case R_NDS32_GOTOFF_LO19: ++ case R_NDS32_PLTREL_HI20: ++ case R_NDS32_PLTREL_LO12: ++ case R_NDS32_PLT_GOTREL_HI20: ++ case R_NDS32_PLT_GOTREL_LO12: ++ case R_NDS32_PLT_GOTREL_LO15: ++ case R_NDS32_PLT_GOTREL_LO19: ++ case R_NDS32_PLT_GOTREL_LO20: ++ case R_NDS32_17IFC_PCREL_RELA: ++ case R_NDS32_10IFCU_PCREL_RELA: ++ case R_NDS32_TLS_LE_HI20: ++ case R_NDS32_TLS_LE_LO12: ++ case R_NDS32_TLS_IE_HI20: ++ case R_NDS32_TLS_IE_LO12S2: ++ case R_NDS32_TLS_LE_20: ++ case R_NDS32_TLS_LE_15S0: ++ case R_NDS32_TLS_LE_15S1: ++ case R_NDS32_TLS_LE_15S2: ++ case R_NDS32_TLS_DESC_HI20: ++ case R_NDS32_TLS_DESC_LO12: ++ case R_NDS32_TLS_IE_LO12: ++ case R_NDS32_TLS_IEGP_HI20: ++ case R_NDS32_TLS_IEGP_LO12: ++ case R_NDS32_TLS_IEGP_LO12S2: ++ /* Instruction related relocs must handle endian properly. */ ++ /* NOTE: PIC IS NOT HANDLE YET; DO IT LATER. */ ++ r = nds32_elf_final_link_relocate (howto, input_bfd, ++ input_section, contents, ++ rel->r_offset, relocation, ++ rel->r_addend); ++ break; ++ ++ case R_NDS32_ICT_HI20: ++ case R_NDS32_ICT_LO12: ++ case R_NDS32_ICT_25PC: ++ r = nds32_elf_final_link_relocate (howto, input_bfd, input_section, ++ contents, rel->r_offset, ++ relocation, 0); ++ break; ++ ++ default: ++ /* All other relocs can use default handler. */ ++ r = _bfd_final_link_relocate (howto, input_bfd, input_section, ++ contents, rel->r_offset, ++ relocation, rel->r_addend); ++ break; ++ } ++ ++check_reloc: ++ ++ if (r != bfd_reloc_ok) ++ { ++ /* FIXME: This should be generic enough to go in a utility. */ ++ const char *name; ++ ++ if (h != NULL) ++ name = h->root.root.string; ++ else ++ { ++ name = bfd_elf_string_from_elf_section ++ (input_bfd, symtab_hdr->sh_link, sym->st_name); ++ if (name == NULL || *name == '\0') ++ name = bfd_section_name (input_bfd, sec); ++ } ++ ++ if (errmsg != NULL) ++ goto common_error; ++ ++ switch (r) ++ { ++ case bfd_reloc_overflow: ++ if (!((*info->callbacks->reloc_overflow) ++ (info, (h ? &h->root : NULL), name, howto->name, ++ (bfd_vma) 0, input_bfd, input_section, offset))) ++ return FALSE; ++ break; ++ ++ case bfd_reloc_undefined: ++ if (!((*info->callbacks->undefined_symbol) ++ (info, name, input_bfd, input_section, offset, TRUE))) ++ return FALSE; ++ break; ++ ++ case bfd_reloc_outofrange: ++ errmsg = _("internal error: out of range error"); ++ goto common_error; ++ ++ case bfd_reloc_notsupported: ++ errmsg = _("internal error: unsupported relocation error"); ++ goto common_error; ++ ++ case bfd_reloc_dangerous: ++ errmsg = _("internal error: dangerous error"); ++ goto common_error; ++ ++ default: ++ errmsg = _("internal error: unknown error"); ++ /* Fall through. */ ++ ++common_error: ++ if (!((*info->callbacks->warning) ++ (info, errmsg, name, input_bfd, input_section, offset))) ++ return FALSE; ++ break; ++ } ++ } ++ } ++ ++ /* Resotre header size to avoid overflow load. */ ++ if (elf_nds32_tdata (input_bfd)->hdr_size != 0) ++ symtab_hdr->sh_size = elf_nds32_tdata (input_bfd)->hdr_size; ++ ++ return ret; ++} ++ ++/* Finish up dynamic symbol handling. We set the contents of various ++ dynamic sections here. */ ++ ++static bfd_boolean ++nds32_elf_finish_dynamic_symbol (bfd *output_bfd, struct bfd_link_info *info, ++ struct elf_link_hash_entry *h, ++ Elf_Internal_Sym *sym) ++{ ++ struct elf_link_hash_table *ehtab; ++ struct elf_nds32_link_hash_entry *hent; ++ bfd_byte *loc; ++ ++ ehtab = elf_hash_table (info); ++ hent = (struct elf_nds32_link_hash_entry *) h; ++ ++ if (h->plt.offset != (bfd_vma) - 1) ++ { ++ asection *splt; ++ asection *sgot; ++ asection *srela; ++ ++ bfd_vma plt_index; ++ bfd_vma got_offset; ++ bfd_vma local_plt_offset; ++ Elf_Internal_Rela rela; ++ ++ /* This symbol has an entry in the procedure linkage table. Set ++ it up. */ ++ ++ BFD_ASSERT (h->dynindx != -1); ++ ++ splt = ehtab->splt; ++ sgot = ehtab->sgotplt; ++ srela = ehtab->srelplt; ++ BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL); ++ ++ /* Get the index in the procedure linkage table which ++ corresponds to this symbol. This is the index of this symbol ++ in all the symbols for which we are making plt entries. The ++ first entry in the procedure linkage table is reserved. */ ++ plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; ++ ++ /* Get the offset into the .got table of the entry that ++ corresponds to this function. Each .got entry is 4 bytes. ++ The first three are reserved. */ ++ got_offset = (plt_index + 3) * 4; ++ ++ /* Fill in the entry in the procedure linkage table. */ ++ if (!info->shared) ++ { ++ unsigned long insn; ++ ++ insn = PLT_ENTRY_WORD0 + (((sgot->output_section->vma ++ + sgot->output_offset + got_offset) >> 12) ++ & 0xfffff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset); ++ ++ insn = PLT_ENTRY_WORD1 + (((sgot->output_section->vma ++ + sgot->output_offset + got_offset) & 0x0fff) ++ >> 2); ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 4); ++ ++ insn = PLT_ENTRY_WORD2; ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 8); ++ ++ insn = PLT_ENTRY_WORD3 + (plt_index & 0x7ffff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 12); ++ ++ insn = PLT_ENTRY_WORD4 ++ + (((unsigned int) ((-(h->plt.offset + 16)) >> 1)) & 0xffffff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 16); ++ local_plt_offset = 12; ++ } ++ else ++ { ++ /* sda_base must be set at this time. */ ++ unsigned long insn; ++ long offset; ++ ++ /* FIXME, sda_base is 65536, it will damage opcode. */ ++ offset = sgot->output_section->vma + sgot->output_offset + got_offset ++ - elf_gp (output_bfd); ++ insn = PLT_PIC_ENTRY_WORD0 + ((offset >> 12) & 0xfffff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset); ++ ++ insn = PLT_PIC_ENTRY_WORD1 + (offset & 0xfff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 4); ++ ++ insn = PLT_PIC_ENTRY_WORD2; ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 8); ++ ++ insn = PLT_PIC_ENTRY_WORD3; ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 12); ++ ++ insn = PLT_PIC_ENTRY_WORD4 + (plt_index & 0x7fffff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 16); ++ ++ insn = PLT_PIC_ENTRY_WORD5 ++ + (((unsigned int) ((-(h->plt.offset + 20)) >> 1)) & 0xffffff); ++ bfd_putb32 (insn, splt->contents + h->plt.offset + 20); ++ ++ local_plt_offset = 16; ++ } ++ ++ /* Fill in the entry in the global offset table, ++ so it will fall through to the next instruction for the first time. */ ++ bfd_put_32 (output_bfd, ++ (splt->output_section->vma + splt->output_offset ++ + h->plt.offset + local_plt_offset), ++ sgot->contents + got_offset); ++ ++ /* Fill in the entry in the .rela.plt section. */ ++ rela.r_offset = (sgot->output_section->vma ++ + sgot->output_offset + got_offset); ++ rela.r_info = ELF32_R_INFO (h->dynindx, R_NDS32_JMP_SLOT); ++ rela.r_addend = 0; ++ loc = srela->contents; ++ loc += plt_index * sizeof (Elf32_External_Rela); ++ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); ++ ++ if (!h->def_regular) ++ { ++ /* Mark the symbol as undefined, rather than as defined in ++ the .plt section. Leave the value alone. */ ++ sym->st_shndx = SHN_UNDEF; ++ if (!h->ref_regular_nonweak) ++ sym->st_value = 0; ++ } ++ } ++ ++ if ((h->got.offset != (bfd_vma) -1) && (hent->tls_type == GOT_NORMAL)) ++ { ++ asection *sgot; ++ asection *srelagot; ++ Elf_Internal_Rela rela; ++ ++ /* This symbol has an entry in the global offset table. ++ Set it up. */ ++ ++ sgot = ehtab->sgot; ++ srelagot = ehtab->srelgot; ++ BFD_ASSERT (sgot != NULL && srelagot != NULL); ++ ++ rela.r_offset = (sgot->output_section->vma ++ + sgot->output_offset + (h->got.offset & ~1)); ++ ++ /* If this is a -Bsymbolic link, and the symbol is defined ++ locally, we just want to emit a RELATIVE reloc. Likewise if ++ the symbol was forced to be local because of a version file. ++ The entry in the global offset table will already have been ++ initialized in the relocate_section function. */ ++ if ((info->shared ++ && (info->symbolic || h->dynindx == -1 || h->forced_local) ++ && h->def_regular) ++ || (info->pie && h->def_regular)) ++ { ++ rela.r_info = ELF32_R_INFO (0, R_NDS32_RELATIVE); ++ rela.r_addend = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ ++ /* FIXME: cancel PLT trampoline, too late ?? */ ++ /* h->plt.offset = (bfd_vma) -1; */ ++ } ++ else ++ { ++ BFD_ASSERT ((h->got.offset & 1) == 0); ++ bfd_put_32 (output_bfd, (bfd_vma) 0, ++ sgot->contents + h->got.offset); ++ rela.r_info = ELF32_R_INFO (h->dynindx, R_NDS32_GLOB_DAT); ++ rela.r_addend = 0; ++ } ++ ++ loc = srelagot->contents; ++ loc += srelagot->reloc_count * sizeof (Elf32_External_Rela); ++ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); ++ ++srelagot->reloc_count; ++ BFD_ASSERT (loc < (srelagot->contents + srelagot->size)); ++ } ++ ++ if (h->needs_copy) ++ { ++ asection *s; ++ Elf_Internal_Rela rela; ++ ++ /* This symbols needs a copy reloc. Set it up. */ ++ ++ BFD_ASSERT (h->dynindx != -1 ++ && (h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak)); ++ ++ s = bfd_get_section_by_name (h->root.u.def.section->owner, ".rela.bss"); ++ BFD_ASSERT (s != NULL); ++ ++ rela.r_offset = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ rela.r_info = ELF32_R_INFO (h->dynindx, R_NDS32_COPY); ++ rela.r_addend = 0; ++ loc = s->contents; ++ loc += s->reloc_count * sizeof (Elf32_External_Rela); ++ bfd_elf32_swap_reloca_out (output_bfd, &rela, loc); ++ ++s->reloc_count; ++ } ++ ++ /* Mark some specially defined symbols as absolute. */ ++ if (strcmp (h->root.root.string, "_DYNAMIC") == 0 ++ || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0) ++ sym->st_shndx = SHN_ABS; ++ ++ return TRUE; ++} ++ ++ ++/* Finish up the dynamic sections. */ ++ ++static bfd_boolean ++nds32_elf_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) ++{ ++ bfd *dynobj; ++ asection *sdyn; ++ asection *sgotplt; ++ struct elf_link_hash_table *ehtab; ++ struct elf_nds32_link_hash_table *htab; ++ ++ ehtab = elf_hash_table (info); ++ htab = nds32_elf_hash_table (info); ++ if (htab == NULL) ++ return FALSE; ++ ++ dynobj = elf_hash_table (info)->dynobj; ++ ++ sgotplt = ehtab->sgotplt; ++ /* A broken linker script might have discarded the dynamic sections. ++ Catch this here so that we do not seg-fault later on. */ ++ if (sgotplt != NULL && bfd_is_abs_section (sgotplt->output_section)) ++ return FALSE; ++ sdyn = bfd_get_section_by_name (dynobj, ".dynamic"); ++ ++ if (elf_hash_table (info)->dynamic_sections_created) ++ { ++ asection *splt; ++ Elf32_External_Dyn *dyncon, *dynconend; ++ ++ BFD_ASSERT (sgotplt != NULL && sdyn != NULL); ++ ++ dyncon = (Elf32_External_Dyn *) sdyn->contents; ++ dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size); ++ ++ for (; dyncon < dynconend; dyncon++) ++ { ++ Elf_Internal_Dyn dyn; ++ asection *s; ++ ++ bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn); ++ ++ switch (dyn.d_tag) ++ { ++ default: ++ break; ++ ++ case DT_PLTGOT: ++ /* name = ".got"; */ ++ s = ehtab->sgot->output_section; ++ goto get_vma; ++ case DT_JMPREL: ++ s = ehtab->srelplt->output_section; ++get_vma: ++ BFD_ASSERT (s != NULL); ++ dyn.d_un.d_ptr = s->vma; ++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); ++ break; ++ ++ case DT_PLTRELSZ: ++ s = ehtab->srelplt->output_section; ++ BFD_ASSERT (s != NULL); ++ dyn.d_un.d_val = s->size; ++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); ++ break; ++ ++ case DT_RELASZ: ++ /* My reading of the SVR4 ABI indicates that the ++ procedure linkage table relocs (DT_JMPREL) should be ++ included in the overall relocs (DT_RELA). This is ++ what Solaris does. However, UnixWare can not handle ++ that case. Therefore, we override the DT_RELASZ entry ++ here to make it not include the JMPREL relocs. Since ++ the linker script arranges for .rela.plt to follow all ++ other relocation sections, we don't have to worry ++ about changing the DT_RELA entry. */ ++ if (ehtab->srelplt != NULL) ++ { ++ s = ehtab->srelplt->output_section; ++ dyn.d_un.d_val -= s->size; ++ } ++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); ++ break; ++ ++ case DT_TLSDESC_PLT: ++ s = htab->root.splt; ++ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset ++ + htab->dt_tlsdesc_plt); ++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); ++ break; ++ ++ case DT_TLSDESC_GOT: ++ s = htab->root.sgot; ++ dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset ++ + htab->dt_tlsdesc_got); ++ bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon); ++ break; ++ } ++ } ++ ++ /* Fill in the first entry in the procedure linkage table. */ ++ splt = ehtab->splt; ++ if (splt && splt->size > 0) ++ { ++ if (info->shared) ++ { ++ unsigned long insn; ++ long offset; ++ ++ /* FIXME, sda_base is 65536, it will damage opcode. */ ++ offset = sgotplt->output_section->vma + sgotplt->output_offset + 4 ++ - elf_gp (output_bfd); ++ insn = PLT0_PIC_ENTRY_WORD0 | ((offset >> 12) & 0xfffff); ++ bfd_putb32 (insn, splt->contents); ++ ++ /* here has a typo? */ ++ insn = PLT0_PIC_ENTRY_WORD1 | (offset & 0xfff); ++ bfd_putb32 (insn, splt->contents + 4); ++ ++ insn = PLT0_PIC_ENTRY_WORD2; ++ bfd_putb32 (insn, splt->contents + 8); ++ ++ insn = PLT0_PIC_ENTRY_WORD3; ++ bfd_putb32 (insn, splt->contents + 12); ++ ++ insn = PLT0_PIC_ENTRY_WORD4; ++ bfd_putb32 (insn, splt->contents + 16); ++ ++ insn = PLT0_PIC_ENTRY_WORD5; ++ bfd_putb32 (insn, splt->contents + 20); ++ } ++ else ++ { ++ unsigned long insn; ++ unsigned long addr; ++ ++ /* addr = .got + 4 */ ++ addr = sgotplt->output_section->vma + sgotplt->output_offset + 4; ++ insn = PLT0_ENTRY_WORD0 | ((addr >> 12) & 0xfffff); ++ bfd_putb32 (insn, splt->contents); ++ ++ insn = PLT0_ENTRY_WORD1 | (addr & 0x0fff); ++ bfd_putb32 (insn, splt->contents + 4); ++ ++ insn = PLT0_ENTRY_WORD2; ++ bfd_putb32 (insn, splt->contents + 8); ++ ++ insn = PLT0_ENTRY_WORD3; ++ bfd_putb32 (insn, splt->contents + 12); ++ ++ insn = PLT0_ENTRY_WORD4; ++ bfd_putb32 (insn, splt->contents + 16); ++ } ++ ++ elf_section_data (splt->output_section)->this_hdr.sh_entsize = ++ PLT_ENTRY_SIZE; ++ } ++ ++ if (htab->dt_tlsdesc_plt) ++ { ++ /* Calculate addresses. */ ++ asection *sgot = sgot = ehtab->sgot; ++ bfd_vma pltgot = sgotplt->output_section->vma ++ + sgotplt->output_offset; ++ bfd_vma tlsdesc_got = sgot->output_section->vma + sgot->output_offset ++ + htab->dt_tlsdesc_got; ++ ++ /* Get GP offset. */ ++ pltgot -= elf_gp (output_bfd) - 4; /* PLTGOT[1] */ ++ tlsdesc_got -= elf_gp (output_bfd); ++ ++ /* Do relocation. */ ++ dl_tlsdesc_lazy_trampoline[0] += ((1 << 20) - 1) & (tlsdesc_got >> 12); ++ dl_tlsdesc_lazy_trampoline[1] += 0xfff & tlsdesc_got; ++ dl_tlsdesc_lazy_trampoline[4] += ((1 << 20) - 1) & (pltgot >> 12); ++ dl_tlsdesc_lazy_trampoline[5] += 0xfff & pltgot; ++ ++ /* TODO: relaxation. */ ++ ++ /* Insert .plt. */ ++ nds32_put_trampoline (splt->contents + htab->dt_tlsdesc_plt, ++ dl_tlsdesc_lazy_trampoline, ++ ARRAY_SIZE (dl_tlsdesc_lazy_trampoline)); ++ } ++ } ++ ++ /* Fill in the first three entries in the global offset table. */ ++ if (sgotplt && sgotplt->size > 0) ++ { ++ if (sdyn == NULL) ++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents); ++ else ++ bfd_put_32 (output_bfd, ++ sdyn->output_section->vma + sdyn->output_offset, ++ sgotplt->contents); ++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4); ++ bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8); ++ ++ elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4; ++ } ++ ++ return TRUE; ++} ++ ++ ++/* Set the right machine number. */ ++ ++static bfd_boolean ++nds32_elf_object_p (bfd *abfd) ++{ ++ static unsigned int cur_arch = 0; ++ ++ if (E_N1_ARCH != (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH)) ++ { ++ /* E_N1_ARCH is a wild card, so it is set only when no others exist. */ ++ cur_arch = (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH); ++ } ++ ++ switch (cur_arch) ++ { ++ default: ++ case E_N1_ARCH: ++ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1); ++ break; ++ case E_N1H_ARCH: ++ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h); ++ break; ++ case E_NDS_ARCH_STAR_V2_0: ++ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h_v2); ++ break; ++ case E_NDS_ARCH_STAR_V3_0: ++ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h_v3); ++ break; ++ case E_NDS_ARCH_STAR_V3_M: ++ bfd_default_set_arch_mach (abfd, bfd_arch_nds32, bfd_mach_n1h_v3m); ++ break; ++ } ++ ++ return TRUE; ++} ++ ++/* Store the machine number in the flags field. */ ++ ++static void ++nds32_elf_final_write_processing (bfd *abfd, ++ bfd_boolean linker ATTRIBUTE_UNUSED) ++{ ++ unsigned long val; ++ static unsigned int cur_mach = 0; ++ unsigned int i; ++ ++ if (bfd_mach_n1 != bfd_get_mach (abfd)) ++ { ++ cur_mach = bfd_get_mach (abfd); ++ } ++ ++ switch (cur_mach) ++ { ++ case bfd_mach_n1: ++ /* Only happen when object is empty, since the case is abandon. */ ++ val = E_N1_ARCH; ++ val |= E_NDS_ABI_AABI; ++ val |= E_NDS32_ELF_VER_1_4; ++ break; ++ case bfd_mach_n1h: ++ val = E_N1H_ARCH; ++ break; ++ case bfd_mach_n1h_v2: ++ val = E_NDS_ARCH_STAR_V2_0; ++ break; ++ case bfd_mach_n1h_v3: ++ val = E_NDS_ARCH_STAR_V3_0; ++ break; ++ case bfd_mach_n1h_v3m: ++ val = E_NDS_ARCH_STAR_V3_M; ++ break; ++ default: ++ val = 0; ++ break; ++ } ++ ++ elf_elfheader (abfd)->e_flags &= ~EF_NDS_ARCH; ++ elf_elfheader (abfd)->e_flags |= val; ++ ++ if (ict_file) ++ { ++ fprintf (ict_file, ".section " NDS32_ICT_SECTION ", \"ax\"\n" ++ ".globl _INDIRECT_CALL_TABLE_BASE_\n" ++ "_INDIRECT_CALL_TABLE_BASE_:\n"); ++ /* Output rom patch entries. */ ++ indirect_call_table.frozen = 1; ++ for (i = 0; i < indirect_call_table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ struct elf_nds32_ict_hash_entry *entry; ++ ++ for (p = indirect_call_table.table[i]; p != NULL; p = p->next) ++ { ++ entry = (struct elf_nds32_ict_hash_entry *) p; ++ fprintf (ict_file, "\tj\t%s\n", entry->root.string); ++ } ++ } ++ indirect_call_table.frozen = 0; ++ } ++} ++ ++/* Function to keep NDS32 specific file flags. */ ++ ++static bfd_boolean ++nds32_elf_set_private_flags (bfd *abfd, flagword flags) ++{ ++ BFD_ASSERT (!elf_flags_init (abfd) ++ || elf_elfheader (abfd)->e_flags == flags); ++ ++ elf_elfheader (abfd)->e_flags = flags; ++ elf_flags_init (abfd) = TRUE; ++ return TRUE; ++} ++ ++static unsigned int ++convert_e_flags (unsigned int e_flags, unsigned int arch) ++{ ++ if ((e_flags & EF_NDS_ARCH) == E_NDS_ARCH_STAR_V0_9) ++ { ++ /* From 0.9 to 1.0. */ ++ e_flags = (e_flags & (~EF_NDS_ARCH)) | E_NDS_ARCH_STAR_V1_0; ++ ++ /* Invert E_NDS32_HAS_NO_MAC_INST. */ ++ e_flags ^= E_NDS32_HAS_NO_MAC_INST; ++ if (arch == E_NDS_ARCH_STAR_V1_0) ++ { ++ /* Done. */ ++ return e_flags; ++ } ++ } ++ ++ /* From 1.0 to 2.0. */ ++ e_flags = (e_flags & (~EF_NDS_ARCH)) | E_NDS_ARCH_STAR_V2_0; ++ ++ /* Clear E_NDS32_HAS_MFUSR_PC_INST. */ ++ e_flags &= ~E_NDS32_HAS_MFUSR_PC_INST; ++ ++ /* Invert E_NDS32_HAS_NO_MAC_INST. */ ++ e_flags ^= E_NDS32_HAS_NO_MAC_INST; ++ return e_flags; ++} ++ ++static bfd_boolean ++nds32_check_vec_size (bfd *ibfd) ++{ ++ static unsigned int nds32_vec_size = 0; ++ ++ asection *sec_t = NULL; ++ bfd_byte *contents = NULL; ++ ++ sec_t = bfd_get_section_by_name (ibfd, ".nds32_e_flags"); ++ ++ if (sec_t && sec_t->size >= 4) ++ { ++ /* Get vec_size in file. */ ++ unsigned int flag_t; ++ ++ nds32_get_section_contents (ibfd, sec_t, &contents, TRUE); ++ flag_t = bfd_get_32 (ibfd, contents); ++ ++ /* The value could only be 4 or 16. */ ++ ++ if (!nds32_vec_size) ++ /* Set if not set yet. */ ++ nds32_vec_size = (flag_t & 0x3); ++ else if (nds32_vec_size != (flag_t & 0x3)) ++ { ++ (*_bfd_error_handler) (_("%B: ISR vector size mismatch" ++ " with previous modules, previous %u-byte, current %u-byte"), ++ ibfd, ++ nds32_vec_size == 1 ? 4 : nds32_vec_size == 2 ? 16 : 0xffffffff, ++ (flag_t & 0x3) == 1 ? 4 : (flag_t & 0x3) == 2 ? 16 : 0xffffffff); ++ return FALSE; ++ } ++ else ++ /* Only keep the first vec_size section. */ ++ sec_t->flags |= SEC_EXCLUDE; ++ } ++ ++ return TRUE; ++} ++ ++/* Merge backend specific data from an object file to the output ++ object file when linking. */ ++ ++static bfd_boolean ++nds32_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd) ++{ ++ flagword out_flags; ++ flagword in_flags; ++ flagword out_16regs; ++ flagword in_no_mac; ++ flagword out_no_mac; ++ flagword in_16regs; ++ flagword out_version; ++ flagword in_version; ++ flagword out_fpu_config; ++ flagword in_fpu_config; ++ ++ /* TODO: Revise to use object-attributes instead. */ ++ if (!nds32_check_vec_size (ibfd)) ++ return FALSE; ++ ++ if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour ++ || bfd_get_flavour (obfd) != bfd_target_elf_flavour) ++ return TRUE; ++ ++ if (bfd_little_endian (ibfd) != bfd_little_endian (obfd)) ++ { ++ (*_bfd_error_handler) ++ (_("%B: warning: Endian mismatch with previous modules."), ibfd); ++ ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ /* [Bug 11585] [Ticket 7067] -B option in objcopy cannot work as expected. ++ e_flags = 0 shall be treat as generic one. ++ no checking, and no merging. ++ */ ++ if (elf_elfheader (ibfd)->e_flags) ++ { ++ in_version = elf_elfheader (ibfd)->e_flags & EF_NDS32_ELF_VERSION; ++ if (in_version == E_NDS32_ELF_VER_1_2) ++ { ++ (*_bfd_error_handler) ++ (_("%B: warning: Older version of object file encountered, " ++ "Please recompile with current tool chain."), ibfd); ++ } ++ ++ /* We may need to merge V1 and V2 arch object files to V2. */ ++ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) ++ != (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) ++ { ++ /* Need to convert version. */ ++ if ((elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) ++ == E_NDS_ARCH_STAR_RESERVED) ++ { ++ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; ++ } ++ else if ((elf_elfheader (obfd)->e_flags & EF_NDS_ARCH) ++ == E_NDS_ARCH_STAR_V0_9 ++ || (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH) ++ > (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)) ++ { ++ elf_elfheader (obfd)->e_flags = ++ convert_e_flags (elf_elfheader (obfd)->e_flags, ++ (elf_elfheader (ibfd)->e_flags & EF_NDS_ARCH)); ++ } ++ else ++ { ++ elf_elfheader (ibfd)->e_flags = ++ convert_e_flags (elf_elfheader (ibfd)->e_flags, ++ (elf_elfheader (obfd)->e_flags & EF_NDS_ARCH)); ++ } ++ } ++ ++ /* Extract some flags. */ ++ in_flags = elf_elfheader (ibfd)->e_flags ++ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION ++ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); ++ ++ /* The following flags need special treatment. */ ++ in_16regs = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; ++ in_no_mac = elf_elfheader (ibfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; ++ in_fpu_config = elf_elfheader (ibfd)->e_flags & E_NDS32_FPU_REG_CONF; ++ ++ /* Extract some flags. */ ++ out_flags = elf_elfheader (obfd)->e_flags ++ & (~(E_NDS32_HAS_REDUCED_REGS | EF_NDS32_ELF_VERSION ++ | E_NDS32_HAS_NO_MAC_INST | E_NDS32_FPU_REG_CONF)); ++ ++ /* The following flags need special treatment. */ ++ out_16regs = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_REDUCED_REGS; ++ out_no_mac = elf_elfheader (obfd)->e_flags & E_NDS32_HAS_NO_MAC_INST; ++ out_fpu_config = elf_elfheader (obfd)->e_flags & E_NDS32_FPU_REG_CONF; ++ out_version = elf_elfheader (obfd)->e_flags & EF_NDS32_ELF_VERSION; ++ if (!elf_flags_init (obfd)) ++ { ++ /* If the input is the default architecture then do not ++ bother setting the flags for the output architecture, ++ instead allow future merges to do this. If no future ++ merges ever set these flags then they will retain their ++ unitialised values, which surprise surprise, correspond ++ to the default values. */ ++ if (bfd_get_arch_info (ibfd)->the_default) ++ return TRUE; ++ ++ elf_flags_init (obfd) = TRUE; ++ elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags; ++ ++ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) ++ && bfd_get_arch_info (obfd)->the_default) ++ { ++ return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), ++ bfd_get_mach (ibfd)); ++ } ++ ++ return TRUE; ++ } ++ ++ /* Check flag compatibility. */ ++ if ((in_flags & EF_NDS_ABI) != (out_flags & EF_NDS_ABI)) ++ { ++ (*_bfd_error_handler) ++ (_("%B: error: ABI mismatch with previous modules."), ibfd); ++ ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ if ((in_flags & EF_NDS_ARCH) != (out_flags & EF_NDS_ARCH)) ++ { ++ if (((in_flags & EF_NDS_ARCH) != E_N1_ARCH)) ++ { ++ (*_bfd_error_handler) ++ (_("%B: error: Instruction set mismatch with previous modules."), ibfd); ++ ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ } ++ ++ /* When linking with V1.2 and V1.3 objects together the output is V1.2. ++ and perf ext1 and DIV are mergerd to perf ext1. */ ++ if (in_version == E_NDS32_ELF_VER_1_2 || out_version == E_NDS32_ELF_VER_1_2) ++ { ++ elf_elfheader (obfd)->e_flags = ++ (in_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) ++ | (out_flags & (~(E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) ++ | (((in_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) ++ ? E_NDS32_HAS_EXT_INST : 0) ++ | (((out_flags & (E_NDS32_HAS_EXT_INST | E_NDS32_HAS_DIV_INST))) ++ ? E_NDS32_HAS_EXT_INST : 0) ++ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) ++ | ((in_version > out_version) ? out_version : in_version); ++ } ++ else ++ { ++ if (in_version != out_version) ++ (*_bfd_error_handler) ( ++ _("%B: warning: Incompatible elf-versions %s and %s."), ibfd, ++ nds32_elfver_strtab[out_version], ++ nds32_elfver_strtab[in_version]); ++ ++ elf_elfheader (obfd)->e_flags = in_flags | out_flags ++ | (in_16regs & out_16regs) | (in_no_mac & out_no_mac) ++ | (in_fpu_config > out_fpu_config ? in_fpu_config : out_fpu_config) ++ | (in_version > out_version ? out_version : in_version); ++ } ++ } ++ return TRUE; ++} ++ ++/* Display the flags field. */ ++ ++static bfd_boolean ++nds32_elf_print_private_bfd_data (bfd *abfd, void *ptr) ++{ ++ FILE *file = (FILE *) ptr; ++ ++ BFD_ASSERT (abfd != NULL && ptr != NULL); ++ ++ _bfd_elf_print_private_bfd_data (abfd, ptr); ++ ++ fprintf (file, _("private flags = %lx"), elf_elfheader (abfd)->e_flags); ++ ++ switch (elf_elfheader (abfd)->e_flags & EF_NDS_ARCH) ++ { ++ default: ++ case E_N1_ARCH: ++ fprintf (file, _(": n1 instructions")); ++ break; ++ case E_N1H_ARCH: ++ fprintf (file, _(": n1h instructions")); ++ break; ++ } ++ ++ fputc ('\n', file); ++ ++ return TRUE; ++} ++ ++static unsigned int ++nds32_elf_action_discarded (asection *sec) ++{ ++ ++ if (strncmp ++ (".gcc_except_table", sec->name, sizeof (".gcc_except_table") - 1) == 0) ++ return 0; ++ ++ return _bfd_elf_default_action_discarded (sec); ++} ++ ++static asection * ++nds32_elf_gc_mark_hook (asection *sec, struct bfd_link_info *info, ++ Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, ++ Elf_Internal_Sym *sym) ++{ ++ if (h != NULL) ++ switch (ELF32_R_TYPE (rel->r_info)) ++ { ++ case R_NDS32_GNU_VTINHERIT: ++ case R_NDS32_GNU_VTENTRY: ++ case R_NDS32_RELA_GNU_VTINHERIT: ++ case R_NDS32_RELA_GNU_VTENTRY: ++ return NULL; ++ } ++ ++ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); ++} ++ ++static bfd_boolean ++nds32_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info, asection *sec, ++ const Elf_Internal_Rela *relocs) ++{ ++ /* Update the got entry reference counts for the section being removed. */ ++ Elf_Internal_Shdr *symtab_hdr; ++ struct elf_link_hash_entry **sym_hashes; ++ bfd_signed_vma *local_got_refcounts; ++ const Elf_Internal_Rela *rel, *relend; ++ ++ elf_section_data (sec)->local_dynrel = NULL; ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ sym_hashes = elf_sym_hashes (abfd); ++ local_got_refcounts = elf_local_got_refcounts (abfd); ++ ++ relend = relocs + sec->reloc_count; ++ for (rel = relocs; rel < relend; rel++) ++ { ++ unsigned long r_symndx; ++ struct elf_link_hash_entry *h = NULL; ++ ++ r_symndx = ELF32_R_SYM (rel->r_info); ++ if (r_symndx >= symtab_hdr->sh_info) ++ { ++ /* External symbol. */ ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ } ++ ++ switch (ELF32_R_TYPE (rel->r_info)) ++ { ++ case R_NDS32_GOT_HI20: ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOT_LO15: ++ case R_NDS32_GOT_LO19: ++ case R_NDS32_GOT17S2_RELA: ++ case R_NDS32_GOT15S2_RELA: ++ case R_NDS32_GOTOFF: ++ case R_NDS32_GOTOFF_HI20: ++ case R_NDS32_GOTOFF_LO12: ++ case R_NDS32_GOTOFF_LO15: ++ case R_NDS32_GOTOFF_LO19: ++ case R_NDS32_GOT20: ++ case R_NDS32_GOTPC_HI20: ++ case R_NDS32_GOTPC_LO12: ++ case R_NDS32_GOTPC20: ++ if (h != NULL) ++ { ++ if (h->got.refcount > 0) ++ h->got.refcount--; ++ } ++ else ++ { ++ if (local_got_refcounts && local_got_refcounts[r_symndx] > 0) ++ local_got_refcounts[r_symndx]--; ++ } ++ break; ++ ++ case R_NDS32_16_RELA: ++ case R_NDS32_20_RELA: ++ case R_NDS32_5_RELA: ++ case R_NDS32_32_RELA: ++ case R_NDS32_HI20_RELA: ++ case R_NDS32_LO12S3_RELA: ++ case R_NDS32_LO12S2_RELA: ++ case R_NDS32_LO12S2_DP_RELA: ++ case R_NDS32_LO12S2_SP_RELA: ++ case R_NDS32_LO12S1_RELA: ++ case R_NDS32_LO12S0_RELA: ++ case R_NDS32_LO12S0_ORI_RELA: ++ case R_NDS32_SDA16S3_RELA: ++ case R_NDS32_SDA17S2_RELA: ++ case R_NDS32_SDA18S1_RELA: ++ case R_NDS32_SDA19S0_RELA: ++ case R_NDS32_SDA15S3_RELA: ++ case R_NDS32_SDA15S2_RELA: ++ case R_NDS32_SDA12S2_DP_RELA: ++ case R_NDS32_SDA12S2_SP_RELA: ++ case R_NDS32_SDA15S1_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ case R_NDS32_SDA_FP7U2_RELA: ++ case R_NDS32_15_PCREL_RELA: ++ case R_NDS32_17_PCREL_RELA: ++ case R_NDS32_25_PCREL_RELA: ++ if (h != NULL) ++ { ++ struct elf_nds32_link_hash_entry *eh; ++ struct elf_nds32_dyn_relocs **pp; ++ struct elf_nds32_dyn_relocs *p; ++ ++ if (!info->shared && h->plt.refcount > 0) ++ h->plt.refcount -= 1; ++ ++ eh = (struct elf_nds32_link_hash_entry *) h; ++ ++ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next) ++ if (p->sec == sec) ++ { ++ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA ++ || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA ++ || ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA) ++ p->pc_count -= 1; ++ p->count -= 1; ++ if (p->count == 0) ++ *pp = p->next; ++ break; ++ } ++ } ++ break; ++ ++ case R_NDS32_9_PLTREL: ++ case R_NDS32_25_PLTREL: ++ if (h != NULL) ++ { ++ if (h->plt.refcount > 0) ++ h->plt.refcount--; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ return TRUE; ++} ++ ++static enum elf_nds32_tls_type ++get_tls_type (enum elf_nds32_reloc_type r_type, ++ struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) ++{ ++ enum elf_nds32_tls_type tls_type; ++ switch (r_type) ++ { ++ case R_NDS32_TLS_LE_HI20: ++ case R_NDS32_TLS_LE_LO12: ++ tls_type = GOT_TLS_LE; ++ break; ++ case R_NDS32_TLS_IE_HI20: ++ case R_NDS32_TLS_IE_LO12S2: ++ case R_NDS32_TLS_IE_LO12: ++ tls_type = GOT_TLS_IE; ++ break; ++ case R_NDS32_TLS_IEGP_HI20: ++ case R_NDS32_TLS_IEGP_LO12: ++ case R_NDS32_TLS_IEGP_LO12S2: ++ tls_type = GOT_TLS_IEGP; ++ break; ++ case R_NDS32_TLS_DESC_HI20: ++ case R_NDS32_TLS_DESC_LO12: ++ case R_NDS32_TLS_DESC_ADD: ++ case R_NDS32_TLS_DESC_FUNC: ++ case R_NDS32_TLS_DESC_CALL: ++ tls_type = GOT_TLS_DESC; ++ break; ++ default: ++ tls_type = GOT_NORMAL; ++ break; ++ } ++ return tls_type; ++} ++ ++/* Ensure that we have allocated bookkeeping structures for ABFD's local ++ symbols. */ ++ ++static bfd_boolean ++elf32_nds32_allocate_local_sym_info (bfd *abfd) ++{ ++ if (elf_local_got_refcounts (abfd) == NULL) ++ { ++ bfd_size_type num_syms; ++ bfd_size_type size; ++ char *data; ++ ++ num_syms = elf_tdata (abfd)->symtab_hdr.sh_info; ++ /* This space is for got_refcounts, got_tls_type, tlsdesc_gotent, and ++ gp_offset. The details can refer to struct elf_nds32_obj_tdata. */ ++ size = num_syms * (sizeof (bfd_signed_vma) + sizeof (char) ++ + sizeof (bfd_vma) + sizeof (int) ++ + sizeof (bfd_boolean) + sizeof (bfd_vma)); ++ data = bfd_zalloc (abfd, size); ++ if (data == NULL) ++ return FALSE; ++ ++ elf_local_got_refcounts (abfd) = (bfd_signed_vma *) data; ++ data += num_syms * sizeof (bfd_signed_vma); ++ ++ elf32_nds32_local_got_tls_type (abfd) = (char *) data; ++ data += num_syms * sizeof (char); ++ ++ elf32_nds32_local_tlsdesc_gotent (abfd) = (bfd_vma *) data; ++ data += num_syms * sizeof (bfd_vma); ++ ++ elf32_nds32_local_gp_offset (abfd) = (int *) data; ++ data += num_syms * sizeof (int); ++ } ++ ++ return TRUE; ++} ++ ++/* Look through the relocs for a section during the first phase. ++ Since we don't do .gots or .plts, we just need to consider the ++ virtual table relocs for gc. */ ++ ++static bfd_boolean ++nds32_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, ++ asection *sec, const Elf_Internal_Rela *relocs) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; ++ const Elf_Internal_Rela *rel; ++ const Elf_Internal_Rela *rel_end; ++ struct elf_link_hash_table *ehtab; ++ struct elf_nds32_link_hash_table *htab; ++ bfd *dynobj; ++ asection *sreloc = NULL; ++ ++ /* No need for relocation if relocatable already. */ ++ if (info->relocatable) ++ { ++ elf32_nds32_check_relax_group (abfd, sec); ++ return TRUE; ++ } ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ sym_hashes = elf_sym_hashes (abfd); ++ sym_hashes_end = ++ sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym); ++ if (!elf_bad_symtab (abfd)) ++ sym_hashes_end -= symtab_hdr->sh_info; ++ ++ ehtab = elf_hash_table (info); ++ htab = nds32_elf_hash_table (info); ++ dynobj = htab->root.dynobj; ++ ++ rel_end = relocs + sec->reloc_count; ++ for (rel = relocs; rel < rel_end; rel++) ++ { ++ enum elf_nds32_reloc_type r_type; ++ struct elf_link_hash_entry *h; ++ unsigned long r_symndx; ++ enum elf_nds32_tls_type tls_type, old_tls_type; ++ struct elf_nds32_ict_hash_entry *entry; ++ ++ r_symndx = ELF32_R_SYM (rel->r_info); ++ r_type = ELF32_R_TYPE (rel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ h = NULL; ++ else ++ { ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ } ++ ++ /* create .got section if necessary ++ Some relocs require a global offset table. We create ++ got section here, since these relocation need a got section ++ and if it is not created yet. */ ++ if (ehtab->sgot == NULL) ++ { ++ switch (r_type) ++ { ++ case R_NDS32_GOT_HI20: ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOT_LO15: ++ case R_NDS32_GOT_LO19: ++ case R_NDS32_GOT17S2_RELA: ++ case R_NDS32_GOT15S2_RELA: ++ case R_NDS32_GOTOFF: ++ case R_NDS32_GOTOFF_HI20: ++ case R_NDS32_GOTOFF_LO12: ++ case R_NDS32_GOTOFF_LO15: ++ case R_NDS32_GOTOFF_LO19: ++ case R_NDS32_GOTPC20: ++ case R_NDS32_GOTPC_HI20: ++ case R_NDS32_GOTPC_LO12: ++ case R_NDS32_GOT20: ++ case R_NDS32_TLS_IE_HI20: ++ case R_NDS32_TLS_IE_LO12: ++ case R_NDS32_TLS_IE_LO12S2: ++ case R_NDS32_TLS_IEGP_HI20: ++ case R_NDS32_TLS_IEGP_LO12: ++ case R_NDS32_TLS_IEGP_LO12S2: ++ case R_NDS32_TLS_DESC_HI20: ++ case R_NDS32_TLS_DESC_LO12: ++ if (dynobj == NULL) ++ htab->root.dynobj = dynobj = abfd; ++ if (!create_got_section (dynobj, info)) ++ return FALSE; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* Check relocation type. */ ++ switch ((int) r_type) ++ { ++ case R_NDS32_TLS_LE_HI20: ++ case R_NDS32_TLS_LE_LO12: ++ case R_NDS32_GOT_HI20: ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOT_LO15: ++ case R_NDS32_GOT_LO19: ++ case R_NDS32_GOT20: ++ case R_NDS32_TLS_IE_HI20: ++ case R_NDS32_TLS_IE_LO12: ++ case R_NDS32_TLS_IE_LO12S2: ++ case R_NDS32_TLS_IEGP_HI20: ++ case R_NDS32_TLS_IEGP_LO12: ++ case R_NDS32_TLS_IEGP_LO12S2: ++ case R_NDS32_TLS_DESC_HI20: ++ case R_NDS32_TLS_DESC_LO12: ++ tls_type = get_tls_type (r_type, h); ++ if (h) ++ { ++ if (tls_type != GOT_TLS_LE) ++ h->got.refcount += 1; ++ old_tls_type = elf32_nds32_hash_entry (h)->tls_type; ++ } ++ else ++ { ++ /* This is a global offset table entry for a local symbol. */ ++ if (!elf32_nds32_allocate_local_sym_info (abfd)) ++ return FALSE; ++ ++ BFD_ASSERT (r_symndx < symtab_hdr->sh_info); ++ if (tls_type != GOT_TLS_LE) ++ elf_local_got_refcounts (abfd)[r_symndx] += 1; ++ old_tls_type = elf32_nds32_local_got_tls_type (abfd)[r_symndx]; ++ } ++ ++ /* We would already issued an error message if there ++ is a TLS/non-TLS mismatch, based on the symbol ++ type. So just combine any TLS types needed. */ ++ if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL ++ && tls_type != GOT_NORMAL) ++ tls_type |= old_tls_type; ++ ++ /* DESC to IE/IEGP if link to executable */ ++ if ((tls_type & GOT_TLS_DESC) && (info->executable)) ++ tls_type |= (info->pie ? GOT_TLS_IEGP : GOT_TLS_IE); ++ ++ if (old_tls_type != tls_type) ++ { ++ if (h != NULL) ++ elf32_nds32_hash_entry (h)->tls_type = tls_type; ++ else ++ elf32_nds32_local_got_tls_type (abfd)[r_symndx] = tls_type; ++ } ++ break; ++ ++ case R_NDS32_9_PLTREL: ++ case R_NDS32_25_PLTREL: ++ case R_NDS32_PLTREL_HI20: ++ case R_NDS32_PLTREL_LO12: ++ case R_NDS32_PLT_GOTREL_HI20: ++ case R_NDS32_PLT_GOTREL_LO12: ++ case R_NDS32_PLT_GOTREL_LO15: ++ case R_NDS32_PLT_GOTREL_LO19: ++ case R_NDS32_PLT_GOTREL_LO20: ++ /* This symbol requires a procedure linkage table entry. ++ We actually build the entry in adjust_dynamic_symbol, ++ because this might be a case of linking PIC code without ++ linking in any dynamic objects, in which case we don't ++ need to generate a procedure linkage table after all. */ ++ ++ /* If this is a local symbol, we resolve it directly without ++ creating a procedure linkage table entry. */ ++ /* explain: continue v.s. break here following: */ ++ if (h == NULL) ++ continue; ++ ++ if (h->forced_local ++ || (info->pie && h->def_regular)) ++ break; ++ ++ elf32_nds32_hash_entry (h)->tls_type = GOT_NORMAL; ++ h->needs_plt = 1; ++ h->plt.refcount += 1; ++ break; ++ ++ case R_NDS32_16_RELA: ++ case R_NDS32_20_RELA: ++ case R_NDS32_5_RELA: ++ case R_NDS32_32_RELA: ++ case R_NDS32_HI20_RELA: ++ case R_NDS32_LO12S3_RELA: ++ case R_NDS32_LO12S2_RELA: ++ case R_NDS32_LO12S2_DP_RELA: ++ case R_NDS32_LO12S2_SP_RELA: ++ case R_NDS32_LO12S1_RELA: ++ case R_NDS32_LO12S0_RELA: ++ case R_NDS32_LO12S0_ORI_RELA: ++ case R_NDS32_SDA16S3_RELA: ++ case R_NDS32_SDA17S2_RELA: ++ case R_NDS32_SDA18S1_RELA: ++ case R_NDS32_SDA19S0_RELA: ++ case R_NDS32_SDA15S3_RELA: ++ case R_NDS32_SDA15S2_RELA: ++ case R_NDS32_SDA12S2_DP_RELA: ++ case R_NDS32_SDA12S2_SP_RELA: ++ case R_NDS32_SDA15S1_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ case R_NDS32_SDA_FP7U2_RELA: ++ case R_NDS32_15_PCREL_RELA: ++ case R_NDS32_17_PCREL_RELA: ++ case R_NDS32_25_PCREL_RELA: ++ ++ if (h != NULL && !info->shared) ++ { ++ h->non_got_ref = 1; ++ h->plt.refcount += 1; ++ } ++ ++ /* If we are creating a shared library, and this is a reloc against ++ a global symbol, or a non PC relative reloc against a local ++ symbol, then we need to copy the reloc into the shared library. ++ However, if we are linking with -Bsymbolic, we do not need to ++ copy a reloc against a global symbol which is defined in an ++ object we are including in the link (i.e., DEF_REGULAR is set). ++ At this point we have not seen all the input files, so it is ++ possible that DEF_REGULAR is not set now but will be set later ++ (it is never cleared). We account for that possibility below by ++ storing information in the dyn_relocs field of the hash table ++ entry. A similar situation occurs when creating shared libraries ++ and symbol visibility changes render the symbol local. ++ ++ If on the other hand, we are creating an executable, we may need ++ to keep relocations for symbols satisfied by a dynamic library ++ if we manage to avoid copy relocs for the symbol. */ ++ if ((info->shared ++ && (sec->flags & SEC_ALLOC) != 0 ++ && ((r_type != R_NDS32_25_PCREL_RELA ++ && r_type != R_NDS32_15_PCREL_RELA ++ && r_type != R_NDS32_17_PCREL_RELA ++ && !(r_type == R_NDS32_32_RELA ++ && strcmp (sec->name, ".eh_frame") == 0)) ++ || (h != NULL ++ && (!info->symbolic ++ || h->root.type == bfd_link_hash_defweak ++ || !h->def_regular)))) ++ || (!info->shared ++ && (sec->flags & SEC_ALLOC) != 0 ++ && h != NULL ++ && (h->root.type == bfd_link_hash_defweak ++ || !h->def_regular))) ++ { ++ struct elf_nds32_dyn_relocs *p; ++ struct elf_nds32_dyn_relocs **head; ++ ++ if (dynobj == NULL) ++ htab->root.dynobj = dynobj = abfd; ++ ++ /* When creating a shared object, we must copy these ++ relocs into the output file. We create a reloc ++ section in dynobj and make room for the reloc. */ ++ if (sreloc == NULL) ++ { ++ const char *name; ++ ++ name = bfd_elf_string_from_elf_section ++ (abfd, elf_elfheader (abfd)->e_shstrndx, ++ elf_section_data (sec)->rela.hdr->sh_name); ++ if (name == NULL) ++ return FALSE; ++ ++ BFD_ASSERT (strncmp (name, ".rela", 5) == 0 ++ && strcmp (bfd_get_section_name (abfd, sec), ++ name + 5) == 0); ++ ++ sreloc = bfd_get_section_by_name (dynobj, name); ++ if (sreloc == NULL) ++ { ++ flagword flags; ++ ++ sreloc = bfd_make_section (dynobj, name); ++ flags = (SEC_HAS_CONTENTS | SEC_READONLY ++ | SEC_IN_MEMORY | SEC_LINKER_CREATED); ++ if ((sec->flags & SEC_ALLOC) != 0) ++ flags |= SEC_ALLOC | SEC_LOAD; ++ if (sreloc == NULL ++ || !bfd_set_section_flags (dynobj, sreloc, flags) ++ || !bfd_set_section_alignment (dynobj, sreloc, 2)) ++ return FALSE; ++ ++ elf_section_type (sreloc) = SHT_RELA; ++ } ++ elf_section_data (sec)->sreloc = sreloc; ++ } ++ ++ /* If this is a global symbol, we count the number of ++ relocations we need for this symbol. */ ++ if (h != NULL) ++ head = &((struct elf_nds32_link_hash_entry *) h)->dyn_relocs; ++ else ++ { ++ asection *s; ++ ++ Elf_Internal_Sym *isym; ++ isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx); ++ if (isym == NULL) ++ return FALSE; ++ ++ /* Track dynamic relocs needed for local syms too. */ ++ s = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ if (s == NULL) ++ return FALSE; ++ ++ head = ((struct elf_nds32_dyn_relocs **) ++ &elf_section_data (s)->local_dynrel); ++ } ++ ++ p = *head; ++ if (p == NULL || p->sec != sec) ++ { ++ bfd_size_type amt = sizeof (*p); ++ p = (struct elf_nds32_dyn_relocs *) bfd_alloc (dynobj, amt); ++ if (p == NULL) ++ return FALSE; ++ p->next = *head; ++ *head = p; ++ p->sec = sec; ++ p->count = 0; ++ p->pc_count = 0; ++ } ++ ++ p->count += 1; ++ if (ELF32_R_TYPE (rel->r_info) == R_NDS32_25_PCREL_RELA ++ || ELF32_R_TYPE (rel->r_info) == R_NDS32_15_PCREL_RELA ++ || ELF32_R_TYPE (rel->r_info) == R_NDS32_17_PCREL_RELA) ++ p->pc_count += 1; ++ } ++ break; ++ ++ /* Merge jump-patch table symbol here. */ ++ case R_NDS32_ICT_HI20: ++ case R_NDS32_ICT_LO12: ++ case R_NDS32_ICT_25PC: ++ if (rel->r_addend != 0) ++ { ++ (*_bfd_error_handler) ++ (_("%B %s: Error: Rom-patch relocation offset: 0x%lx " ++ "with addend 0x%lx\n"), ++ abfd, sec->name, rel->r_offset, rel->r_addend); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ ++ if (h) ++ { ++ elf32_nds32_hash_entry (h)->indirect_call = TRUE; ++ entry = (struct elf_nds32_ict_hash_entry *) ++ bfd_hash_lookup (&indirect_call_table, h->root.root.string, ++ TRUE, TRUE); ++ entry->h = h; ++ if (entry == NULL) ++ { ++ (*_bfd_error_handler) ++ (_("%B: failed creating indirect call %s hash table\n"), ++ abfd, h->root.root.string); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ } ++ else ++ { ++ /* Rom-patch functions cannot be local. */ ++ (*_bfd_error_handler) ++ (_("%B: indirect call relocation with local symbol.\n"), abfd); ++ bfd_set_error (bfd_error_bad_value); ++ return FALSE; ++ } ++ break; ++ ++ /* This relocation describes the C++ object vtable hierarchy. ++ Reconstruct it for later use during GC. */ ++ case R_NDS32_RELA_GNU_VTINHERIT: ++ case R_NDS32_GNU_VTINHERIT: ++ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) ++ return FALSE; ++ break; ++ ++ /* This relocation describes which C++ vtable entries are actually ++ used. Record for later use during GC. */ ++ case R_NDS32_GNU_VTENTRY: ++ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) ++ return FALSE; ++ break; ++ case R_NDS32_RELA_GNU_VTENTRY: ++ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) ++ return FALSE; ++ break; ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Write VAL in uleb128 format to P, returning a pointer to the ++ following byte. ++ This code is copied from elf-attr.c. */ ++ ++static bfd_byte * ++write_uleb128 (bfd_byte *p, unsigned int val) ++{ ++ bfd_byte c; ++ do ++ { ++ c = val & 0x7f; ++ val >>= 7; ++ if (val) ++ c |= 0x80; ++ *(p++) = c; ++ } ++ while (val); ++ return p; ++} ++ ++static bfd_signed_vma ++calculate_offset (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr) ++{ ++ bfd_signed_vma foff; ++ bfd_vma symval, addend; ++ asection *sym_sec; ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) ++ { ++ Elf_Internal_Sym *isym; ++ ++ /* A local symbol. */ ++ isym = isymbuf + ELF32_R_SYM (irel->r_info); ++ ++ if (isym->st_shndx == SHN_UNDEF) ++ sym_sec = bfd_und_section_ptr; ++ else if (isym->st_shndx == SHN_ABS) ++ sym_sec = bfd_abs_section_ptr; ++ else if (isym->st_shndx == SHN_COMMON) ++ sym_sec = bfd_com_section_ptr; ++ else ++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ symval = isym->st_value + sym_sec->output_section->vma ++ + sym_sec->output_offset; ++ } ++ else ++ { ++ unsigned long indx; ++ struct elf_link_hash_entry *h; ++ ++ /* An external symbol. */ ++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[indx]; ++ BFD_ASSERT (h != NULL); ++ ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak) ++ /* This appears to be a reference to an undefined ++ symbol. Just ignore it--it will be caught by the ++ regular reloc processing. */ ++ return 0; ++ ++ if (h->root.u.def.section->flags & SEC_MERGE) ++ { ++ sym_sec = h->root.u.def.section; ++ symval = _bfd_merged_section_offset (abfd, &sym_sec, ++ elf_section_data (sym_sec)->sec_info, ++ h->root.u.def.value); ++ symval = symval + sym_sec->output_section->vma ++ + sym_sec->output_offset; ++ } ++ else ++ symval = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ } ++ ++ addend = irel->r_addend; ++ ++ foff = (symval + addend ++ - (irel->r_offset + sec->output_section->vma + sec->output_offset)); ++ return foff; ++} ++ ++static bfd_vma ++calculate_plt_memory_address (bfd *abfd, struct bfd_link_info *link_info, ++ Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Rela *irel, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ bfd_vma symval; ++ ++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) ++ { ++ Elf_Internal_Sym *isym; ++ asection *sym_sec; ++ /* A local symbol. */ ++ isym = isymbuf + ELF32_R_SYM (irel->r_info); ++ ++ if (isym->st_shndx == SHN_UNDEF) ++ sym_sec = bfd_und_section_ptr; ++ else if (isym->st_shndx == SHN_ABS) ++ sym_sec = bfd_abs_section_ptr; ++ else if (isym->st_shndx == SHN_COMMON) ++ sym_sec = bfd_com_section_ptr; ++ else ++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ symval = isym->st_value + sym_sec->output_section->vma ++ + sym_sec->output_offset; ++ } ++ else ++ { ++ unsigned long indx; ++ struct elf_link_hash_entry *h; ++ struct elf_link_hash_table *ehtab; ++ asection *splt; ++ ++ /* An external symbol. */ ++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[indx]; ++ BFD_ASSERT (h != NULL); ++ ehtab = elf_hash_table (link_info); ++ splt = ehtab->splt; ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (h->plt.offset == (bfd_vma) - 1) ++ { ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak) ++ /* This appears to be a reference to an undefined ++ symbol. Just ignore it--it will be caught by the ++ regular reloc processing. */ ++ return 0; ++ symval = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ } ++ else ++ symval = splt->output_section->vma + h->plt.offset; ++ } ++ ++ return symval; ++} ++ ++static bfd_signed_vma ++calculate_plt_offset (bfd *abfd, asection *sec, struct bfd_link_info *link_info, ++ Elf_Internal_Sym *isymbuf, Elf_Internal_Rela *irel, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ bfd_vma foff; ++ if ((foff = calculate_plt_memory_address (abfd, link_info, isymbuf, irel, ++ symtab_hdr)) == 0) ++ return 0; ++ else ++ return foff - (irel->r_offset ++ + sec->output_section->vma + sec->output_offset); ++} ++ ++/* Convert a 32-bit instruction to 16-bit one. ++ INSN is the input 32-bit instruction, INSN16 is the output 16-bit ++ instruction. If INSN_TYPE is not NULL, it the CGEN instruction ++ type of INSN16. Return 1 if successful. */ ++ ++static int ++nds32_convert_32_to_16_alu1 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, ++ int *pinsn_type) ++{ ++ uint16_t insn16 = 0; ++ int insn_type; ++ unsigned long mach = bfd_get_mach (abfd); ++ ++ if (N32_SH5 (insn) != 0) ++ return 0; ++ ++ switch (N32_SUB5 (insn)) ++ { ++ case N32_ALU1_ADD_SLLI: ++ case N32_ALU1_ADD_SRLI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IS_RB3 (insn)) ++ { ++ insn16 = N16_TYPE333 (ADD333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_RB5 (insn)); ++ insn_type = NDS32_INSN_ADD333; ++ } ++ else if (N32_IS_RT4 (insn)) ++ { ++ if (N32_RT5 (insn) == N32_RA5 (insn)) ++ insn16 = N16_TYPE45 (ADD45, N32_RT54 (insn), N32_RB5 (insn)); ++ else if (N32_RT5 (insn) == N32_RB5 (insn)) ++ insn16 = N16_TYPE45 (ADD45, N32_RT54 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_ADD45; ++ } ++ break; ++ ++ case N32_ALU1_SUB_SLLI: ++ case N32_ALU1_SUB_SRLI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IS_RB3 (insn)) ++ { ++ insn16 = N16_TYPE333 (SUB333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_RB5 (insn)); ++ insn_type = NDS32_INSN_SUB333; ++ } ++ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn)) ++ { ++ insn16 = N16_TYPE45 (SUB45, N32_RT54 (insn), N32_RB5 (insn)); ++ insn_type = NDS32_INSN_SUB45; ++ } ++ break; ++ ++ case N32_ALU1_AND_SLLI: ++ case N32_ALU1_AND_SRLI: ++ /* and $rt, $rt, $rb -> and33 for v3, v3m. */ ++ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && N32_IS_RB3 (insn)) ++ { ++ if (N32_RT5 (insn) == N32_RA5 (insn)) ++ insn16 = N16_MISC33 (AND33, N32_RT5 (insn), N32_RB5 (insn)); ++ else if (N32_RT5 (insn) == N32_RB5 (insn)) ++ insn16 = N16_MISC33 (AND33, N32_RT5 (insn), N32_RA5 (insn)); ++ if (insn16) ++ insn_type = NDS32_INSN_AND33; ++ } ++ break; ++ ++ case N32_ALU1_XOR_SLLI: ++ case N32_ALU1_XOR_SRLI: ++ /* xor $rt, $rt, $rb -> xor33 for v3, v3m. */ ++ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && N32_IS_RB3 (insn)) ++ { ++ if (N32_RT5 (insn) == N32_RA5 (insn)) ++ insn16 = N16_MISC33 (XOR33, N32_RT5 (insn), N32_RB5 (insn)); ++ else if (N32_RT5 (insn) == N32_RB5 (insn)) ++ insn16 = N16_MISC33 (XOR33, N32_RT5 (insn), N32_RA5 (insn)); ++ if (insn16) ++ insn_type = NDS32_INSN_XOR33; ++ } ++ break; ++ ++ case N32_ALU1_OR_SLLI: ++ case N32_ALU1_OR_SRLI: ++ /* or $rt, $rt, $rb -> or33 for v3, v3m. */ ++ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && N32_IS_RB3 (insn)) ++ { ++ if (N32_RT5 (insn) == N32_RA5 (insn)) ++ insn16 = N16_MISC33 (OR33, N32_RT5 (insn), N32_RB5 (insn)); ++ else if (N32_RT5 (insn) == N32_RB5 (insn)) ++ insn16 = N16_MISC33 (OR33, N32_RT5 (insn), N32_RA5 (insn)); ++ if (insn16) ++ insn_type = NDS32_INSN_OR33; ++ } ++ break; ++ case N32_ALU1_NOR: ++ /* nor $rt, $ra, $ra -> not33 for v3, v3m. */ ++ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RB3 (insn) ++ && N32_RA5 (insn) == N32_RB5 (insn)) ++ { ++ insn16 = N16_MISC33 (NOT33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_NOT33; ++ } ++ break; ++ case N32_ALU1_SRAI: ++ if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn)) ++ { ++ insn16 = N16_TYPE45 (SRAI45, N32_RT54 (insn), N32_UB5 (insn)); ++ insn_type = NDS32_INSN_SRAI45; ++ } ++ break; ++ ++ case N32_ALU1_SRLI: ++ if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn)) ++ { ++ insn16 = N16_TYPE45 (SRLI45, N32_RT54 (insn), N32_UB5 (insn)); ++ insn_type = NDS32_INSN_SRLI45; ++ } ++ break; ++ ++ case N32_ALU1_SLLI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_UB5 (insn) < 8) ++ { ++ insn16 = N16_TYPE333 (SLLI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_UB5 (insn)); ++ insn_type = NDS32_INSN_SLLI333; ++ } ++ break; ++ ++ case N32_ALU1_ZEH: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)) ++ { ++ insn16 = N16_BFMI333 (ZEH33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_ZEH33; ++ } ++ break; ++ ++ case N32_ALU1_SEB: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)) ++ { ++ insn16 = N16_BFMI333 (SEB33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_SEB33; ++ } ++ break; ++ ++ case N32_ALU1_SEH: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)) ++ { ++ insn16 = N16_BFMI333 (SEH33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_SEH33; ++ } ++ break; ++ ++ case N32_ALU1_SLT: ++ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn)) ++ { ++ /* Implicit r15. */ ++ insn16 = N16_TYPE45 (SLT45, N32_RA54 (insn), N32_RB5 (insn)); ++ insn_type = NDS32_INSN_SLT45; ++ } ++ break; ++ ++ case N32_ALU1_SLTS: ++ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn)) ++ { ++ /* Implicit r15. */ ++ insn16 = N16_TYPE45 (SLTS45, N32_RA54 (insn), N32_RB5 (insn)); ++ insn_type = NDS32_INSN_SLTS45; ++ } ++ break; ++ } ++ ++ if ((insn16 & 0x8000) == 0) ++ return 0; ++ ++ if (pinsn16) ++ *pinsn16 = insn16; ++ if (pinsn_type) ++ *pinsn_type = insn_type; ++ return 1; ++} ++ ++static int ++nds32_convert_32_to_16_alu2 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, ++ int *pinsn_type) ++{ ++ uint16_t insn16 = 0; ++ int insn_type; ++ unsigned long mach = bfd_get_mach (abfd); ++ ++ /* TODO: bset, bclr, btgl, btst. */ ++ if (__GF (insn, 6, 4) != 0) ++ return 0; ++ ++ switch (N32_IMMU (insn, 6)) ++ { ++ case N32_ALU2_MUL: ++ if (mach >= MACH_V3 && N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && N32_IS_RB3 (insn)) ++ { ++ if (N32_RT5 (insn) == N32_RA5 (insn)) ++ insn16 = N16_MISC33 (MUL33, N32_RT5 (insn), N32_RB5 (insn)); ++ else if (N32_RT5 (insn) == N32_RB5 (insn)) ++ insn16 = N16_MISC33 (MUL33, N32_RT5 (insn), N32_RA5 (insn)); ++ if (insn16) ++ insn_type = NDS32_INSN_MUL33; ++ } ++ } ++ ++ if ((insn16 & 0x8000) == 0) ++ return 0; ++ ++ if (pinsn16) ++ *pinsn16 = insn16; ++ if (pinsn_type) ++ *pinsn_type = insn_type; ++ return 1; ++} ++ ++int ++nds32_convert_32_to_16 (bfd *abfd, uint32_t insn, uint16_t *pinsn16, ++ int *pinsn_type) ++{ ++ int op6; ++ uint16_t insn16 = 0; ++ int insn_type; ++ unsigned long mach = bfd_get_mach (abfd); ++ ++ /* Decode 32-bit instruction. */ ++ if (insn & 0x80000000) ++ { ++ /* Not 32-bit insn. */ ++ return 0; ++ } ++ ++ op6 = N32_OP6 (insn); ++ ++ /* Convert it to 16-bit instruction. */ ++ switch (op6) ++ { ++ case N32_OP6_MOVI: ++ if (IS_WITHIN_S (N32_IMM20S (insn), 5)) ++ { ++ insn16 = N16_TYPE55 (MOVI55, N32_RT5 (insn), N32_IMM20S (insn)); ++ insn_type = NDS32_INSN_MOVI55; ++ } ++ else if (mach >= MACH_V3 && N32_IMM20S (insn) >= 16 ++ && N32_IMM20S (insn) < 48 && N32_IS_RT4 (insn)) ++ { ++ insn16 = N16_TYPE45 (MOVPI45, N32_RT54 (insn), ++ N32_IMM20S (insn) - 16); ++ insn_type = NDS32_INSN_MOVPI45; ++ } ++ break; ++ ++ case N32_OP6_ADDI: ++ if (N32_IMM15S (insn) == 0) ++ { ++ /* Do not convert `addi $sp, $sp, 0' to `mov55 $sp, $sp', ++ because `mov55 $sp, $sp' is ifret16 in V3 ISA. */ ++ if (mach <= MACH_V2 ++ || N32_RT5 (insn) != REG_SP || N32_RA5 (insn) != REG_SP) ++ { ++ insn16 = N16_TYPE55 (MOV55, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_MOV55; ++ } ++ } ++ else if (N32_IMM15S (insn) > 0) ++ { ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IMM15S (insn) < 8) ++ { ++ insn16 = N16_TYPE333 (ADDI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_ADDI333; ++ } ++ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn) ++ && N32_IMM15S (insn) < 32) ++ { ++ insn16 = N16_TYPE45 (ADDI45, N32_RT54 (insn), N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_ADDI45; ++ } ++ else if (mach >= MACH_V2 && N32_RT5 (insn) == REG_SP ++ && N32_RT5 (insn) == N32_RA5 (insn) ++ && N32_IMM15S (insn) < 512) ++ { ++ insn16 = N16_TYPE10 (ADDI10S, N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_ADDI10_SP; ++ } ++ else if (mach >= MACH_V3 && N32_IS_RT3 (insn) ++ && N32_RA5 (insn) == REG_SP && N32_IMM15S (insn) < 256 ++ && (N32_IMM15S (insn) % 4 == 0)) ++ { ++ insn16 = N16_TYPE36 (ADDRI36_SP, N32_RT5 (insn), ++ N32_IMM15S (insn) >> 2); ++ insn_type = NDS32_INSN_ADDRI36_SP; ++ } ++ } ++ else ++ { ++ /* Less than 0. */ ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) && N32_IMM15S (insn) > -8) ++ { ++ insn16 = N16_TYPE333 (SUBI333, N32_RT5 (insn), N32_RA5 (insn), ++ 0 - N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SUBI333; ++ } ++ else if (N32_IS_RT4 (insn) && N32_RT5 (insn) == N32_RA5 (insn) ++ && N32_IMM15S (insn) > -32) ++ { ++ insn16 = N16_TYPE45 (SUBI45, N32_RT54 (insn), 0 - N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SUBI45; ++ } ++ else if (mach >= MACH_V2 && N32_RT5 (insn) == REG_SP ++ && N32_RT5 (insn) == N32_RA5 (insn) ++ && N32_IMM15S (insn) >= -512) ++ { ++ insn16 = N16_TYPE10 (ADDI10S, N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_ADDI10_SP; ++ } ++ } ++ break; ++ ++ case N32_OP6_ORI: ++ if (N32_IMM15S (insn) == 0) ++ { ++ /* Do not convert `ori $sp, $sp, 0' to `mov55 $sp, $sp', ++ because `mov55 $sp, $sp' is ifret16 in V3 ISA. */ ++ if (mach <= MACH_V2 ++ || N32_RT5 (insn) != REG_SP || N32_RA5 (insn) != REG_SP) ++ { ++ insn16 = N16_TYPE55 (MOV55, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_MOV55; ++ } ++ } ++ break; ++ ++ case N32_OP6_SUBRI: ++ if (mach >= MACH_V3 && N32_IS_RT3 (insn) ++ && N32_IS_RA3 (insn) && N32_IMM15S (insn) == 0) ++ { ++ insn16 = N16_MISC33 (NEG33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_NEG33; ++ } ++ break; ++ ++ case N32_OP6_ANDI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn)) ++ { ++ if (N32_IMM15U (insn) == 1) ++ { ++ insn16 = N16_BFMI333 (XLSB33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_XLSB33; ++ } ++ else if (N32_IMM15U (insn) == 0x7ff) ++ { ++ insn16 = N16_BFMI333 (X11B33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_X11B33; ++ } ++ else if (N32_IMM15U (insn) == 0xff) ++ { ++ insn16 = N16_BFMI333 (ZEB33, N32_RT5 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_ZEB33; ++ } ++ else if (mach >= MACH_V3 && N32_RT5 (insn) == N32_RA5 (insn) ++ && N32_IMM15U (insn) < 256) ++ { ++ int imm15u = N32_IMM15U (insn); ++ ++ if (__builtin_popcount (imm15u) == 1) ++ { ++ /* BMSKI33 */ ++ int imm3u = __builtin_ctz (imm15u); ++ ++ insn16 = N16_BFMI333 (BMSKI33, N32_RT5 (insn), imm3u); ++ insn_type = NDS32_INSN_BMSKI33; ++ } ++ else if (imm15u != 0 && __builtin_popcount (imm15u + 1) == 1) ++ { ++ /* FEXTI33 */ ++ int imm3u = __builtin_ctz (imm15u + 1) - 1; ++ ++ insn16 = N16_BFMI333 (FEXTI33, N32_RT5 (insn), imm3u); ++ insn_type = NDS32_INSN_FEXTI33; ++ } ++ } ++ } ++ break; ++ ++ case N32_OP6_SLTI: ++ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 5)) ++ { ++ insn16 = N16_TYPE45 (SLTI45, N32_RA54 (insn), N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SLTI45; ++ } ++ break; ++ ++ case N32_OP6_SLTSI: ++ if (N32_RT5 (insn) == REG_R15 && N32_IS_RA4 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 5)) ++ { ++ insn16 = N16_TYPE45 (SLTSI45, N32_RA54 (insn), N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SLTSI45; ++ } ++ break; ++ ++ case N32_OP6_LWI: ++ if (N32_IS_RT4 (insn) && N32_IMM15S (insn) == 0) ++ { ++ insn16 = N16_TYPE45 (LWI450, N32_RT54 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_LWI450; ++ } ++ else if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (LWI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_LWI333; ++ } ++ else if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_FP ++ && IS_WITHIN_U (N32_IMM15S (insn), 7)) ++ { ++ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 0, N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_LWI37; ++ } ++ else if (mach >= MACH_V2 && N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_SP ++ && IS_WITHIN_U (N32_IMM15S (insn), 7)) ++ { ++ insn16 = N16_TYPE37 (XWI37SP, N32_RT5 (insn), 0, N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_LWI37_SP; ++ } ++ else if (mach >= MACH_V2 && N32_IS_RT4 (insn) && N32_RA5 (insn) == REG_R8 ++ && -32 <= N32_IMM15S (insn) && N32_IMM15S (insn) < 0) ++ { ++ insn16 = N16_TYPE45 (LWI45_FE, N32_RT54 (insn), ++ N32_IMM15S (insn) + 32); ++ insn_type = NDS32_INSN_LWI45_FE; ++ } ++ break; ++ ++ case N32_OP6_SWI: ++ if (N32_IS_RT4 (insn) && N32_IMM15S (insn) == 0) ++ { ++ insn16 = N16_TYPE45 (SWI450, N32_RT54 (insn), N32_RA5 (insn)); ++ insn_type = NDS32_INSN_SWI450; ++ } ++ else if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (SWI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SWI333; ++ } ++ else if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_FP ++ && IS_WITHIN_U (N32_IMM15S (insn), 7)) ++ { ++ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 1, N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SWI37; ++ } ++ else if (mach >= MACH_V2 && N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_SP ++ && IS_WITHIN_U (N32_IMM15S (insn), 7)) ++ { ++ insn16 = N16_TYPE37 (XWI37SP, N32_RT5 (insn), 1, N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SWI37_SP; ++ } ++ break; ++ ++ case N32_OP6_LWI_BI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (LWI333_BI, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_LWI333_BI; ++ } ++ break; ++ ++ case N32_OP6_SWI_BI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (SWI333_BI, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SWI333_BI; ++ } ++ break; ++ ++ case N32_OP6_LHI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (LHI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_LHI333; ++ } ++ break; ++ ++ case N32_OP6_SHI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (SHI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SHI333; ++ } ++ break; ++ ++ case N32_OP6_LBI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (LBI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_LBI333; ++ } ++ break; ++ ++ case N32_OP6_SBI: ++ if (N32_IS_RT3 (insn) && N32_IS_RA3 (insn) ++ && IS_WITHIN_U (N32_IMM15S (insn), 3)) ++ { ++ insn16 = N16_TYPE333 (SBI333, N32_RT5 (insn), N32_RA5 (insn), ++ N32_IMM15S (insn)); ++ insn_type = NDS32_INSN_SBI333; ++ } ++ break; ++ ++ case N32_OP6_ALU1: ++ return nds32_convert_32_to_16_alu1 (abfd, insn, pinsn16, pinsn_type); ++ ++ case N32_OP6_ALU2: ++ return nds32_convert_32_to_16_alu2 (abfd, insn, pinsn16, pinsn_type); ++ ++ case N32_OP6_BR1: ++ if (!IS_WITHIN_S (N32_IMM14S (insn), 8)) ++ goto done; ++ ++ if ((insn & __BIT (14)) == 0) ++ { ++ /* N32_BR1_BEQ */ ++ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5 ++ && N32_RT5 (insn) != REG_R5) ++ insn16 = N16_TYPE38 (BEQS38, N32_RT5 (insn), N32_IMM14S (insn)); ++ else if (N32_IS_RA3 (insn) && N32_RT5 (insn) == REG_R5 ++ && N32_RA5 (insn) != REG_R5) ++ insn16 = N16_TYPE38 (BEQS38, N32_RA5 (insn), N32_IMM14S (insn)); ++ insn_type = NDS32_INSN_BEQS38; ++ break; ++ } ++ else ++ { ++ /* N32_BR1_BNE */ ++ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5 ++ && N32_RT5 (insn) != REG_R5) ++ insn16 = N16_TYPE38 (BNES38, N32_RT5 (insn), N32_IMM14S (insn)); ++ else if (N32_IS_RA3 (insn) && N32_RT5 (insn) == REG_R5 ++ && N32_RA5 (insn) != REG_R5) ++ insn16 = N16_TYPE38 (BNES38, N32_RA5 (insn), N32_IMM14S (insn)); ++ insn_type = NDS32_INSN_BNES38; ++ break; ++ } ++ break; ++ ++ case N32_OP6_BR2: ++ switch (N32_BR2_SUB (insn)) ++ { ++ case N32_BR2_BEQZ: ++ if (N32_IS_RT3 (insn) && IS_WITHIN_S (N32_IMM16S (insn), 8)) ++ { ++ insn16 = N16_TYPE38 (BEQZ38, N32_RT5 (insn), N32_IMM16S (insn)); ++ insn_type = NDS32_INSN_BEQZ38; ++ } ++ else if (N32_RT5 (insn) == REG_R15 && IS_WITHIN_S (N32_IMM16S (insn), 8)) ++ { ++ insn16 = N16_TYPE8 (BEQZS8, N32_IMM16S (insn)); ++ insn_type = NDS32_INSN_BEQZS8; ++ } ++ break; ++ ++ case N32_BR2_BNEZ: ++ if (N32_IS_RT3 (insn) && IS_WITHIN_S (N32_IMM16S (insn), 8)) ++ { ++ insn16 = N16_TYPE38 (BNEZ38, N32_RT5 (insn), N32_IMM16S (insn)); ++ insn_type = NDS32_INSN_BNEZ38; ++ } ++ else if (N32_RT5 (insn) == REG_R15 && IS_WITHIN_S (N32_IMM16S (insn), 8)) ++ { ++ insn16 = N16_TYPE8 (BNEZS8, N32_IMM16S (insn)); ++ insn_type = NDS32_INSN_BNEZS8; ++ } ++ break; ++ ++ case N32_BR2_SOP0: ++ if (__GF (insn, 20, 5) == 0 && IS_WITHIN_U (N32_IMM16S (insn), 9)) ++ { ++ insn16 = N16_TYPE9 (IFCALL9, N32_IMM16S (insn)); ++ insn_type = NDS32_INSN_IFCALL9; ++ } ++ break; ++ } ++ break; ++ ++ case N32_OP6_JI: ++ if ((insn & __BIT (24)) == 0) ++ { ++ /* N32_JI_J */ ++ if (IS_WITHIN_S (N32_IMM24S (insn), 8)) ++ { ++ insn16 = N16_TYPE8 (J8, N32_IMM24S (insn)); ++ insn_type = NDS32_INSN_J8; ++ } ++ } ++ break; ++ ++ case N32_OP6_JREG: ++ if (__GF (insn, 8, 2) != 0) ++ goto done; ++ ++ switch (N32_IMMU (insn, 5)) ++ { ++ case N32_JREG_JR: ++ if (N32_JREG_HINT (insn) == 0) ++ { ++ /* jr */ ++ insn16 = N16_TYPE5 (JR5, N32_RB5 (insn)); ++ insn_type = NDS32_INSN_JR5; ++ } ++ else if (N32_JREG_HINT (insn) == 1) ++ { ++ /* ret */ ++ insn16 = N16_TYPE5 (RET5, N32_RB5 (insn)); ++ insn_type = NDS32_INSN_RET5; ++ } ++ else if (N32_JREG_HINT (insn) == 3) ++ { ++ /* ifret = mov55 $sp, $sp */ ++ insn16 = N16_TYPE55 (MOV55, REG_SP, REG_SP); ++ insn_type = NDS32_INSN_IFRET; ++ } ++ break; ++ ++ case N32_JREG_JRAL: ++ /* It's convertible when return rt5 is $lp and address ++ translation is kept. */ ++ if (N32_RT5 (insn) == REG_LP && N32_JREG_HINT (insn) == 0) ++ { ++ insn16 = N16_TYPE5 (JRAL5, N32_RB5 (insn)); ++ insn_type = NDS32_INSN_JRAL5; ++ } ++ break; ++ } ++ break; ++ ++ case N32_OP6_MISC: ++ if (N32_SUB5 (insn) == N32_MISC_BREAK && N32_SWID (insn) < 32) ++ { ++ /* For v3, swid above 31 are used for ex9.it. */ ++ insn16 = N16_TYPE5 (BREAK16, N32_SWID (insn)); ++ insn_type = NDS32_INSN_BREAK16; ++ } ++ break; ++ ++ default: ++ /* This instruction has no 16-bit variant. */ ++ goto done; ++ } ++ ++done: ++ /* Bit-15 of insn16 should be set for a valid instruction. */ ++ if ((insn16 & 0x8000) == 0) ++ return 0; ++ ++ if (pinsn16) ++ *pinsn16 = insn16; ++ if (pinsn_type) ++ *pinsn_type = insn_type; ++ return 1; ++} ++ ++static int ++special_convert_32_to_16 (unsigned long insn, uint16_t *pinsn16, ++ Elf_Internal_Rela *reloc) ++{ ++ uint16_t insn16 = 0; ++ ++ if ((reloc->r_addend & R_NDS32_INSN16_FP7U2_FLAG) == 0 ++ || (ELF32_R_TYPE (reloc->r_info) != R_NDS32_INSN16)) ++ return 0; ++ ++ if (!N32_IS_RT3 (insn)) ++ return 0; ++ ++ switch (N32_OP6 (insn)) ++ { ++ case N32_OP6_LWI: ++ if (N32_RA5 (insn) == REG_GP && IS_WITHIN_U (N32_IMM15S (insn), 7)) ++ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 0, N32_IMM15S (insn)); ++ break; ++ case N32_OP6_SWI: ++ if (N32_RA5 (insn) == REG_GP && IS_WITHIN_U (N32_IMM15S (insn), 7)) ++ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 1, N32_IMM15S (insn)); ++ break; ++ case N32_OP6_HWGP: ++ if (!IS_WITHIN_U (N32_IMM17S (insn), 7)) ++ break; ++ ++ if (__GF (insn, 17, 3) == 6) ++ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 0, N32_IMM17S (insn)); ++ else if (__GF (insn, 17, 3) == 7) ++ insn16 = N16_TYPE37 (XWI37, N32_RT5 (insn), 1, N32_IMM17S (insn)); ++ break; ++ } ++ ++ if ((insn16 & 0x8000) == 0) ++ return 0; ++ ++ *pinsn16 = insn16; ++ return 1; ++} ++ ++/* Convert a 16-bit instruction to 32-bit one. ++ INSN16 it the input and PINSN it the point to output. ++ Return non-zero on successful. Otherwise 0 is returned. */ ++ ++int ++nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn) ++{ ++ uint32_t insn = 0xffffffff; ++ unsigned long mach = bfd_get_mach (abfd); ++ ++ /* NOTE: push25, pop25 and movd44 do not have 32-bit variants. */ ++ ++ switch (__GF (insn16, 9, 6)) ++ { ++ case 0x4: /* add45 */ ++ insn = N32_ALU1 (ADD, N16_RT4 (insn16), N16_RT4 (insn16), N16_RA5 (insn16)); ++ goto done; ++ case 0x5: /* sub45 */ ++ insn = N32_ALU1 (SUB, N16_RT4 (insn16), N16_RT4 (insn16), N16_RA5 (insn16)); ++ goto done; ++ case 0x6: /* addi45 */ ++ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16)); ++ goto done; ++ case 0x7: /* subi45 */ ++ insn = N32_TYPE2 (ADDI, N16_RT4 (insn16), N16_RT4 (insn16), -N16_IMM5U (insn16)); ++ goto done; ++ case 0x8: /* srai45 */ ++ insn = N32_ALU1 (SRAI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16)); ++ goto done; ++ case 0x9: /* srli45 */ ++ insn = N32_ALU1 (SRLI, N16_RT4 (insn16), N16_RT4 (insn16), N16_IMM5U (insn16)); ++ goto done; ++ ++ case 0xa: /* slli333 */ ++ insn = N32_ALU1 (SLLI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0xc: /* add333 */ ++ insn = N32_ALU1 (ADD, N16_RT3 (insn16), N16_RA3 (insn16), N16_RB3 (insn16)); ++ goto done; ++ case 0xd: /* sub333 */ ++ insn = N32_ALU1 (SUB, N16_RT3 (insn16), N16_RA3 (insn16), N16_RB3 (insn16)); ++ goto done; ++ case 0xe: /* addi333 */ ++ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0xf: /* subi333 */ ++ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), N16_RA3 (insn16), -N16_IMM3U (insn16)); ++ goto done; ++ ++ case 0x10: /* lwi333 */ ++ insn = N32_TYPE2 (LWI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x12: /* lhi333 */ ++ insn = N32_TYPE2 (LHI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x13: /* lbi333 */ ++ insn = N32_TYPE2 (LBI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x11: /* lwi333.bi */ ++ insn = N32_TYPE2 (LWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x14: /* swi333 */ ++ insn = N32_TYPE2 (SWI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x16: /* shi333 */ ++ insn = N32_TYPE2 (SHI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x17: /* sbi333 */ ++ insn = N32_TYPE2 (SBI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ case 0x15: /* swi333.bi */ ++ insn = N32_TYPE2 (SWI_BI, N16_RT3 (insn16), N16_RA3 (insn16), N16_IMM3U (insn16)); ++ goto done; ++ ++ case 0x18: /* addri36.sp */ ++ insn = N32_TYPE2 (ADDI, N16_RT3 (insn16), REG_SP, N16_IMM6U (insn16) << 2); ++ goto done; ++ ++ case 0x19: /* lwi45.fe */ ++ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), REG_R8, (N16_IMM5U (insn16) - 32)); ++ goto done; ++ case 0x1a: /* lwi450 */ ++ insn = N32_TYPE2 (LWI, N16_RT4 (insn16), N16_RA5 (insn16), 0); ++ goto done; ++ case 0x1b: /* swi450 */ ++ insn = N32_TYPE2 (SWI, N16_RT4 (insn16), N16_RA5 (insn16), 0); ++ goto done; ++ ++ /* These are r15 implied instructions. */ ++ case 0x30: /* slts45 */ ++ insn = N32_ALU1 (SLTS, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16)); ++ goto done; ++ case 0x31: /* slt45 */ ++ insn = N32_ALU1 (SLT, REG_TA, N16_RT4 (insn16), N16_RA5 (insn16)); ++ goto done; ++ case 0x32: /* sltsi45 */ ++ insn = N32_TYPE2 (SLTSI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16)); ++ goto done; ++ case 0x33: /* slti45 */ ++ insn = N32_TYPE2 (SLTI, REG_TA, N16_RT4 (insn16), N16_IMM5U (insn16)); ++ goto done; ++ case 0x34: /* beqzs8, bnezs8 */ ++ if (insn16 & __BIT (8)) ++ insn = N32_BR2 (BNEZ, REG_TA, N16_IMM8S (insn16)); ++ else ++ insn = N32_BR2 (BEQZ, REG_TA, N16_IMM8S (insn16)); ++ goto done; ++ ++ case 0x35: /* break16, ex9.it */ ++ /* Only consider range of v3 break16. */ ++ insn = N32_TYPE0 (MISC, (N16_IMM5U (insn16) << 5) | N32_MISC_BREAK); ++ goto done; ++ ++ case 0x3c: /* ifcall9 */ ++ insn = N32_BR2 (SOP0, 0, N16_IMM9U (insn16)); ++ goto done; ++ case 0x3d: /* movpi45 */ ++ insn = N32_TYPE1 (MOVI, N16_RT4 (insn16), N16_IMM5U (insn16) + 16); ++ goto done; ++ ++ case 0x3f: /* MISC33 */ ++ switch (insn16 & 0x7) ++ { ++ case 2: /* neg33 */ ++ insn = N32_TYPE2 (SUBRI, N16_RT3 (insn16), N16_RA3 (insn16), 0); ++ break; ++ case 3: /* not33 */ ++ insn = N32_ALU1 (NOR, N16_RT3 (insn16), N16_RA3 (insn16), N16_RA3 (insn16)); ++ break; ++ case 4: /* mul33 */ ++ insn = N32_ALU2 (MUL, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); ++ break; ++ case 5: /* xor33 */ ++ insn = N32_ALU1 (XOR, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); ++ break; ++ case 6: /* and33 */ ++ insn = N32_ALU1 (AND, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); ++ break; ++ case 7: /* or33 */ ++ insn = N32_ALU1 (OR, N16_RT3 (insn16), N16_RT3 (insn16), N16_RA3 (insn16)); ++ break; ++ } ++ goto done; ++ ++ case 0xb: /* ... */ ++ switch (insn16 & 0x7) ++ { ++ case 0: /* zeb33 */ ++ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0xff); ++ break; ++ case 1: /* zeh33 */ ++ insn = N32_ALU1 (ZEH, N16_RT3 (insn16), N16_RA3 (insn16), 0); ++ break; ++ case 2: /* seb33 */ ++ insn = N32_ALU1 (SEB, N16_RT3 (insn16), N16_RA3 (insn16), 0); ++ break; ++ case 3: /* seh33 */ ++ insn = N32_ALU1 (SEH, N16_RT3 (insn16), N16_RA3 (insn16), 0); ++ break; ++ case 4: /* xlsb33 */ ++ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 1); ++ break; ++ case 5: /* x11b33 */ ++ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RA3 (insn16), 0x7ff); ++ break; ++ case 6: /* bmski33 */ ++ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16), ++ 1 << __GF (insn16, 3, 3)); ++ break; ++ case 7: /* fexti33 */ ++ insn = N32_TYPE2 (ANDI, N16_RT3 (insn16), N16_RT3 (insn16), ++ (1 << (__GF (insn16, 3, 3) + 1)) - 1); ++ break; ++ } ++ goto done; ++ } ++ ++ switch (__GF (insn16, 10, 5)) ++ { ++ case 0x0: /* mov55 or ifret16 */ ++ if (mach >= MACH_V3 && N16_RT5 (insn16) == REG_SP ++ && N16_RT5 (insn16) == N16_RA5 (insn16)) ++ insn = N32_JREG (JR, 0, 0, 0, 3); ++ else ++ insn = N32_TYPE2 (ADDI, N16_RT5 (insn16), N16_RA5 (insn16), 0); ++ goto done; ++ case 0x1: /* movi55 */ ++ insn = N32_TYPE1 (MOVI, N16_RT5 (insn16), N16_IMM5S (insn16)); ++ goto done; ++ case 0x1b: /* addi10s (V2) */ ++ insn = N32_TYPE2 (ADDI, REG_SP, REG_SP, N16_IMM10S (insn16)); ++ goto done; ++ } ++ ++ switch (__GF (insn16, 11, 4)) ++ { ++ case 0x7: /* lwi37.fp/swi37.fp */ ++ if (insn16 & __BIT (7)) /* swi37.fp */ ++ insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16)); ++ else /* lwi37.fp */ ++ insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_FP, N16_IMM7U (insn16)); ++ goto done; ++ case 0x8: /* beqz38 */ ++ insn = N32_BR2 (BEQZ, N16_RT38 (insn16), N16_IMM8S (insn16)); ++ goto done; ++ case 0x9: /* bnez38 */ ++ insn = N32_BR2 (BNEZ, N16_RT38 (insn16), N16_IMM8S (insn16)); ++ goto done; ++ case 0xa: /* beqs38/j8, implied r5 */ ++ if (N16_RT38 (insn16) == 5) ++ insn = N32_JI (J, N16_IMM8S (insn16)); ++ else ++ insn = N32_BR1 (BEQ, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16)); ++ goto done; ++ case 0xb: /* bnes38 and others */ ++ if (N16_RT38 (insn16) == 5) ++ { ++ switch (__GF (insn16, 5, 3)) ++ { ++ case 0: /* jr5 */ ++ insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 0); ++ break; ++ case 4: /* ret5 */ ++ insn = N32_JREG (JR, 0, N16_RA5 (insn16), 0, 1); ++ break; ++ case 1: /* jral5 */ ++ insn = N32_JREG (JRAL, REG_LP, N16_RA5 (insn16), 0, 0); ++ break; ++ case 2: /* ex9.it imm5 */ ++ /* ex9.it had no 32-bit variantl. */ ++ break; ++ case 5: /* add5.pc */ ++ /* add5.pc had no 32-bit variantl. */ ++ break; ++ } ++ } ++ else /* bnes38 */ ++ insn = N32_BR1 (BNE, N16_RT38 (insn16), REG_R5, N16_IMM8S (insn16)); ++ goto done; ++ case 0xe: /* lwi37/swi37 */ ++ if (insn16 & (1 << 7)) /* swi37.sp */ ++ insn = N32_TYPE2 (SWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16)); ++ else /* lwi37.sp */ ++ insn = N32_TYPE2 (LWI, N16_RT38 (insn16), REG_SP, N16_IMM7U (insn16)); ++ goto done; ++ } ++ ++done: ++ if (insn & 0x80000000) ++ return 0; ++ ++ if (pinsn) ++ *pinsn = insn; ++ return 1; ++} ++ ++static bfd_boolean ++is_sda_access_insn (unsigned long insn) ++{ ++ switch (N32_OP6 (insn)) ++ { ++ case N32_OP6_LWI: ++ case N32_OP6_LHI: ++ case N32_OP6_LHSI: ++ case N32_OP6_LBI: ++ case N32_OP6_LBSI: ++ case N32_OP6_SWI: ++ case N32_OP6_SHI: ++ case N32_OP6_SBI: ++ case N32_OP6_LWC: ++ case N32_OP6_LDC: ++ case N32_OP6_SWC: ++ case N32_OP6_SDC: ++ return TRUE; ++ default: ++ ; ++ } ++ return FALSE; ++} ++ ++static unsigned long ++turn_insn_to_sda_access (uint32_t insn, bfd_signed_vma type, uint32_t *pinsn) ++{ ++ uint32_t oinsn = 0; ++ ++ switch (type) ++ { ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOTOFF_LO12: ++ case R_NDS32_PLTREL_LO12: ++ case R_NDS32_PLT_GOTREL_LO12: ++ case R_NDS32_LO12S0_RELA: ++ switch (N32_OP6 (insn)) ++ { ++ case N32_OP6_LBI: ++ /* lbi.gp */ ++ oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), 0); ++ break; ++ case N32_OP6_LBSI: ++ /* lbsi.gp */ ++ oinsn = N32_TYPE1 (LBGP, N32_RT5 (insn), __BIT (19)); ++ break; ++ case N32_OP6_SBI: ++ /* sbi.gp */ ++ oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), 0); ++ break; ++ case N32_OP6_ORI: ++ /* addi.gp */ ++ oinsn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19)); ++ break; ++ } ++ break; ++ ++ case R_NDS32_LO12S1_RELA: ++ switch (N32_OP6 (insn)) ++ { ++ case N32_OP6_LHI: ++ /* lhi.gp */ ++ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), 0); ++ break; ++ case N32_OP6_LHSI: ++ /* lhsi.gp */ ++ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (18)); ++ break; ++ case N32_OP6_SHI: ++ /* shi.gp */ ++ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (19)); ++ break; ++ } ++ break; ++ ++ case R_NDS32_LO12S2_RELA: ++ switch (N32_OP6 (insn)) ++ { ++ case N32_OP6_LWI: ++ /* lwi.gp */ ++ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3)); ++ break; ++ case N32_OP6_SWI: ++ /* swi.gp */ ++ oinsn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (7, 17, 3)); ++ break; ++ } ++ break; ++ ++ case R_NDS32_LO12S2_DP_RELA: ++ case R_NDS32_LO12S2_SP_RELA: ++ oinsn = (insn & 0x7ff07000) | (REG_GP << 15); ++ break; ++ } ++ ++ if (oinsn) ++ *pinsn = oinsn; ++ ++ return oinsn != 0; ++} ++ ++/* Linker hasn't found the correct merge section for non-section symbol ++ in relax time, this work is left to the function elf_link_input_bfd(). ++ So for non-section symbol, _bfd_merged_section_offset is also needed ++ to find the correct symbol address. */ ++ ++static bfd_vma ++nds32_elf_rela_local_sym (bfd *abfd, Elf_Internal_Sym *sym, ++ asection **psec, Elf_Internal_Rela *rel) ++{ ++ asection *sec = *psec; ++ bfd_vma relocation; ++ ++ relocation = (sec->output_section->vma ++ + sec->output_offset + sym->st_value); ++ if ((sec->flags & SEC_MERGE) && sec->sec_info_type == SEC_INFO_TYPE_MERGE) ++ { ++ if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) ++ rel->r_addend = ++ _bfd_merged_section_offset (abfd, psec, ++ elf_section_data (sec)->sec_info, ++ sym->st_value + rel->r_addend); ++ else ++ rel->r_addend = ++ _bfd_merged_section_offset (abfd, psec, ++ elf_section_data (sec)->sec_info, ++ sym->st_value) + rel->r_addend; ++ ++ if (sec != *psec) ++ { ++ /* If we have changed the section, and our original section is ++ marked with SEC_EXCLUDE, it means that the original ++ SEC_MERGE section has been completely subsumed in some ++ other SEC_MERGE section. In this case, we need to leave ++ some info around for --emit-relocs. */ ++ if ((sec->flags & SEC_EXCLUDE) != 0) ++ sec->kept_section = *psec; ++ sec = *psec; ++ } ++ rel->r_addend -= relocation; ++ rel->r_addend += sec->output_section->vma + sec->output_offset; ++ } ++ return relocation; ++} ++ ++static bfd_vma ++calculate_memory_address (bfd *abfd, Elf_Internal_Rela *irel, ++ Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ bfd_signed_vma foff; ++ bfd_vma symval, addend; ++ Elf_Internal_Rela irel_fn; ++ Elf_Internal_Sym *isym; ++ asection *sym_sec; ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) ++ { ++ /* A local symbol. */ ++ isym = isymbuf + ELF32_R_SYM (irel->r_info); ++ ++ if (isym->st_shndx == SHN_UNDEF) ++ sym_sec = bfd_und_section_ptr; ++ else if (isym->st_shndx == SHN_ABS) ++ sym_sec = bfd_abs_section_ptr; ++ else if (isym->st_shndx == SHN_COMMON) ++ sym_sec = bfd_com_section_ptr; ++ else ++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ memcpy (&irel_fn, irel, sizeof (Elf_Internal_Rela)); ++ symval = nds32_elf_rela_local_sym (abfd, isym, &sym_sec, &irel_fn); ++ addend = irel_fn.r_addend; ++ } ++ else ++ { ++ unsigned long indx; ++ struct elf_link_hash_entry *h; ++ ++ /* An external symbol. */ ++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[indx]; ++ BFD_ASSERT (h != NULL); ++ ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak) ++ /* This appears to be a reference to an undefined ++ symbol. Just ignore it--it will be caught by the ++ regular reloc processing. */ ++ return 0; ++ ++ if (h->root.u.def.section->flags & SEC_MERGE) ++ { ++ sym_sec = h->root.u.def.section; ++ symval = _bfd_merged_section_offset (abfd, &sym_sec, elf_section_data ++ (sym_sec)->sec_info, h->root.u.def.value); ++ symval = symval + sym_sec->output_section->vma ++ + sym_sec->output_offset; ++ } ++ else ++ symval = (h->root.u.def.value ++ + h->root.u.def.section->output_section->vma ++ + h->root.u.def.section->output_offset); ++ addend = irel->r_addend; ++ } ++ ++ foff = symval + addend; ++ ++ return foff; ++} ++ ++static bfd_vma ++calculate_got_memory_address (bfd *abfd, struct bfd_link_info *link_info, ++ Elf_Internal_Rela *irel, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ int symndx; ++ bfd_vma *local_got_offsets; ++ /* Get the value of the symbol referred to by the reloc. */ ++ struct elf_link_hash_entry *h; ++ struct elf_link_hash_table *ehtab = elf_hash_table (link_info); ++ ++ /* An external symbol. */ ++ symndx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[symndx]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ ++ if (symndx >= 0) ++ { ++ BFD_ASSERT (h != NULL); ++ return ehtab->sgot->output_section->vma + ehtab->sgot->output_offset ++ + h->got.offset; ++ } ++ local_got_offsets = elf_local_got_offsets (abfd); ++ BFD_ASSERT (local_got_offsets != NULL); ++ return ehtab->sgot->output_section->vma + ehtab->sgot->output_offset ++ + local_got_offsets[ELF32_R_SYM (irel->r_info)]; ++ ++ /* The _GLOBAL_OFFSET_TABLE_ may be undefweak(or should be?). */ ++ /* The check of h->root.type is passed. */ ++} ++ ++static int ++is_16bit_NOP (bfd *abfd ATTRIBUTE_UNUSED, ++ asection *sec, Elf_Internal_Rela *rel) ++{ ++ bfd_byte *contents; ++ unsigned short insn16; ++ ++ if (!(rel->r_addend & R_NDS32_INSN16_CONVERT_FLAG)) ++ return FALSE; ++ contents = elf_section_data (sec)->this_hdr.contents; ++ insn16 = bfd_getb16 (contents + rel->r_offset); ++ if (insn16 == NDS32_NOP16) ++ return TRUE; ++ return FALSE; ++} ++ ++/* It checks whether the instruction could be converted to ++ 16-bit form and returns the converted one. ++ ++ `internal_relocs' is supposed to be sorted. */ ++ ++static int ++is_convert_32_to_16 (bfd *abfd, asection *sec, ++ Elf_Internal_Rela *reloc, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend, ++ uint16_t *insn16) ++{ ++#define NORMAL_32_TO_16 (1 << 0) ++#define SPECIAL_32_TO_16 (1 << 1) ++ bfd_byte *contents = NULL; ++ bfd_signed_vma off; ++ bfd_vma mem_addr; ++ uint32_t insn = 0; ++ Elf_Internal_Rela *pc_rel; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Sym *isymbuf = NULL; ++ int convert_type; ++ bfd_vma offset; ++ ++ if (reloc->r_offset + 4 > sec->size) ++ return FALSE; ++ ++ offset = reloc->r_offset; ++ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) ++ return FALSE; ++ insn = bfd_getb32 (contents + offset); ++ ++ if (nds32_convert_32_to_16 (abfd, insn, insn16, NULL)) ++ convert_type = NORMAL_32_TO_16; ++ else if (special_convert_32_to_16 (insn, insn16, reloc)) ++ convert_type = SPECIAL_32_TO_16; ++ else ++ return FALSE; ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (!nds32_get_local_syms (abfd, sec, &isymbuf)) ++ return FALSE; ++ ++ /* Find the first relocation of the same relocation-type, ++ so we iteratie them forward. */ ++ pc_rel = reloc; ++ while ((pc_rel - 1) >= internal_relocs && pc_rel[-1].r_offset == offset) ++ pc_rel--; ++ ++ for (; pc_rel < irelend && pc_rel->r_offset == offset; pc_rel++) ++ { ++ if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_15_PCREL_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17_PCREL_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PCREL_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PLTREL) ++ { ++ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr); ++ if (off >= ACCURATE_8BIT_S1 || off < -ACCURATE_8BIT_S1 ++ || off == 0) ++ return FALSE; ++ break; ++ } ++ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_20_RELA) ++ { ++ /* movi => movi55 */ ++ mem_addr = calculate_memory_address (abfd, pc_rel, isymbuf, symtab_hdr); ++ /* mem_addr is unsigned, but the value should be between [-16, 15]. */ ++ if ((mem_addr + 0x10) >> 5) ++ return FALSE; ++ break; ++ } ++ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_TLS_LE_20) ++ || (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_TLS_LE_LO12)) ++ { ++ /* It never happen movi to movi55 for R_NDS32_TLS_LE_20, ++ because it can be relaxed to addi for TLS_LE_ADD. */ ++ return FALSE; ++ } ++ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA15S2_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA17S2_RELA) ++ && (reloc->r_addend & R_NDS32_INSN16_FP7U2_FLAG) ++ && convert_type == SPECIAL_32_TO_16) ++ { ++ /* fp-as-gp ++ We've selected a best fp-base for this access, so we can ++ always resolve it anyway. Do nothing. */ ++ break; ++ } ++ else if ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_NONE ++ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_RELA_GNU_VTINHERIT)) ++ || ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_RELA_GNU_VTENTRY) ++ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_INSN16)) ++ || ((ELF32_R_TYPE (pc_rel->r_info) > R_NDS32_LOADSTORE) ++ && (ELF32_R_TYPE (pc_rel->r_info) < R_NDS32_DWARF2_OP1_RELA))) ++ { ++ /* Prevent unresolved addi instruction translate to addi45 or addi333. */ ++ return FALSE; ++ } ++ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17IFC_PCREL_RELA)) ++ { ++ off = calculate_offset (abfd, sec, pc_rel, isymbuf, symtab_hdr); ++ if (off >= ACCURATE_U9BIT_S1 || off <= 0) ++ return FALSE; ++ break; ++ } ++ } ++ ++ return TRUE; ++} ++ ++static void ++nds32_elf_write_16 (bfd *abfd ATTRIBUTE_UNUSED, bfd_byte *contents, ++ Elf_Internal_Rela *reloc, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend, ++ unsigned short insn16) ++{ ++ Elf_Internal_Rela *pc_rel; ++ bfd_vma offset; ++ ++ offset = reloc->r_offset; ++ bfd_putb16 (insn16, contents + offset); ++ /* Find the first relocation of the same relocation-type, ++ so we iteratie them forward. */ ++ pc_rel = reloc; ++ while ((pc_rel - 1) > internal_relocs && pc_rel[-1].r_offset == offset) ++ pc_rel--; ++ ++ for (; pc_rel < irelend && pc_rel->r_offset == offset; pc_rel++) ++ { ++ if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_15_PCREL_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17_PCREL_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PCREL_RELA) ++ { ++ pc_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_9_PCREL_RELA); ++ } ++ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_25_PLTREL) ++ pc_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_9_PLTREL); ++ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_20_RELA) ++ pc_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_5_RELA); ++ else if (ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA15S2_RELA ++ || ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_SDA17S2_RELA) ++ pc_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_SDA_FP7U2_RELA); ++ else if ((ELF32_R_TYPE (pc_rel->r_info) == R_NDS32_17IFC_PCREL_RELA)) ++ pc_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (pc_rel->r_info), R_NDS32_10IFCU_PCREL_RELA); ++ } ++} ++ ++/* Find a relocation of type specified by `reloc_type' ++ of the same r_offset with reloc. ++ If not found, return irelend. ++ ++ Assuming relocations are sorted by r_offset, ++ we find the relocation from `reloc' backward untill relocs, ++ or find it from `reloc' forward untill irelend. */ ++ ++static Elf_Internal_Rela * ++find_relocs_at_address (Elf_Internal_Rela *reloc, ++ Elf_Internal_Rela *relocs, ++ Elf_Internal_Rela *irelend, ++ enum elf_nds32_reloc_type reloc_type) ++{ ++ Elf_Internal_Rela *rel_t; ++ ++ /* Find backward. */ ++ for (rel_t = reloc; ++ rel_t >= relocs && rel_t->r_offset == reloc->r_offset; ++ rel_t--) ++ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type) ++ return rel_t; ++ ++ /* We didn't find it backward. Try find it forward. */ ++ for (rel_t = reloc; ++ rel_t < irelend && rel_t->r_offset == reloc->r_offset; ++ rel_t++) ++ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type) ++ return rel_t; ++ ++ return irelend; ++} ++ ++/* Find a relocation of specified type and offset. ++ `reloc' is just a refence point to find a relocation at specified offset. ++ If not found, return irelend. ++ ++ Assuming relocations are sorted by r_offset, ++ we find the relocation from `reloc' backward untill relocs, ++ or find it from `reloc' forward untill irelend. */ ++ ++static Elf_Internal_Rela * ++find_relocs_at_address_addr (Elf_Internal_Rela *reloc, ++ Elf_Internal_Rela *relocs, ++ Elf_Internal_Rela *irelend, ++ unsigned char reloc_type, ++ bfd_vma offset_p) ++{ ++ Elf_Internal_Rela *rel_t = NULL; ++ ++ /* First, we try to find a relocation of offset `offset_p', ++ and then we use find_relocs_at_address to find specific type. */ ++ ++ if (reloc->r_offset > offset_p) ++ { ++ /* Find backward. */ ++ for (rel_t = reloc; ++ rel_t >= relocs && rel_t->r_offset > offset_p; rel_t--) ++ /* Do nothing. */; ++ } ++ else if (reloc->r_offset < offset_p) ++ { ++ /* Find forward. */ ++ for (rel_t = reloc; ++ rel_t < irelend && rel_t->r_offset < offset_p; rel_t++) ++ /* Do nothing. */; ++ } ++ else ++ rel_t = reloc; ++ ++ /* Not found? */ ++ if (rel_t < relocs || rel_t == irelend || rel_t->r_offset != offset_p) ++ return irelend; ++ ++ return find_relocs_at_address (rel_t, relocs, irelend, reloc_type); ++} ++ ++static bfd_boolean ++nds32_elf_check_dup_relocs (Elf_Internal_Rela *reloc, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend, ++ unsigned char reloc_type) ++{ ++ Elf_Internal_Rela *rel_t; ++ ++ for (rel_t = reloc; ++ rel_t >= internal_relocs && rel_t->r_offset == reloc->r_offset; ++ rel_t--) ++ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type) ++ { ++ if (ELF32_R_SYM (rel_t->r_info) == ELF32_R_SYM (reloc->r_info) ++ && rel_t->r_addend == reloc->r_addend) ++ continue; ++ return TRUE; ++ } ++ ++ for (rel_t = reloc; rel_t < irelend && rel_t->r_offset == reloc->r_offset; ++ rel_t++) ++ if (ELF32_R_TYPE (rel_t->r_info) == reloc_type) ++ { ++ if (ELF32_R_SYM (rel_t->r_info) == ELF32_R_SYM (reloc->r_info) ++ && rel_t->r_addend == reloc->r_addend) ++ continue; ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++typedef struct nds32_elf_blank nds32_elf_blank_t; ++struct nds32_elf_blank ++{ ++ /* Where the blank begins. */ ++ bfd_vma offset; ++ /* The size of the blank. */ ++ bfd_vma size; ++ /* The accumulative size before this blank. */ ++ bfd_vma total_size; ++ nds32_elf_blank_t *next; ++ nds32_elf_blank_t *prev; ++}; ++ ++static nds32_elf_blank_t *blank_free_list = NULL; ++ ++static nds32_elf_blank_t * ++create_nds32_elf_blank (bfd_vma offset_p, bfd_vma size_p) ++{ ++ nds32_elf_blank_t *blank_t; ++ ++ if (blank_free_list) ++ { ++ blank_t = blank_free_list; ++ blank_free_list = blank_free_list->next; ++ } ++ else ++ blank_t = bfd_malloc (sizeof (nds32_elf_blank_t)); ++ ++ if (blank_t == NULL) ++ return NULL; ++ ++ blank_t->offset = offset_p; ++ blank_t->size = size_p; ++ blank_t->total_size = 0; ++ blank_t->next = NULL; ++ blank_t->prev = NULL; ++ ++ return blank_t; ++} ++ ++static void ++remove_nds32_elf_blank (nds32_elf_blank_t *blank_p) ++{ ++ if (blank_free_list) ++ { ++ blank_free_list->prev = blank_p; ++ blank_p->next = blank_free_list; ++ } ++ else ++ blank_p->next = NULL; ++ ++ blank_p->prev = NULL; ++ blank_free_list = blank_p; ++} ++ ++static void ++clean_nds32_elf_blank (void) ++{ ++ nds32_elf_blank_t *blank_t; ++ ++ while (blank_free_list) ++ { ++ blank_t = blank_free_list; ++ blank_free_list = blank_free_list->next; ++ free (blank_t); ++ } ++} ++ ++static nds32_elf_blank_t * ++search_nds32_elf_blank (nds32_elf_blank_t *blank_p, bfd_vma addr) ++{ ++ nds32_elf_blank_t *blank_t; ++ ++ if (!blank_p) ++ return NULL; ++ blank_t = blank_p; ++ ++ while (blank_t && addr < blank_t->offset) ++ blank_t = blank_t->prev; ++ while (blank_t && blank_t->next && addr >= blank_t->next->offset) ++ blank_t = blank_t->next; ++ ++ return blank_t; ++} ++ ++static bfd_vma ++get_nds32_elf_blank_total (nds32_elf_blank_t **blank_p, bfd_vma addr, ++ int overwrite) ++{ ++ nds32_elf_blank_t *blank_t; ++ ++ blank_t = search_nds32_elf_blank (*blank_p, addr); ++ if (!blank_t) ++ return 0; ++ ++ if (overwrite) ++ *blank_p = blank_t; ++ ++ if (addr < blank_t->offset + blank_t->size) ++ return blank_t->total_size + (addr - blank_t->offset); ++ else ++ return blank_t->total_size + blank_t->size; ++} ++ ++static bfd_boolean ++insert_nds32_elf_blank (nds32_elf_blank_t **blank_p, bfd_vma addr, bfd_vma len) ++{ ++ nds32_elf_blank_t *blank_t, *blank_t2; ++ ++ if (!*blank_p) ++ { ++ *blank_p = create_nds32_elf_blank (addr, len); ++ return *blank_p ? TRUE : FALSE; ++ } ++ ++ blank_t = search_nds32_elf_blank (*blank_p, addr); ++ ++ if (blank_t == NULL) ++ { ++ blank_t = create_nds32_elf_blank (addr, len); ++ if (!blank_t) ++ return FALSE; ++ while ((*blank_p)->prev != NULL) ++ *blank_p = (*blank_p)->prev; ++ blank_t->next = *blank_p; ++ (*blank_p)->prev = blank_t; ++ (*blank_p) = blank_t; ++ return TRUE; ++ } ++ ++ if (addr < blank_t->offset + blank_t->size ++ && ((addr + len) > (blank_t->offset + blank_t->size))) ++ blank_t->size = addr + len - blank_t->offset - blank_t->size; ++ else ++ { ++ blank_t2 = create_nds32_elf_blank (addr, len); ++ if (!blank_t2) ++ return FALSE; ++ if (blank_t->next) ++ { ++ blank_t->next->prev = blank_t2; ++ blank_t2->next = blank_t->next; ++ } ++ blank_t2->prev = blank_t; ++ blank_t->next = blank_t2; ++ *blank_p = blank_t2; ++ } ++ ++ return TRUE; ++} ++ ++static bfd_boolean ++insert_nds32_elf_blank_recalc_total (nds32_elf_blank_t **blank_p, bfd_vma addr, ++ bfd_vma len) ++{ ++ nds32_elf_blank_t *blank_t; ++ ++ if (!insert_nds32_elf_blank (blank_p, addr, len)) ++ return FALSE; ++ ++ blank_t = *blank_p; ++ ++ if (!blank_t->prev) ++ { ++ blank_t->total_size = 0; ++ blank_t = blank_t->next; ++ } ++ ++ while (blank_t) ++ { ++ blank_t->total_size = blank_t->prev->total_size + blank_t->prev->size; ++ blank_t = blank_t->next; ++ } ++ ++ return TRUE; ++} ++ ++static void ++calc_nds32_blank_total (nds32_elf_blank_t *blank_p) ++{ ++ nds32_elf_blank_t *blank_t; ++ bfd_vma total_size = 0; ++ ++ if (!blank_p) ++ return; ++ ++ blank_t = blank_p; ++ while (blank_t->prev) ++ blank_t = blank_t->prev; ++ while (blank_t) ++ { ++ blank_t->total_size = total_size; ++ total_size += blank_t->size; ++ blank_t = blank_t->next; ++ } ++} ++ ++static bfd_boolean ++nds32_elf_relax_delete_blanks (bfd *abfd, asection *sec, ++ nds32_elf_blank_t *blank_p) ++{ ++ Elf_Internal_Shdr *symtab_hdr; /* Symbol table header of this bfd. */ ++ Elf_Internal_Sym *isym = NULL; /* Symbol table of this bfd. */ ++ Elf_Internal_Sym *isymend; /* Symbol entry iterator. */ ++ unsigned int sec_shndx; /* The section the be relaxed. */ ++ bfd_byte *contents; /* Contents data of iterating section. */ ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *irelend; ++ struct elf_link_hash_entry **sym_hashes; ++ struct elf_link_hash_entry **end_hashes; ++ unsigned int symcount; ++ asection *sect; ++ nds32_elf_blank_t *blank_t; ++ nds32_elf_blank_t *blank_t2; ++ nds32_elf_blank_t *blank_head; ++ ++ blank_head = blank_t = blank_p; ++ while (blank_head->prev != NULL) ++ blank_head = blank_head->prev; ++ while (blank_t->next != NULL) ++ blank_t = blank_t->next; ++ ++ if (blank_t->offset + blank_t->size <= sec->size) ++ { ++ blank_t->next = create_nds32_elf_blank (sec->size + 4, 0); ++ blank_t->next->prev = blank_t; ++ } ++ if (blank_head->offset > 0) ++ { ++ blank_head->prev = create_nds32_elf_blank (0, 0); ++ blank_head->prev->next = blank_head; ++ blank_head = blank_head->prev; ++ } ++ ++ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); ++ ++ /* The deletion must stop at the next ALIGN reloc for an alignment ++ power larger than the number of bytes we are deleting. */ ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (!nds32_get_local_syms (abfd, sec, &isym)) ++ return FALSE; ++ ++ if (isym == NULL) ++ { ++ isym = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ symtab_hdr->sh_info, 0, NULL, NULL, NULL); ++ symtab_hdr->contents = (bfd_byte *) isym; ++ } ++ ++ if (isym == NULL || symtab_hdr->sh_info == 0) ++ return FALSE; ++ ++ blank_t = blank_head; ++ calc_nds32_blank_total (blank_head); ++ ++ for (sect = abfd->sections; sect != NULL; sect = sect->next) ++ { ++ /* Adjust all the relocs. */ ++ ++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sect, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sect->reloc_count; ++ ++ blank_t = blank_head; ++ blank_t2 = blank_head; ++ ++ if (!(sect->flags & SEC_RELOC)) ++ continue; ++ ++ nds32_get_section_contents (abfd, sect, &contents, TRUE); ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ bfd_vma raddr; ++ ++ if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_DIFF8 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_DIFF32 ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx) ++ { ++ unsigned long val = 0; ++ unsigned long mask; ++ long before, between; ++ long offset; ++ ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ case R_NDS32_DIFF8: ++ offset = bfd_get_8 (abfd, contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF16: ++ offset = bfd_get_16 (abfd, contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF32: ++ val = bfd_get_32 (abfd, contents + irel->r_offset); ++ /* Get the signed bit and mask for the high part. The ++ gcc will alarm when right shift 32-bit since the ++ type size of long may be 32-bit. */ ++ mask = 0 - (val >> 31); ++ if (mask) ++ offset = (val | (mask - 0xffffffff)); ++ else ++ offset = val; ++ break; ++ default: ++ BFD_ASSERT (0); ++ } ++ ++ /* DIFF value ++ 0 |encoded in location| ++ |------------|-------------------|--------- ++ sym+off(addend) ++ -- before ---| ***************** ++ --------------------- between ---| ++ ++ We only care how much data are relax between DIFF, marked as ***. */ ++ ++ before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0); ++ between = get_nds32_elf_blank_total (&blank_t, irel->r_addend + offset, 0); ++ if (between == before) ++ goto done_adjust_diff; ++ ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ case R_NDS32_DIFF8: ++ bfd_put_8 (abfd, offset - (between - before), contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF16: ++ bfd_put_16 (abfd, offset - (between - before), contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF32: ++ bfd_put_32 (abfd, offset - (between - before), contents + irel->r_offset); ++ break; ++ } ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_DIFF_ULEB128 ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx) ++ { ++ bfd_vma val = 0; ++ unsigned int len = 0; ++ unsigned long before, between; ++ bfd_byte *endp, *p; ++ ++ val = read_unsigned_leb128 (abfd, contents + irel->r_offset, &len); ++ ++ before = get_nds32_elf_blank_total (&blank_t, irel->r_addend, 0); ++ between = get_nds32_elf_blank_total (&blank_t, irel->r_addend + val, 0); ++ if (between == before) ++ goto done_adjust_diff; ++ ++ p = contents + irel->r_offset; ++ endp = p + len -1; ++ memset (p, 0x80, len); ++ *(endp) = 0; ++ p = write_uleb128 (p, val - (between - before)) - 1; ++ if (p < endp) ++ *p |= 0x80; ++ } ++done_adjust_diff: ++ ++ if (sec == sect) ++ { ++ raddr = irel->r_offset; ++ irel->r_offset -= get_nds32_elf_blank_total (&blank_t2, irel->r_offset, 1); ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE) ++ continue; ++ if (blank_t2 && blank_t2->next ++ && (blank_t2->offset > raddr || blank_t2->next->offset <= raddr)) ++ (*_bfd_error_handler) (_("%B: %s\n"), abfd, ++ "Error: search_nds32_elf_blank reports wrong node"); ++ ++ /* Mark reloc in deleted portion as NONE. ++ For some relocs like R_NDS32_LABEL that doesn't modify the ++ content in the section. R_NDS32_LABEL doesn't belong to the ++ instruction in the section, so we should preserve it. */ ++ if (raddr >= blank_t2->offset ++ && raddr < blank_t2->offset + blank_t2->size ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_BEGIN ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_REGION_END ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_SUBTRAHEND ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_MINUEND) ++ { ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), ++ R_NDS32_NONE); ++ continue; ++ } ++ } ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY) ++ continue; ++ ++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx ++ && ELF_ST_TYPE (isym[ELF32_R_SYM (irel->r_info)].st_info) == STT_SECTION) ++ { ++ if (irel->r_addend <= sec->size) ++ irel->r_addend -= ++ get_nds32_elf_blank_total (&blank_t, irel->r_addend, 1); ++ } ++ } ++ } ++ ++ /* Adjust the local symbols defined in this section. */ ++ blank_t = blank_head; ++ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) ++ { ++ if (isym->st_shndx == sec_shndx) ++ { ++ if (isym->st_value <= sec->size) ++ { ++ bfd_vma ahead; ++ bfd_vma orig_addr = isym->st_value; ++ ++ ahead = get_nds32_elf_blank_total (&blank_t, isym->st_value, 1); ++ isym->st_value -= ahead; ++ ++ /* Adjust function size. */ ++ if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC && isym->st_size > 0) ++ isym->st_size -= get_nds32_elf_blank_total ++ (&blank_t, orig_addr + isym->st_size, 0) - ahead; ++ } ++ } ++ } ++ ++ /* Now adjust the global symbols defined in this section. */ ++ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) ++ - symtab_hdr->sh_info); ++ sym_hashes = elf_sym_hashes (abfd); ++ end_hashes = sym_hashes + symcount; ++ blank_t = blank_head; ++ for (; sym_hashes < end_hashes; sym_hashes++) ++ { ++ struct elf_link_hash_entry *sym_hash = *sym_hashes; ++ ++ if ((sym_hash->root.type == bfd_link_hash_defined ++ || sym_hash->root.type == bfd_link_hash_defweak) ++ && sym_hash->root.u.def.section == sec) ++ { ++ if (sym_hash->root.u.def.value <= sec->size) ++ { ++ bfd_vma ahead; ++ bfd_vma orig_addr = sym_hash->root.u.def.value; ++ ++ ahead = get_nds32_elf_blank_total (&blank_t, sym_hash->root.u.def.value, 1); ++ sym_hash->root.u.def.value -= ahead; ++ ++ /* Adjust function size. */ ++ if (sym_hash->type == STT_FUNC) ++ sym_hash->size -= get_nds32_elf_blank_total ++ (&blank_t, orig_addr + sym_hash->size, 0) - ahead; ++ ++ } ++ } ++ } ++ ++ contents = elf_section_data (sec)->this_hdr.contents; ++ blank_t = blank_head; ++ while (blank_t->next) ++ { ++ /* Actually delete the bytes. */ ++ ++ /* If current blank is the last blank overlap with current section, ++ go to finish process. */ ++ if (sec->size <= (blank_t->next->offset)) ++ break; ++ ++ memmove (contents + blank_t->offset - blank_t->total_size, ++ contents + blank_t->offset + blank_t->size, ++ blank_t->next->offset - (blank_t->offset + blank_t->size)); ++ ++ blank_t = blank_t->next; ++ } ++ ++ if (sec->size > (blank_t->offset + blank_t->size)) ++ { ++ /* There are remaining code between blank and section boundary. ++ Move the remaining code to appropriate location. */ ++ memmove (contents + blank_t->offset - blank_t->total_size, ++ contents + blank_t->offset + blank_t->size, ++ sec->size - (blank_t->offset + blank_t->size)); ++ sec->size -= blank_t->total_size + blank_t->size; ++ } ++ else ++ /* This blank is not entirely included in the section, ++ reduce the section size by only part of the blank size. */ ++ sec->size -= blank_t->total_size + (sec->size - blank_t->offset); ++ ++ while (blank_head) ++ { ++ blank_t = blank_head; ++ blank_head = blank_head->next; ++ remove_nds32_elf_blank (blank_t); ++ } ++ ++ return TRUE; ++} ++ ++/* Get the contents of a section. */ ++ ++static int ++nds32_get_section_contents (bfd *abfd, asection *sec, ++ bfd_byte **contents_p, bfd_boolean cache) ++{ ++ /* Get the section contents. */ ++ if (elf_section_data (sec)->this_hdr.contents != NULL) ++ *contents_p = elf_section_data (sec)->this_hdr.contents; ++ else ++ { ++ if (!bfd_malloc_and_get_section (abfd, sec, contents_p)) ++ return FALSE; ++ if (cache) ++ elf_section_data (sec)->this_hdr.contents = *contents_p; ++ } ++ ++ return TRUE; ++} ++ ++/* Get the contents of the internal symbol of abfd. */ ++ ++static int ++nds32_get_local_syms (bfd *abfd, asection *sec ATTRIBUTE_UNUSED, ++ Elf_Internal_Sym **isymbuf_p) ++{ ++ Elf_Internal_Shdr *symtab_hdr; ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ /* Read this BFD's local symbols if we haven't done so already. */ ++ if (*isymbuf_p == NULL && symtab_hdr->sh_info != 0) ++ { ++ *isymbuf_p = (Elf_Internal_Sym *) symtab_hdr->contents; ++ if (*isymbuf_p == NULL) ++ { ++ *isymbuf_p = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ symtab_hdr->sh_info, 0, ++ NULL, NULL, NULL); ++ if (*isymbuf_p == NULL) ++ return FALSE; ++ } ++ } ++ symtab_hdr->contents = (bfd_byte *) (*isymbuf_p); ++ ++ return TRUE; ++} ++ ++/* Range of small data. */ ++static bfd_vma sdata_range[2][2]; ++static bfd_vma const sdata_init_range[2] = ++{ ACCURATE_12BIT_S1, ACCURATE_19BIT }; ++ ++static int ++nds32_elf_insn_size (bfd *abfd ATTRIBUTE_UNUSED, ++ bfd_byte *contents, bfd_vma addr) ++{ ++ unsigned long insn = bfd_getb32 (contents + addr); ++ ++ if (insn & 0x80000000) ++ return 2; ++ ++ return 4; ++} ++ ++/* Set the gp relax range. We have to measure the safe range ++ to do gp relaxation. */ ++ ++static void ++relax_range_measurement (bfd *abfd) ++{ ++ asection *sec_f, *sec_b; ++ /* For upper bound. */ ++ bfd_vma maxpgsz = get_elf_backend_data (abfd)->maxpagesize; ++ bfd_vma align; ++ static int decide_relax_range = 0; ++ int i; ++ int range_number = ARRAY_SIZE (sdata_init_range); ++ ++ if (decide_relax_range) ++ return; ++ decide_relax_range = 1; ++ ++ if (sda_rela_sec == NULL) ++ { ++ /* Since there is no data sections, we assume the range is page size. */ ++ for (i = 0; i < range_number; i++) ++ { ++ sdata_range[i][0] = sdata_init_range[i] - 0x1000; ++ sdata_range[i][1] = sdata_init_range[i] - 0x1000; ++ } ++ return; ++ } ++ ++ /* Get the biggest alignment power after the gp located section. */ ++ sec_f = sda_rela_sec->output_section; ++ sec_b = sec_f->next; ++ align = 0; ++ while (sec_b != NULL) ++ { ++ if ((unsigned)(1 << sec_b->alignment_power) > align) ++ align = (1 << sec_b->alignment_power); ++ sec_b = sec_b->next; ++ } ++ ++ /* I guess we can not determine the section before ++ gp located section, so we assume the align is max page size. */ ++ for (i = 0; i < range_number; i++) ++ { ++ sdata_range[i][1] = sdata_init_range[i] - align; ++ BFD_ASSERT (sdata_range[i][1] <= sdata_init_range[i]); ++ sdata_range[i][0] = sdata_init_range[i] - maxpgsz; ++ BFD_ASSERT (sdata_range[i][0] <= sdata_init_range[i]); ++ } ++} ++ ++/* These are macros used to check flags encoded in r_addend. ++ They are only used by nds32_elf_relax_section (). */ ++#define GET_SEQ_LEN(addend) ((addend) & 0x000000ff) ++#define IS_1ST_CONVERT(addend) ((addend) & 0x80000000) ++#define IS_OPTIMIZE(addend) ((addend) & 0x40000000) ++#define IS_16BIT_ON(addend) ((addend) & 0x20000000) ++ ++/* Relax LONGCALL1 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longcall1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 3 variations for LONGCALL1 ++ case 4-4-2; 16-bit on, optimize off or optimize for space ++ sethi ta, hi20(symbol) ; LONGCALL1/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jral5 ta ; ++ ++ case 4-4-4; 16-bit off, optimize don't care ++ sethi ta, hi20(symbol) ; LONGCALL1/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jral ta ; ++ ++ case 4-4-4; 16-bit on, optimize for speed ++ sethi ta, hi20(symbol) ; LONGCALL1/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jral ta ; ++ Check code for -mlong-calls output. */ ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ bfd_vma laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ uint32_t insn; ++ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend; ++ bfd_signed_vma foff; ++ uint16_t insn16; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ ++ hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_HI20_RELA, laddr); ++ lo_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_LO12S0_ORI_RELA, ++ laddr + 4); ++ ++ if (hi_irelfn == irelend || lo_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL1 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); ++ ++ /* This condition only happened when symbol is undefined. */ ++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 ++ || foff >= CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ /* Relax to: jal symbol; 25_PCREL */ ++ /* For simplicity of coding, we are going to modify the section ++ contents, the section relocs, and the BFD symbol table. We ++ must tell the rest of the code not to free up this ++ information. It would be possible to instead create a table ++ of changes which have to be made, as is done in coff-mips.c; ++ that would be more work, but would require less memory when ++ the linker is run. */ ++ ++ /* Replace the long call with a jal. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), ++ R_NDS32_25_PCREL_RELA); ++ irel->r_addend = hi_irelfn->r_addend; ++ ++ /* We don't resolve this here but resolve it in relocate_section. */ ++ insn = INSN_JAL; ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ hi_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE); ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE); ++ *insn_len = 4; ++ ++ if (seq_len & 0x2) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len); ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_INSN16); ++ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ *insn_len += 2; ++ } ++ return TRUE; ++} ++ ++#define CONVERT_CONDITION_CALL(insn) (((insn) & 0xffff0000) ^ 0x90000) ++/* Relax LONGCALL2 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longcall2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* bltz rt, .L1 ; LONGCALL2 ++ jal symbol ; 25_PCREL ++ .L1: */ ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ bfd_vma laddr; ++ uint32_t insn; ++ Elf_Internal_Rela *i1_irelfn, *cond_irelfn, *irelend; ++ bfd_signed_vma foff; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ i1_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_25_PCREL_RELA, laddr + 4); ++ ++ if (i1_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL2 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ insn = bfd_getb32 (contents + laddr); ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, i1_irelfn, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 ++ || foff >= CONSERVATIVE_16BIT_S1) ++ return FALSE; ++ ++ /* Relax to bgezal rt, label ; 17_PCREL ++ or bltzal rt, label ; 17_PCREL */ ++ ++ /* Convert to complimentary conditional call. */ ++ insn = CONVERT_CONDITION_CALL (insn); ++ ++ /* For simplicity of coding, we are going to modify the section ++ contents, the section relocs, and the BFD symbol table. We ++ must tell the rest of the code not to free up this ++ information. It would be possible to instead create a table ++ of changes which have to be made, as is done in coff-mips.c; ++ that would be more work, but would require less memory when ++ the linker is run. */ ++ ++ /* Clean unnessary relocations. */ ++ i1_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (i1_irelfn->r_info), R_NDS32_NONE); ++ cond_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_17_PCREL_RELA, laddr); ++ if (cond_irelfn != irelend) ++ cond_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irelfn->r_info), R_NDS32_NONE); ++ ++ /* Replace the long call with a bgezal. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (i1_irelfn->r_info), ++ R_NDS32_17_PCREL_RELA); ++ irel->r_addend = i1_irelfn->r_addend; ++ ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ *insn_len = 4; ++ return TRUE; ++} ++ ++/* Relax LONGCALL3 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longcall3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 3 variations for LONGCALL3 ++ case 4-4-4-2; 16-bit on, optimize off or optimize for space ++ bltz rt, $1 ; LONGCALL3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jral5 ta ; ++ $1 ++ ++ case 4-4-4-4; 16-bit off, optimize don't care ++ bltz rt, $1 ; LONGCALL3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jral ta ; ++ $1 ++ ++ case 4-4-4-4; 16-bit on, optimize for speed ++ bltz rt, $1 ; LONGCALL3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jral ta ; ++ $1 */ ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ bfd_vma laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ uint32_t insn; ++ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend; ++ bfd_signed_vma foff; ++ uint16_t insn16; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ ++ hi_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_HI20_RELA, laddr + 4); ++ lo_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_LO12S0_ORI_RELA, laddr + 8); ++ ++ if (hi_irelfn == irelend || lo_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL3 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 ++ || foff >= CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ insn = bfd_getb32 (contents + laddr); ++ if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) ++ { ++ /* Relax to bgezal rt, label ; 17_PCREL ++ or bltzal rt, label ; 17_PCREL */ ++ ++ /* Convert to complimentary conditional call. */ ++ insn = CONVERT_CONDITION_CALL (insn); ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ *insn_len = 4; ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE); ++ hi_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE); ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE); ++ ++ cond_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_17_PCREL_RELA, laddr); ++ if (cond_irelfn != irelend) ++ { ++ cond_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), ++ R_NDS32_17_PCREL_RELA); ++ cond_irelfn->r_addend = hi_irelfn->r_addend; ++ } ++ ++ if (seq_len & 0x2) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len); ++ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), ++ R_NDS32_INSN16); ++ hi_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ insn_len += 2; ++ } ++ } ++ else if (foff >= -CONSERVATIVE_24BIT_S1 && foff < CONSERVATIVE_24BIT_S1) ++ { ++ /* Relax to the following instruction sequence ++ bltz rt, $1 ; LONGCALL2 ++ jal symbol ; 25_PCREL ++ $1 */ ++ *insn_len = 8; ++ insn = INSN_JAL; ++ bfd_putb32 (insn, contents + hi_irelfn->r_offset); ++ ++ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), ++ R_NDS32_25_PCREL_RELA); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_LONGCALL2); ++ ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE); ++ ++ if (seq_len & 0x2) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len); ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_INSN16); ++ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ insn_len += 2; ++ } ++ } ++ return TRUE; ++} ++ ++/* Relax LONGJUMP1 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump1 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 3 variations for LONGJUMP1 ++ case 4-4-2; 16-bit bit on, optimize off or optimize for space ++ sethi ta, hi20(symbol) ; LONGJUMP1/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr5 ta ; ++ ++ case 4-4-4; 16-bit off, optimize don't care ++ sethi ta, hi20(symbol) ; LONGJUMP1/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr ta ; ++ ++ case 4-4-4; 16-bit on, optimize for speed ++ sethi ta, hi20(symbol) ; LONGJUMP1/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr ta ; */ ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ bfd_vma laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ int insn16_on; /* 16-bit on/off. */ ++ uint32_t insn; ++ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *irelend; ++ bfd_signed_vma foff; ++ uint16_t insn16; ++ unsigned long reloc; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ insn16_on = IS_16BIT_ON (irel->r_addend); ++ ++ hi_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_HI20_RELA, laddr); ++ lo_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_LO12S0_ORI_RELA, laddr + 4); ++ if (hi_irelfn == irelend || lo_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP1 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff >= CONSERVATIVE_24BIT_S1 ++ || foff < -CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ if (insn16_on && foff >= -ACCURATE_8BIT_S1 ++ && foff < ACCURATE_8BIT_S1 && (seq_len & 0x2)) ++ { ++ /* j8 label */ ++ /* 16-bit on, but not optimized for speed. */ ++ reloc = R_NDS32_9_PCREL_RELA; ++ insn16 = INSN_J8; ++ bfd_putb16 (insn16, contents + irel->r_offset); ++ *insn_len = 2; ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ } ++ else ++ { ++ /* j label */ ++ reloc = R_NDS32_25_PCREL_RELA; ++ insn = INSN_J; ++ bfd_putb32 (insn, contents + irel->r_offset); ++ *insn_len = 4; ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_INSN16); ++ irel->r_addend = 0; ++ } ++ ++ hi_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), reloc); ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), R_NDS32_NONE); ++ ++ if ((seq_len & 0x2) && ((*insn_len & 2) == 0)) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len); ++ lo_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), ++ R_NDS32_INSN16); ++ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ *insn_len += 2; ++ } ++ return TRUE; ++} ++ ++/* Revert condition branch. This function does not check if the input ++ instruction is condition branch or not. */ ++ ++static void ++nds32_elf_convert_branch (uint16_t insn16, uint32_t insn, ++ uint16_t *re_insn16, uint32_t *re_insn) ++{ ++ uint32_t comp_insn = 0; ++ uint16_t comp_insn16 = 0; ++ ++ if (insn) ++ { ++ if (N32_OP6 (insn) == N32_OP6_BR1) ++ { ++ /* beqs label. */ ++ comp_insn = (insn ^ 0x4000) & 0xffffc000; ++ if (N32_IS_RT3 (insn) && N32_RA5 (insn) == REG_R5) ++ { ++ /* Insn can be contracted to 16-bit implied r5. */ ++ comp_insn16 = ++ (comp_insn & 0x4000) ? INSN_BNES38 : INSN_BEQS38; ++ comp_insn16 |= (N32_RT5 (insn) & 0x7) << 8; ++ } ++ } ++ else if (N32_OP6 (insn) == N32_OP6_BR3) ++ { ++ /* bnec $ta, imm11, label. */ ++ comp_insn = (insn ^ 0x80000) & 0xffffff00; ++ } ++ else ++ { ++ comp_insn = (insn ^ 0x10000) & 0xffffc000; ++ if (N32_BR2_SUB (insn) == N32_BR2_BEQZ ++ || N32_BR2_SUB (insn) == N32_BR2_BNEZ) ++ { ++ if (N32_IS_RT3 (insn)) ++ { ++ /* Insn can be contracted to 16-bit. */ ++ comp_insn16 = ++ (comp_insn & 0x10000) ? INSN_BNEZ38 : INSN_BEQZ38; ++ comp_insn16 |= (N32_RT5 (insn) & 0x7) << 8; ++ } ++ else if (N32_RT5 (insn) == REG_R15) ++ { ++ /* Insn can be contracted to 16-bit. */ ++ comp_insn16 = ++ (comp_insn & 0x10000) ? INSN_BNES38 : INSN_BEQS38; ++ } ++ } ++ } ++ } ++ else ++ { ++ switch ((insn16 & 0xf000) >> 12) ++ { ++ case 0xc: ++ /* beqz38 or bnez38 */ ++ comp_insn16 = (insn16 ^ 0x0800) & 0xff00; ++ comp_insn = (comp_insn16 & 0x0800) ? INSN_BNEZ : INSN_BEQZ; ++ comp_insn |= ((comp_insn16 & 0x0700) >> 8) << 20; ++ break; ++ ++ case 0xd: ++ /* beqs38 or bnes38 */ ++ comp_insn16 = (insn16 ^ 0x0800) & 0xff00; ++ comp_insn = (comp_insn16 & 0x0800) ? INSN_BNE : INSN_BEQ; ++ comp_insn |= (((comp_insn16 & 0x0700) >> 8) << 20) ++ | (REG_R5 << 15); ++ break; ++ ++ case 0xe: ++ /* beqzS8 or bnezS8 */ ++ comp_insn16 = (insn16 ^ 0x0100) & 0xff00; ++ comp_insn = (comp_insn16 & 0x0100) ? INSN_BNEZ : INSN_BEQZ; ++ comp_insn |= REG_R15 << 20; ++ break; ++ ++ default: ++ break; ++ } ++ } ++ if (comp_insn && re_insn) ++ *re_insn = comp_insn; ++ if (comp_insn16 && re_insn16) ++ *re_insn16 = comp_insn16; ++} ++ ++/* Relax LONGJUMP2 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump2 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 3 variations for LONGJUMP2 ++ case 2-4; 1st insn convertible, 16-bit on, ++ optimize off or optimize for space ++ bnes38 rt, ra, $1 ; LONGJUMP2 ++ j label ; 25_PCREL ++ $1: ++ ++ case 4-4; 1st insn not convertible ++ bne rt, ra, $1 ; LONGJUMP2 ++ j label ; 25_PCREL ++ $1: ++ ++ case 4-4; 1st insn convertible, 16-bit on, optimize for speed ++ bne rt, ra, $1 ; LONGJUMP2 ++ j label ; 25_PCREL ++ $1: */ ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ bfd_vma laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ Elf_Internal_Rela *i2_irelfn, *cond_irelfn, *irelend; ++ int first_size; ++ unsigned int i; ++ bfd_signed_vma foff; ++ uint32_t insn, re_insn = 0; ++ uint16_t insn16, re_insn16 = 0; ++ unsigned long reloc, cond_reloc; ++ ++ enum elf_nds32_reloc_type checked_types[] = ++ { R_NDS32_15_PCREL_RELA, R_NDS32_9_PCREL_RELA }; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ first_size = (seq_len == 6) ? 2 : 4; ++ ++ i2_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, ++ irelend, R_NDS32_25_PCREL_RELA, ++ laddr + first_size); ++ ++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) ++ { ++ cond_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ checked_types[i], laddr); ++ if (cond_irelfn != irelend) ++ break; ++ } ++ ++ if (i2_irelfn == irelend || cond_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP2 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = ++ calculate_offset (abfd, sec, i2_irelfn, isymbuf, symtab_hdr); ++ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 ++ || foff >= CONSERVATIVE_16BIT_S1) ++ return FALSE; ++ ++ /* Get the all corresponding instructions. */ ++ if (first_size == 4) ++ { ++ insn = bfd_getb32 (contents + laddr); ++ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn); ++ } ++ else ++ { ++ insn16 = bfd_getb16 (contents + laddr); ++ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn); ++ } ++ ++ if (re_insn16 && foff >= -(ACCURATE_8BIT_S1 - first_size) ++ && foff < ACCURATE_8BIT_S1 - first_size) ++ { ++ if (first_size == 4) ++ { ++ /* Don't convert it to 16-bit now, keep this as relaxable for ++ ``label reloc; INSN16''. */ ++ ++ /* Save comp_insn32 to buffer. */ ++ bfd_putb32 (re_insn, contents + irel->r_offset); ++ *insn_len = 4; ++ reloc = (N32_OP6 (re_insn) == N32_OP6_BR1) ? ++ R_NDS32_15_PCREL_RELA : R_NDS32_17_PCREL_RELA; ++ cond_reloc = R_NDS32_INSN16; ++ } ++ else ++ { ++ bfd_putb16 (re_insn16, contents + irel->r_offset); ++ *insn_len = 2; ++ reloc = R_NDS32_9_PCREL_RELA; ++ cond_reloc = R_NDS32_NONE; ++ } ++ } ++ else if (N32_OP6 (re_insn) == N32_OP6_BR1 ++ && (foff >= -(ACCURATE_14BIT_S1 - first_size) ++ && foff < ACCURATE_14BIT_S1 - first_size)) ++ { ++ /* beqs label ; 15_PCREL */ ++ bfd_putb32 (re_insn, contents + irel->r_offset); ++ *insn_len = 4; ++ reloc = R_NDS32_15_PCREL_RELA; ++ cond_reloc = R_NDS32_NONE; ++ } ++ else if (N32_OP6 (re_insn) == N32_OP6_BR2 ++ && foff >= -CONSERVATIVE_16BIT_S1 ++ && foff < CONSERVATIVE_16BIT_S1) ++ { ++ /* beqz label ; 17_PCREL */ ++ bfd_putb32 (re_insn, contents + irel->r_offset); ++ *insn_len = 4; ++ reloc = R_NDS32_17_PCREL_RELA; ++ cond_reloc = R_NDS32_NONE; ++ } ++ else ++ return FALSE; ++ ++ /* Set all relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (i2_irelfn->r_info), reloc); ++ irel->r_addend = i2_irelfn->r_addend; ++ ++ cond_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irelfn->r_info), ++ cond_reloc); ++ cond_irelfn->r_addend = 0; ++ ++ if ((seq_len ^ *insn_len ) & 0x2) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + irel->r_offset + 4); ++ i2_irelfn->r_offset = 4; ++ i2_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (i2_irelfn->r_info), ++ R_NDS32_INSN16); ++ i2_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ *insn_len += 2; ++ } ++ else ++ i2_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (i2_irelfn->r_info), ++ R_NDS32_NONE); ++ return TRUE; ++} ++ ++/* Relax LONGJUMP3 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump3 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 5 variations for LONGJUMP3 ++ case 1: 2-4-4-2; 1st insn convertible, 16-bit on, ++ optimize off or optimize for space ++ bnes38 rt, ra, $1 ; LONGJUMP3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr5 ta ; ++ $1: ; ++ ++ case 2: 2-4-4-2; 1st insn convertible, 16-bit on, optimize for speed ++ bnes38 rt, ra, $1 ; LONGJUMP3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr5 ta ; ++ $1: ; LABEL ++ ++ case 3: 4-4-4-2; 1st insn not convertible, 16-bit on, ++ optimize off or optimize for space ++ bne rt, ra, $1 ; LONGJUMP3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr5 ta ; ++ $1: ; ++ ++ case 4: 4-4-4-4; 1st insn don't care, 16-bit off, optimize don't care ++ 16-bit off if no INSN16 ++ bne rt, ra, $1 ; LONGJUMP3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr ta ; ++ $1: ; ++ ++ case 5: 4-4-4-4; 1st insn not convertible, 16-bit on, optimize for speed ++ 16-bit off if no INSN16 ++ bne rt, ra, $1 ; LONGJUMP3 ++ sethi ta, hi20(symbol) ; HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0 ++ jr ta ; ++ $1: ; LABEL */ ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ enum elf_nds32_reloc_type checked_types[] = ++ { R_NDS32_15_PCREL_RELA, R_NDS32_9_PCREL_RELA }; ++ ++ int reloc_off = 0, cond_removed = 0, convertible; ++ bfd_vma laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ Elf_Internal_Rela *hi_irelfn, *lo_irelfn, *cond_irelfn, *irelend; ++ int first_size; ++ unsigned int i; ++ bfd_signed_vma foff; ++ uint32_t insn, re_insn = 0; ++ uint16_t insn16, re_insn16 = 0; ++ unsigned long reloc, cond_reloc; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ ++ convertible = IS_1ST_CONVERT (irel->r_addend); ++ ++ if (convertible) ++ first_size = 2; ++ else ++ first_size = 4; ++ ++ /* Get all needed relocations. */ ++ hi_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_HI20_RELA, laddr + first_size); ++ lo_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_LO12S0_ORI_RELA, ++ laddr + first_size + 4); ++ ++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) ++ { ++ cond_irelfn = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ checked_types[i], laddr); ++ if (cond_irelfn != irelend) ++ break; ++ } ++ ++ if (hi_irelfn == irelend || lo_irelfn == irelend || cond_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP3 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, hi_irelfn, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 ++ || foff >= CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ /* Get the all corresponding instructions. */ ++ if (first_size == 4) ++ { ++ insn = bfd_getb32 (contents + laddr); ++ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn); ++ } ++ else ++ { ++ insn16 = bfd_getb16 (contents + laddr); ++ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn); ++ } ++ ++ /* For simplicity of coding, we are going to modify the section ++ contents, the section relocs, and the BFD symbol table. We ++ must tell the rest of the code not to free up this ++ information. It would be possible to instead create a table ++ of changes which have to be made, as is done in coff-mips.c; ++ that would be more work, but would require less memory when ++ the linker is run. */ ++ ++ if (re_insn16 && foff >= -ACCURATE_8BIT_S1 - first_size ++ && foff < ACCURATE_8BIT_S1 - first_size) ++ { ++ if (!(seq_len & 0x2)) ++ { ++ /* Don't convert it to 16-bit now, keep this as relaxable ++ for ``label reloc; INSN1a''6. */ ++ /* Save comp_insn32 to buffer. */ ++ bfd_putb32 (re_insn, contents + irel->r_offset); ++ *insn_len = 4; ++ reloc = (N32_OP6 (re_insn) == N32_OP6_BR1) ? ++ R_NDS32_15_PCREL_RELA : R_NDS32_17_PCREL_RELA; ++ cond_reloc = R_NDS32_INSN16; ++ } ++ else ++ { ++ /* Not optimize for speed; convert sequence to 16-bit. */ ++ /* Save comp_insn16 to buffer. */ ++ bfd_putb16 (re_insn16, contents + irel->r_offset); ++ *insn_len = 2; ++ reloc = R_NDS32_9_PCREL_RELA; ++ cond_reloc = R_NDS32_NONE; ++ } ++ cond_removed = 1; ++ } ++ else if (N32_OP6 (re_insn) == N32_OP6_BR1 ++ && (foff >= -(ACCURATE_14BIT_S1 - first_size) ++ && foff < ACCURATE_14BIT_S1 - first_size)) ++ { ++ /* beqs label ; 15_PCREL */ ++ bfd_putb32 (re_insn, contents + irel->r_offset); ++ *insn_len = 4; ++ reloc = R_NDS32_15_PCREL_RELA; ++ cond_reloc = R_NDS32_NONE; ++ cond_removed = 1; ++ } ++ else if (N32_OP6 (re_insn) == N32_OP6_BR2 ++ && foff >= -CONSERVATIVE_16BIT_S1 ++ && foff < CONSERVATIVE_16BIT_S1) ++ { ++ /* beqz label ; 17_PCREL */ ++ bfd_putb32 (re_insn, contents + irel->r_offset); ++ *insn_len = 4; ++ reloc = R_NDS32_17_PCREL_RELA; ++ cond_reloc = R_NDS32_NONE; ++ cond_removed = 1; ++ } ++ else if (foff >= -CONSERVATIVE_24BIT_S1 - reloc_off ++ && foff < CONSERVATIVE_24BIT_S1 - reloc_off) ++ { ++ /* Relax to one of the following 3 variations ++ ++ case 2-4; 1st insn convertible, 16-bit on, optimize off or optimize ++ for space ++ bnes38 rt, $1 ; LONGJUMP2 ++ j label ; 25_PCREL ++ $1 ++ ++ case 4-4; 1st insn not convertible, others don't care ++ bne rt, ra, $1 ; LONGJUMP2 ++ j label ; 25_PCREL ++ $1 ++ ++ case 4-4; 1st insn convertible, 16-bit on, optimize for speed ++ bne rt, ra, $1 ; LONGJUMP2 ++ j label ; 25_PCREL ++ $1 */ ++ ++ /* Offset for first instruction. */ ++ ++ /* Use j label as second instruction. */ ++ *insn_len = 4 + first_size; ++ insn = INSN_J; ++ bfd_putb32 (insn, contents + hi_irelfn->r_offset); ++ reloc = R_NDS32_LONGJUMP2; ++ cond_reloc = R_NDS32_25_PLTREL; ++ } ++ else ++ return FALSE; ++ ++ if (cond_removed == 1) ++ { ++ /* Set all relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), reloc); ++ irel->r_addend = hi_irelfn->r_addend; ++ ++ cond_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irelfn->r_info), ++ cond_reloc); ++ cond_irelfn->r_addend = 0; ++ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), ++ R_NDS32_NONE); ++ } ++ else ++ { ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc); ++ irel->r_addend = irel->r_addend; ++ hi_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), ++ cond_reloc); ++ } ++ ++ if ((seq_len ^ *insn_len ) & 0x2) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + irel->r_offset + *insn_len); ++ lo_irelfn->r_offset = *insn_len; ++ lo_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), ++ R_NDS32_INSN16); ++ lo_irelfn->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ *insn_len += 2; ++ } ++ else ++ lo_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (lo_irelfn->r_info), ++ R_NDS32_NONE); ++ return TRUE; ++} ++ ++/* Relax LONGCALL4 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longcall4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* The pattern for LONGCALL4. Support for function cse. ++ sethi ta, hi20(symbol) ; LONGCALL4/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR ++ jral ta ; PTR_RES/EMPTY/INSN16 */ ++ ++ bfd_vma laddr; ++ uint32_t insn; ++ Elf_Internal_Rela *hi_irel, *ptr_irel, *insn_irel, *em_irel, *call_irel; ++ Elf_Internal_Rela *irelend; ++ bfd_signed_vma foff; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ hi_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_HI20_RELA, laddr); ++ ++ if (hi_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr); ++ ++ /* This condition only happened when symbol is undefined. */ ++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 ++ || foff >= CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ /* Relax to: jal symbol; 25_PCREL */ ++ /* For simplicity of coding, we are going to modify the section ++ contents, the section relocs, and the BFD symbol table. We ++ must tell the rest of the code not to free up this ++ information. It would be possible to instead create a table ++ of changes which have to be made, as is done in coff-mips.c; ++ that would be more work, but would require less memory when ++ the linker is run. */ ++ ++ ptr_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED, irel->r_addend); ++ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_EMPTY, irel->r_addend); ++ ++ if (ptr_irel == irelend || em_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL4 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ /* Check these is enough space to insert jal in R_NDS32_EMPTY. */ ++ insn = bfd_getb32 (contents + irel->r_addend); ++ if (insn & 0x80000000) ++ return FALSE; ++ ++ /* Replace the long call with a jal. */ ++ em_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), ++ R_NDS32_25_PCREL_RELA); ++ ptr_irel->r_addend = 1; ++ ++ /* We don't resolve this here but resolve it in relocate_section. */ ++ insn = INSN_JAL; ++ bfd_putb32 (insn, contents + em_irel->r_offset); ++ ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ /* If there is function cse, HI20 can not remove now. */ ++ call_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_LONGCALL4, laddr); ++ if (call_irel == irelend) ++ { ++ *insn_len = 0; ++ hi_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irel->r_info), R_NDS32_NONE); ++ } ++ ++ insn_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_INSN16, irel->r_addend); ++ if (insn_irel != irelend) ++ insn_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ return TRUE; ++} ++ ++/* Relax LONGCALL5 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longcall5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* The pattern for LONGCALL5. ++ bltz rt, .L1 ; LONGCALL5/17_PCREL ++ jal symbol ; 25_PCREL ++ .L1: */ ++ ++ bfd_vma laddr; ++ uint32_t insn; ++ Elf_Internal_Rela *cond_irel, *irelend; ++ bfd_signed_vma foff; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_25_PCREL_RELA, irel->r_addend); ++ if (cond_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL5 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 ++ || foff >= CONSERVATIVE_16BIT_S1) ++ return FALSE; ++ ++ /* Relax to bgezal rt, label ; 17_PCREL ++ or bltzal rt, label ; 17_PCREL */ ++ ++ /* Convert to complimentary conditional call. */ ++ insn = CONVERT_CONDITION_CALL (insn); ++ ++ /* For simplicity of coding, we are going to modify the section ++ contents, the section relocs, and the BFD symbol table. We ++ must tell the rest of the code not to free up this ++ information. It would be possible to instead create a table ++ of changes which have to be made, as is done in coff-mips.c; ++ that would be more work, but would require less memory when ++ the linker is run. */ ++ ++ /* Modify relocation and contents. */ ++ cond_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_17_PCREL_RELA); ++ ++ /* Replace the long call with a bgezal. */ ++ bfd_putb32 (insn, contents + cond_irel->r_offset); ++ *insn_len = 0; ++ ++ /* Clean unnessary relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ cond_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_17_PCREL_RELA, laddr); ++ cond_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE); ++ ++ return TRUE; ++} ++ ++/* Relax LONGCALL6 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longcall6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* The pattern for LONGCALL6. ++ bltz rt, .L1 ; LONGCALL6/17_PCREL ++ sethi ta, hi20(symbol) ; HI20/PTR ++ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR ++ jral ta ; PTR_RES/EMPTY/INSN16 ++ .L1 */ ++ ++ bfd_vma laddr; ++ uint32_t insn; ++ Elf_Internal_Rela *em_irel, *cond_irel, *irelend; ++ bfd_signed_vma foff; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_EMPTY, irel->r_addend); ++ ++ if (em_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 ++ || foff >= CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ /* Check these is enough space to insert jal in R_NDS32_EMPTY. */ ++ insn = bfd_getb32 (contents + irel->r_addend); ++ if (insn & 0x80000000) ++ return FALSE; ++ ++ insn = bfd_getb32 (contents + laddr); ++ if (foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) ++ { ++ /* Relax to bgezal rt, label ; 17_PCREL ++ or bltzal rt, label ; 17_PCREL */ ++ ++ /* Convert to complimentary conditional call. */ ++ *insn_len = 0; ++ insn = CONVERT_CONDITION_CALL (insn); ++ bfd_putb32 (insn, contents + em_irel->r_offset); ++ ++ em_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), R_NDS32_17_PCREL_RELA); ++ ++ /* Set resolved relocation. */ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED, irel->r_addend); ++ if (cond_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ cond_irel->r_addend = 1; ++ ++ /* Clear relocations. */ ++ ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_17_PCREL_RELA, laddr); ++ if (cond_irel != irelend) ++ cond_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE); ++ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_INSN16, irel->r_addend); ++ if (cond_irel != irelend) ++ cond_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE); ++ ++ } ++ else if (foff >= -CONSERVATIVE_24BIT_S1 && foff < CONSERVATIVE_24BIT_S1) ++ { ++ /* Relax to the following instruction sequence ++ bltz rt, .L1 ; LONGCALL2/17_PCREL ++ jal symbol ; 25_PCREL/PTR_RES ++ .L1 */ ++ *insn_len = 4; ++ /* Convert instruction. */ ++ insn = INSN_JAL; ++ bfd_putb32 (insn, contents + em_irel->r_offset); ++ ++ /* Convert relocations. */ ++ em_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), ++ R_NDS32_25_PCREL_RELA); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_LONGCALL5); ++ ++ /* Set resolved relocation. */ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED, irel->r_addend); ++ if (cond_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGCALL6 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ cond_irel->r_addend = 1; ++ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_INSN16, irel->r_addend); ++ if (cond_irel != irelend) ++ cond_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE); ++ } ++ return TRUE; ++} ++ ++/* Relax LONGJUMP4 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump4 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* The pattern for LONGJUMP4. ++ sethi ta, hi20(symbol) ; LONGJUMP4/HI20 ++ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR ++ jr ta ; PTR_RES/INSN16/EMPTY */ ++ ++ bfd_vma laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ uint32_t insn; ++ Elf_Internal_Rela *hi_irel, *ptr_irel, *em_irel, *call_irel, *irelend; ++ bfd_signed_vma foff; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ hi_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_HI20_RELA, laddr); ++ ++ if (hi_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, hi_irel, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff >= CONSERVATIVE_24BIT_S1 ++ || foff < -CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ /* Convert it to "j label", it may be converted to j8 in the final ++ pass of relaxation. Therefore, we do not consider this currently.*/ ++ ptr_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED, irel->r_addend); ++ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_EMPTY, irel->r_addend); ++ ++ if (ptr_irel == irelend || em_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP4 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ em_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), R_NDS32_25_PCREL_RELA); ++ ptr_irel->r_addend = 1; ++ ++ /* Write instruction. */ ++ insn = INSN_J; ++ bfd_putb32 (insn, contents + em_irel->r_offset); ++ ++ /* Clear relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ /* If there is function cse, HI20 can not remove now. */ ++ call_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_LONGJUMP4, laddr); ++ if (call_irel == irelend) ++ { ++ *insn_len = 0; ++ hi_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irel->r_info), R_NDS32_NONE); ++ } ++ ++ return TRUE; ++} ++ ++/* Relax LONGJUMP5 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump5 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ int *seq_len, bfd_byte *contents, ++ Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 2 variations for LONGJUMP5 ++ case 2-4; 1st insn convertible, 16-bit on. ++ bnes38 rt, ra, .L1 ; LONGJUMP5/9_PCREL/INSN16 ++ j label ; 25_PCREL/INSN16 ++ $1: ++ ++ case 4-4; 1st insn not convertible ++ bne rt, ra, .L1 ; LONGJUMP5/15_PCREL/INSN16 ++ j label ; 25_PCREL/INSN16 ++ .L1: */ ++ ++ bfd_vma laddr; ++ Elf_Internal_Rela *cond_irel, *irelend; ++ unsigned int i; ++ bfd_signed_vma foff; ++ uint32_t insn, re_insn = 0; ++ uint16_t insn16, re_insn16 = 0; ++ unsigned long reloc; ++ ++ enum elf_nds32_reloc_type checked_types[] = ++ { R_NDS32_17_PCREL_RELA, R_NDS32_15_PCREL_RELA, ++ R_NDS32_9_PCREL_RELA, R_NDS32_INSN16 }; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_25_PCREL_RELA, irel->r_addend); ++ if (cond_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP5 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_16BIT_S1 ++ || foff >= CONSERVATIVE_16BIT_S1) ++ return FALSE; ++ ++ /* Get the all corresponding instructions. */ ++ insn = bfd_getb32 (contents + laddr); ++ /* Check instruction size. */ ++ if (insn & 0x80000000) ++ { ++ *seq_len = 0; ++ insn16 = insn >> 16; ++ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn); ++ } ++ else ++ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn); ++ ++ if (N32_OP6 (re_insn) == N32_OP6_BR1 ++ && (foff >= -CONSERVATIVE_14BIT_S1 && foff < CONSERVATIVE_14BIT_S1)) ++ { ++ /* beqs label ; 15_PCREL. */ ++ bfd_putb32 (re_insn, contents + cond_irel->r_offset); ++ reloc = R_NDS32_15_PCREL_RELA; ++ } ++ else if (N32_OP6 (re_insn) == N32_OP6_BR2 ++ && foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) ++ { ++ /* beqz label ; 17_PCREL. */ ++ bfd_putb32 (re_insn, contents + cond_irel->r_offset); ++ reloc = R_NDS32_17_PCREL_RELA; ++ } ++ else if ( N32_OP6 (re_insn) == N32_OP6_BR3 ++ && foff >= -CONSERVATIVE_8BIT_S1 && foff < CONSERVATIVE_8BIT_S1) ++ { ++ /* beqc label ; 9_PCREL. */ ++ bfd_putb32 (re_insn, contents + cond_irel->r_offset); ++ reloc = R_NDS32_WORD_9_PCREL_RELA; ++ } ++ else ++ return FALSE; ++ ++ /* Set all relocations. */ ++ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), reloc); ++ ++ /* Clean relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) ++ { ++ cond_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ checked_types[i], laddr); ++ if (cond_irel != irelend) ++ { ++ if (*seq_len == 0 ++ && (ELF32_R_TYPE (cond_irel->r_info) == R_NDS32_INSN16)) ++ { ++ /* If the branch instruction is 2 byte, it cannot remove ++ directly. Only convert it to nop16 and remove it after ++ checking alignment issue. */ ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + laddr); ++ cond_irel->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ } ++ else ++ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), ++ R_NDS32_NONE); ++ } ++ } ++ *insn_len = 0; ++ ++ return TRUE; ++} ++ ++/* Relax LONGJUMP6 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump6 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ int *seq_len, bfd_byte *contents, ++ Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 5 variations for LONGJUMP6 ++ case : 2-4-4-4; 1st insn convertible, 16-bit on. ++ bnes38 rt, ra, .L1 ; LONGJUMP6/15_PCREL/INSN16 ++ sethi ta, hi20(symbol) ; HI20/PTR ++ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR ++ jr ta ; PTR_RES/INSN16/EMPTY ++ .L1: ++ ++ case : 4-4-4-4; 1st insn not convertible, 16-bit on. ++ bne rt, ra, .L1 ; LONGJUMP6/15_PCREL/INSN16 ++ sethi ta, hi20(symbol) ; HI20/PTR ++ ori ta, ta, lo12(symbol) ; LO12S0_ORI/PTR ++ jr ta ; PTR_RES/INSN16/EMPTY ++ .L1: */ ++ ++ enum elf_nds32_reloc_type checked_types[] = ++ { R_NDS32_17_PCREL_RELA, R_NDS32_15_PCREL_RELA, ++ R_NDS32_9_PCREL_RELA, R_NDS32_INSN16 }; ++ ++ int reloc_off = 0, cond_removed = 0; ++ bfd_vma laddr; ++ Elf_Internal_Rela *cond_irel, *em_irel, *irelend, *insn_irel; ++ unsigned int i; ++ bfd_signed_vma foff; ++ uint32_t insn, re_insn = 0; ++ uint16_t insn16, re_insn16 = 0; ++ unsigned long reloc; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ em_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_EMPTY, irel->r_addend); ++ ++ if (em_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP6 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, em_irel, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_24BIT_S1 ++ || foff >= CONSERVATIVE_24BIT_S1) ++ return FALSE; ++ ++ insn = bfd_getb32 (contents + laddr); ++ /* Check instruction size. */ ++ if (insn & 0x80000000) ++ { ++ *seq_len = 0; ++ insn16 = insn >> 16; ++ nds32_elf_convert_branch (insn16, 0, &re_insn16, &re_insn); ++ } ++ else ++ nds32_elf_convert_branch (0, insn, &re_insn16, &re_insn); ++ ++ /* For simplicity of coding, we are going to modify the section ++ contents, the section relocs, and the BFD symbol table. We ++ must tell the rest of the code not to free up this ++ information. It would be possible to instead create a table ++ of changes which have to be made, as is done in coff-mips.c; ++ that would be more work, but would require less memory when ++ the linker is run. */ ++ ++ if (N32_OP6 (re_insn) == N32_OP6_BR1 ++ && (foff >= -CONSERVATIVE_14BIT_S1 && foff < CONSERVATIVE_14BIT_S1)) ++ { ++ /* beqs label ; 15_PCREL */ ++ bfd_putb32 (re_insn, contents + em_irel->r_offset); ++ reloc = R_NDS32_15_PCREL_RELA; ++ cond_removed = 1; ++ } ++ else if (N32_OP6 (re_insn) == N32_OP6_BR2 ++ && foff >= -CONSERVATIVE_16BIT_S1 && foff < CONSERVATIVE_16BIT_S1) ++ { ++ /* beqz label ; 17_PCREL */ ++ bfd_putb32 (re_insn, contents + em_irel->r_offset); ++ reloc = R_NDS32_17_PCREL_RELA; ++ cond_removed = 1; ++ } ++ else if (foff >= -CONSERVATIVE_24BIT_S1 - reloc_off ++ && foff < CONSERVATIVE_24BIT_S1 - reloc_off) ++ { ++ /* Relax to one of the following 2 variations ++ ++ case 2-4; 1st insn convertible, 16-bit on. ++ bnes38 rt, ra, .L1 ; LONGJUMP5/9_PCREL/INSN16 ++ j label ; 25_PCREL/INSN16 ++ $1: ++ ++ case 4-4; 1st insn not convertible ++ bne rt, ra, .L1 ; LONGJUMP5/15_PCREL/INSN16 ++ j label ; 25_PCREL/INSN16 ++ .L1: */ ++ ++ /* Use j label as second instruction. */ ++ insn = INSN_J; ++ reloc = R_NDS32_25_PCREL_RELA; ++ bfd_putb32 (insn, contents + em_irel->r_offset); ++ } ++ else ++ return FALSE; ++ ++ /* Set all relocations. */ ++ em_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (em_irel->r_info), reloc); ++ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED, em_irel->r_offset); ++ cond_irel->r_addend = 1; ++ ++ /* Use INSN16 of first branch instruction to distinguish if keeping ++ INSN16 of final instruction or not. */ ++ insn_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_INSN16, irel->r_offset); ++ if (insn_irel == irelend) ++ { ++ /* Clean the final INSN16. */ ++ insn_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_INSN16, em_irel->r_offset); ++ insn_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), ++ R_NDS32_NONE); ++ } ++ ++ if (cond_removed == 1) ++ { ++ *insn_len = 0; ++ ++ /* Clear relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ for (i = 0; i < ARRAY_SIZE (checked_types); i++) ++ { ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ checked_types[i], laddr); ++ if (cond_irel != irelend) ++ { ++ if (*seq_len == 0 ++ && (ELF32_R_TYPE (cond_irel->r_info) == R_NDS32_INSN16)) ++ { ++ /* If the branch instruction is 2 byte, it cannot remove ++ directly. Only convert it to nop16 and remove it after ++ checking alignment issue. */ ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + laddr); ++ cond_irel->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ } ++ else ++ cond_irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), R_NDS32_NONE); ++ } ++ } ++ } ++ else ++ { ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), ++ R_NDS32_LONGJUMP5); ++ } ++ ++ return TRUE; ++} ++ ++/* Relax LONGJUMP7 relocation for nds32_elf_relax_section.*/ ++ ++static bfd_boolean ++nds32_elf_relax_longjump7 (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ int *seq_len, bfd_byte *contents, ++ Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ /* There are 2 variations for LONGJUMP5 ++ case 2-4; 1st insn convertible, 16-bit on. ++ movi55 ta, imm11 ; LONGJUMP7/INSN16 ++ beq rt, ta, label ; 15_PCREL ++ ++ case 4-4; 1st insn not convertible ++ movi55 ta, imm11 ; LONGJUMP7/INSN16 ++ beq rt, ta, label ; 15_PCREL */ ++ ++ bfd_vma laddr; ++ Elf_Internal_Rela *cond_irel, *irelend, *insn_irel; ++ bfd_signed_vma foff; ++ uint32_t insn, re_insn = 0; ++ uint16_t insn16; ++ uint32_t imm11; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ ++ /* Get the reloc for the address from which the register is ++ being loaded. This reloc will tell us which function is ++ actually being called. */ ++ ++ cond_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_15_PCREL_RELA, irel->r_addend); ++ if (cond_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LONGJUMP7 points to unrecognized" ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = calculate_offset (abfd, sec, cond_irel, isymbuf, symtab_hdr); ++ ++ if (foff == 0 || foff < -CONSERVATIVE_8BIT_S1 ++ || foff >= CONSERVATIVE_8BIT_S1) ++ return FALSE; ++ ++ /* Get the first instruction for its size. */ ++ insn = bfd_getb32 (contents + laddr); ++ if (insn & 0x80000000) ++ { ++ *seq_len = 0; ++ /* Get the immediate from movi55. */ ++ imm11 = N16_IMM5S (insn >> 16); ++ } ++ else ++ { ++ /* Get the immediate from movi. */ ++ imm11 = N32_IMM20S (insn); ++ } ++ ++ /* Get the branch instruction. */ ++ insn = bfd_getb32 (contents + irel->r_addend); ++ /* Convert instruction to BR3. */ ++ if ((insn >> 14) & 0x1) ++ re_insn = N32_BR3 (BNEC, N32_RT5 (insn), imm11, 0); ++ else ++ re_insn = N32_BR3 (BEQC, N32_RT5 (insn), imm11, 0); ++ ++ bfd_putb32 (re_insn, contents + cond_irel->r_offset); ++ ++ /* Set all relocations. */ ++ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), ++ R_NDS32_WORD_9_PCREL_RELA); ++ ++ /* Clean relocations. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ insn_irel = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_INSN16, irel->r_offset); ++ if (insn_irel != irelend) ++ { ++ if (*seq_len == 0) ++ { ++ /* If the first insntruction is 16bit, convert it to nop16. */ ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + laddr); ++ insn_irel->r_addend = R_NDS32_INSN16_CONVERT_FLAG; ++ } ++ else ++ cond_irel->r_info = ELF32_R_INFO (ELF32_R_SYM (cond_irel->r_info), ++ R_NDS32_NONE); ++ } ++ *insn_len = 0; ++ ++ return TRUE; ++} ++ ++/* Record the offset to gp, and check if it changed after relaxing. ++ If the offset is fixed or the offset is near enough, try to relax ++ the pattern. This is avoid truncated to fit when relaxing fixed ++ address symbol. Ex: _stack. */ ++static bfd_boolean ++nds32_elf_relax_guard (bfd_vma *access_addr, bfd_vma local_sda, asection *sec, ++ Elf_Internal_Rela *irel, bfd_boolean *again, ++ bfd_boolean init, ++ struct elf_nds32_link_hash_table *table, ++ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr) ++ ++{ ++ /* The default linker script value. */ ++ int offset_to_gp; ++ static bfd_boolean sec_pass = FALSE; ++ static asection *first_sec = NULL, *sym_sec; ++ /* Record the number of instructions which may be removed. */ ++ static int count = 0, record_count; ++ Elf_Internal_Sym *isym; ++ struct elf_link_hash_entry *h = NULL; ++ int indx; ++ unsigned long r_symndx; ++ bfd *abfd = sec->owner; ++ static bfd_vma record_sda = 0; ++ int sda_offset = 0; ++ ++ /* Force doing relaxation when hyper-relax is high. */ ++ if (table->hyper_relax == 2) ++ return TRUE; ++ ++ /* Record the first section to get the round. */ ++ if (init) ++ { ++ if (!first_sec) ++ first_sec = sec; ++ else if (first_sec == sec) ++ { ++ record_count = count; ++ count = 0; ++ sec_pass = TRUE; ++ } ++ ++ if (!sec_pass) ++ *again = TRUE; ++ ++ return TRUE;; ++ } ++ ++ if (record_sda == 0) ++ record_sda = local_sda; ++ else if (local_sda > record_sda) ++ /* In normal case, SDA is fixed or smaller except there is ++ DATA_SEGMENT_ALIGN in linker script.*/ ++ sda_offset = local_sda - record_sda; ++ ++ /* Although we doesn't delete all instructions here, counting all of ++ them to be conservative. */ ++ count++; ++ ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ /* Global symbols. */ ++ if (r_symndx >= symtab_hdr->sh_info) ++ { ++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[indx]; ++ sym_sec = h->root.u.def.section; ++ if (NDS32_GUARD_SEC_P (sym_sec->flags) ++ || bfd_is_abs_section (sym_sec)) ++ { ++ /* Forbid doing relaxation when hyper-relax is low. */ ++ if (table->hyper_relax == 0) ++ return FALSE; ++ ++ offset_to_gp = *access_addr - local_sda; ++ if (elf32_nds32_hash_entry (h)->offset_to_gp == 0) ++ elf32_nds32_hash_entry (h)->offset_to_gp = offset_to_gp; ++ else if (abs (elf32_nds32_hash_entry (h)->offset_to_gp) ++ < abs (offset_to_gp) - sda_offset) ++ { ++ if (*access_addr >= local_sda) ++ *access_addr += (record_count * 4); ++ else ++ *access_addr -= (record_count * 4); ++ } ++ return sec_pass; ++ } ++ } ++ else ++ { ++ if (!elf32_nds32_allocate_local_sym_info (abfd)) ++ return FALSE; ++ isym = isymbuf + r_symndx; ++ ++ sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ if (NDS32_GUARD_SEC_P (sym_sec->flags)) ++ { ++ /* Forbid doing relaxation when hyper-relax is low. */ ++ if (table->hyper_relax == 0) ++ return FALSE; ++ ++ offset_to_gp = *access_addr - local_sda; ++ if (elf32_nds32_local_gp_offset (abfd)[r_symndx] == 0) ++ elf32_nds32_local_gp_offset (abfd)[r_symndx] = offset_to_gp; ++ else if (abs (elf32_nds32_local_gp_offset (abfd)[r_symndx]) ++ < abs (offset_to_gp) - sda_offset) ++ { ++ if (*access_addr >= local_sda) ++ *access_addr += (record_count * 4); ++ else ++ *access_addr -= (record_count * 4); ++ } ++ return sec_pass; ++ } ++ } ++ ++ return TRUE; ++} ++#define GET_LOADSTORE_RANGE(addend) (((addend) >> 8) & 0x3f) ++ ++/* Relax LOADSTORE relocation for nds32_elf_relax_section. */ ++ ++static bfd_boolean ++nds32_elf_relax_loadstore (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr, int load_store_relax, ++ struct elf_nds32_link_hash_table *table) ++{ ++ int eliminate_sethi = 0, range_type, i; ++ bfd_vma local_sda, laddr; ++ int seq_len; /* Original length of instruction sequence. */ ++ uint32_t insn; ++ Elf_Internal_Rela *hi_irelfn = NULL, *irelend; ++ bfd_vma access_addr = 0; ++ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */ ++ enum elf_nds32_reloc_type checked_types[] = ++ { R_NDS32_HI20_RELA, R_NDS32_GOT_HI20, ++ R_NDS32_GOTPC_HI20, R_NDS32_GOTOFF_HI20, ++ R_NDS32_PLTREL_HI20, R_NDS32_PLT_GOTREL_HI20, ++ R_NDS32_TLS_LE_HI20, R_NDS32_TLS_IE_HI20, ++ R_NDS32_TLS_IEGP_HI20, R_NDS32_TLS_DESC_HI20 ++ }; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ laddr = irel->r_offset; ++ *insn_len = seq_len; ++ ++ /* Get the high part relocation. */ ++ for (i = 0; (unsigned) i < ARRAY_SIZE (checked_types); i++) ++ { ++ hi_irelfn = find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ checked_types[i], laddr); ++ if (hi_irelfn != irelend) ++ break; ++ } ++ ++ if (hi_irelfn == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_LOADSTORE points to unrecognized " ++ "reloc at 0x%lx.", abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ range_type = GET_LOADSTORE_RANGE (irel->r_addend); ++ nds32_elf_final_sda_base (sec->output_section->owner, ++ link_info, &local_sda, FALSE); ++ ++ switch (ELF32_R_TYPE (hi_irelfn->r_info)) ++ { ++ case R_NDS32_HI20_RELA: ++ insn = bfd_getb32 (contents + laddr); ++ access_addr = ++ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr); ++ ++ /* Try movi. */ ++ if (range_type == NDS32_LOADSTORE_IMM) ++ { ++ struct elf_link_hash_entry *h = NULL; ++ int indx; ++ ++ if (ELF32_R_SYM (hi_irelfn->r_info) >= symtab_hdr->sh_info) ++ { ++ indx = ELF32_R_SYM (hi_irelfn->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[indx]; ++ } ++ ++ if ((access_addr < CONSERVATIVE_20BIT) ++ && (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0))) ++ { ++ eliminate_sethi = 1; ++ break; ++ } ++ } ++ ++ if (!nds32_elf_relax_guard (&access_addr, local_sda, sec, hi_irelfn, ++ NULL, FALSE, table, isymbuf, symtab_hdr)) ++ return FALSE; ++ ++ ++ if (!load_store_relax) ++ return FALSE; ++ ++ /* Case for set gp register. */ ++ if (N32_RT5 (insn) == REG_GP) ++ break; ++ ++ if (range_type == NDS32_LOADSTORE_FLOAT_S ++ || range_type == NDS32_LOADSTORE_FLOAT_S) ++ { ++ range_l = sdata_range[0][0]; ++ range_h = sdata_range[0][1]; ++ } ++ else ++ { ++ range_l = sdata_range[1][0]; ++ range_h = sdata_range[1][1]; ++ } ++ break; ++ ++ case R_NDS32_GOT_HI20: ++ access_addr = ++ calculate_got_memory_address (abfd, link_info, hi_irelfn, symtab_hdr); ++ ++ /* If this symbol is not in .got, the return value will be -1. ++ Since the gp value is set to SDA_BASE but not GLOBAL_OFFSET_TABLE, ++ a negative offset is allowed. */ ++ if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT ++ && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT) ++ eliminate_sethi = 1; ++ break; ++ ++ case R_NDS32_PLT_GOTREL_HI20: ++ access_addr = calculate_plt_memory_address (abfd, link_info, isymbuf, ++ hi_irelfn, symtab_hdr); ++ ++ if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT ++ && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT) ++ eliminate_sethi = 1; ++ break; ++ ++ case R_NDS32_GOTOFF_HI20: ++ access_addr = ++ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr); ++ ++ if ((bfd_signed_vma) (access_addr - local_sda) < CONSERVATIVE_20BIT ++ && (bfd_signed_vma) (access_addr - local_sda) >= -CONSERVATIVE_20BIT) ++ eliminate_sethi = 1; ++ break; ++ ++ case R_NDS32_GOTPC_HI20: ++ /* The access_addr must consider r_addend of hi_irel. */ ++ access_addr = sec->output_section->vma + sec->output_offset ++ + irel->r_offset + hi_irelfn->r_addend; ++ ++ if ((bfd_signed_vma) (local_sda - access_addr) < CONSERVATIVE_20BIT ++ && (bfd_signed_vma) (local_sda - access_addr) >= -CONSERVATIVE_20BIT) ++ eliminate_sethi = 1; ++ break; ++ ++ case R_NDS32_TLS_LE_HI20: ++ access_addr = ++ calculate_memory_address (abfd, hi_irelfn, isymbuf, symtab_hdr); ++ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL); ++ access_addr -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET); ++ if ((range_type == NDS32_LOADSTORE_IMM) ++ && (bfd_signed_vma) (access_addr) < CONSERVATIVE_20BIT ++ && (bfd_signed_vma) (access_addr) >= -CONSERVATIVE_20BIT) ++ eliminate_sethi = 1; ++ break; ++ ++ /* TODO: TLS IE/IEGP */ ++ case R_NDS32_TLS_IE_HI20: ++ case R_NDS32_TLS_IEGP_HI20: ++ break; ++ ++ /* TODO: TLS DESC */ ++ case R_NDS32_TLS_DESC_HI20: ++ break; ++ ++ default: ++ return FALSE; ++ } ++ ++ /* Delete sethi instruction. */ ++ if (eliminate_sethi == 1 ++ || (local_sda <= access_addr && (access_addr - local_sda) < range_h) ++ || (local_sda > access_addr && (local_sda - access_addr) <= range_l)) ++ { ++ hi_irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (hi_irelfn->r_info), R_NDS32_NONE); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ *insn_len = 0; ++ } ++ return TRUE; ++} ++ ++/* Relax LO12 relocation for nds32_elf_relax_section.*/ ++ ++static void ++nds32_elf_relax_lo12 (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, bfd_byte *contents, ++ Elf_Internal_Sym *isymbuf, Elf_Internal_Shdr *symtab_hdr, ++ struct elf_nds32_link_hash_table *table) ++{ ++ uint32_t insn; ++ bfd_vma local_sda, laddr; ++ unsigned long reloc; ++ bfd_vma access_addr; ++ bfd_vma range_l = 0, range_h = 0; /* Upper/lower bound. */ ++ Elf_Internal_Rela *irelfn = NULL, *irelend; ++ struct elf_link_hash_entry *h = NULL; ++ int indx; ++ ++ /* For SDA base relative relaxation. */ ++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, ++ &local_sda, FALSE); ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ ++ if (!is_sda_access_insn (insn) && N32_OP6 (insn) != N32_OP6_ORI) ++ return; ++ ++ access_addr = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); ++ ++ if (ELF32_R_SYM (irel->r_info) >= symtab_hdr->sh_info) ++ { ++ indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ h = elf_sym_hashes (abfd)[indx]; ++ } ++ ++ /* Try movi. */ ++ if (N32_OP6 (insn) == N32_OP6_ORI && access_addr < CONSERVATIVE_20BIT ++ && (!h || (h && strcmp (h->root.root.string, FP_BASE_NAME) != 0))) ++ { ++ reloc = R_NDS32_20_RELA; ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc); ++ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0); ++ bfd_putb32 (insn, contents + laddr); ++ } ++ else ++ { ++ if (!nds32_elf_relax_guard (&access_addr, local_sda, sec, irel, NULL, ++ FALSE, table, isymbuf, symtab_hdr)) ++ return; ++ ++ range_l = sdata_range[1][0]; ++ range_h = sdata_range[1][1]; ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ case R_NDS32_LO12S0_RELA: ++ reloc = R_NDS32_SDA19S0_RELA; ++ break; ++ case R_NDS32_LO12S1_RELA: ++ reloc = R_NDS32_SDA18S1_RELA; ++ break; ++ case R_NDS32_LO12S2_RELA: ++ reloc = R_NDS32_SDA17S2_RELA; ++ break; ++ case R_NDS32_LO12S2_DP_RELA: ++ range_l = sdata_range[0][0]; ++ range_h = sdata_range[0][1]; ++ reloc = R_NDS32_SDA12S2_DP_RELA; ++ break; ++ case R_NDS32_LO12S2_SP_RELA: ++ range_l = sdata_range[0][0]; ++ range_h = sdata_range[0][1]; ++ reloc = R_NDS32_SDA12S2_SP_RELA; ++ break; ++ default: ++ return; ++ } ++ ++ /* There are range_h and range_l because linker has to promise ++ all sections move cross one page together. */ ++ if ((local_sda <= access_addr && (access_addr - local_sda) < range_h) ++ || (local_sda > access_addr && (local_sda - access_addr) <= range_l)) ++ { ++ if (N32_OP6 (insn) == N32_OP6_ORI && N32_RT5 (insn) == REG_GP) ++ { ++ /* Maybe we should add R_NDS32_INSN16 reloc type here ++ or manually do some optimization. sethi can't be ++ eliminated when updating $gp so the relative ori ++ needs to be preserved. */ ++ return; ++ } ++ if (!turn_insn_to_sda_access (insn, ELF32_R_TYPE (irel->r_info), ++ &insn)) ++ return; ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc); ++ bfd_putb32 (insn, contents + laddr); ++ ++ irelfn = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_INSN16); ++ /* SDA17 must keep INSN16 for converting fp_as_gp. */ ++ if (irelfn != irelend && reloc != R_NDS32_SDA17S2_RELA) ++ irelfn->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_NDS32_NONE); ++ ++ } ++ } ++ return; ++} ++ ++/* Relax low part of PIC instruction pattern. */ ++ ++static void ++nds32_elf_relax_piclo12 (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ uint32_t insn; ++ bfd_vma local_sda, laddr; ++ bfd_signed_vma foff; ++ unsigned long reloc; ++ ++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, ++ &local_sda, FALSE); ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ ++ if (N32_OP6 (insn) != N32_OP6_ORI) ++ return; ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_GOT_LO12) ++ { ++ foff = calculate_got_memory_address (abfd, link_info, irel, ++ symtab_hdr) - local_sda; ++ reloc = R_NDS32_GOT20; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_PLT_GOTREL_LO12) ++ { ++ foff = calculate_plt_memory_address (abfd, link_info, isymbuf, irel, ++ symtab_hdr) - local_sda; ++ reloc = R_NDS32_PLT_GOTREL_LO20; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTOFF_LO12) ++ { ++ foff = calculate_memory_address (abfd, irel, isymbuf, ++ symtab_hdr) - local_sda; ++ reloc = R_NDS32_GOTOFF; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTPC_LO12) ++ { ++ foff = local_sda - sec->output_section->vma + sec->output_offset ++ + irel->r_offset + irel->r_addend; ++ reloc = R_NDS32_GOTPC20; ++ } ++ else ++ return; ++ ++ if ((foff < CONSERVATIVE_20BIT) && (foff >= -CONSERVATIVE_20BIT)) ++ { ++ /* Turn into MOVI. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc); ++ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0); ++ bfd_putb32 (insn, contents + laddr); ++ } ++} ++ ++/* Relax low part of LE TLS instruction pattern. */ ++ ++static void ++nds32_elf_relax_letlslo12 (struct bfd_link_info *link_info, bfd *abfd, ++ Elf_Internal_Rela *irel, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr) ++{ ++ uint32_t insn; ++ bfd_vma laddr; ++ bfd_signed_vma foff; ++ unsigned long reloc; ++ ++ laddr = irel->r_offset; ++ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); ++ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL); ++ foff -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET); ++ insn = bfd_getb32 (contents + laddr); ++ ++ if ( (bfd_signed_vma) (foff) < CONSERVATIVE_20BIT ++ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_20BIT) ++ { ++ /* Pattern sethi-ori transform to movi. */ ++ reloc = R_NDS32_TLS_LE_20; ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), reloc); ++ insn = N32_TYPE1 (MOVI, N32_RT5 (insn), 0); ++ bfd_putb32 (insn, contents + laddr); ++ } ++} ++ ++/* Relax LE TLS calculate address instruction pattern. */ ++ ++static void ++nds32_elf_relax_letlsadd (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) ++{ ++ /* Local TLS non-pic ++ sethi ta, hi20(symbol@tpoff) ; TLS_LE_HI20 ++ ori ta, ta, lo12(symbol@tpoff) ; TLS_LE_LO12 ++ add ra, ta, tp ; TLS_LE_ADD */ ++ ++ uint32_t insn; ++ bfd_vma laddr; ++ bfd_signed_vma foff; ++ Elf_Internal_Rela *i1_irelfn, *irelend; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED); ++ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); ++ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL); ++ foff -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET); ++ ++ /* The range is +/-16k. */ ++ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT ++ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT) ++ { ++ /* Transform add to addi. */ ++ insn = N32_TYPE2 (ADDI, N32_RT5 (insn), N32_RB5 (insn), 0); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S0); ++ ++ bfd_putb32 (insn, contents + laddr); ++ if (i1_irelfn != irelend) ++ { ++ i1_irelfn->r_addend |= 1; ++ *again = TRUE; ++ } ++ } ++} ++ ++/* Relax LE TLS load store instruction pattern. */ ++ ++static void ++nds32_elf_relax_letlsls (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) ++{ ++ uint32_t insn; ++ bfd_vma laddr; ++ bfd_signed_vma foff; ++ Elf_Internal_Rela *i1_irelfn, *irelend; ++ int success = 0; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED); ++ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); ++ BFD_ASSERT (elf_hash_table (link_info)->tls_sec != NULL); ++ foff -= (elf_hash_table (link_info)->tls_sec->vma + TP_OFFSET); ++ ++ switch ((N32_OP6 (insn) << 8) | (insn & 0xff)) ++ { ++ case (N32_OP6_MEM << 8) | N32_MEM_LB: ++ case (N32_OP6_MEM << 8) | N32_MEM_SB: ++ case (N32_OP6_MEM << 8) | N32_MEM_LBS: ++ /* The range is +/-16k. */ ++ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT ++ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT) ++ { ++ insn = ++ ((insn & 0xff) << 25) | (insn & 0x1f00000) | ((insn & 0x7c00) << 5); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S0); ++ success = 1; ++ break; ++ } ++ case (N32_OP6_MEM << 8) | N32_MEM_LH: ++ case (N32_OP6_MEM << 8) | N32_MEM_SH: ++ case (N32_OP6_MEM << 8) | N32_MEM_LHS: ++ /* The range is +/-32k. */ ++ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT_S1 ++ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT_S1) ++ { ++ insn = ++ ((insn & 0xff) << 25) | (insn & 0x1f00000) | ((insn & 0x7c00) << 5); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S1); ++ success = 1; ++ break; ++ } ++ case (N32_OP6_MEM << 8) | N32_MEM_LW: ++ case (N32_OP6_MEM << 8) | N32_MEM_SW: ++ /* The range is +/-64k. */ ++ if ((bfd_signed_vma) (foff) < CONSERVATIVE_15BIT_S2 ++ && (bfd_signed_vma) (foff) >= -CONSERVATIVE_15BIT_S2) ++ { ++ insn = ++ ((insn & 0xff) << 25) | (insn & 0x1f00000) | ((insn & 0x7c00) << 5); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_TLS_LE_15S2); ++ success = 1; ++ break; ++ } ++ default: ++ break; ++ } ++ ++ if (success) ++ { ++ bfd_putb32 (insn, contents + laddr); ++ if (i1_irelfn != irelend) ++ { ++ i1_irelfn->r_addend |= 1; ++ *again = TRUE; ++ } ++ } ++} ++ ++/* Relax PTR relocation for nds32_elf_relax_section. */ ++ ++static bfd_boolean ++nds32_elf_relax_ptr (bfd *abfd, asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, int *insn_len, ++ int *seq_len, bfd_byte *contents) ++{ ++ Elf_Internal_Rela *ptr_irel, *irelend, *count_irel, *re_irel; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ ++ re_irel = ++ find_relocs_at_address_addr (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED, irel->r_addend); ++ ++ if (re_irel == irelend) ++ { ++ (*_bfd_error_handler) ++ ("%B: warning: R_NDS32_PTR points to unrecognized reloc at 0x%lx.", ++ abfd, (long) irel->r_offset); ++ return FALSE; ++ } ++ ++ if (re_irel->r_addend != 1) ++ return FALSE; ++ ++ /* Pointed target is relaxed and no longer needs this void *, ++ change the type to NONE. */ ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++ /* Find PTR_COUNT to decide remove it or not. If PTR_COUNT does ++ not exist, it means only count 1 and remove it directly. */ ++ /* TODO: I hope we can obsolate R_NDS32_COUNT in the future. */ ++ count_irel = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR_COUNT); ++ ptr_irel = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR); ++ if (count_irel != irelend) ++ { ++ if (--count_irel->r_addend > 0) ++ return FALSE; ++ } ++ ++ if (ptr_irel != irelend) ++ return FALSE; ++ ++ /* If the PTR_COUNT is already 0, remove current instruction. */ ++ *seq_len = nds32_elf_insn_size (abfd, contents, irel->r_offset); ++ *insn_len = 0; ++ return TRUE; ++} ++ ++/* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */ ++ ++static void ++nds32_elf_relax_pltgot_suff (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) ++{ ++ uint32_t insn; ++ bfd_signed_vma foff; ++ Elf_Internal_Rela *i1_irelfn, *irelend; ++ bfd_vma local_sda, laddr; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ ++ /* FIXME: It's a little trouble to turn JRAL5 to JAL since ++ we need additional space. It might be help if we could ++ borrow some space from instructions to be eliminated ++ such as sethi, ori, add. */ ++ if (insn & 0x80000000) ++ return; ++ ++ if (nds32_elf_check_dup_relocs ++ (irel, internal_relocs, irelend, R_NDS32_PLT_GOT_SUFF)) ++ return; ++ ++ i1_irelfn = ++ find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED); ++ ++ /* FIXIT 090606 ++ The boundary should be reduced since the .plt section hasn't ++ been created and the address of specific entry is still unknown ++ Maybe the range between the function call and the begin of the ++ .text section can be used to decide if the .plt is in the range ++ of function call. */ ++ ++ if (N32_OP6 (insn) == N32_OP6_ALU1 ++ && N32_SUB5 (insn) == N32_ALU1_ADD) ++ { ++ /* Get the value of the symbol referred to by the reloc. */ ++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, ++ &local_sda, FALSE); ++ foff = (bfd_signed_vma) (calculate_plt_memory_address ++ (abfd, link_info, isymbuf, irel, ++ symtab_hdr) - local_sda); ++ /* This condition only happened when symbol is undefined. */ ++ if (foff == 0) ++ return; ++ ++ if (foff < -CONSERVATIVE_19BIT || foff >= CONSERVATIVE_19BIT) ++ return; ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), ++ R_NDS32_PLT_GOTREL_LO19); ++ /* addi.gp */ ++ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19)); ++ } ++ else if (N32_OP6 (insn) == N32_OP6_JREG ++ && N32_SUB5 (insn) == N32_JREG_JRAL) ++ { ++ /* Get the value of the symbol referred to by the reloc. */ ++ foff = ++ calculate_plt_offset (abfd, sec, link_info, isymbuf, irel, symtab_hdr); ++ /* This condition only happened when symbol is undefined. */ ++ if (foff == 0) ++ return; ++ if (foff < -CONSERVATIVE_24BIT_S1 || foff >= CONSERVATIVE_24BIT_S1) ++ return; ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_25_PLTREL); ++ insn = INSN_JAL; ++ } ++ else ++ return; ++ ++ bfd_putb32 (insn, contents + laddr); ++ if (i1_irelfn != irelend) ++ { ++ i1_irelfn->r_addend |= 1; ++ *again = TRUE; ++ } ++} ++ ++/* Relax GOT_SUFF relocation for nds32_elf_relax_section. */ ++ ++static void ++nds32_elf_relax_got_suff (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, ++ bfd_byte *contents, Elf_Internal_Shdr *symtab_hdr, ++ bfd_boolean *again) ++{ ++ uint32_t insn; ++ bfd_signed_vma foff; ++ Elf_Internal_Rela *i1_irelfn, *irelend; ++ bfd_vma local_sda, laddr; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ if (insn & 0x80000000) ++ return; ++ ++ if (nds32_elf_check_dup_relocs ++ (irel, internal_relocs, irelend, R_NDS32_GOT_SUFF)) ++ return; ++ ++ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED); ++ ++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, ++ &local_sda, FALSE); ++ foff = calculate_got_memory_address (abfd, link_info, irel, ++ symtab_hdr) - local_sda; ++ ++ if (foff < CONSERVATIVE_19BIT && foff >= -CONSERVATIVE_19BIT) ++ { ++ /* Turn LW to LWI.GP. Change relocation type to R_NDS32_GOT_REL. */ ++ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_GOT17S2_RELA); ++ bfd_putb32 (insn, contents + laddr); ++ if (i1_irelfn != irelend) ++ { ++ i1_irelfn->r_addend |= 1; ++ *again = TRUE; ++ } ++ } ++} ++ ++/* Relax PLT_GOT_SUFF relocation for nds32_elf_relax_section. */ ++ ++static void ++nds32_elf_relax_gotoff_suff (struct bfd_link_info *link_info, bfd *abfd, ++ asection *sec, Elf_Internal_Rela *irel, ++ Elf_Internal_Rela *internal_relocs, ++ bfd_byte *contents, Elf_Internal_Sym *isymbuf, ++ Elf_Internal_Shdr *symtab_hdr, bfd_boolean *again) ++{ ++ int opc_insn_gotoff; ++ uint32_t insn; ++ bfd_signed_vma foff; ++ Elf_Internal_Rela *i1_irelfn, *i2_irelfn, *irelend; ++ bfd_vma local_sda, laddr; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ laddr = irel->r_offset; ++ insn = bfd_getb32 (contents + laddr); ++ ++ if (insn & 0x80000000) ++ return; ++ ++ if (nds32_elf_check_dup_relocs ++ (irel, internal_relocs, irelend, R_NDS32_GOTOFF_SUFF)) ++ return; ++ ++ i1_irelfn = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_PTR_RESOLVED); ++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, ++ &local_sda, FALSE); ++ foff = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); ++ foff = foff - local_sda; ++ ++ if (foff >= CONSERVATIVE_19BIT || foff < -CONSERVATIVE_19BIT) ++ return; ++ ++ /* Concatenate opcode and sub-opcode for switch case. ++ It may be MEM or ALU1. */ ++ opc_insn_gotoff = (N32_OP6 (insn) << 8) | (insn & 0xff); ++ switch (opc_insn_gotoff) ++ { ++ case (N32_OP6_MEM << 8) | N32_MEM_LW: ++ /* 4-byte aligned. */ ++ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (6, 17, 3)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA17S2_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_SW: ++ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __MF (7, 17, 3)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA17S2_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_LH: ++ /* 2-byte aligned. */ ++ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), 0); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_LHS: ++ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (18)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_SH: ++ insn = N32_TYPE1 (HWGP, N32_RT5 (insn), __BIT (19)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA18S1_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_LB: ++ /* 1-byte aligned. */ ++ insn = N32_TYPE1 (LBGP, N32_RT5 (insn), 0); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_LBS: ++ insn = N32_TYPE1 (LBGP, N32_RT5 (insn), __BIT (19)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA); ++ break; ++ case (N32_OP6_MEM << 8) | N32_MEM_SB: ++ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), 0); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA); ++ break; ++ case (N32_OP6_ALU1 << 8) | N32_ALU1_ADD: ++ insn = N32_TYPE1 (SBGP, N32_RT5 (insn), __BIT (19)); ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_SDA19S0_RELA); ++ break; ++ default: ++ return; ++ } ++ ++ bfd_putb32 (insn, contents + laddr); ++ if (i1_irelfn != irelend) ++ { ++ i1_irelfn->r_addend |= 1; ++ *again = TRUE; ++ } ++ if ((i2_irelfn = find_relocs_at_address (irel, internal_relocs, irelend, ++ R_NDS32_INSN16)) != irelend) ++ i2_irelfn->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ ++} ++ ++static bfd_boolean ++nds32_relax_adjust_label (bfd *abfd, asection *sec, ++ Elf_Internal_Rela *internal_relocs, ++ bfd_byte *contents, ++ nds32_elf_blank_t **relax_blank_list, ++ int optimize, int opt_size) ++{ ++ /* This code block is used to adjust 4-byte alignment by relax a pair ++ of instruction a time. ++ ++ It recognizes three types of relocations. ++ 1. R_NDS32_LABEL - a alignment. ++ 2. R_NDS32_INSN16 - relax a 32-bit instruction to 16-bit. ++ 3. is_16bit_NOP () - remove a 16-bit instruction. */ ++ ++ /* TODO: It seems currently implementation only support 4-byte alignment. ++ We should handle any-alignment. */ ++ ++ Elf_Internal_Rela *insn_rel = NULL, *label_rel = NULL, *irel; ++ Elf_Internal_Rela *tmp_rel, *tmp2_rel = NULL; ++ Elf_Internal_Rela rel_temp; ++ Elf_Internal_Rela *irelend; ++ bfd_vma address; ++ uint16_t insn16; ++ ++ /* Checking for branch relaxation relies on the relocations to ++ be sorted on 'r_offset'. This is not guaranteed so we must sort. */ ++ nds32_insertion_sort (internal_relocs, sec->reloc_count, ++ sizeof (Elf_Internal_Rela), compar_reloc); ++ ++ irelend = internal_relocs + sec->reloc_count; ++ ++ /* Force R_NDS32_LABEL before R_NDS32_INSN16. */ ++ /* FIXME: Can we generate the right order in assembler? ++ So we don't have to swapping them here. */ ++ ++ for (label_rel = internal_relocs, insn_rel = internal_relocs; ++ label_rel < irelend; label_rel++) ++ { ++ if (ELF32_R_TYPE (label_rel->r_info) != R_NDS32_LABEL) ++ continue; ++ ++ /* Find the first reloc has the same offset with label_rel. */ ++ while (insn_rel < irelend && insn_rel->r_offset < label_rel->r_offset) ++ insn_rel++; ++ ++ for (;insn_rel < irelend && insn_rel->r_offset == label_rel->r_offset; ++ insn_rel++) ++ /* Check if there were R_NDS32_INSN16 and R_NDS32_LABEL at the same ++ address. */ ++ if (ELF32_R_TYPE (insn_rel->r_info) == R_NDS32_INSN16) ++ break; ++ ++ if (insn_rel < irelend && insn_rel->r_offset == label_rel->r_offset ++ && insn_rel < label_rel) ++ { ++ /* Swap the two reloc if the R_NDS32_INSN16 is ++ before R_NDS32_LABEL. */ ++ memcpy (&rel_temp, insn_rel, sizeof (Elf_Internal_Rela)); ++ memcpy (insn_rel, label_rel, sizeof (Elf_Internal_Rela)); ++ memcpy (label_rel, &rel_temp, sizeof (Elf_Internal_Rela)); ++ } ++ } ++ ++ label_rel = NULL; ++ insn_rel = NULL; ++ /* If there were a sequence of R_NDS32_LABEL end up with .align 2 ++ or higher, remove other R_NDS32_LABEL with lower alignment. ++ If an R_NDS32_INSN16 in between R_NDS32_LABELs must be converted, ++ then the R_NDS32_LABEL sequence is broke. */ ++ for (tmp_rel = internal_relocs; tmp_rel < irelend; tmp_rel++) ++ { ++ if (ELF32_R_TYPE (tmp_rel->r_info) == R_NDS32_LABEL) ++ { ++ if (label_rel == NULL) ++ { ++ if (tmp_rel->r_addend < 2) ++ label_rel = tmp_rel; ++ continue; ++ } ++ else if (tmp_rel->r_addend > 1) ++ { ++ /* Remove all LABEL relocation from label_rel to tmp_rel ++ including relocations with same offset as tmp_rel. */ ++ for (tmp2_rel = label_rel; tmp2_rel < tmp_rel; tmp2_rel++) ++ { ++ if (tmp2_rel->r_offset == tmp_rel->r_offset) ++ break; ++ ++ if (ELF32_R_TYPE (tmp2_rel->r_info) == R_NDS32_LABEL ++ && tmp2_rel->r_addend < 2) ++ tmp2_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (tmp2_rel->r_info), ++ R_NDS32_NONE); ++ } ++ label_rel = NULL; ++ } ++ } ++ else if (ELF32_R_TYPE (tmp_rel->r_info) == R_NDS32_INSN16 && label_rel) ++ { ++ /* A new INSN16 which can be converted, so clear label_rel. */ ++ if (is_convert_32_to_16 (abfd, sec, tmp_rel, internal_relocs, ++ irelend, &insn16) ++ || is_16bit_NOP (abfd, sec, tmp_rel)) ++ label_rel = NULL; ++ } ++ } ++ ++ label_rel = NULL; ++ insn_rel = NULL; ++ /* Optimized for speed and nothing has not been relaxed. ++ It's time to align labels. ++ We may convert a 16-bit instruction right before a label to ++ 32-bit, in order to align the label if necessary ++ all reloc entries has been sorted by r_offset. */ ++ for (irel = internal_relocs; ++ irel < irelend && irel->r_offset < sec->size; irel++) ++ { ++ if (ELF32_R_TYPE (irel->r_info) != R_NDS32_INSN16 ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL) ++ continue; ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_INSN16) ++ { ++ /* A new INSN16 found, resize the old one. */ ++ if (is_convert_32_to_16 ++ (abfd, sec, irel, internal_relocs, irelend, &insn16) ++ || is_16bit_NOP (abfd, sec, irel)) ++ { ++ if (insn_rel) ++ { ++ /* Previous INSN16 reloc exists, reduce its ++ size to 16-bit. */ ++ if (is_convert_32_to_16 (abfd, sec, insn_rel, internal_relocs, ++ irelend, &insn16)) ++ { ++ nds32_elf_write_16 (abfd, contents, insn_rel, ++ internal_relocs, irelend, insn16); ++ ++ if (!insert_nds32_elf_blank_recalc_total ++ (relax_blank_list, insn_rel->r_offset + 2, 2)) ++ return FALSE; ++ } ++ else if (is_16bit_NOP (abfd, sec, insn_rel)) ++ { ++ if (!insert_nds32_elf_blank_recalc_total ++ (relax_blank_list, insn_rel->r_offset, 2)) ++ return FALSE; ++ } ++ insn_rel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (insn_rel->r_info), R_NDS32_NONE); ++ } ++ /* Save the new one for later use. */ ++ insn_rel = irel; ++ } ++ else ++ irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), ++ R_NDS32_NONE); ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL) ++ { ++ /* Search for label. */ ++ int force_relax = 0; ++ ++ /* Label on 16-bit instruction or optimization ++ needless, just reset this reloc. */ ++ insn16 = bfd_getb16 (contents + irel->r_offset); ++ if ((irel->r_addend & 0x1f) < 2 && (!optimize || (insn16 & 0x8000))) ++ { ++ irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_NDS32_NONE); ++ continue; ++ } ++ ++ address = ++ irel->r_offset - get_nds32_elf_blank_total (relax_blank_list, ++ irel->r_offset, 1); ++ ++ if (!insn_rel) ++ { ++ /* Check if there is case which can not be aligned. */ ++ if (irel->r_addend == 2 && address & 0x2) ++ return FALSE; ++ continue; ++ } ++ ++ /* Try to align this label. */ ++ ++ if ((irel->r_addend & 0x1f) < 2) ++ { ++ /* Check if there is a INSN16 at the same address. ++ Label_rel always seats before insn_rel after ++ our sort. */ ++ ++ /* Search for INSN16 at LABEL location. If INSN16 is at ++ same location and this LABEL alignment is lower than 2, ++ the INSN16 can be converted to 2-byte. */ ++ for (tmp_rel = irel; ++ tmp_rel < irelend && tmp_rel->r_offset == irel->r_offset; ++ tmp_rel++) ++ { ++ if (ELF32_R_TYPE (tmp_rel->r_info) == R_NDS32_INSN16 ++ && (is_convert_32_to_16 ++ (abfd, sec, tmp_rel, internal_relocs, ++ irelend, &insn16) ++ || is_16bit_NOP (abfd, sec, tmp_rel))) ++ { ++ force_relax = 1; ++ break; ++ } ++ } ++ } ++ ++ if (force_relax || irel->r_addend == 1 || address & 0x2) ++ { ++ /* Label not aligned. */ ++ /* Previous reloc exists, reduce its size to 16-bit. */ ++ if (is_convert_32_to_16 (abfd, sec, insn_rel, ++ internal_relocs, irelend, &insn16)) ++ { ++ nds32_elf_write_16 (abfd, contents, insn_rel, ++ internal_relocs, irelend, insn16); ++ ++ if (!insert_nds32_elf_blank_recalc_total ++ (relax_blank_list, insn_rel->r_offset + 2, 2)) ++ return FALSE; ++ } ++ else if (is_16bit_NOP (abfd, sec, insn_rel)) ++ { ++ if (!insert_nds32_elf_blank_recalc_total ++ (relax_blank_list, insn_rel->r_offset, 2)) ++ return FALSE; ++ } ++ ++ } ++ /* INSN16 reloc is used. */ ++ insn_rel = NULL; ++ } ++ } ++ ++ address = ++ sec->size - get_nds32_elf_blank_total (relax_blank_list, sec->size, 0); ++ if (insn_rel && (address & 0x2 || opt_size)) ++ { ++ if (is_convert_32_to_16 (abfd, sec, insn_rel, internal_relocs, ++ irelend, &insn16)) ++ { ++ nds32_elf_write_16 (abfd, contents, insn_rel, internal_relocs, ++ irelend, insn16); ++ if (!insert_nds32_elf_blank_recalc_total ++ (relax_blank_list, insn_rel->r_offset + 2, 2)) ++ return FALSE; ++ insn_rel->r_info = ELF32_R_INFO (ELF32_R_SYM (insn_rel->r_info), ++ R_NDS32_NONE); ++ } ++ else if (is_16bit_NOP (abfd, sec, insn_rel)) ++ { ++ if (!insert_nds32_elf_blank_recalc_total ++ (relax_blank_list, insn_rel->r_offset, 2)) ++ return FALSE; ++ insn_rel->r_info = ELF32_R_INFO (ELF32_R_SYM (insn_rel->r_info), ++ R_NDS32_NONE); ++ } ++ } ++ insn_rel = NULL; ++ return TRUE; ++} ++ ++/* Pick relaxation round. */ ++ ++static int ++nds32_elf_pick_relax (bfd_boolean init, asection *sec, bfd_boolean *again, ++ struct elf_nds32_link_hash_table *table, ++ struct bfd_link_info *link_info) ++{ ++ static asection *final_sec, *first_sec = NULL; ++ static bfd_boolean normal_again = FALSE; ++ static bfd_boolean set = FALSE; ++ static bfd_boolean first = TRUE; ++ int round_table[] = { ++ NDS32_RELAX_IFC_ROUND, ++ NDS32_RELAX_NORMAL_ROUND, ++ NDS32_RELAX_JUMP_IFC_ROUND, ++ NDS32_RELAX_EX9_BUILD_ROUND, ++ NDS32_RELAX_EX9_REPLACE_ROUND, ++ }; ++ static int pass = 0; ++ static int relax_round; ++ ++ /* The new round. */ ++ if (init && first_sec == sec) ++ { ++ set = TRUE; ++ normal_again = FALSE; ++ } ++ ++ if (first) ++ { ++ /* Run an empty run to get the final section. */ ++ relax_round = NDS32_RELAX_EMPTY_ROUND; ++ ++ /* We have to do ifc optimization before general relax. ++ Decide the first round here. */ ++ if (table->target_optimize & NDS32_RELAX_IFC_ON) ++ pass = 0; ++ else ++ pass = 1; ++ ++ /* It has to enter relax again because we can ++ not make sure what the final turn is. */ ++ *again = TRUE; ++ ++ first = FALSE; ++ first_sec = sec; ++ } ++ ++ if (!set) ++ { ++ /* Not reenter yet. */ ++ final_sec = sec; ++ return relax_round; ++ } ++ ++ relax_round = round_table[pass]; ++ ++ if (!init && relax_round == NDS32_RELAX_NORMAL_ROUND && *again) ++ normal_again = TRUE; ++ ++ if (!init && final_sec == sec) ++ { ++ switch (relax_round) ++ { ++ case NDS32_RELAX_IFC_ROUND: ++ nds32_elf_ifc_cse_algo (link_info); ++ *again = TRUE; ++ pass++; ++ break; ++ case NDS32_RELAX_NORMAL_ROUND: ++ if (!normal_again) ++ { ++ /* Normal relaxation done. */ ++ if (table->target_optimize & NDS32_RELAX_IFC_ON) ++ { ++ pass++; ++ *again = TRUE; ++ } ++ else if (table->target_optimize & NDS32_RELAX_EX9_ON) ++ { ++ pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */ ++ *again = TRUE; ++ } ++ else if (table->ex9_import_file) ++ { ++ /* Import ex9 table. */ ++ if (table->update_ex9_table) ++ pass += 2; /* NDS32_RELAX_EX9_BUILD_ROUND */ ++ else ++ pass += 3; /* NDS32_RELAX_EX9_REPLACE_ROUND */ ++ nds32_elf_ex9_import_table (link_info); ++ *again = TRUE; ++ } ++ } ++ break; ++ case NDS32_RELAX_JUMP_IFC_ROUND: ++ if (!nds32_elf_ifc_finish (link_info)) ++ (*_bfd_error_handler) (_("error: Jump IFC Fail.")); ++ if (table->target_optimize & NDS32_RELAX_EX9_ON) ++ { ++ pass++; ++ *again = TRUE; ++ } ++ break; ++ case NDS32_RELAX_EX9_BUILD_ROUND: ++ nds32_elf_ex9_finish (link_info); ++ pass++; ++ *again = TRUE; ++ break; ++ case NDS32_RELAX_EX9_REPLACE_ROUND: ++ if (table->target_optimize & NDS32_RELAX_IFC_ON) ++ { ++ /* Do jump IFC optimization again. */ ++ if (!nds32_elf_ifc_finish (link_info)) ++ (*_bfd_error_handler) (_("error: Jump IFC Fail.")); ++ } ++ break; ++ default: ++ break; ++ } ++ } ++ ++ return relax_round; ++} ++ ++static bfd_boolean ++nds32_elf_relax_section (bfd *abfd, asection *sec, ++ struct bfd_link_info *link_info, bfd_boolean *again) ++{ ++ nds32_elf_blank_t *relax_blank_list = NULL; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *irelend; ++ Elf_Internal_Sym *isymbuf = NULL; ++ bfd_byte *contents = NULL; ++ bfd_boolean result = TRUE; ++ int optimize = 0; ++ int opt_size = 0; ++ uint32_t insn; ++ uint16_t insn16; ++ ++ /* Target dependent option. */ ++ struct elf_nds32_link_hash_table *table; ++ int load_store_relax; ++ int relax_round; ++ ++ relax_blank_list = NULL; ++ *again = FALSE; ++ ++ /* Nothing to do for ++ relocatable link or ++ non-relocatable section or ++ non-code section or ++ empty content or ++ no reloc entry. */ ++ if (link_info->relocatable ++ || (sec->flags & SEC_RELOC) == 0 ++ || (sec->flags & SEC_EXCLUDE) == 1 ++ || (sec->flags & SEC_CODE) == 0 ++ || sec->size == 0 ++ || sec->reloc_count == 0) ++ return TRUE; ++ ++ /* 09.12.11 Workaround. */ ++ /* We have to adjust align for R_NDS32_LABEL if needed. ++ The adjust approach only can fix 2-byte align once. */ ++ if (sec->alignment_power > 2) ++ return TRUE; ++ ++#ifdef NDS32_LINUX_TOOLCHAIN ++ /* Do TLS model conversion once at first. */ ++ nds32_elf_unify_tls_model (abfd, sec, contents, link_info); ++#endif ++ ++ /* The optimization type to do. */ ++ ++ table = nds32_elf_hash_table (link_info); ++ relax_round = nds32_elf_pick_relax (TRUE, sec, again, table, link_info); ++ ++ switch (relax_round) ++ { ++ case NDS32_RELAX_JUMP_IFC_ROUND: ++ /* Here is the entrance of ifc jump relaxation. */ ++ if (!nds32_elf_ifc_calc (link_info, abfd, sec)) ++ return FALSE; ++ nds32_elf_pick_relax (FALSE, sec, again, table, link_info); ++ return TRUE; ++ ++ case NDS32_RELAX_EX9_BUILD_ROUND: ++ /* Here is the entrance of ex9 relaxation. There are two pass of ++ ex9 relaxation. The one is to traverse all instructions and build ++ the hash table. The other one is to compare instructions and replace ++ it by ex9.it. */ ++ if (!nds32_elf_ex9_build_hash_table (abfd, sec, link_info)) ++ return FALSE; ++ nds32_elf_pick_relax (FALSE, sec, again, table, link_info); ++ return TRUE; ++ ++ case NDS32_RELAX_EX9_REPLACE_ROUND: ++ if (!nds32_elf_ex9_replace_instruction (link_info, abfd, sec)) ++ return FALSE; ++ return TRUE; ++ ++ case NDS32_RELAX_IFC_ROUND: ++ /* The entrance of link time ifc. We must to do it before all relaxation ++ beginging, because it may magnify size. */ ++ if (!nds32_elf_ifc_trace_code (link_info, abfd, sec)) ++ return FALSE; ++ nds32_elf_pick_relax (FALSE, sec, again, table, link_info); ++ return TRUE; ++ ++ case NDS32_RELAX_EMPTY_ROUND: ++ nds32_elf_pick_relax (FALSE, sec, again, table, link_info); ++ return TRUE; ++ ++ case NDS32_RELAX_NORMAL_ROUND: ++ /* Save the first section for abs symbol relaxation. */ ++ nds32_elf_relax_guard (NULL, 0, sec, NULL, again, TRUE, ++ table, NULL, NULL); ++ default: ++ if (sec->reloc_count == 0) ++ return TRUE; ++ break; ++ } ++ ++ /* The begining of general relaxation. */ ++ ++ if (is_SDA_BASE_set == 0) ++ { ++ bfd_vma gp; ++ is_SDA_BASE_set = 1; ++ nds32_elf_final_sda_base (sec->output_section->owner, link_info, ++ &gp, FALSE); ++ relax_range_measurement (abfd); ++ } ++ ++ if (is_ITB_BASE_set == 0) ++ { ++ /* Set the _ITB_BASE_. */ ++ if (!nds32_elf_ex9_itb_base (link_info)) ++ { ++ (*_bfd_error_handler) (_("%B: error: Cannot set _ITB_BASE_"), abfd); ++ bfd_set_error (bfd_error_bad_value); ++ } ++ } ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ if (internal_relocs == NULL) ++ goto error_return; ++ ++ irelend = internal_relocs + sec->reloc_count; ++ irel = find_relocs_at_address (internal_relocs, internal_relocs, ++ irelend, R_NDS32_RELAX_ENTRY); ++ ++ if (irel == irelend) ++ return TRUE; ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY) ++ { ++ if (irel->r_addend & R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG) ++ { ++ nds32_elf_pick_relax (FALSE, sec, again, table, link_info); ++ return TRUE; ++ } ++ ++ if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG) ++ optimize = 1; ++ ++ if (irel->r_addend & R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG) ++ opt_size = 1; ++ } ++ ++ load_store_relax = table->load_store_relax; ++ ++ /* Get symbol table and section content. */ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE) ++ || !nds32_get_local_syms (abfd, sec, &isymbuf)) ++ goto error_return; ++ ++ /* Do relax loop only when finalize is not done. ++ Take care of relaxable relocs except INSN16. */ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ int seq_len; /* Original length of instruction sequence. */ ++ int insn_len = 0; /* Final length of instruction sequence. */ ++ bfd_boolean removed; ++ ++ insn = 0; ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ && (irel->r_addend & 0x1f) >= 2) ++ optimize = 1; ++ ++ /* Relocation Types ++ R_NDS32_LONGCALL1 53 ++ R_NDS32_LONGCALL2 54 ++ R_NDS32_LONGCALL3 55 ++ R_NDS32_LONGJUMP1 56 ++ R_NDS32_LONGJUMP2 57 ++ R_NDS32_LONGJUMP3 58 ++ R_NDS32_LOADSTORE 59 */ ++ if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_LONGCALL1 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_LOADSTORE) ++ seq_len = GET_SEQ_LEN (irel->r_addend); ++ ++ /* Relocation Types ++ R_NDS32_LONGCALL4 107 ++ R_NDS32_LONGCALL5 108 ++ R_NDS32_LONGCALL6 109 ++ R_NDS32_LONGJUMP4 110 ++ R_NDS32_LONGJUMP5 111 ++ R_NDS32_LONGJUMP6 112 ++ R_NDS32_LONGJUMP7 113 */ ++ else if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_LONGCALL4 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_LONGJUMP7) ++ seq_len = 4; ++ ++ /* Relocation Types ++ R_NDS32_LO12S0_RELA 30 ++ R_NDS32_LO12S1_RELA 29 ++ R_NDS32_LO12S2_RELA 28 ++ R_NDS32_LO12S2_SP_RELA 71 ++ R_NDS32_LO12S2_DP_RELA 70 ++ R_NDS32_GOT_LO12 46 ++ R_NDS32_GOTOFF_LO12 50 ++ R_NDS32_PLTREL_LO12 65 ++ R_NDS32_PLT_GOTREL_LO12 67 ++ R_NDS32_17IFC_PCREL_RELA 96 ++ R_NDS32_GOT_SUFF 193 ++ R_NDS32_GOTOFF_SUFF 194 ++ R_NDS32_PLT_GOT_SUFF 195 ++ R_NDS32_MULCALL_SUFF 196 ++ R_NDS32_PTR 197 */ ++ else if ((ELF32_R_TYPE (irel->r_info) <= R_NDS32_LO12S0_RELA ++ && ELF32_R_TYPE (irel->r_info) >= R_NDS32_LO12S2_RELA) ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_SP_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_DP_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_GOT_LO12 ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTOFF_LO12 ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_GOTPC_LO12 ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_PLTREL_LO12 ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_PLT_GOTREL_LO12 ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_GOT_SUFF ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_PTR) ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_17IFC_PCREL_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LO12 ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_ADD ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_TLS_LE_LS) ++ seq_len = 0; ++ else ++ continue; ++ ++ insn_len = seq_len; ++ removed = FALSE; ++ ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ case R_NDS32_LONGCALL1: ++ removed = nds32_elf_relax_longcall1 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGCALL2: ++ removed = nds32_elf_relax_longcall2 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGCALL3: ++ removed = nds32_elf_relax_longcall3 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP1: ++ removed = nds32_elf_relax_longjump1 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP2: ++ removed = nds32_elf_relax_longjump2 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP3: ++ removed = nds32_elf_relax_longjump3 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGCALL4: ++ removed = nds32_elf_relax_longcall4 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGCALL5: ++ removed = nds32_elf_relax_longcall5 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGCALL6: ++ removed = nds32_elf_relax_longcall6 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP4: ++ removed = nds32_elf_relax_longjump4 (abfd, sec, irel, internal_relocs, ++ &insn_len, contents, isymbuf, ++ symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP5: ++ removed = nds32_elf_relax_longjump5 (abfd, sec, irel, internal_relocs, ++ &insn_len, &seq_len, contents, ++ isymbuf, symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP6: ++ removed = nds32_elf_relax_longjump6 (abfd, sec, irel, internal_relocs, ++ &insn_len, &seq_len, contents, ++ isymbuf, symtab_hdr); ++ break; ++ case R_NDS32_LONGJUMP7: ++ removed = nds32_elf_relax_longjump7 (abfd, sec, irel, internal_relocs, ++ &insn_len, &seq_len, contents, ++ isymbuf, symtab_hdr); ++ break; ++ case R_NDS32_LOADSTORE: ++ removed = nds32_elf_relax_loadstore (link_info, abfd, sec, irel, ++ internal_relocs, &insn_len, ++ contents, isymbuf, symtab_hdr, ++ load_store_relax, table); ++ break; ++ case R_NDS32_LO12S0_RELA: ++ case R_NDS32_LO12S1_RELA: ++ case R_NDS32_LO12S2_RELA: ++ case R_NDS32_LO12S2_DP_RELA: ++ case R_NDS32_LO12S2_SP_RELA: ++ /* Relax for low part. */ ++ nds32_elf_relax_lo12 (link_info, abfd, sec, irel, internal_relocs, ++ contents, isymbuf, symtab_hdr, table); ++ ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ case R_NDS32_GOT_LO12: ++ case R_NDS32_GOTOFF_LO12: ++ case R_NDS32_PLTREL_LO12: ++ case R_NDS32_PLT_GOTREL_LO12: ++ case R_NDS32_GOTPC_LO12: ++ /* Relax for PIC gp-relative low part. */ ++ nds32_elf_relax_piclo12 (link_info, abfd, sec, irel, contents, ++ isymbuf, symtab_hdr); ++ ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ case R_NDS32_TLS_LE_LO12: ++ /* Relax for LE TLS low part. */ ++ nds32_elf_relax_letlslo12 (link_info, abfd, irel, contents, ++ isymbuf, symtab_hdr); ++ ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ case R_NDS32_TLS_LE_ADD: ++ nds32_elf_relax_letlsadd (link_info, abfd, sec, irel, internal_relocs, ++ contents, isymbuf, symtab_hdr, again); ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ case R_NDS32_TLS_LE_LS: ++ nds32_elf_relax_letlsls (link_info, abfd, sec, irel, internal_relocs, ++ contents, isymbuf, symtab_hdr, again); ++ continue; ++ case R_NDS32_PTR: ++ removed = nds32_elf_relax_ptr (abfd, sec, irel, internal_relocs, ++ &insn_len, &seq_len, contents); ++ break; ++ case R_NDS32_PLT_GOT_SUFF: ++ nds32_elf_relax_pltgot_suff (link_info, abfd, sec, irel, ++ internal_relocs, contents, ++ isymbuf, symtab_hdr, again); ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ case R_NDS32_GOT_SUFF: ++ nds32_elf_relax_got_suff (link_info, abfd, sec, irel, ++ internal_relocs, contents, ++ symtab_hdr, again); ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ case R_NDS32_GOTOFF_SUFF: ++ nds32_elf_relax_gotoff_suff (link_info, abfd, sec, irel, ++ internal_relocs, contents, ++ isymbuf, symtab_hdr, again); ++ /* It is impossible to delete blank, so just continue. */ ++ continue; ++ default: ++ continue; ++ ++ } ++ if (removed && seq_len - insn_len > 0) ++ { ++ if (!insert_nds32_elf_blank ++ (&relax_blank_list, irel->r_offset + insn_len, ++ seq_len - insn_len)) ++ goto error_return; ++ *again = TRUE; ++ } ++ } ++ ++ calc_nds32_blank_total (relax_blank_list); ++ ++ if (table->relax_fp_as_gp) ++ { ++ if (!nds32_relax_fp_as_gp (link_info, abfd, sec, internal_relocs, ++ irelend, isymbuf)) ++ goto error_return; ++ ++ if (*again == FALSE) ++ { ++ if (!nds32_fag_remove_unused_fpbase (abfd, sec, internal_relocs, ++ irelend)) ++ goto error_return; ++ } ++ } ++ ++ nds32_elf_pick_relax (FALSE, sec, again, table, link_info); ++ ++ if (*again == FALSE) ++ { ++ if (!nds32_relax_adjust_label (abfd, sec, internal_relocs, contents, ++ &relax_blank_list, optimize, opt_size)) ++ goto error_return; ++ } ++ ++ /* It doesn't matter optimize_for_space_no_align anymore. ++ If object file is assembled with flag '-Os', ++ the we don't adjust jump-destination on 4-byte boundary. */ ++ ++ if (relax_blank_list) ++ { ++ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list); ++ relax_blank_list = NULL; ++ } ++ ++ if (*again == FALSE) ++ { ++ /* Closing the section, so we don't relax it anymore. */ ++ bfd_vma sec_size_align; ++ Elf_Internal_Rela *tmp_rel; ++ ++ /* Pad to alignment boundary. Only handle current section alignment. */ ++ sec_size_align = (sec->size + (~((bfd_vma)(-1) << sec->alignment_power))) ++ & ((bfd_vma)(-1) << sec->alignment_power); ++ if ((sec_size_align - sec->size) & 0x2) ++ { ++ insn16 = NDS32_NOP16; ++ bfd_putb16 (insn16, contents + sec->size); ++ sec->size += 2; ++ } ++ ++ while (sec_size_align != sec->size) ++ { ++ insn = NDS32_NOP32; ++ bfd_putb32 (insn, contents + sec->size); ++ sec->size += 4; ++ } ++ ++ tmp_rel = find_relocs_at_address (internal_relocs, internal_relocs, ++ irelend, R_NDS32_RELAX_ENTRY); ++ if (tmp_rel != irelend) ++ tmp_rel->r_addend |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG; ++ ++ clean_nds32_elf_blank (); ++ } ++ ++finish: ++ if (internal_relocs != NULL ++ && elf_section_data (sec)->relocs != internal_relocs) ++ free (internal_relocs); ++ ++ if (contents != NULL ++ && elf_section_data (sec)->this_hdr.contents != contents) ++ free (contents); ++ ++ if (isymbuf != NULL && symtab_hdr->contents != (bfd_byte *) isymbuf) ++ free (isymbuf); ++ ++ return result; ++ ++error_return: ++ result = FALSE; ++ goto finish; ++} ++ ++static struct bfd_elf_special_section const nds32_elf_special_sections[] = { ++ {".sdata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE}, ++ {".sbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE}, ++ {NULL, 0, 0, 0, 0} ++}; ++ ++static bfd_boolean ++nds32_elf_output_arch_syms (bfd *output_bfd ATTRIBUTE_UNUSED, ++ struct bfd_link_info *info, ++ void *finfo ATTRIBUTE_UNUSED, ++ bfd_boolean (*func) (void *, const char *, ++ Elf_Internal_Sym *, ++ asection *, ++ struct elf_link_hash_entry *) ++ ATTRIBUTE_UNUSED) ++{ ++ FILE *sym_ld_script = NULL; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (info); ++ sym_ld_script = table->sym_ld_script; ++ ++ if (check_start_export_sym) ++ fprintf (sym_ld_script, "}\n"); ++ ++ return TRUE; ++} ++ ++static enum elf_reloc_type_class ++nds32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ const asection *rel_sec ATTRIBUTE_UNUSED, ++ const Elf_Internal_Rela *rela) ++{ ++ switch ((int) ELF32_R_TYPE (rela->r_info)) ++ { ++ case R_NDS32_RELATIVE: ++ return reloc_class_relative; ++ case R_NDS32_JMP_SLOT: ++ return reloc_class_plt; ++ case R_NDS32_COPY: ++ return reloc_class_copy; ++ default: ++ return reloc_class_normal; ++ } ++} ++ ++/* Put target dependent option into info hash table. */ ++void ++bfd_elf32_nds32_set_target_option (struct bfd_link_info *link_info, ++ int relax_fp_as_gp, ++ int eliminate_gc_relocs, ++ FILE * sym_ld_script, int load_store_relax, ++ int target_optimize, int relax_status, ++ int relax_round, FILE * ex9_export_file, ++ FILE * ex9_import_file, ++ int update_ex9_table, int ex9_limit, ++ bfd_boolean ex9_loop_aware, ++ bfd_boolean ifc_loop_aware, ++ int hyper_relax) ++{ ++ struct elf_nds32_link_hash_table *table; ++ ++ /* Initialize indirect call hash table. */ ++ nds32_elf_ict_hash_init (); ++ ++ table = nds32_elf_hash_table (link_info); ++ if (table == NULL) ++ return; ++ ++ table->relax_fp_as_gp = relax_fp_as_gp; ++ table->eliminate_gc_relocs = eliminate_gc_relocs; ++ table->sym_ld_script = sym_ld_script; ++ table ->load_store_relax = load_store_relax; ++ table->target_optimize = target_optimize; ++ table->relax_status = relax_status; ++ table->relax_round = relax_round; ++ table->ex9_export_file = ex9_export_file; ++ table->ex9_import_file = ex9_import_file; ++ table->update_ex9_table = update_ex9_table; ++ table->ex9_limit = ex9_limit; ++ table->ex9_loop_aware = ex9_loop_aware; ++ table->ifc_loop_aware = ifc_loop_aware; ++ table->hyper_relax = hyper_relax; ++ ++ /* We have to do ifc optimization before general relax. */ ++ if (target_optimize & NDS32_RELAX_IFC_ON) ++ { ++ /* Initialize ifc hash table. */ ++ if (!nds32_elf_ifc_init ()) ++ return; ++ } ++ if (target_optimize & NDS32_RELAX_EX9_ON ++ || (ex9_import_file != NULL && update_ex9_table == 1)) ++ { ++ /* Initialize ex9 hash table. */ ++ if (!nds32_elf_ex9_init ()) ++ return; ++ } ++} ++ ++void ++bfd_elf32_nds32_append_section (struct bfd_link_info *link_info, ++ bfd *abfd, int target_optimize) ++{ ++ asection *itable; ++ struct bfd_link_hash_entry *h; ++ unsigned int i, count = 0; ++ ++ /* Insert section ".ex9.itable". */ ++ if (target_optimize & NDS32_RELAX_EX9_ON) ++ { ++ itable = bfd_make_section_with_flags (abfd, ".ex9.itable", ++ SEC_CODE | SEC_ALLOC | SEC_LOAD ++ | SEC_HAS_CONTENTS | SEC_READONLY ++ | SEC_IN_MEMORY | SEC_KEEP ++ | SEC_RELOC); ++ if (itable) ++ { ++ itable->gc_mark = 1; ++ itable->alignment_power = 2; ++ itable->size = 0x1000; ++ itable->contents = bfd_zalloc (abfd, itable->size); ++ ++ /* Add a symbol in the head of ex9.itable to objdump clearly. */ ++ h = bfd_link_hash_lookup (link_info->hash, "_EX9_BASE_", ++ FALSE, FALSE, FALSE); ++ _bfd_generic_link_add_one_symbol ++ (link_info, link_info->output_bfd, "_EX9_BASE_", ++ BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE, ++ get_elf_backend_data (link_info->output_bfd)->collect, &h); ++ } ++ } ++ ++ /* Count number of indirect call function. */ ++ indirect_call_table.frozen = 1; ++ for (i = 0; i < indirect_call_table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ struct elf_nds32_ict_hash_entry *entry; ++ ++ for (p = indirect_call_table.table[i]; p != NULL; p = p->next) ++ { ++ entry = (struct elf_nds32_ict_hash_entry *) p; ++ entry->order = count; ++ count++; ++ } ++ } ++ indirect_call_table.frozen = 0; ++ ++ if (count) ++ { ++ h = bfd_link_hash_lookup (link_info->hash, "_INDIRECT_CALL_TABLE_BASE_", ++ FALSE, FALSE, FALSE); ++ if (h && (h->type == bfd_link_hash_defined ++ || h->type == bfd_link_hash_defweak ++ || h->type == bfd_link_hash_common)) ++ { ++ (*_bfd_error_handler) (_("Warning: _INDIRECT_CALL_TABLE_BASE_ has already" ++ "be defined. All ICT suffix is ignored.")); ++ ignore_indirect_call = TRUE; ++ return; ++ } ++ ++ itable = bfd_make_section_with_flags (abfd, NDS32_ICT_SECTION, ++ SEC_CODE | SEC_ALLOC | SEC_LOAD ++ | SEC_HAS_CONTENTS | SEC_READONLY ++ | SEC_IN_MEMORY | SEC_KEEP ++ | SEC_RELOC); ++ if (itable) ++ { ++ itable->gc_mark = 1; ++ itable->alignment_power = 2; ++ itable->size = count * 4; ++ itable->contents = bfd_zalloc (abfd, itable->size); ++ ++ /* Add a symbol in the head of .nds32.ict to objdump clearly. */ ++ h = bfd_link_hash_lookup (link_info->hash, ++ "_INDIRECT_CALL_TABLE_BASE_", ++ FALSE, FALSE, FALSE); ++ _bfd_generic_link_add_one_symbol ++ (link_info, link_info->output_bfd, "_INDIRECT_CALL_TABLE_BASE_", ++ BSF_GLOBAL | BSF_WEAK, itable, 0, (const char *) NULL, FALSE, ++ get_elf_backend_data (link_info->output_bfd)->collect, &h); ++ } ++ ++ ict_file = fopen ("nds32_ict.s", FOPEN_WT); ++ if(ict_file == NULL) ++ (*_bfd_error_handler) (_("Warning: Fail to build nds32_ict.s.")); ++ } ++} ++ ++/* These functions and data-structures are used for fp-as-gp ++ optimization. */ ++ ++#define FAG_THRESHOLD 3 /* At least 3 gp-access. */ ++/* lwi37.fp covers 508 bytes, but there may be 32-byte padding between ++ the read-only section and read-write section. */ ++#define FAG_WINDOW (508 - 32) ++ ++/* An nds32_fag represent a gp-relative access. ++ We find best fp-base by using a sliding window ++ to find a base address which can cover most gp-access. */ ++struct nds32_fag ++{ ++ struct nds32_fag *next; /* NULL-teminated linked list. */ ++ bfd_vma addr; /* The address of this fag. */ ++ Elf_Internal_Rela **relas; /* The relocations associated with this fag. ++ It is used for applying FP7U2_FLAG. */ ++ int count; /* How many times this address is referred. ++ There should be exactly `count' relocations ++ in relas. */ ++ int relas_capcity; /* The buffer size of relas. ++ We use an array instead of linked-list, ++ and realloc is used to adjust buffer size. */ ++}; ++ ++static void ++nds32_fag_init (struct nds32_fag *head) ++{ ++ memset (head, 0, sizeof (struct nds32_fag)); ++} ++ ++static void ++nds32_fag_verify (struct nds32_fag *head) ++{ ++ struct nds32_fag *iter; ++ struct nds32_fag *prev; ++ ++ prev = NULL; ++ iter = head->next; ++ while (iter) ++ { ++ if (prev && prev->addr >= iter->addr) ++ puts ("Bug in fp-as-gp insertion."); ++ prev = iter; ++ iter = iter->next; ++ } ++} ++ ++/* Insert a fag in ascending order. ++ If a fag of the same address already exists, ++ they are chained by relas array. */ ++ ++static void ++nds32_fag_insert (struct nds32_fag *head, bfd_vma addr, ++ Elf_Internal_Rela * rel) ++{ ++ struct nds32_fag *iter; ++ struct nds32_fag *new_fag; ++ const int INIT_RELAS_CAP = 4; ++ ++ for (iter = head; ++ iter->next && iter->next->addr <= addr; ++ iter = iter->next) ++ /* Find somewhere to insert. */ ; ++ ++ /* `iter' will be equal to `head' if the list is empty. */ ++ if (iter != head && iter->addr == addr) ++ { ++ /* The address exists in the list. ++ Insert `rel' into relocation list, relas. */ ++ ++ /* Check whether relas is big enough. */ ++ if (iter->count >= iter->relas_capcity) ++ { ++ iter->relas_capcity *= 2; ++ iter->relas = bfd_realloc ++ (iter->relas, iter->relas_capcity * sizeof (void *)); ++ } ++ iter->relas[iter->count++] = rel; ++ return; ++ } ++ ++ /* This is a new address. Create a fag node for it. */ ++ new_fag = bfd_malloc (sizeof (struct nds32_fag)); ++ memset (new_fag, 0, sizeof (*new_fag)); ++ new_fag->addr = addr; ++ new_fag->count = 1; ++ new_fag->next = iter->next; ++ new_fag->relas_capcity = INIT_RELAS_CAP; ++ new_fag->relas = (Elf_Internal_Rela **) ++ bfd_malloc (new_fag->relas_capcity * sizeof (void *)); ++ new_fag->relas[0] = rel; ++ iter->next = new_fag; ++ ++ nds32_fag_verify (head); ++} ++ ++static void ++nds32_fag_free_list (struct nds32_fag *head) ++{ ++ struct nds32_fag *iter; ++ ++ iter = head->next; ++ while (iter) ++ { ++ struct nds32_fag *tmp = iter; ++ iter = iter->next; ++ free (tmp->relas); ++ tmp->relas = NULL; ++ free (tmp); ++ } ++} ++ ++/* Find the best fp-base address. ++ The relocation associated with that address is returned, ++ so we can track the symbol instead of a fixed address. ++ ++ When relaxation, the address of an datum may change, ++ because a text section is shrinked, so the data section ++ moves forward. If the aligments of text and data section ++ are different, their distance may change too. ++ Therefore, tracking a fixed address is not appriate. */ ++ ++static int ++nds32_fag_find_base (struct nds32_fag *head, struct nds32_fag **bestpp) ++{ ++ struct nds32_fag *base; /* First fag in the window. */ ++ struct nds32_fag *last; /* First fag outside the window. */ ++ int accu = 0; /* Usage accumulation. */ ++ struct nds32_fag *best; /* Best fag. */ ++ int baccu = 0; /* Best accumulation. */ ++ ++ /* Use first fag for initial, and find the last fag in the window. ++ ++ In each iteration, we could simply subtract previous fag ++ and accumulate following fags which are inside the window, ++ untill we each the end. */ ++ ++ if (head->next == NULL) ++ { ++ *bestpp = NULL; ++ return 0; ++ } ++ ++ /* Initialize base. */ ++ base = head->next; ++ best = base; ++ for (last = base; ++ last && last->addr < base->addr + FAG_WINDOW; ++ last = last->next) ++ accu += last->count; ++ ++ baccu = accu; ++ ++ /* Record the best base in each iteration. */ ++ while (base->next) ++ { ++ accu -= base->count; ++ base = base->next; ++ /* Account fags in window. */ ++ for (/* Nothing. */; ++ last && last->addr < base->addr + FAG_WINDOW; ++ last = last->next) ++ accu += last->count; ++ ++ /* A better fp-base? */ ++ if (accu > baccu) ++ { ++ best = base; ++ baccu = accu; ++ } ++ } ++ ++ if (bestpp) ++ *bestpp = best; ++ return baccu; ++} ++ ++/* Apply R_NDS32_INSN16_FP7U2_FLAG on gp-relative accesses, ++ so we can convert it fo fp-relative access later. ++ `best_fag' is the best fp-base. Only those inside the window ++ of best_fag is applied the flag. */ ++ ++static bfd_boolean ++nds32_fag_mark_relax (struct bfd_link_info *link_info, ++ asection *sec, struct nds32_fag *best_fag, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend) ++{ ++ struct nds32_fag *ifag; ++ bfd_vma best_fpbase, gp; ++ bfd *output_bfd; ++ ++ output_bfd = sec->output_section->owner; ++ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); ++ best_fpbase = best_fag->addr; ++ ++ if (best_fpbase > gp + sdata_range[1][1] ++ || best_fpbase < gp - sdata_range[1][0]) ++ return FALSE; ++ ++ /* Mark these inside the window R_NDS32_INSN16_FP7U2_FLAG flag, ++ so we know they can be converted to lwi37.fp. */ ++ for (ifag = best_fag; ++ ifag && ifag->addr < best_fpbase + FAG_WINDOW; ifag = ifag->next) ++ { ++ int i; ++ ++ for (i = 0; i < ifag->count; i++) ++ { ++ Elf_Internal_Rela *insn16_rel; ++ Elf_Internal_Rela *fag_rel; ++ ++ fag_rel = ifag->relas[i]; ++ ++ /* Only if this is within the WINDOWS, FP7U2_FLAG ++ is applied. */ ++ ++ insn16_rel = find_relocs_at_address ++ (fag_rel, internal_relocs, irelend, R_NDS32_INSN16); ++ ++ if (insn16_rel != irelend) ++ insn16_rel->r_addend = R_NDS32_INSN16_FP7U2_FLAG; ++ } ++ } ++ return TRUE; ++} ++ ++/* Reset INSN16 to clean fp as gp. */ ++ ++static void ++nds32_fag_unmark_relax (struct nds32_fag *fag, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend) ++{ ++ struct nds32_fag *ifag; ++ int i; ++ Elf_Internal_Rela *insn16_rel; ++ Elf_Internal_Rela *fag_rel; ++ ++ for (ifag = fag; ifag; ifag = ifag->next) ++ { ++ for (i = 0; i < ifag->count; i++) ++ { ++ fag_rel = ifag->relas[i]; ++ ++ /* Restore the INSN16 relocation. */ ++ insn16_rel = find_relocs_at_address ++ (fag_rel, internal_relocs, irelend, R_NDS32_INSN16); ++ ++ if (insn16_rel != irelend) ++ insn16_rel->r_addend &= ~R_NDS32_INSN16_FP7U2_FLAG; ++ } ++ } ++} ++ ++/* This is the main function of fp-as-gp optimization. ++ It should be called by relax_section. */ ++ ++static bfd_boolean ++nds32_relax_fp_as_gp (struct bfd_link_info *link_info, ++ bfd *abfd, asection *sec, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend, ++ Elf_Internal_Sym *isymbuf) ++{ ++ Elf_Internal_Rela *begin_rel = NULL; ++ Elf_Internal_Rela *irel; ++ struct nds32_fag fag_head; ++ Elf_Internal_Shdr *symtab_hdr; ++ bfd_byte *contents; ++ bfd_boolean ifc_inside = FALSE; ++ ++ /* FIXME: Can we bfd_elf_link_read_relocs for the relocs? */ ++ ++ /* Per-function fp-base selection. ++ 1. Create a list for all the gp-relative access. ++ 2. Base on those gp-relative address, ++ find a fp-base which can cover most access. ++ 3. Use the fp-base for fp-as-gp relaxation. ++ ++ NOTE: If fp-as-gp is not worth to do, (e.g., less than 3 times), ++ we should ++ 1. delete the `la $fp, _FP_BASE_' instruction and ++ 2. not convert lwi.gp to lwi37.fp. ++ ++ To delete the _FP_BASE_ instruction, we simply apply ++ R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG flag in the r_addend to disable it. ++ ++ To suppress the conversion, we simply NOT to apply ++ R_NDS32_INSN16_FP7U2_FLAG flag. */ ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE) ++ || !nds32_get_local_syms (abfd, sec, &isymbuf)) ++ return FALSE; ++ ++ /* Check whether it is worth for fp-as-gp optimization, ++ i.e., at least 3 gp-load. ++ ++ Set R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG if we should NOT ++ apply this optimization. */ ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ /* We recognize R_NDS32_RELAX_REGION_BEGIN/_END for the region. ++ One we enter the begin of the region, we track all the LW/ST ++ instructions, so when we leave the region, we try to find ++ the best fp-base address for those LW/ST instructions. */ ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN ++ && (irel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ { ++ /* Begin of the region. */ ++ if (begin_rel) ++ (*_bfd_error_handler) (_("%B: Nested OMIT_FP in %A."), abfd, sec); ++ ++ begin_rel = irel; ++ nds32_fag_init (&fag_head); ++ ifc_inside = FALSE; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END ++ && (irel->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ { ++ int accu; ++ struct nds32_fag *best_fag, *tmp_fag; ++ int dist; ++ ++ /* End of the region. ++ Check whether it is worth to do fp-as-gp. */ ++ ++ if (begin_rel == NULL) ++ { ++ (*_bfd_error_handler) (_("%B: Unmatched OMIT_FP in %A."), abfd, sec); ++ continue; ++ } ++ ++ accu = nds32_fag_find_base (&fag_head, &best_fag); ++ ++ /* Clean FP7U2_FLAG because they may set ever. */ ++ tmp_fag = fag_head.next; ++ nds32_fag_unmark_relax (tmp_fag, internal_relocs, irelend); ++ ++ /* Check if it is worth, and FP_BASE is near enough to SDA_BASE. */ ++ if (accu < FAG_THRESHOLD ++ || !nds32_fag_mark_relax (link_info, sec, best_fag, ++ internal_relocs, irelend)) ++ { ++ /* Not worth to do fp-as-gp. */ ++ begin_rel->r_addend |= R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG; ++ begin_rel->r_addend &= ~R_NDS32_RELAX_REGION_OMIT_FP_FLAG; ++ irel->r_addend |= R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG; ++ irel->r_addend &= ~R_NDS32_RELAX_REGION_OMIT_FP_FLAG; ++ nds32_fag_free_list (&fag_head); ++ begin_rel = NULL; ++ continue; ++ } ++ ++ /* R_SYM of R_NDS32_RELAX_REGION_BEGIN is not used by assembler, ++ so we use it to record the distance to the reloction of best ++ fp-base. */ ++ dist = best_fag->relas[0] - begin_rel; ++ BFD_ASSERT (dist > 0 && dist < 0xffffff); ++ /* Use high 16 bits of addend to record the _FP_BASE_ matched ++ relocation. And get the base value when relocating. */ ++ begin_rel->r_addend &= (0x1 << 16) - 1; ++ begin_rel->r_addend |= dist << 16; ++ ++ nds32_fag_free_list (&fag_head); ++ begin_rel = NULL; ++ } ++ ++ if (begin_rel == NULL || ifc_inside) ++ /* Skip if we are not in the region of fp-as-gp. */ ++ continue; ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA15S2_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA17S2_RELA) ++ { ++ bfd_vma addr; ++ uint32_t insn; ++ ++ /* A gp-relative access is found. Insert it to the fag-list. */ ++ ++ /* Rt is necessary an RT3, so it can be converted to lwi37.fp. */ ++ insn = bfd_getb32 (contents + irel->r_offset); ++ if (!N32_IS_RT3 (insn)) ++ continue; ++ ++ addr = calculate_memory_address (abfd, irel, isymbuf, symtab_hdr); ++ nds32_fag_insert (&fag_head, addr, irel); ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA_FP7U2_RELA) ++ { ++ begin_rel = NULL; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_17IFC_PCREL_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_10IFCU_PCREL_RELA) ++ { ++ /* Suppress fp as gp when encounter ifc. */ ++ ifc_inside = TRUE; ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Remove unused `la $fp, _FD_BASE_' instruction. */ ++ ++static bfd_boolean ++nds32_fag_remove_unused_fpbase (bfd *abfd, asection *sec, ++ Elf_Internal_Rela *internal_relocs, ++ Elf_Internal_Rela *irelend) ++{ ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Shdr *symtab_hdr; ++ bfd_byte *contents = NULL; ++ nds32_elf_blank_t *relax_blank_list = NULL; ++ bfd_boolean result = TRUE; ++ bfd_boolean unused_region = FALSE; ++ ++ /* ++ NOTE: Disable fp-as-gp if we encounter ifcall relocations. ++ * R_NDS32_17IFC_PCREL_RELA ++ * R_NDS32_10IFCU_PCREL_RELA ++ ++ CASE?????????????? ++ */ ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ nds32_get_section_contents (abfd, sec, &contents, TRUE); ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ /* To remove unused fp-base, we simply find the REGION_NOT_OMIT_FP ++ we marked to in previous pass. ++ DO NOT scan relocations again, since we've alreadly decided it ++ and set the flag. */ ++ const char *syname; ++ int syndx; ++ uint32_t insn; ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_BEGIN ++ && (irel->r_addend & R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG)) ++ unused_region = TRUE; ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_REGION_END ++ && (irel->r_addend & R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG)) ++ unused_region = FALSE; ++ ++ /* We're not in the region. */ ++ if (!unused_region) ++ continue; ++ ++ /* _FP_BASE_ must be a GLOBAL symbol. */ ++ syndx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; ++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) ++ continue; ++ ++ /* The symbol name must be _FP_BASE_. */ ++ syname = elf_sym_hashes (abfd)[syndx]->root.root.string; ++ if (strcmp (syname, FP_BASE_NAME) != 0) ++ continue; ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA19S0_RELA) ++ { ++ /* addi.gp $fp, -256 */ ++ insn = bfd_getb32 (contents + irel->r_offset); ++ if (insn != INSN_ADDIGP_TO_FP) ++ continue; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_SDA15S0_RELA) ++ { ++ /* addi $fp, $gp, -256 */ ++ insn = bfd_getb32 (contents + irel->r_offset); ++ if (insn != INSN_ADDI_GP_TO_FP) ++ continue; ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_20_RELA) ++ { ++ /* movi $fp, FP_BASE */ ++ insn = bfd_getb32 (contents + irel->r_offset); ++ if (insn != INSN_MOVI_TO_FP) ++ continue; ++ } ++ else ++ continue; ++ ++ /* We got here because a FP_BASE instruction is found. */ ++ if (!insert_nds32_elf_blank_recalc_total ++ (&relax_blank_list, irel->r_offset, 4)) ++ goto error_return; ++ } ++ ++finish: ++ if (relax_blank_list) ++ { ++ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list); ++ relax_blank_list = NULL; ++ } ++ return result; ++ ++error_return: ++ result = FALSE; ++ goto finish; ++} ++ ++/* This is a version of bfd_generic_get_relocated_section_contents. ++ We need this variety because relaxation will modify the dwarf ++ infomation. When there is undefined symbol reference error mesage, ++ linker need to dump line number where the symbol be used. However ++ the address is be relaxed, it can not get the original dwarf contents. ++ The variety only modify function call for reading in the section. */ ++ ++static bfd_byte * ++nds32_elf_get_relocated_section_contents (bfd *abfd, ++ struct bfd_link_info *link_info, ++ struct bfd_link_order *link_order, ++ bfd_byte *data, ++ bfd_boolean relocatable, ++ asymbol **symbols) ++{ ++ bfd *input_bfd = link_order->u.indirect.section->owner; ++ asection *input_section = link_order->u.indirect.section; ++ long reloc_size; ++ arelent **reloc_vector; ++ long reloc_count; ++ ++ reloc_size = bfd_get_reloc_upper_bound (input_bfd, input_section); ++ if (reloc_size < 0) ++ return NULL; ++ ++ /* Read in the section. */ ++ if (!nds32_get_section_contents (input_bfd, input_section, &data, FALSE)) ++ return NULL; ++ ++ if (reloc_size == 0) ++ return data; ++ ++ reloc_vector = (arelent **) bfd_malloc (reloc_size); ++ if (reloc_vector == NULL) ++ return NULL; ++ ++ reloc_count = bfd_canonicalize_reloc (input_bfd, input_section, ++ reloc_vector, symbols); ++ if (reloc_count < 0) ++ goto error_return; ++ ++ if (reloc_count > 0) ++ { ++ arelent **parent; ++ for (parent = reloc_vector; *parent != NULL; parent++) ++ { ++ char *error_message = NULL; ++ asymbol *symbol; ++ bfd_reloc_status_type r; ++ ++ symbol = *(*parent)->sym_ptr_ptr; ++ if (symbol->section && discarded_section (symbol->section)) ++ { ++ bfd_byte *p; ++ static reloc_howto_type none_howto ++ = HOWTO (0, 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, ++ "unused", FALSE, 0, 0, FALSE); ++ ++ p = data + (*parent)->address * bfd_octets_per_byte (input_bfd); ++ _bfd_clear_contents ((*parent)->howto, input_bfd, input_section, ++ p); ++ (*parent)->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr; ++ (*parent)->addend = 0; ++ (*parent)->howto = &none_howto; ++ r = bfd_reloc_ok; ++ } ++ else ++ r = bfd_perform_relocation (input_bfd, *parent, data, ++ input_section, ++ relocatable ? abfd : NULL, ++ &error_message); ++ ++ if (relocatable) ++ { ++ asection *os = input_section->output_section; ++ ++ /* A partial link, so keep the relocs. */ ++ os->orelocation[os->reloc_count] = *parent; ++ os->reloc_count++; ++ } ++ ++ if (r != bfd_reloc_ok) ++ { ++ switch (r) ++ { ++ case bfd_reloc_undefined: ++ if (!((*link_info->callbacks->undefined_symbol) ++ (link_info, bfd_asymbol_name (*(*parent)->sym_ptr_ptr), ++ input_bfd, input_section, (*parent)->address, TRUE))) ++ goto error_return; ++ break; ++ case bfd_reloc_dangerous: ++ BFD_ASSERT (error_message != NULL); ++ if (!((*link_info->callbacks->reloc_dangerous) ++ (link_info, error_message, input_bfd, input_section, ++ (*parent)->address))) ++ goto error_return; ++ break; ++ case bfd_reloc_overflow: ++ if (!((*link_info->callbacks->reloc_overflow) ++ (link_info, NULL, ++ bfd_asymbol_name (*(*parent)->sym_ptr_ptr), ++ (*parent)->howto->name, (*parent)->addend, ++ input_bfd, input_section, (*parent)->address))) ++ goto error_return; ++ break; ++ case bfd_reloc_outofrange: ++ /* PR ld/13730: ++ This error can result when processing some partially ++ complete binaries. Do not abort, but issue an error ++ message instead. */ ++ link_info->callbacks->einfo ++ (_("%X%P: %B(%A): relocation \"%R\" goes out of range\n"), ++ abfd, input_section, * parent); ++ goto error_return; ++ ++ default: ++ abort (); ++ break; ++ } ++ } ++ } ++ } ++ ++ free (reloc_vector); ++ return data; ++ ++error_return: ++ free (reloc_vector); ++ return NULL; ++} ++ ++/* Check target symbol. */ ++ ++static bfd_boolean ++nds32_elf_is_target_special_symbol (bfd *abfd ATTRIBUTE_UNUSED, asymbol *sym) ++{ ++ if (!sym || !sym->name || sym->name[0] != '$') ++ return FALSE; ++ return TRUE; ++} ++ ++/* nds32 find maybe function sym. Ignore target special symbol ++ first, and then go the general function. */ ++ ++static bfd_size_type ++nds32_elf_maybe_function_sym (const asymbol *sym, asection *sec, ++ bfd_vma *code_off) ++{ ++ if (nds32_elf_is_target_special_symbol (NULL, (asymbol *) sym)) ++ return 0; ++ ++ return _bfd_elf_maybe_function_sym (sym, sec, code_off); ++} ++ ++ ++/* Link-time IFC relaxation. ++ In this optimization, we chains jump instructions ++ of the same destination with ifcall. */ ++ ++ ++/* List to save jal and j relocation. */ ++struct elf_nds32_ifc_symbol_entry ++{ ++ asection *sec; ++ struct elf_link_hash_entry *h; ++ struct elf_nds32_ifc_irel_list *irel_head; ++ unsigned long insn; ++ int times; ++ int enable; /* Apply ifc. */ ++ int ex9_enable; /* Apply ifc after ex9. */ ++ struct elf_nds32_ifc_symbol_entry *next; ++}; ++ ++struct elf_nds32_ifc_irel_list ++{ ++ Elf_Internal_Rela *irel; ++ asection *sec; ++ bfd_vma addr; ++ /* If this is set, then it is the last instruction for ++ ifc-chain, so it must be keep for the actual branching. */ ++ int keep; ++ struct elf_nds32_ifc_irel_list *next; ++}; ++ ++static struct elf_nds32_ifc_symbol_entry *ifc_symbol_head = NULL; ++ ++/* Insert symbol of jal and j for ifc. */ ++ ++static void ++nds32_elf_ifc_insert_symbol (asection *sec, ++ struct elf_link_hash_entry *h, ++ Elf_Internal_Rela *irel, ++ unsigned long insn) ++{ ++ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; ++ ++ /* Check there is target of existing entry the same as the new one. */ ++ while (ptr != NULL) ++ { ++ if (((h == NULL && ptr->sec == sec ++ && ELF32_R_SYM (ptr->irel_head->irel->r_info) == ELF32_R_SYM (irel->r_info) ++ && ptr->irel_head->irel->r_addend == irel->r_addend) ++ || h != NULL) ++ && ptr->h == h ++ && ptr->insn == insn) ++ { ++ /* The same target exist, so insert into list. */ ++ struct elf_nds32_ifc_irel_list *irel_list = ptr->irel_head; ++ ++ while (irel_list->next != NULL) ++ irel_list = irel_list->next; ++ irel_list->next = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list)); ++ irel_list = irel_list->next; ++ irel_list->irel = irel; ++ irel_list->keep = 1; ++ ++ if (h == NULL) ++ irel_list->sec = NULL; ++ else ++ irel_list->sec = sec; ++ irel_list->next = NULL; ++ return; ++ } ++ if (ptr->next == NULL) ++ break; ++ ptr = ptr->next; ++ } ++ ++ /* There is no same target entry, so build a new one. */ ++ if (ifc_symbol_head == NULL) ++ { ++ ifc_symbol_head = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry)); ++ ptr = ifc_symbol_head; ++ } ++ else ++ { ++ ptr->next = bfd_malloc (sizeof (struct elf_nds32_ifc_symbol_entry)); ++ ptr = ptr->next; ++ } ++ ++ ptr->h = h; ++ ptr->irel_head = bfd_malloc (sizeof (struct elf_nds32_ifc_irel_list)); ++ ptr->irel_head->irel = irel; ++ ptr->insn = insn; ++ ptr->irel_head->keep = 1; ++ ++ if (h == NULL) ++ { ++ /* Local symbols. */ ++ ptr->sec = sec; ++ ptr->irel_head->sec = NULL; ++ } ++ else ++ { ++ /* Global symbol. */ ++ ptr->sec = NULL; ++ ptr->irel_head->sec = sec; ++ } ++ ++ ptr->irel_head->next = NULL; ++ ptr->times = 0; ++ ptr->enable = 0; ++ ptr->ex9_enable = 0; ++ ptr->next = NULL; ++} ++ ++/* Check if ignoring ifc. */ ++ ++static bfd_boolean ++nds32_elf_ifc_check_region (Elf_Internal_Rela **irel, ++ Elf_Internal_Rela *irelend, ++ struct bfd_link_info *info) ++{ ++ struct elf_nds32_link_hash_table *table; ++ int nest = 0; ++ bfd_boolean ifc_loop_aware; ++ bfd_boolean security = FALSE; ++ ++ table = nds32_elf_hash_table (info); ++ ifc_loop_aware = table->ifc_loop_aware; ++ ++ if ((ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_BEGIN ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_IFC_FLAG ++ || (ifc_loop_aware == 1 ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) ++ || (*irel)->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ || (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_SECURITY_16)) ++ { ++ /* Check the region if loop, no_ifc, or security. If it is true, ++ ignore the region till region end. */ ++ if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_SECURITY_16) ++ security = TRUE; ++ else ++ nest++; ++ ++ (*irel)++; ++ while ((*irel) != NULL && (*irel) < irelend) ++ { ++ if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_BEGIN ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_IFC_FLAG ++ || (ifc_loop_aware == 1 ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) ++ || (*irel)->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ nest++; ++ ++ else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_SECURITY_16 ++ && (*irel)->r_addend != NDS32_SECURITY_END) ++ security = TRUE; ++ ++ if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_END ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_IFC_FLAG ++ || (ifc_loop_aware == 1 ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) ++ || (*irel)->r_addend & R_NDS32_RELAX_REGION_OMIT_FP_FLAG)) ++ { ++ if (nest > 0) ++ nest--; ++ } ++ else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_SECURITY_16 ++ && (*irel)->r_addend == NDS32_SECURITY_END) ++ security = FALSE; ++ ++ if (nest <= 0 && !security) ++ break; ++ ++ (*irel)++; ++ } ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ ++/* Gather all jal and j instructions. */ ++ ++static bfd_boolean ++nds32_elf_ifc_calc (struct bfd_link_info *info, ++ bfd *abfd, asection *sec) ++{ ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irelend; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Shdr *symtab_hdr; ++ bfd_byte *contents = NULL; ++ uint32_t insn, insn_with_reg; ++ unsigned long r_symndx; ++ struct elf_link_hash_entry *h; ++ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); ++ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sec->reloc_count; ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ /* Check if the object enable ifc. */ ++ irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend, ++ R_NDS32_RELAX_ENTRY); ++ ++ if (irel == NULL ++ || irel >= irelend ++ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY ++ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_IFC_FLAG))) ++ return TRUE; ++ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) ++ return FALSE; ++ ++ while (irel != NULL && irel < irelend) ++ { ++ /* Traverse all relocation and gather all of them to build the list. */ ++ ++ if (nds32_elf_ifc_check_region (&irel, irelend, info)) ++ if (irel == NULL || irel >= irelend) ++ return TRUE; ++ ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA) ++ { ++ insn = bfd_getb32 (contents + irel->r_offset); ++ nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg); ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Local symbol. */ ++ nds32_elf_ifc_insert_symbol (sec, NULL, irel, insn_with_reg); ++ } ++ else ++ { ++ /* External symbol. */ ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ nds32_elf_ifc_insert_symbol (sec, h, irel, insn_with_reg); ++ } ++ } ++ irel++; ++ } ++ return TRUE; ++} ++ ++/* Determine whether j and jal should be substituted. */ ++ ++static void ++nds32_elf_ifc_filter (struct bfd_link_info *info) ++{ ++ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; ++ struct elf_nds32_ifc_irel_list *irel_ptr = NULL; ++ struct elf_nds32_ifc_irel_list *irel_keeper = NULL; ++ struct elf_nds32_link_hash_table *table; ++ int target_optimize; ++ bfd_vma address; ++ ++ table = nds32_elf_hash_table (info); ++ target_optimize = table->target_optimize; ++ while (ptr) ++ { ++ irel_ptr = ptr->irel_head; ++ if (ptr->h == NULL) ++ { ++ /* Local symbol. */ ++ irel_keeper = irel_ptr; ++ while (irel_ptr && irel_ptr->next) ++ { ++ /* Check there is jump target can be used. */ ++ if ((irel_ptr->next->irel->r_offset ++ - irel_keeper->irel->r_offset) > 1022) ++ irel_keeper = irel_ptr->next; ++ else ++ { ++ ptr->enable = 1; ++ irel_ptr->keep = 0; ++ } ++ irel_ptr = irel_ptr->next; ++ } ++ } ++ else ++ { ++ /* Global symbol. */ ++ /* We have to get the absolute address and decide ++ whether to keep it or not.*/ ++ while (irel_ptr) ++ { ++ address = (irel_ptr->irel->r_offset ++ + irel_ptr->sec->output_section->vma ++ + irel_ptr->sec->output_offset); ++ irel_ptr->addr = address; ++ irel_ptr = irel_ptr->next; ++ } ++ ++ irel_ptr = ptr->irel_head; ++ while (irel_ptr) ++ { ++ /* Sort by address. */ ++ struct elf_nds32_ifc_irel_list *irel_dest = irel_ptr; ++ struct elf_nds32_ifc_irel_list *irel_temp = irel_ptr; ++ struct elf_nds32_ifc_irel_list *irel_ptr_prev = NULL; ++ struct elf_nds32_ifc_irel_list *irel_dest_prev = NULL; ++ ++ /* Get the smallest one. */ ++ while (irel_temp->next) ++ { ++ if (irel_temp->next->addr < irel_dest->addr) ++ { ++ irel_dest_prev = irel_temp; ++ irel_dest = irel_temp->next; ++ } ++ irel_temp = irel_temp->next; ++ } ++ ++ if (irel_dest != irel_ptr) ++ { ++ if (irel_ptr_prev) ++ irel_ptr_prev->next = irel_dest; ++ if (irel_dest_prev) ++ irel_dest_prev->next = irel_ptr; ++ irel_temp = irel_ptr->next; ++ irel_ptr->next = irel_dest->next; ++ irel_dest->next = irel_temp; ++ } ++ irel_ptr_prev = irel_ptr; ++ irel_ptr = irel_ptr->next; ++ } ++ ++ irel_ptr = ptr->irel_head; ++ irel_keeper = irel_ptr; ++ while (irel_ptr && irel_ptr->next) ++ { ++ if ((irel_ptr->next->addr - irel_keeper->addr) > 1022) ++ irel_keeper = irel_ptr->next; ++ else ++ { ++ ptr->enable = 1; ++ irel_ptr->keep = 0; ++ } ++ irel_ptr = irel_ptr->next; ++ } ++ } ++ ++ /* Ex9 enable. Reserve it for ex9. */ ++ if ((target_optimize & NDS32_RELAX_EX9_ON) ++ && ptr->irel_head != irel_keeper) ++ ptr->enable = 0; ++ ptr = ptr->next; ++ } ++} ++ ++/* Determine whether j and jal should be substituted after ex9 done. */ ++ ++static void ++nds32_elf_ifc_filter_after_ex9 (void) ++{ ++ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; ++ struct elf_nds32_ifc_irel_list *irel_ptr = NULL; ++ ++ while (ptr) ++ { ++ if (ptr->enable == 0) ++ { ++ /* Check whether ifc is applied or not. */ ++ irel_ptr = ptr->irel_head; ++ ptr->ex9_enable = 1; ++ while (irel_ptr) ++ { ++ if (ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_TRAN) ++ { ++ /* Ex9 already. */ ++ ptr->ex9_enable = 0; ++ break; ++ } ++ irel_ptr = irel_ptr->next; ++ } ++ } ++ ptr = ptr->next; ++ } ++} ++ ++/* Wrapper to do ifc relaxation. */ ++ ++bfd_boolean ++nds32_elf_ifc_finish (struct bfd_link_info *info) ++{ ++ int relax_status; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (info); ++ relax_status = table->relax_status; ++ ++ if (!(relax_status & NDS32_RELAX_JUMP_IFC_DONE)) ++ nds32_elf_ifc_filter (info); ++ else ++ nds32_elf_ifc_filter_after_ex9 (); ++ ++ if (!nds32_elf_ifc_replace (info)) ++ return FALSE; ++ ++ if (table) ++ table->relax_status |= NDS32_RELAX_JUMP_IFC_DONE; ++ return TRUE; ++} ++ ++/* Traverse the result of ifc filter and replace it with ifcall9. */ ++ ++static bfd_boolean ++nds32_elf_ifc_replace (struct bfd_link_info *info) ++{ ++ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; ++ struct elf_nds32_ifc_irel_list *irel_ptr = NULL; ++ nds32_elf_blank_t *relax_blank_list = NULL; ++ bfd_byte *contents = NULL; ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *irelend; ++ unsigned short insn16 = INSN_IFCALL9; ++ struct elf_nds32_link_hash_table *table; ++ int relax_status; ++ ++ table = nds32_elf_hash_table (info); ++ relax_status = table->relax_status; ++ ++ while (ptr) ++ { ++ /* Traverse the ifc gather list, and replace the ++ filter entries by ifcall9. */ ++ if ((!(relax_status & NDS32_RELAX_JUMP_IFC_DONE) ++ && ptr->enable == 1) ++ || ((relax_status & NDS32_RELAX_JUMP_IFC_DONE) ++ && ptr->ex9_enable == 1)) ++ { ++ irel_ptr = ptr->irel_head; ++ if (ptr->h == NULL) ++ { ++ /* Local symbol. */ ++ internal_relocs = _bfd_elf_link_read_relocs ++ (ptr->sec->owner, ptr->sec, NULL, NULL, TRUE /* keep_memory */); ++ irelend = internal_relocs + ptr->sec->reloc_count; ++ ++ if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec, ++ &contents, TRUE)) ++ return FALSE; ++ ++ while (irel_ptr) ++ { ++ if (irel_ptr->keep == 0 && irel_ptr->next) ++ { ++ /* The one can be replaced. We have to check whether ++ there is any alignment point in the region. */ ++ irel = irel_ptr->irel; ++ while (((irel_ptr->next->keep == 0 ++ && irel < irel_ptr->next->irel) ++ || (irel_ptr->next->keep == 1 && irel < irelend)) ++ && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ && (irel->r_addend & 0x1f) == 2)) ++ irel++; ++ if (irel >= irelend ++ || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ && (irel->r_addend & 0x1f) == 2 ++ && ((irel->r_offset - get_nds32_elf_blank_total ++ (&relax_blank_list, irel->r_offset, 1)) ++ & 0x02) == 0)) ++ { ++ /* Replace by ifcall9. */ ++ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); ++ if (!insert_nds32_elf_blank_recalc_total ++ (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2)) ++ return FALSE; ++ irel_ptr->irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), ++ R_NDS32_10IFCU_PCREL_RELA); ++ } ++ } ++ irel_ptr = irel_ptr->next; ++ } ++ ++ /* Delete the redundant code. */ ++ if (relax_blank_list) ++ { ++ nds32_elf_relax_delete_blanks (ptr->sec->owner, ptr->sec, ++ relax_blank_list); ++ relax_blank_list = NULL; ++ } ++ } ++ else ++ { ++ /* Global symbol. */ ++ while (irel_ptr) ++ { ++ if (irel_ptr->keep == 0 && irel_ptr->next) ++ { ++ /* The one can be replaced, and we have to check ++ whether there is any alignment point in the region. */ ++ internal_relocs = _bfd_elf_link_read_relocs ++ (irel_ptr->sec->owner, irel_ptr->sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + irel_ptr->sec->reloc_count; ++ if (!nds32_get_section_contents (irel_ptr->sec->owner, ++ irel_ptr->sec, &contents, ++ TRUE)) ++ return FALSE; ++ ++ irel = irel_ptr->irel; ++ while (((irel_ptr->sec == irel_ptr->next->sec ++ && irel_ptr->next->keep == 0 ++ && irel < irel_ptr->next->irel) ++ || ((irel_ptr->sec != irel_ptr->next->sec ++ || irel_ptr->next->keep == 1) ++ && irel < irelend)) ++ && !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ && (irel->r_addend & 0x1f) == 2)) ++ irel++; ++ if (irel >= irelend ++ || !(ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ && (irel->r_addend & 0x1f) == 2 ++ && ((irel->r_offset ++ - get_nds32_elf_blank_total (&relax_blank_list, ++ irel->r_offset, 1)) & 0x02) == 0)) ++ { ++ /* Replace by ifcall9. */ ++ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); ++ if (!insert_nds32_elf_blank_recalc_total ++ (&relax_blank_list, irel_ptr->irel->r_offset + 2, 2)) ++ return FALSE; ++ ++ /* Delete the redundant code, and clear the relocation. */ ++ nds32_elf_relax_delete_blanks (irel_ptr->sec->owner, ++ irel_ptr->sec, ++ relax_blank_list); ++ irel_ptr->irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), ++ R_NDS32_10IFCU_PCREL_RELA); ++ relax_blank_list = NULL; ++ } ++ } ++ ++ irel_ptr = irel_ptr->next; ++ } ++ } ++ } ++ ptr = ptr->next; ++ } ++ ++ return TRUE; ++} ++ ++/* Relocate ifcall. */ ++ ++static bfd_boolean ++nds32_elf_ifc_reloc (void) ++{ ++ struct elf_nds32_ifc_symbol_entry *ptr = ifc_symbol_head; ++ struct elf_nds32_ifc_irel_list *irel_ptr = NULL; ++ struct elf_nds32_ifc_irel_list *irel_keeper = NULL; ++ bfd_vma relocation, address; ++ unsigned short insn16; ++ static bfd_boolean done = FALSE; ++ ++ if (done) ++ return TRUE; ++ ++ done = TRUE; ++ ++ bfd_byte *contents = NULL; ++ ++ while (ptr) ++ { ++ /* Check the entry is enable ifcall. */ ++ if (ptr->enable == 1 || ptr->ex9_enable == 1) ++ { ++ /* Get the reserve jump. */ ++ irel_ptr = ptr->irel_head; ++ while (irel_ptr) ++ { ++ if (irel_ptr->keep == 1) ++ { ++ irel_keeper = irel_ptr; ++ break; ++ } ++ irel_ptr = irel_ptr->next; ++ } ++ ++ irel_ptr = ptr->irel_head; ++ if (ptr->h == NULL) ++ { ++ /* Local symbol. */ ++ if (!nds32_get_section_contents (ptr->sec->owner, ptr->sec, ++ &contents, TRUE)) ++ return FALSE; ++ ++ while (irel_ptr) ++ { ++ if (irel_ptr->keep == 0 ++ && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA) ++ { ++ relocation = irel_keeper->irel->r_offset; ++ relocation = relocation - irel_ptr->irel->r_offset; ++ while (irel_keeper && relocation > 1022) ++ { ++ irel_keeper = irel_keeper->next; ++ if (irel_keeper && irel_keeper->keep == 1) ++ { ++ relocation = irel_keeper->irel->r_offset; ++ relocation = relocation - irel_ptr->irel->r_offset; ++ } ++ } ++ if (relocation > 1022) ++ { ++ /* Double check. */ ++ irel_keeper = ptr->irel_head; ++ while (irel_keeper) ++ { ++ if (irel_keeper->keep == 1) ++ { ++ relocation = irel_keeper->irel->r_offset; ++ relocation = relocation - irel_ptr->irel->r_offset; ++ } ++ if (relocation <= 1022) ++ break; ++ irel_keeper = irel_keeper->next; ++ } ++ if (!irel_keeper) ++ return FALSE; ++ } ++ irel_ptr->irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), ++ R_NDS32_NONE); ++ insn16 = INSN_IFCALL9 | (relocation >> 1); ++ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); ++ } ++ irel_ptr = irel_ptr->next; ++ } ++ } ++ else ++ { ++ /* Global symbol. */ ++ while (irel_ptr) ++ { ++ if (irel_ptr->keep == 0 ++ && ELF32_R_TYPE (irel_ptr->irel->r_info) == R_NDS32_10IFCU_PCREL_RELA) ++ { ++ /* Get the distance between ifcall and jump. */ ++ relocation = (irel_keeper->irel->r_offset ++ + irel_keeper->sec->output_section->vma ++ + irel_keeper->sec->output_offset); ++ address = (irel_ptr->irel->r_offset ++ + irel_ptr->sec->output_section->vma ++ + irel_ptr->sec->output_offset); ++ relocation = relocation - address; ++ ++ /* The distance is over ragne, find callee again. */ ++ while (irel_keeper && relocation > 1022) ++ { ++ irel_keeper = irel_keeper->next; ++ if (irel_keeper && irel_keeper->keep ==1) ++ { ++ relocation = (irel_keeper->irel->r_offset ++ + irel_keeper->sec->output_section->vma ++ + irel_keeper->sec->output_offset); ++ relocation = relocation - address; ++ } ++ } ++ ++ if (relocation > 1022) ++ { ++ /* Double check. */ ++ irel_keeper = ptr->irel_head; ++ while (irel_keeper) ++ { ++ if (irel_keeper->keep == 1) ++ { ++ ++ relocation = (irel_keeper->irel->r_offset ++ + irel_keeper->sec->output_section->vma ++ + irel_keeper->sec->output_offset); ++ relocation = relocation - address; ++ } ++ if (relocation <= 1022) ++ break; ++ irel_keeper = irel_keeper->next; ++ } ++ if (!irel_keeper) ++ return FALSE; ++ } ++ if (!nds32_get_section_contents ++ (irel_ptr->sec->owner, irel_ptr->sec, &contents, TRUE)) ++ return FALSE; ++ insn16 = INSN_IFCALL9 | (relocation >> 1); ++ bfd_putb16 (insn16, contents + irel_ptr->irel->r_offset); ++ irel_ptr->irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), ++ R_NDS32_NONE); ++ } ++ irel_ptr =irel_ptr->next; ++ } ++ } ++ } ++ ptr = ptr->next; ++ } ++ ++ return TRUE; ++} ++ ++/* End of IFC relaxation. */ ++ ++/* EX9 Instruction Table Relaxation. */ ++#define EX9_SECTION ".ex9.itable" ++ ++/* Global hash list. */ ++struct elf_link_hash_entry_list ++{ ++ struct elf_link_hash_entry *h; ++ struct elf_link_hash_entry_list *next; ++}; ++ ++/* Save different destination but same insn. */ ++struct elf_link_hash_entry_mul_list ++{ ++ /* Global symbol times. */ ++ int times; ++ /* Save relocation for each global symbol but useful?? */ ++ Elf_Internal_Rela *irel; ++ /* For sethi, two sethi may have the same high-part but different low-parts. */ ++ Elf_Internal_Rela rel_backup; ++ struct elf_link_hash_entry_list *h_list; ++ struct elf_link_hash_entry_mul_list *next; ++}; ++ ++/* Instruction hash table. */ ++struct elf_nds32_code_hash_entry ++{ ++ struct bfd_hash_entry root; ++ int times; ++ /* For insn that can use relocation or constant ex: sethi. */ ++ int const_insn; ++ asection *sec; ++ struct elf_link_hash_entry_mul_list *m_list; ++ /* Using r_addend. */ ++ Elf_Internal_Rela *irel; ++ /* Using r_info. */ ++ Elf_Internal_Rela rel_backup; ++}; ++ ++/* Instruction count list. */ ++struct elf_nds32_insn_times_entry ++{ ++ const char *string; ++ int times; ++ int order; ++ asection *sec; ++ struct elf_link_hash_entry_mul_list *m_list; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela rel_backup; ++ struct elf_nds32_insn_times_entry *next; ++}; ++ ++/* J and JAL symbol list. */ ++struct elf_nds32_symbol_entry ++{ ++ char *string; ++ unsigned long insn; ++ struct elf_nds32_symbol_entry *next; ++}; ++ ++/* Relocation list. */ ++struct elf_nds32_irel_entry ++{ ++ Elf_Internal_Rela *irel; ++ struct elf_nds32_irel_entry *next; ++}; ++ ++/* ex9.it insn need to be fixed. */ ++struct elf_nds32_ex9_refix ++{ ++ Elf_Internal_Rela *irel; ++ asection *sec; ++ struct elf_link_hash_entry *h; ++ int order; ++ struct elf_nds32_ex9_refix *next; ++}; ++ ++static struct bfd_hash_table ex9_code_table; ++static struct elf_nds32_insn_times_entry *ex9_insn_head = NULL; ++static struct elf_nds32_ex9_refix *ex9_refix_head = NULL; ++ ++/* EX9 hash function. */ ++ ++static struct bfd_hash_entry * ++nds32_elf_code_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ struct elf_nds32_code_hash_entry *ret; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (entry == NULL) ++ { ++ entry = (struct bfd_hash_entry *) ++ bfd_hash_allocate (table, sizeof (*ret)); ++ if (entry == NULL) ++ return entry; ++ } ++ ++ /* Call the allocation method of the superclass. */ ++ entry = bfd_hash_newfunc (entry, table, string); ++ if (entry == NULL) ++ return entry; ++ ++ ret = (struct elf_nds32_code_hash_entry*) entry; ++ ret->times = 0; ++ ret->const_insn = 0; ++ ret->m_list = NULL; ++ ret->sec = NULL; ++ ret->irel = NULL; ++ return &ret->root; ++} ++ ++/* Insert ex9 entry ++ this insert must be stable sorted by times. */ ++ ++static void ++nds32_elf_ex9_insert_entry (struct elf_nds32_insn_times_entry *ptr) ++{ ++ struct elf_nds32_insn_times_entry *temp; ++ struct elf_nds32_insn_times_entry *temp2; ++ ++ if (ex9_insn_head == NULL) ++ { ++ ex9_insn_head = ptr; ++ ptr->next = NULL; ++ } ++ else ++ { ++ temp = ex9_insn_head; ++ temp2 = ex9_insn_head; ++ while (temp->next && ++ (temp->next->times >= ptr->times ++ || temp->times == -1)) ++ { ++ if (temp->times == -1) ++ temp2 = temp; ++ temp = temp->next; ++ } ++ if (ptr->times > temp->times && temp->times != -1) ++ { ++ ptr->next = temp; ++ if (temp2->times == -1) ++ temp2->next = ptr; ++ else ++ ex9_insn_head = ptr; ++ } ++ else if (temp->next == NULL) ++ { ++ temp->next = ptr; ++ ptr->next = NULL; ++ } ++ else ++ { ++ ptr->next = temp->next; ++ temp->next = ptr; ++ } ++ } ++} ++ ++/* Examine each insn times in hash table. ++ Handle multi-link hash entry. ++ ++ TODO: This function doesn't assign so much info since it is fake. */ ++ ++static int ++nds32_elf_examine_insn_times (struct elf_nds32_code_hash_entry *h) ++{ ++ struct elf_nds32_insn_times_entry *ptr; ++ int times; ++ ++ if (h->m_list == NULL) ++ { ++ /* Local symbol insn or insn without relocation. */ ++ if (h->times < 3) ++ return TRUE; ++ ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = h->times; ++ ptr->string = h->root.string; ++ ptr->m_list = NULL; ++ ptr->sec = h->sec; ++ ptr->irel = h->irel; ++ ptr->rel_backup = h->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ else ++ { ++ /* Global symbol insn. */ ++ /* Only sethi insn has multiple m_list. */ ++ struct elf_link_hash_entry_mul_list *m_list = h->m_list; ++ ++ times = 0; ++ while (m_list) ++ { ++ times += m_list->times; ++ m_list = m_list->next; ++ } ++ if (times >= 3) ++ { ++ m_list = h->m_list; ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = times; /* Use the total times. */ ++ ptr->string = h->root.string; ++ ptr->m_list = m_list; ++ ptr->sec = h->sec; ++ ptr->irel = m_list->irel; ++ ptr->rel_backup = m_list->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ if (h->const_insn == 1) ++ { ++ /* sethi with constant value. */ ++ if (h->times < 3) ++ return TRUE; ++ ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = h->times; ++ ptr->string = h->root.string; ++ ptr->m_list = NULL; ++ ptr->sec = NULL; ++ ptr->irel = NULL; ++ ptr->rel_backup = h->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ } ++ return TRUE; ++} ++ ++/* Count each insn times in hash table. ++ Handle multi-link hash entry. */ ++ ++static int ++nds32_elf_count_insn_times (struct elf_nds32_code_hash_entry *h) ++{ ++ int reservation, times; ++ unsigned long relocation, min_relocation; ++ struct elf_nds32_insn_times_entry *ptr; ++ ++ if (h->m_list == NULL) ++ { ++ /* Local symbol insn or insn without relocation. */ ++ if (h->times < 3) ++ return TRUE; ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = h->times; ++ ptr->string = h->root.string; ++ ptr->m_list = NULL; ++ ptr->sec = h->sec; ++ ptr->irel = h->irel; ++ ptr->rel_backup = h->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ else ++ { ++ /* Global symbol insn. */ ++ /* Only sethi insn has multiple m_list. */ ++ struct elf_link_hash_entry_mul_list *m_list = h->m_list; ++ ++ if (ELF32_R_TYPE (m_list->rel_backup.r_info) == R_NDS32_HI20_RELA ++ && m_list->next != NULL) ++ { ++ /* Sethi insn has different symbol or addend but has same hi20. */ ++ times = 0; ++ reservation = 1; ++ relocation = 0; ++ min_relocation = 0xffffffff; ++ while (m_list) ++ { ++ /* Get the minimum sethi address ++ and calculate how many entry the sethi-list have to use. */ ++ if ((m_list->h_list->h->root.type == bfd_link_hash_defined ++ || m_list->h_list->h->root.type == bfd_link_hash_defweak) ++ && (m_list->h_list->h->root.u.def.section != NULL ++ && m_list->h_list->h->root.u.def.section->output_section != NULL)) ++ { ++ relocation = (m_list->h_list->h->root.u.def.value + ++ m_list->h_list->h->root.u.def.section->output_section->vma + ++ m_list->h_list->h->root.u.def.section->output_offset); ++ relocation += m_list->irel->r_addend; ++ } ++ else ++ relocation = 0; ++ if (relocation < min_relocation) ++ min_relocation = relocation; ++ times += m_list->times; ++ m_list = m_list->next; ++ } ++ if (min_relocation < ex9_relax_size) ++ reservation = (min_relocation >> 12) + 1; ++ else ++ reservation = (min_relocation >> 12) ++ - ((min_relocation - ex9_relax_size) >> 12) + 1; ++ if ((reservation * 3) <= times) ++ { ++ /* Efficient enough to use ex9. */ ++ int i; ++ ++ for (i = reservation ; i > 0; i--) ++ { ++ /* Allocate number of reservation ex9 entry. */ ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = h->m_list->times / reservation; ++ ptr->string = h->root.string; ++ ptr->m_list = h->m_list; ++ ptr->sec = h->sec; ++ ptr->irel = h->m_list->irel; ++ ptr->rel_backup = h->m_list->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ } ++ } ++ else ++ { ++ /* Normal global symbol that means no different address symbol ++ using same ex9 entry. */ ++ if (m_list->times >= 3) ++ { ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = m_list->times; ++ ptr->string = h->root.string; ++ ptr->m_list = h->m_list; ++ ptr->sec = h->sec; ++ ptr->irel = h->m_list->irel; ++ ptr->rel_backup = h->m_list->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ } ++ ++ if (h->const_insn == 1) ++ { ++ /* sethi with constant value. */ ++ if (h->times < 3) ++ return TRUE; ++ ++ ptr = (struct elf_nds32_insn_times_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->times = h->times; ++ ptr->string = h->root.string; ++ ptr->m_list = NULL; ++ ptr->sec = NULL; ++ ptr->irel = NULL; ++ ptr->rel_backup = h->rel_backup; ++ nds32_elf_ex9_insert_entry (ptr); ++ } ++ } ++ ++ return TRUE; ++} ++ ++/* Hash table traverse function. */ ++ ++static void ++nds32_elf_code_hash_traverse (int (*func) (struct elf_nds32_code_hash_entry*)) ++{ ++ unsigned int i; ++ ++ ex9_code_table.frozen = 1; ++ for (i = 0; i < ex9_code_table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ ++ for (p = ex9_code_table.table[i]; p != NULL; p = p->next) ++ if (!func ((struct elf_nds32_code_hash_entry *) p)) ++ goto out; ++ } ++out: ++ ex9_code_table.frozen = 0; ++} ++ ++ ++/* Give order number to insn list. */ ++ ++static void ++nds32_elf_order_insn_times (struct bfd_link_info *info) ++{ ++ struct elf_nds32_insn_times_entry *ex9_insn; ++ struct elf_nds32_insn_times_entry *temp = NULL; ++ struct elf_nds32_link_hash_table *table; ++ int ex9_limit; ++ int number = 0; ++ ++ if (ex9_insn_head == NULL) ++ return; ++ ++/* The max number of entries is 512. */ ++ ex9_insn = ex9_insn_head; ++ table = nds32_elf_hash_table (info); ++ ex9_limit = table->ex9_limit; ++ ++ ex9_insn = ex9_insn_head; ++ ++ while (ex9_insn != NULL && number < ex9_limit) ++ { ++ ex9_insn->order = number; ++ number++; ++ temp = ex9_insn; ++ ex9_insn = ex9_insn->next; ++ } ++ ++ if (ex9_insn && temp) ++ temp->next = NULL; ++ ++ while (ex9_insn != NULL) ++ { ++ /* Free useless entry. */ ++ temp = ex9_insn; ++ ex9_insn = ex9_insn->next; ++ free (temp); ++ } ++} ++ ++/* Get section .ex9.itable. */ ++ ++static asection* ++nds32_elf_ex9_get_section (bfd *input_bfds) ++{ ++ asection *sec = NULL; ++ bfd *abfd; ++ ++ if (ex9_section != NULL) ++ return ex9_section; ++ ++ for (abfd = input_bfds; abfd != NULL; abfd = abfd->link_next) ++ { ++ sec = bfd_get_section_by_name (abfd, EX9_SECTION); ++ if (sec != NULL) ++ break; ++ } ++ ++ ex9_section = sec; ++ return sec; ++} ++ ++/* Build .ex9.itable section. */ ++ ++static void ++nds32_elf_ex9_build_itable (struct bfd_link_info *link_info) ++{ ++ asection *table_sec; ++ struct elf_nds32_insn_times_entry *ptr; ++ int number = 0; ++ bfd_byte *contents = NULL; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (link_info); ++ ++ /* Find the section .ex9.itable, and put all entries into it. */ ++ table_sec = nds32_elf_ex9_get_section (link_info->input_bfds); ++ ++ if (table_sec != NULL) ++ { ++ if (!nds32_get_section_contents (table_sec->owner, table_sec, ++ &contents, TRUE)) ++ return; ++ ++ for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next) ++ number++; ++ ++ table_sec->size = number * 4; ++ ++ if (number == 0) ++ return; ++ ++ /* Check $itb register if set. */ ++ if (!table->ex9_import_file ++ && !bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_", ++ FALSE, FALSE, TRUE)) ++ { ++ (*_bfd_error_handler) ++ (_("\nError: Instruction Table(IT) is used, but Instruction " ++ "Table Base($ITB) isn't set.\nPlease add the following " ++ "instructions in _start of crt0.S:\n" ++ "\"la $r0,_ITB_BASE_;mtusr $r0,$ITB\"")); ++ exit (1); ++ } ++ ++ elf_elfheader (link_info->output_bfd)->e_flags |= E_NDS32_HAS_EX9_INST; ++ number = 0; ++ for (ptr = ex9_insn_head; ptr !=NULL ; ptr = ptr->next) ++ { ++ long val; ++ ++ val = strtol (ptr->string, NULL, 16); ++ bfd_putb32 ((bfd_vma) val, (char *) contents + (number * 4)); ++ number++; ++ } ++ } ++} ++ ++/* Get insn with regs according to relocation type. */ ++ ++static void ++nds32_elf_get_insn_with_reg (Elf_Internal_Rela *irel, ++ uint32_t insn, uint32_t *insn_with_reg) ++{ ++ reloc_howto_type *howto = NULL; ++ ++ if (irel == NULL ++ || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table) ++ && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY) ++ >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table))) ++ { ++ *insn_with_reg = insn; ++ return; ++ } ++ ++ howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info)); ++ *insn_with_reg = insn & (0xffffffff ^ howto->dst_mask); ++} ++ ++/* Mask number of address bits according to relocation. */ ++ ++static unsigned long ++nds32_elf_irel_mask (Elf_Internal_Rela *irel) ++{ ++ reloc_howto_type *howto = NULL; ++ ++ if (irel == NULL ++ || (ELF32_R_TYPE (irel->r_info) >= (int) ARRAY_SIZE (nds32_elf_howto_table) ++ && (ELF32_R_TYPE (irel->r_info) - R_NDS32_RELAX_ENTRY) ++ >= (int) ARRAY_SIZE (nds32_elf_relax_howto_table))) ++ return 0; ++ ++ howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info)); ++ return howto->dst_mask; ++} ++ ++static void ++nds32_elf_insert_irel_entry (struct elf_nds32_irel_entry **irel_list, ++ struct elf_nds32_irel_entry *irel_ptr) ++{ ++ if (*irel_list == NULL) ++ { ++ *irel_list = irel_ptr; ++ irel_ptr->next = NULL; ++ } ++ else ++ { ++ irel_ptr->next = *irel_list; ++ *irel_list = irel_ptr; ++ } ++} ++ ++static void ++nds32_elf_ex9_insert_fix (asection * sec, Elf_Internal_Rela * irel, ++ struct elf_link_hash_entry *h, int order) ++{ ++ struct elf_nds32_ex9_refix *ptr; ++ ++ ptr = bfd_malloc (sizeof (struct elf_nds32_ex9_refix)); ++ ptr->sec = sec; ++ ptr->irel = irel; ++ ptr->h = h; ++ ptr->order = order; ++ ptr->next = NULL; ++ ++ if (ex9_refix_head == NULL) ++ ex9_refix_head = ptr; ++ else ++ { ++ struct elf_nds32_ex9_refix *temp = ex9_refix_head; ++ ++ while (temp->next != NULL) ++ temp = temp->next; ++ temp->next = ptr; ++ } ++} ++ ++enum ++{ ++ DATA_EXIST = 1, ++ CLEAN_PRE = 1 << 1, ++ PUSH_PRE = 1 << 2 ++}; ++ ++/* Check relocation type if supporting for ex9. */ ++ ++static int ++nds32_elf_ex9_relocation_check (struct bfd_link_info *info, ++ Elf_Internal_Rela **irel, ++ Elf_Internal_Rela *irelend, ++ nds32_elf_blank_t *relax_blank_list, ++ asection *sec, bfd_vma *off, ++ bfd_byte *contents) ++{ ++ /* Suppress ex9 if `.no_relax ex9' or inner loop. */ ++ bfd_boolean nested_ex9, nested_loop; ++ bfd_boolean ex9_loop_aware; ++ /* We use the highest 1 byte of result to record ++ how many bytes location counter has to move. */ ++ int result = 0; ++ Elf_Internal_Rela *irel_save = NULL; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (info); ++ ex9_loop_aware = table->ex9_loop_aware; ++ ++ while ((*irel) != NULL && (*irel) < irelend && *off == (*irel)->r_offset) ++ { ++ switch (ELF32_R_TYPE ((*irel)->r_info)) ++ { ++ case R_NDS32_RELAX_REGION_BEGIN: ++ /* Ignore code block. */ ++ nested_ex9 = FALSE; ++ nested_loop = FALSE; ++ if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) ++ || (ex9_loop_aware ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG))) ++ { ++ /* Check the region if loop or not. If it is true and ++ ex9-loop-aware is true, ignore the region till region end. */ ++ /* To save the status for in .no_relax ex9 region and ++ loop region to conform the block can do ex9 relaxation. */ ++ nested_ex9 = ((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG); ++ nested_loop = (ex9_loop_aware ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)); ++ while ((*irel) && (*irel) < irelend && (nested_ex9 || nested_loop)) ++ { ++ (*irel)++; ++ if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_BEGIN) ++ { ++ /* There may be nested region. */ ++ if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0) ++ nested_ex9 = TRUE; ++ else if (ex9_loop_aware ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) ++ nested_loop = TRUE; ++ } ++ else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_RELAX_REGION_END) ++ { ++ /* The end of region. */ ++ if (((*irel)->r_addend & R_NDS32_RELAX_REGION_NO_EX9_FLAG) != 0) ++ nested_ex9 = FALSE; ++ else if (ex9_loop_aware ++ && ((*irel)->r_addend & R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG)) ++ nested_loop = FALSE; ++ } ++ else if (ELF32_R_TYPE ((*irel)->r_info) == R_NDS32_LABEL ++ && ((*irel)->r_addend & 0x1f) == 2) ++ { ++ /* Alignment exist in the region. */ ++ result |= CLEAN_PRE; ++ if (((*irel)->r_offset - ++ get_nds32_elf_blank_total (&relax_blank_list, ++ (*irel)->r_offset, 0)) & 0x02) ++ result |= PUSH_PRE; ++ } ++ } ++ if ((*irel) >= irelend) ++ *off = sec->size; ++ else ++ *off = (*irel)->r_offset; ++ ++ /* The final instruction in the region, regard this one as data to ignore it. */ ++ result |= DATA_EXIST; ++ return result; ++ } ++ break; ++ ++ case R_NDS32_LABEL: ++ if (((*irel)->r_addend & 0x1f) == 2) ++ { ++ /* Check this point is align and decide to do ex9 or not. */ ++ result |= CLEAN_PRE; ++ if (((*irel)->r_offset - ++ get_nds32_elf_blank_total (&relax_blank_list, ++ (*irel)->r_offset, 0)) & 0x02) ++ result |= PUSH_PRE; ++ } ++ break; ++ case R_NDS32_32_RELA: ++ /* Data. */ ++ result |= (4 << 24); ++ result |= DATA_EXIST; ++ break; ++ case R_NDS32_16_RELA: ++ /* Data. */ ++ result |= (2 << 24); ++ result |= DATA_EXIST; ++ break; ++ case R_NDS32_DATA: ++ /* Data. */ ++ /* The least code alignment is 2. If the data is only one byte, ++ we have to shift one more byte. */ ++ if ((*irel)->r_addend == 1) ++ result |= ((*irel)->r_addend << 25) ; ++ else ++ result |= ((*irel)->r_addend << 24) ; ++ ++ result |= DATA_EXIST; ++ break; ++ ++ case R_NDS32_25_PCREL_RELA: ++ case R_NDS32_SDA16S3_RELA: ++ case R_NDS32_SDA15S3_RELA: ++ case R_NDS32_SDA15S3: ++ case R_NDS32_SDA17S2_RELA: ++ case R_NDS32_SDA15S2_RELA: ++ case R_NDS32_SDA12S2_SP_RELA: ++ case R_NDS32_SDA12S2_DP_RELA: ++ case R_NDS32_SDA15S2: ++ case R_NDS32_SDA18S1_RELA: ++ case R_NDS32_SDA15S1_RELA: ++ case R_NDS32_SDA15S1: ++ case R_NDS32_SDA19S0_RELA: ++ case R_NDS32_SDA15S0_RELA: ++ case R_NDS32_SDA15S0: ++ case R_NDS32_HI20_RELA: ++ case R_NDS32_LO12S0_ORI_RELA: ++ case R_NDS32_LO12S0_RELA: ++ case R_NDS32_LO12S1_RELA: ++ case R_NDS32_LO12S2_RELA: ++ case R_NDS32_20_RELA: ++ /* These relocation is supported ex9 relaxation currently. */ ++ /* We have to save the relocation for using later, since we have ++ to check there is any alignment in the same address. */ ++ irel_save = *irel; ++ break; ++ default: ++ /* Not support relocations. */ ++ if (ELF32_R_TYPE ((*irel)->r_info) < ARRAY_SIZE (nds32_elf_howto_table) ++ && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_NONE ++ && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_INSN16 ++ && ELF32_R_TYPE ((*irel)->r_info) != R_NDS32_LOADSTORE) ++ { ++ /* Note: To optimize aggressively, it maybe can ignore ++ R_NDS32_INSN16 here. But we have to consider ++ if there is any side-effect. */ ++ if (!(result & DATA_EXIST)) ++ { ++ /* We have to confirm there is no data relocation in the ++ same address. In general case, this won't happen. */ ++ /* We have to do ex9 conservative, for those relocation not ++ considerd we ignore instruction. */ ++ result |= DATA_EXIST; ++ if (*(contents + *off) & 0x80) ++ result |= (2 << 24); ++ else ++ result |= (4 << 24); ++ break; ++ } ++ } ++ } ++ if ((*irel) < irelend ++ && ((*irel) + 1) < irelend ++ && (*irel)->r_offset == ((*irel) + 1)->r_offset) ++ /* There are relocations pointing to the same address, we have to ++ check all of them. */ ++ (*irel)++; ++ else ++ { ++ if (irel_save) ++ *irel = irel_save; ++ return result; ++ } ++ } ++ return result; ++} ++ ++/* Replace with ex9 instruction. */ ++static bfd_boolean ++nds32_elf_ex9_push_insn (uint16_t insn16, bfd_byte *contents, bfd_vma pre_off, ++ nds32_elf_blank_t **relax_blank_list, ++ struct elf_nds32_irel_entry *pre_irel_ptr, ++ struct elf_nds32_irel_entry **irel_list) ++{ ++ if (insn16 != 0) ++ { ++ /* Implement the ex9 relaxation. */ ++ bfd_putb16 (insn16, contents + pre_off); ++ if (!insert_nds32_elf_blank_recalc_total (relax_blank_list, ++ pre_off + 2, 2)) ++ return FALSE; ++ if (pre_irel_ptr != NULL) ++ nds32_elf_insert_irel_entry (irel_list, pre_irel_ptr); ++ } ++ return TRUE; ++} ++ ++/* Replace input file instruction which is in ex9 itable. */ ++ ++static bfd_boolean ++nds32_elf_ex9_replace_instruction (struct bfd_link_info *info, bfd *abfd, asection *sec) ++{ ++ struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head; ++ bfd_byte *contents = NULL; ++ bfd_vma off; ++ uint16_t insn16, insn_ex9; ++ /* `pre_*' are used to track previous instruction that can use ex9.it. */ ++ bfd_vma pre_off = -1; ++ uint16_t pre_insn16 = 0; ++ struct elf_nds32_irel_entry *pre_irel_ptr = NULL; ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *irelend; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Sym *isym = NULL; ++ nds32_elf_blank_t *relax_blank_list = NULL; ++ uint32_t insn = 0; ++ uint32_t insn_with_reg = 0; ++ uint32_t it_insn; ++ uint32_t it_insn_with_reg; ++ unsigned long r_symndx; ++ asection *isec; ++ struct elf_nds32_irel_entry *irel_list = NULL; ++ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); ++ int data_flag, do_replace, save_irel; ++ struct elf_link_hash_entry_list *h_list; ++ ++ ++ /* Load section instructions, relocations, and symbol table. */ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE) ++ || !nds32_get_local_syms (abfd, sec, &isym)) ++ return FALSE; ++ internal_relocs = ++ _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, TRUE /* keep_memory */); ++ irelend = internal_relocs + sec->reloc_count; ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ off = 0; ++ ++ /* Check if the object enable ex9. */ ++ irel = find_relocs_at_address (internal_relocs, internal_relocs, ++ irelend, R_NDS32_RELAX_ENTRY); ++ ++ /* Check this section trigger ex9 relaxation. */ ++ if (irel == NULL ++ || irel >= irelend ++ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY ++ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG))) ++ return TRUE; ++ ++ irel = internal_relocs; ++ ++ /* Check alignment and fetch proper relocation. */ ++ while (off < sec->size) ++ { ++ struct elf_link_hash_entry *h = NULL; ++ struct elf_nds32_irel_entry *irel_ptr = NULL; ++ ++ /* Syn the instruction and the relocation. */ ++ while (irel != NULL && irel < irelend && irel->r_offset < off) ++ irel++; ++ ++ data_flag = nds32_elf_ex9_relocation_check (info, &irel, irelend, ++ relax_blank_list, sec, ++ &off, contents); ++ if (data_flag & PUSH_PRE) ++ if (!nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off, ++ &relax_blank_list, pre_irel_ptr, ++ &irel_list)) ++ return FALSE; ++ ++ if (data_flag & CLEAN_PRE) ++ { ++ pre_off = 0; ++ pre_insn16 = 0; ++ pre_irel_ptr = NULL; ++ } ++ if (data_flag & DATA_EXIST) ++ { ++ /* We save the move offset in the highest byte. */ ++ off += (data_flag >> 24); ++ continue; ++ } ++ ++ if (*(contents + off) & 0x80) ++ { ++ /* 2-byte instruction. */ ++ off += 2; ++ continue; ++ } ++ ++ /* Load the instruction and its opcode with register for comparing. */ ++ ex9_insn = ex9_insn_head; ++ insn = bfd_getb32 (contents + off); ++ insn_with_reg = 0; ++ /* Insn with relocation. Mask instruction. */ ++ if (irel != NULL && irel < irelend && irel->r_offset == off) ++ nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg); ++ ++ while (ex9_insn) ++ { ++ it_insn = strtol (ex9_insn->string, NULL, 16); ++ it_insn_with_reg = 0; ++ do_replace = 0; ++ save_irel = 0; ++ ++ if (irel != NULL && irel < irelend && irel->r_offset == off ++ && ex9_insn->irel != NULL) ++ nds32_elf_get_insn_with_reg (ex9_insn->irel, it_insn, ++ &it_insn_with_reg); ++ ++ /* Instruction and ex9 both have relocation. */ ++ if (insn_with_reg != 0 && it_insn_with_reg != 0 ++ && (ELF32_R_TYPE (irel->r_info) == ++ ELF32_R_TYPE (ex9_insn->irel->r_info)) ++ && (insn_with_reg == it_insn_with_reg)) ++ { ++ /* Insn relocation and format is the same as table entry. */ ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA ++ && ELF32_R_TYPE (irel->r_info) <= ++ R_NDS32_SDA12S2_SP_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA) ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_20_RELA) ++ { ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Local symbol. */ ++ int shndx = isym[r_symndx].st_shndx; ++ ++ isec = elf_elfsections (abfd)[shndx]->bfd_section; ++ if (ex9_insn->sec == isec ++ && ex9_insn->irel->r_addend == irel->r_addend ++ && ex9_insn->irel->r_info == irel->r_info) ++ { ++ do_replace = 1; ++ save_irel = 1; ++ } ++ } ++ else if (ex9_insn->m_list) ++ { ++ /* External symbol. */ ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ h_list = ex9_insn->m_list->h_list; ++ while (h_list) ++ { ++ if (ex9_insn->m_list->irel->r_addend == irel->r_addend ++ && h == h_list->h) ++ { ++ do_replace = 1; ++ save_irel = 1; ++ break; ++ } ++ h_list = h_list->next; ++ } ++ } ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA) ++ { ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Local symbols. Compare its base symbol ++ and offset. */ ++ int shndx = isym[r_symndx].st_shndx; ++ ++ isec = elf_elfsections (abfd)[shndx]->bfd_section; ++ if (ex9_insn->sec == isec ++ && ex9_insn->irel->r_addend == irel->r_addend ++ && ex9_insn->irel->r_info == irel->r_info) ++ { ++ do_replace = 1; ++ save_irel = 1; ++ } ++ } ++ else ++ { ++ /* External symbol. */ ++ struct elf_link_hash_entry_mul_list *m_list; ++ ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ m_list = ex9_insn->m_list; ++ ++ while (m_list && !do_replace) ++ { ++ h_list = m_list->h_list; ++ while (h_list) ++ { ++ if (h == h_list->h ++ && m_list->irel->r_addend == irel->r_addend) ++ { ++ do_replace = 1; ++ save_irel = 1; ++ /* sethi multiple entry must be fixed. */ ++ if (ex9_insn->next && ex9_insn->m_list ++ && ex9_insn->m_list == ex9_insn->next->m_list) ++ nds32_elf_ex9_insert_fix (sec, irel, h, ++ ex9_insn->order); ++ break; ++ } ++ h_list = h_list->next; ++ } ++ m_list = m_list->next; ++ } ++ } ++ } ++ } ++ /* Import table: Check the symbol hash table and the ++ jump target. Only R_NDS32_25_PCREL_RELA now. */ ++ else if (insn_with_reg != 0 && ex9_insn->times == -1 ++ && ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA) ++ { ++ nds32_elf_get_insn_with_reg (irel, it_insn, &it_insn_with_reg); ++ if (insn_with_reg == it_insn_with_reg) ++ { ++ char code[10]; ++ bfd_vma relocation; ++ ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ if (r_symndx >= symtab_hdr->sh_info) ++ { ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && h->root.u.def.section != NULL ++ && h->root.u.def.section->output_section != NULL ++ && h->root.u.def.section->gc_mark == 1 ++ && bfd_is_abs_section (h->root.u.def.section) ++ && h->root.u.def.value > sec->size) ++ { ++ relocation = h->root.u.def.value + ++ h->root.u.def.section->output_section->vma + ++ h->root.u.def.section->output_offset; ++ relocation += irel->r_addend; ++ insn = insn_with_reg ++ | ((relocation >> 1) & 0xffffff); ++ snprintf (code, sizeof (code), "%08x", insn); ++ if (strcmp (code, ex9_insn->string) == 0) ++ { ++ do_replace = 1; ++ save_irel = 1; ++ } ++ } ++ } ++ } ++ } ++ else if ((irel == NULL || irel >= irelend || irel->r_offset != off) ++ && insn == it_insn && ex9_insn->irel == NULL) ++ { ++ /* Instruction without relocation, we only ++ have to compare their byte code. */ ++ do_replace = 1; ++ } ++ ++ /* Insntruction match so replacing the code here. */ ++ if (do_replace == 1) ++ { ++ /* There are two formats of ex9 instruction. */ ++ if (ex9_insn->order < 32) ++ insn_ex9 = INSN_EX9_IT_2; ++ else ++ insn_ex9 = INSN_EX9_IT_1; ++ insn16 = insn_ex9 | ex9_insn->order; ++ ++ /* Insert ex9 instruction. */ ++ nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off, ++ &relax_blank_list, pre_irel_ptr, ++ &irel_list); ++ pre_off = off; ++ pre_insn16 = insn16; ++ ++ if (save_irel) ++ { ++ /* For instuction with relocation do relax. */ ++ irel_ptr = (struct elf_nds32_irel_entry *) ++ bfd_malloc (sizeof (struct elf_nds32_irel_entry)); ++ irel_ptr->irel = irel; ++ irel_ptr->next = NULL; ++ pre_irel_ptr = irel_ptr; ++ } ++ else ++ pre_irel_ptr = NULL; ++ break; ++ } ++ ex9_insn = ex9_insn->next; ++ } ++ off += 4; ++ } ++ ++ /* Insert ex9 instruction. */ ++ nds32_elf_ex9_push_insn (pre_insn16, contents, pre_off, ++ &relax_blank_list, pre_irel_ptr, ++ &irel_list); ++ ++ /* Delete the redundant code. */ ++ if (relax_blank_list) ++ { ++ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list); ++ relax_blank_list = NULL; ++ } ++ ++ /* Clear the relocation that is replaced by ex9. */ ++ while (irel_list) ++ { ++ struct elf_nds32_irel_entry *irel_ptr; ++ ++ irel_ptr = irel_list; ++ irel_list = irel_ptr->next; ++ irel_ptr->irel->r_info = ++ ELF32_R_INFO (ELF32_R_SYM (irel_ptr->irel->r_info), R_NDS32_TRAN); ++ free (irel_ptr); ++ } ++ return TRUE; ++} ++ ++/* Initialize ex9 hash table. */ ++ ++static int ++nds32_elf_ex9_init (void) ++{ ++ if (!bfd_hash_table_init_n (&ex9_code_table, nds32_elf_code_hash_newfunc, ++ sizeof (struct elf_nds32_code_hash_entry), ++ 1023)) ++ { ++ (*_bfd_error_handler) (_("Linker: cannot init ex9 hash table error \n")); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++/* Predict how many bytes will be relaxed with ex9 and ifc. */ ++ ++static void ++nds32_elf_ex9_total_relax (struct bfd_link_info *info) ++{ ++ struct elf_nds32_insn_times_entry *ex9_insn; ++ struct elf_nds32_insn_times_entry *temp; ++ int target_optimize; ++ struct elf_nds32_link_hash_table *table; ++ ++ if (ex9_insn_head == NULL) ++ return; ++ ++ table = nds32_elf_hash_table (info); ++ target_optimize = table->target_optimize; ++ ex9_insn = ex9_insn_head; ++ while (ex9_insn) ++ { ++ ex9_relax_size = ex9_insn->times * 2 + ex9_relax_size; ++ temp = ex9_insn; ++ ex9_insn = ex9_insn->next; ++ free (temp); ++ } ++ ex9_insn_head = NULL; ++ ++ if ((target_optimize & NDS32_RELAX_IFC_ON)) ++ { ++ /* Examine the potential of ifc reduce size. */ ++ struct elf_nds32_ifc_symbol_entry *ifc_ent = ifc_symbol_head; ++ struct elf_nds32_ifc_irel_list *irel_ptr = NULL; ++ int size = 0; ++ ++ while (ifc_ent) ++ { ++ if (ifc_ent->enable == 0) ++ { ++ /* Not ifc yet. */ ++ irel_ptr = ifc_ent->irel_head; ++ while (irel_ptr) ++ { ++ size += 2; ++ irel_ptr = irel_ptr->next; ++ } ++ } ++ size -= 2; ++ ifc_ent = ifc_ent->next; ++ } ++ ex9_relax_size += size; ++ } ++} ++ ++/* Finish ex9 table. */ ++ ++void ++nds32_elf_ex9_finish (struct bfd_link_info *link_info) ++{ ++ nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times); ++ nds32_elf_order_insn_times (link_info); ++ nds32_elf_ex9_total_relax (link_info); ++ /* Traverse the hash table and count its times. */ ++ nds32_elf_code_hash_traverse (nds32_elf_count_insn_times); ++ nds32_elf_order_insn_times (link_info); ++ nds32_elf_ex9_build_itable (link_info); ++} ++ ++/* Relocate the entries in ex9 table. */ ++ ++static bfd_vma ++nds32_elf_ex9_reloc_insn (struct elf_nds32_insn_times_entry *ptr, ++ struct bfd_link_info *link_info) ++{ ++ Elf_Internal_Sym *isym = NULL; ++ bfd_vma relocation = -1; ++ struct elf_link_hash_entry *h; ++ ++ if (ptr->m_list != NULL) ++ { ++ /* Global symbol. */ ++ h = ptr->m_list->h_list->h; ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && h->root.u.def.section != NULL ++ && h->root.u.def.section->output_section != NULL) ++ { ++ ++ relocation = h->root.u.def.value + ++ h->root.u.def.section->output_section->vma + ++ h->root.u.def.section->output_offset; ++ relocation += ptr->m_list->irel->r_addend; ++ } ++ else ++ relocation = 0; ++ } ++ else if (ptr->sec !=NULL) ++ { ++ /* Local symbol. */ ++ Elf_Internal_Sym sym; ++ asection *sec = NULL; ++ asection isec; ++ asection *isec_ptr = &isec; ++ Elf_Internal_Rela irel_backup = *(ptr->irel); ++ asection *sec_backup = ptr->sec; ++ bfd *abfd = ptr->sec->owner; ++ ++ if (!nds32_get_local_syms (abfd, sec, &isym)) ++ return FALSE; ++ isym = isym + ELF32_R_SYM (ptr->irel->r_info); ++ ++ sec = bfd_section_from_elf_index (abfd, isym->st_shndx); ++ if (sec != NULL) ++ *isec_ptr = *sec; ++ sym = *isym; ++ ++ /* The purpose is same as elf_link_input_bfd. */ ++ if (isec_ptr != NULL ++ && isec_ptr->sec_info_type == SEC_INFO_TYPE_MERGE ++ && ELF_ST_TYPE (isym->st_info) != STT_SECTION) ++ { ++ sym.st_value = ++ _bfd_merged_section_offset (ptr->sec->output_section->owner, &isec_ptr, ++ elf_section_data (isec_ptr)->sec_info, ++ isym->st_value); ++ } ++ relocation = _bfd_elf_rela_local_sym (link_info->output_bfd, &sym, ++ &ptr->sec, ptr->irel); ++ if (ptr->irel != NULL) ++ relocation += ptr->irel->r_addend; ++ ++ /* Restore origin value since there may be some insntructions that ++ could not be replaced with ex9.it. */ ++ *(ptr->irel) = irel_backup; ++ ptr->sec = sec_backup; ++ } ++ ++ return relocation; ++} ++ ++/* Import ex9 table and build list. */ ++ ++void ++nds32_elf_ex9_import_table (struct bfd_link_info *info) ++{ ++ int num = 0; ++ bfd_byte *contents; ++ unsigned long insn; ++ FILE *ex9_import_file; ++ int update_ex9_table; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (info); ++ ex9_import_file = table->ex9_import_file; ++ rewind (table->ex9_import_file); ++ ++ contents = bfd_malloc (sizeof (bfd_byte) * 4); ++ ++ /* Read instructions from the input file and build the list. */ ++ while (!feof (ex9_import_file)) ++ { ++ char *code; ++ struct elf_nds32_insn_times_entry *ptr; ++ size_t nread; ++ ++ nread = fread (contents, sizeof (bfd_byte) * 4, 1, ex9_import_file); ++ /* Ignore the final byte 0x0a. */ ++ if (nread < 1) ++ break; ++ insn = bfd_getb32 (contents); ++ code = bfd_malloc (sizeof (char) * 9); ++ snprintf (code, 9, "%08lx", insn); ++ ptr = bfd_malloc (sizeof (struct elf_nds32_insn_times_entry)); ++ ptr->string = code; ++ ptr->order = num; ++ ptr->times = -1; ++ ptr->sec = NULL; ++ ptr->m_list = NULL; ++ ptr->rel_backup.r_offset = 0; ++ ptr->rel_backup.r_info = 0; ++ ptr->rel_backup.r_addend = 0; ++ ptr->irel = NULL; ++ ptr->next = NULL; ++ nds32_elf_ex9_insert_entry (ptr); ++ num++; ++ } ++ ++ update_ex9_table = table->update_ex9_table; ++ if (update_ex9_table == 1) ++ { ++ /* It has to consider of sethi need to use multiple page ++ but it not be done yet. */ ++ nds32_elf_code_hash_traverse (nds32_elf_examine_insn_times); ++ nds32_elf_order_insn_times (info); ++ } ++} ++ ++/* Export ex9 table. */ ++ ++static void ++nds32_elf_ex9_export (struct bfd_link_info *info, ++ bfd_byte *contents, int size) ++{ ++ FILE *ex9_export_file; ++ struct elf_nds32_link_hash_table *table; ++ ++ table = nds32_elf_hash_table (info); ++ ex9_export_file = table->ex9_export_file; ++ fwrite (contents, sizeof (bfd_byte), size, ex9_export_file); ++ fclose (ex9_export_file); ++} ++ ++/* Adjust relocations of J and JAL in ex9.itable. ++ Export ex9 table. */ ++ ++static void ++nds32_elf_ex9_reloc_jmp (struct bfd_link_info *link_info) ++{ ++ asection *table_sec = NULL; ++ struct elf_nds32_insn_times_entry *ex9_insn = ex9_insn_head; ++ struct elf_nds32_insn_times_entry *temp_ptr, *temp_ptr2; ++ uint32_t insn, insn_with_reg, source_insn; ++ bfd_byte *contents = NULL, *source_contents = NULL; ++ int size = 0; ++ bfd_vma gp; ++ int shift, update_ex9_table, offset = 0; ++ reloc_howto_type *howto = NULL; ++ Elf_Internal_Rela rel_backup; ++ unsigned short insn_ex9; ++ struct elf_nds32_link_hash_table *table; ++ FILE *ex9_export_file; ++ static bfd_boolean done = FALSE; ++ ++ if (done) ++ return; ++ ++ done = TRUE; ++ ++ table = nds32_elf_hash_table (link_info); ++ if (table) ++ table->relax_status |= NDS32_RELAX_EX9_DONE; ++ ++ update_ex9_table = table->update_ex9_table; ++ ++ /* Generated ex9.itable exactly. */ ++ if (update_ex9_table == 0) ++ { ++ bfd *output_bfd; ++ table_sec = nds32_elf_ex9_get_section (link_info->input_bfds); ++ ++ if (table_sec == NULL) ++ { ++ (*_bfd_error_handler) (_("ld: error cannot find ex9 section.\n")); ++ return; ++ } ++ ++ output_bfd = table_sec->output_section->owner; ++ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); ++ if (table_sec->size == 0) ++ return; ++ ++ if (!nds32_get_section_contents (table_sec->owner, table_sec, ++ &contents, TRUE)) ++ return; ++ } ++ else ++ { ++ /* Set gp. */ ++ bfd *output_bfd; ++ ++ output_bfd = link_info->input_bfds->sections->output_section->owner; ++ nds32_elf_final_sda_base (output_bfd, link_info, &gp, FALSE); ++ contents = bfd_malloc (sizeof (bfd_byte) * 2048); ++ } ++ ++ /* Relocate instruction. */ ++ while (ex9_insn) ++ { ++ bfd_vma relocation, min_relocation = 0xffffffff; ++ ++ insn = strtol (ex9_insn->string, NULL, 16); ++ insn_with_reg = 0; ++ if (ex9_insn->m_list != NULL || ex9_insn->sec != NULL) ++ { ++ if (ex9_insn->m_list) ++ rel_backup = ex9_insn->m_list->rel_backup; ++ else ++ rel_backup = ex9_insn->rel_backup; ++ ++ nds32_elf_get_insn_with_reg (&rel_backup, insn, &insn_with_reg); ++ howto = ++ bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE ++ (rel_backup.r_info)); ++ shift = howto->rightshift; ++ if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_25_PCREL_RELA ++ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_ORI_RELA ++ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S0_RELA ++ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S1_RELA ++ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_LO12S2_RELA ++ || ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_20_RELA) ++ { ++ relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info); ++ insn = ++ insn_with_reg | ((relocation >> shift) & ++ nds32_elf_irel_mask (&rel_backup)); ++ bfd_putb32 (insn, contents + (ex9_insn->order) * 4); ++ } ++ else if ((ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3 ++ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0) ++ || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA15S3_RELA ++ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA15S0_RELA) ++ || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA12S2_DP_RELA ++ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA12S2_SP_RELA) ++ || (ELF32_R_TYPE (rel_backup.r_info) >= R_NDS32_SDA16S3_RELA ++ && ELF32_R_TYPE (rel_backup.r_info) <= R_NDS32_SDA19S0_RELA)) ++ { ++ relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info); ++ insn = ++ insn_with_reg | (((relocation - gp) >> shift) & ++ nds32_elf_irel_mask (&rel_backup)); ++ bfd_putb32 (insn, contents + (ex9_insn->order) * 4); ++ } ++ else if (ELF32_R_TYPE (rel_backup.r_info) == R_NDS32_HI20_RELA) ++ { ++ /* Sethi may be multiple entry for one insn. */ ++ if (ex9_insn->next && ex9_insn->m_list ++ && ex9_insn->m_list == ex9_insn->next->m_list) ++ { ++ struct elf_link_hash_entry_mul_list *m_list; ++ struct elf_nds32_ex9_refix *fix_ptr; ++ struct elf_link_hash_entry *h; ++ ++ temp_ptr = ex9_insn; ++ temp_ptr2 = ex9_insn; ++ m_list = ex9_insn->m_list; ++ while (m_list) ++ { ++ h = m_list->h_list->h; ++ relocation = h->root.u.def.value + ++ h->root.u.def.section->output_section->vma + ++ h->root.u.def.section->output_offset; ++ relocation += m_list->irel->r_addend; ++ ++ if (relocation < min_relocation) ++ min_relocation = relocation; ++ m_list = m_list->next; ++ } ++ relocation = min_relocation; ++ ++ /* Put insntruction into ex9 table. */ ++ insn = insn_with_reg ++ | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup)); ++ bfd_putb32 (insn, contents + (ex9_insn->order) * 4); ++ relocation = relocation + 0x1000; /* hi20 */ ++ ++ while (ex9_insn->next && ex9_insn->m_list ++ && ex9_insn->m_list == ex9_insn->next->m_list) ++ { ++ /* Multiple sethi. */ ++ ex9_insn = ex9_insn->next; ++ size += 4; ++ insn = ++ insn_with_reg | ((relocation >> shift) & ++ nds32_elf_irel_mask (&rel_backup)); ++ bfd_putb32 (insn, contents + (ex9_insn->order) * 4); ++ relocation = relocation + 0x1000; /* hi20 */ ++ } ++ ++ fix_ptr = ex9_refix_head; ++ while (fix_ptr) ++ { ++ /* Fix ex9 insn. */ ++ /* temp_ptr2 points to the head of multiple sethi. */ ++ temp_ptr = temp_ptr2; ++ while (fix_ptr->order != temp_ptr->order && fix_ptr->next) ++ { ++ fix_ptr = fix_ptr->next; ++ } ++ if (fix_ptr->order != temp_ptr->order) ++ break; ++ ++ /* Set source insn. */ ++ relocation = ++ fix_ptr->h->root.u.def.value + ++ fix_ptr->h->root.u.def.section->output_section->vma + ++ fix_ptr->h->root.u.def.section->output_offset; ++ relocation += fix_ptr->irel->r_addend; ++ /* sethi imm is imm20s. */ ++ source_insn = insn_with_reg | ((relocation >> shift) & 0xfffff); ++ ++ while (temp_ptr) ++ { ++ /* Match entry and source code. */ ++ insn = bfd_getb32 (contents + (temp_ptr->order) * 4 + offset); ++ if (insn == source_insn) ++ { ++ /* Fix the ex9 insn. */ ++ if (temp_ptr->order != fix_ptr->order) ++ { ++ if (!nds32_get_section_contents ++ (fix_ptr->sec->owner, fix_ptr->sec, ++ &source_contents, TRUE)) ++ (*_bfd_error_handler) ++ (_("Linker: error cannot fixed ex9 relocation \n")); ++ if (temp_ptr->order < 32) ++ insn_ex9 = INSN_EX9_IT_2; ++ else ++ insn_ex9 = INSN_EX9_IT_1; ++ insn_ex9 = insn_ex9 | temp_ptr->order; ++ bfd_putb16 (insn_ex9, source_contents + fix_ptr->irel->r_offset); ++ } ++ break; ++ } ++ else ++ { ++ if (!temp_ptr->next || temp_ptr->m_list != temp_ptr->next->m_list) ++ (*_bfd_error_handler) ++ (_("Linker: error cannot fixed ex9 relocation \n")); ++ else ++ temp_ptr = temp_ptr->next; ++ } ++ } ++ fix_ptr = fix_ptr->next; ++ } ++ } ++ else ++ { ++ relocation = nds32_elf_ex9_reloc_insn (ex9_insn, link_info); ++ insn = insn_with_reg ++ | ((relocation >> shift) & nds32_elf_irel_mask (&rel_backup)); ++ bfd_putb32 (insn, contents + (ex9_insn->order) * 4); ++ } ++ } ++ } ++ else ++ { ++ /* Insn without relocation does not have to be fixed ++ if need to update export table. */ ++ if (update_ex9_table == 1) ++ bfd_putb32 (insn, contents + (ex9_insn->order) * 4); ++ } ++ ex9_insn = ex9_insn->next; ++ size += 4; ++ } ++ ++ ex9_export_file = table->ex9_export_file; ++ if (ex9_export_file != NULL) ++ nds32_elf_ex9_export (link_info, contents, table_sec->size); ++ else if (update_ex9_table == 1) ++ { ++ table->ex9_export_file = table->ex9_import_file; ++ rewind (table->ex9_export_file); ++ nds32_elf_ex9_export (link_info, contents, size); ++ } ++} ++ ++/* Check this instruction is convertable to ex9. */ ++static bfd_boolean ++nds32_elf_ex9_check_available (uint32_t insn) ++{ ++ if (N32_OP6 (insn) == N32_OP6_MISC ++ && (N32_SUB5 (insn) == N32_MISC_SYSCALL ++ || N32_SUB5 (insn) == N32_MISC_BREAK ++ || N32_SUB5 (insn) == N32_MISC_TEQZ ++ || N32_SUB5 (insn) == N32_MISC_TNEZ ++ || N32_SUB5 (insn) == N32_MISC_TRAP)) ++ return FALSE; ++ return TRUE; ++} ++ ++/* Generate ex9 hash table. */ ++ ++static bfd_boolean ++nds32_elf_ex9_build_hash_table (bfd *abfd, asection *sec, ++ struct bfd_link_info *link_info) ++{ ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irelend; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *jrel; ++ Elf_Internal_Rela rel_backup; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Sym *isym = NULL; ++ asection *isec; ++ struct elf_link_hash_entry **sym_hashes; ++ bfd_byte *contents = NULL; ++ bfd_vma off = 0; ++ unsigned long r_symndx; ++ uint32_t insn, insn_with_reg; ++ struct elf_link_hash_entry *h; ++ int data_flag, shift, align; ++ bfd_vma relocation; ++ /* Suppress ex9 if `.no_relax ex9' or inner loop. */ ++ reloc_howto_type *howto = NULL; ++ ++ sym_hashes = elf_sym_hashes (abfd); ++ /* Load section instructions, relocations, and symbol table. */ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) ++ return FALSE; ++ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sec->reloc_count; ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (!nds32_get_local_syms (abfd, sec, &isym)) ++ return FALSE; ++ ++ /* Check the object if enable ex9. */ ++ irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend, ++ R_NDS32_RELAX_ENTRY); ++ ++ /* Check this section trigger ex9 relaxation. */ ++ if (irel == NULL ++ || irel >= irelend ++ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY ++ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_EX9_FLAG))) ++ return TRUE; ++ ++ irel = internal_relocs; ++ ++ /* Push each insn into hash table. */ ++ while (off < sec->size) ++ { ++ char code[10]; ++ struct elf_nds32_code_hash_entry *entry; ++ ++ while (irel != NULL && irel < irelend && irel->r_offset < off) ++ irel++; ++ ++ data_flag = nds32_elf_ex9_relocation_check (link_info, &irel, irelend, ++ NULL, sec, &off, contents); ++ if (data_flag & DATA_EXIST) ++ { ++ /* We save the move offset in the highest byte. */ ++ off += (data_flag >> 24); ++ continue; ++ } ++ ++ /* Ignore 2-byte instruction. */ ++ if (*(contents + off) & 0x80) ++ { ++ off += 2; ++ continue; ++ } ++ ++ insn = bfd_getb32 (contents + off); ++ if (!nds32_elf_ex9_check_available (insn)) ++ { ++ off += 4; ++ continue; ++ } ++ ++ h = NULL; ++ isec = NULL; ++ jrel = NULL; ++ rel_backup.r_info = 0; ++ rel_backup.r_offset = 0; ++ rel_backup.r_addend = 0; ++ /* Load the instruction and its opcode with register for comparing. */ ++ insn_with_reg = 0; ++ if (irel != NULL && irel < irelend && irel->r_offset == off) ++ { ++ nds32_elf_get_insn_with_reg (irel, insn, &insn_with_reg); ++ howto = bfd_elf32_bfd_reloc_type_table_lookup (ELF32_R_TYPE (irel->r_info)); ++ shift = howto->rightshift; ++ align = (1 << shift) - 1; ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_HI20_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_ORI_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S0_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S1_RELA ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LO12S2_RELA ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA) ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_20_RELA) ++ { ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ jrel = irel; ++ rel_backup = *irel; ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Local symbol. */ ++ int shndx = isym[r_symndx].st_shndx; ++ ++ bfd_vma st_value = (isym + r_symndx)->st_value; ++ isec = elf_elfsections (abfd)[shndx]->bfd_section; ++ relocation = (isec->output_section->vma + isec->output_offset ++ + st_value + irel->r_addend); ++ } ++ else ++ { ++ /* External symbol. */ ++ bfd_boolean warned ATTRIBUTE_UNUSED; ++ bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED; ++ asection *sym_sec; ++ ++ /* Maybe there is a better way to get h and relocation */ ++ RELOC_FOR_GLOBAL_SYMBOL (link_info, abfd, sec, irel, ++ r_symndx, symtab_hdr, sym_hashes, ++ h, sym_sec, relocation, ++ unresolved_reloc, warned); ++ relocation += irel->r_addend; ++ if ((h->root.type != bfd_link_hash_defined ++ && h->root.type != bfd_link_hash_defweak) ++ || strcmp (h->root.root.string, "_FP_BASE_") == 0) ++ { ++ off += 4; ++ continue; ++ } ++ } ++ ++ /* Check for gp relative instruction alignment. */ ++ if ((ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA)) ++ { ++ bfd_vma gp; ++ bfd *output_bfd = sec->output_section->owner; ++ bfd_reloc_status_type r; ++ ++ /* If the symbol is in the abs section, the out_bfd will be ++ null. This happens when the relocation has a ++ symbol@GOTOFF. */ ++ r = nds32_elf_final_sda_base (output_bfd, link_info, ++ &gp, FALSE); ++ if (r != bfd_reloc_ok) ++ { ++ off += 4; ++ continue; ++ } ++ ++ relocation -= gp; ++ ++ /* Make sure alignment is correct. */ ++ if (relocation & align) ++ { ++ /* Incorrect alignment. */ ++ (*_bfd_error_handler) ++ (_("%s: warning: unaligned small data access. " ++ "For entry: {%d, %d, %d}, addr = 0x%x, align = 0x%x."), ++ bfd_get_filename (abfd), irel->r_offset, ++ irel->r_info, irel->r_addend, relocation, align); ++ off += 4; ++ continue; ++ } ++ } ++ ++ insn = insn_with_reg ++ | ((relocation >> shift) & nds32_elf_irel_mask (irel)); ++ } ++ else ++ { ++ off += 4; ++ continue; ++ } ++ } ++ ++ snprintf (code, sizeof (code), "%08x", insn); ++ /* Copy "code". */ ++ entry = (struct elf_nds32_code_hash_entry*) ++ bfd_hash_lookup (&ex9_code_table, code, TRUE, TRUE); ++ if (entry == NULL) ++ { ++ (*_bfd_error_handler) ++ (_("%P%F: failed creating ex9.it %s hash table: %E\n"), code); ++ return FALSE; ++ } ++ if (h) ++ { ++ if (h->root.type == bfd_link_hash_undefined) ++ return TRUE; ++ /* Global symbol. */ ++ /* In order to do sethi with different symbol but same value. */ ++ if (entry->m_list == NULL) ++ { ++ struct elf_link_hash_entry_mul_list *m_list_new; ++ struct elf_link_hash_entry_list *h_list_new; ++ ++ m_list_new = (struct elf_link_hash_entry_mul_list *) ++ bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list)); ++ h_list_new = (struct elf_link_hash_entry_list *) ++ bfd_malloc (sizeof (struct elf_link_hash_entry_list)); ++ entry->m_list = m_list_new; ++ m_list_new->h_list = h_list_new; ++ m_list_new->rel_backup = rel_backup; ++ m_list_new->times = 1; ++ m_list_new->irel = jrel; ++ m_list_new->next = NULL; ++ h_list_new->h = h; ++ h_list_new->next = NULL; ++ } ++ else ++ { ++ struct elf_link_hash_entry_mul_list *m_list = entry->m_list; ++ struct elf_link_hash_entry_list *h_list; ++ ++ while (m_list) ++ { ++ /* Build the different symbols that point to the same address. */ ++ h_list = m_list->h_list; ++ if (h_list->h->root.u.def.value == h->root.u.def.value ++ && h_list->h->root.u.def.section->output_section->vma ++ == h->root.u.def.section->output_section->vma ++ && h_list->h->root.u.def.section->output_offset ++ == h->root.u.def.section->output_offset ++ && m_list->rel_backup.r_addend == rel_backup.r_addend) ++ { ++ m_list->times++; ++ m_list->irel = jrel; ++ while (h_list->h != h && h_list->next) ++ h_list = h_list->next; ++ if (h_list->h != h) ++ { ++ struct elf_link_hash_entry_list *h_list_new; ++ ++ h_list_new = (struct elf_link_hash_entry_list *) ++ bfd_malloc (sizeof (struct elf_link_hash_entry_list)); ++ h_list->next = h_list_new; ++ h_list_new->h = h; ++ h_list_new->next = NULL; ++ } ++ break; ++ } ++ /* The sethi case may have different address but the ++ hi20 is the same. */ ++ else if (ELF32_R_TYPE (jrel->r_info) == R_NDS32_HI20_RELA ++ && m_list->next == NULL) ++ { ++ struct elf_link_hash_entry_mul_list *m_list_new; ++ struct elf_link_hash_entry_list *h_list_new; ++ ++ m_list_new = (struct elf_link_hash_entry_mul_list *) ++ bfd_malloc (sizeof (struct elf_link_hash_entry_mul_list)); ++ h_list_new = (struct elf_link_hash_entry_list *) ++ bfd_malloc (sizeof (struct elf_link_hash_entry_list)); ++ m_list->next = m_list_new; ++ m_list_new->h_list = h_list_new; ++ m_list_new->rel_backup = rel_backup; ++ m_list_new->times = 1; ++ m_list_new->irel = jrel; ++ m_list_new->next = NULL; ++ h_list_new->h = h; ++ h_list_new->next = NULL; ++ break; ++ } ++ m_list = m_list->next; ++ } ++ if (!m_list) ++ { ++ off += 4; ++ continue; ++ } ++ } ++ } ++ else ++ { ++ /* Local symbol and insn without relocation*/ ++ entry->times++; ++ entry->rel_backup = rel_backup; ++ } ++ ++ /* Use in sethi insn with constant and global symbol in same format. */ ++ if (!jrel) ++ entry->const_insn = 1; ++ else ++ entry->irel = jrel; ++ entry->sec = isec; ++ off += 4; ++ } ++ return TRUE; ++} ++ ++/* Set the _ITB_BASE_, and point it to ex9 table. */ ++ ++bfd_boolean ++nds32_elf_ex9_itb_base (struct bfd_link_info *link_info) ++{ ++ asection *sec; ++ bfd *output_bfd = NULL; ++ struct bfd_link_hash_entry *bh = NULL; ++ ++ if (is_ITB_BASE_set == 1) ++ return TRUE; ++ ++ is_ITB_BASE_set = 1; ++ ++ sec = nds32_elf_ex9_get_section (link_info->input_bfds); ++ if (sec != NULL) ++ output_bfd = sec->output_section->owner; ++ ++ if (output_bfd == NULL) ++ { ++ output_bfd = link_info->output_bfd; ++ if (output_bfd->sections == NULL) ++ return TRUE; ++ else ++ sec = bfd_abs_section_ptr; ++ } ++ ++ /* Do not define _ITB_BASE_ if it is not used. ++ And remain user to set it if needed. */ ++ ++ bh = bfd_link_hash_lookup (link_info->hash, "_ITB_BASE_", ++ FALSE, FALSE, TRUE); ++ if (!bh) ++ return TRUE; ++ ++ return (_bfd_generic_link_add_one_symbol ++ (link_info, output_bfd, "_ITB_BASE_", BSF_GLOBAL | BSF_WEAK, ++ sec, 0, (const char *) NULL, FALSE, ++ get_elf_backend_data (output_bfd)->collect, &bh)); ++} ++/* End EX9.IT */ ++ ++ ++/* Begining IFC. This is common code ifc optimization. */ ++ ++struct elf_nds32_ifc_code_hash_entry; ++struct elf_nds32_ifc_unit; ++ ++/* Save the offset and section. */ ++ ++struct elf_nds32_ifc_member ++{ ++ unsigned long int offset; ++ asection *sec; ++ ++ /* Link to its unit. */ ++ struct elf_nds32_ifc_unit *unit_p; ++ ++ /* Link to its previous entry. */ ++ struct elf_nds32_ifc_code_hash_entry *pre_entry; ++ ++ /* Save next insnstrution member to find group quickly. */ ++ struct elf_nds32_ifc_member *next_member; ++ struct elf_nds32_ifc_member *pre_member; ++ /* Save the jump target for the previous instruction. */ ++ struct bfd_link_hash_entry *bh; ++ bfd_boolean dead; ++ struct elf_nds32_ifc_member *next; ++}; ++ ++/* The unit of elf_nds32_ifc_code_hash_entry. */ ++ ++struct elf_nds32_ifc_unit ++{ ++ int times; ++ int done; ++ struct elf_nds32_ifc_member *member; ++ ++ /* Link to its entry. */ ++ struct elf_nds32_ifc_code_hash_entry *entry_p; ++ ++ /* Save next insnstruction entry. */ ++ struct elf_nds32_ifc_code_hash_entry *hash; ++ struct elf_nds32_ifc_unit *next; ++}; ++ ++/* Instruction hash table. */ ++ ++struct elf_nds32_ifc_code_hash_entry ++{ ++ struct bfd_hash_entry root; ++ int times; ++ int size; ++ struct elf_nds32_ifc_unit *unit; ++ struct elf_link_hash_entry *h; ++ ++ /* Save the max times unit in this entry. */ ++ struct elf_nds32_ifc_unit *max_unit; ++ struct elf_nds32_ifc_code_hash_entry *next; /* For sort times. */ ++ int round; /* Save round of nds32_elf_ifc_find_cse to avoid reentrance. */ ++ struct elf_nds32_ifc_code_hash_entry *max_next; ++ bfd_boolean end; /* This is instruction can break ifc block. */ ++ int max_times; ++}; ++ ++/* Structure for replace using. */ ++ ++struct elf_nds32_ifc_insn_member ++{ ++ struct elf_nds32_ifc_member *member; ++ struct elf_nds32_ifc_insn_member *next; ++}; ++ ++struct elf_nds32_ifc_insn_stack ++{ ++ int live; ++ int extend; ++ int choose; ++ struct elf_nds32_ifc_insn_member *imember; ++ struct elf_nds32_ifc_insn_stack *next; ++}; ++ ++/* Save members in the same section. */ ++ ++struct elf_nds32_ifc_sec_member ++{ ++ struct elf_nds32_ifc_member *member; ++ struct elf_nds32_ifc_sec_member *next; ++}; ++ ++struct elf_nds32_ifc_sec_block ++{ ++ asection *sec; ++ struct elf_nds32_ifc_sec_member *smember; ++ struct elf_nds32_ifc_sec_block *next; ++}; ++ ++struct elf_nds32_ifc_barrier ++{ ++ bfd_vma offset; ++ struct elf_nds32_ifc_barrier *next; ++}; ++ ++/* Ifc global symbol. */ ++struct bfd_hash_table ifc_code_table; ++struct elf_nds32_ifc_code_hash_entry *ifc_insn_head = NULL; ++struct elf_nds32_ifc_sec_block *ifc_block_head = NULL; ++ ++/* IFC hash function. */ ++ ++static struct bfd_hash_entry * ++nds32_elf_ifc_code_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ struct elf_nds32_ifc_code_hash_entry *ret; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (entry == NULL) ++ { ++ entry = (struct bfd_hash_entry *) ++ bfd_hash_allocate (table, sizeof (*ret)); ++ if (entry == NULL) ++ return entry; ++ } ++ ++ /* Call the allocation method of the superclass. */ ++ entry = bfd_hash_newfunc (entry, table, string); ++ if (entry == NULL) ++ return entry; ++ ++ ret = (struct elf_nds32_ifc_code_hash_entry*) entry; ++ ret->times = 0; ++ ret->unit = NULL; ++ ret->next = NULL; ++ ret->size = 0; ++ ret->h = NULL; ++ ret->max_unit = NULL; ++ ret->round = 0; ++ ret->max_next = NULL; ++ ret->max_times = 0; ++ ret->end = FALSE; ++ return &ret->root; ++} ++ ++/* Do TLS model conversion. */ ++ ++typedef struct relax_group_list_t ++{ ++ Elf_Internal_Rela *relo; ++ struct relax_group_list_t *next; ++ struct relax_group_list_t *next_sibling; ++ int id; ++} relax_group_list_t; ++ ++int ++list_insert (relax_group_list_t *pHead, Elf_Internal_Rela *pElem); ++ ++int ++list_insert_sibling (relax_group_list_t *pNode, Elf_Internal_Rela *pElem); ++ ++void ++dump_chain (relax_group_list_t *pHead); ++ ++int ++list_insert (relax_group_list_t *pHead, Elf_Internal_Rela *pElem) ++{ ++ relax_group_list_t *pNext = pHead; ++ ++ /* find place */ ++ while (pNext->next) ++ { ++ if (pNext->next->id > (int) pElem->r_addend) ++ break; ++ ++ pNext = pNext->next; ++ } ++ ++ /* insert node */ ++ relax_group_list_t *pNew = bfd_malloc (sizeof (relax_group_list_t)); ++ if (!pNew) ++ return FALSE; ++ ++ relax_group_list_t *tmp = pNext->next; ++ pNext->next = pNew; ++ ++ pNew->id = pElem->r_addend; ++ pNew->relo = pElem; ++ pNew->next = tmp; ++ pNew->next_sibling = NULL; ++ ++ return TRUE; ++} ++ ++int ++list_insert_sibling (relax_group_list_t *pNode, Elf_Internal_Rela *pElem) ++{ ++ relax_group_list_t *pNext = pNode; ++ ++ /* find place */ ++ while (pNext->next_sibling) ++ { ++ pNext = pNext->next_sibling; ++ } ++ ++ /* insert node */ ++ relax_group_list_t *pNew = bfd_malloc (sizeof (relax_group_list_t)); ++ if (!pNew) ++ return FALSE; ++ ++ relax_group_list_t *tmp = pNext->next_sibling; ++ pNext->next_sibling = pNew; ++ ++ pNew->id = -1; ++ pNew->relo = pElem; ++ pNew->next = NULL; ++ pNew->next_sibling = tmp; ++ ++ return TRUE; ++} ++ ++void ++dump_chain (relax_group_list_t *pHead) ++{ ++ relax_group_list_t *pNext = pHead->next; ++ while (pNext) ++ { ++ printf("group %d @ 0x%08x", pNext->id, (unsigned)pNext->relo->r_offset); ++ relax_group_list_t *pNextSib = pNext->next_sibling; ++ while (pNextSib) ++ { ++ printf(", %d", (unsigned) ELF32_R_TYPE (pNextSib->relo->r_info)); ++ pNextSib = pNextSib->next_sibling; ++ } ++ pNext = pNext->next; ++ printf("\n"); ++ } ++} ++ ++/* check R_NDS32_RELAX_GROUP of each section. ++ * there might be multiple sections in one object file. ++ */ ++int ++elf32_nds32_check_relax_group (bfd *abfd, asection *asec) ++{ ++ elf32_nds32_relax_group_t *relax_group_ptr = ++ elf32_nds32_relax_group_ptr (abfd); ++ ++ int min_id = relax_group_ptr->min_id; ++ int max_id = relax_group_ptr->max_id; ++ ++ Elf_Internal_Rela *rel; ++ Elf_Internal_Rela *relend; ++ Elf_Internal_Rela *relocs; ++ enum elf_nds32_reloc_type rtype; ++ ++ do ++ { ++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ ++ relocs = _bfd_elf_link_read_relocs (abfd, asec, NULL, NULL, ++ TRUE /* keep_memory */); ++ if (relocs == NULL) ++ break; ++ ++ /* check R_NDS32_RELAX_GROUP */ ++ relend = relocs + asec->reloc_count; ++ for (rel = relocs; rel < relend; rel++) ++ { ++ int id; ++ rtype = ELF32_R_TYPE (rel->r_info); ++ if (rtype != R_NDS32_RELAX_GROUP) ++ continue; ++ ++ id = rel->r_addend; ++ if (id < min_id) ++ min_id = id; ++ else if (id > max_id) ++ max_id = id; ++ } ++ } ++ while (FALSE); ++ ++ if ((relocs != NULL) && (elf_section_data (asec)->relocs != relocs)) ++ free (relocs); ++ ++ if ((min_id != relax_group_ptr->min_id) ++ || (max_id != relax_group_ptr->max_id)) ++ { ++ relax_group_ptr->count = max_id - min_id + 1; ++ BFD_ASSERT(min_id <= relax_group_ptr->min_id); ++ relax_group_ptr->min_id = min_id; ++ BFD_ASSERT(max_id >= relax_group_ptr->max_id); ++ relax_group_ptr->max_id = max_id; ++ } ++ ++ return relax_group_ptr->count; ++} ++ ++/* reorder RELAX_GROUP ID when command line option '-r' is applied */ ++/* TODO: find a way to free me. */ ++struct section_id_list_t *relax_group_section_id_list = NULL; ++ ++struct section_id_list_t * ++elf32_nds32_lookup_section_id (int id, struct section_id_list_t **lst_ptr) ++{ ++ struct section_id_list_t *result = NULL; ++ struct section_id_list_t *lst = *lst_ptr; ++ ++ if (NULL == lst) ++ { ++ result = (struct section_id_list_t *) calloc ( ++ 1, sizeof (struct section_id_list_t)); ++ BFD_ASSERT (result); /* feed me */ ++ result->id = id; ++ *lst_ptr = result; ++ } ++ else ++ { ++ struct section_id_list_t *cur = lst; ++ struct section_id_list_t *prv = NULL; ++ struct section_id_list_t *sec = NULL; ++ while (cur) ++ { ++ if (cur->id < id) ++ { ++ prv = cur; ++ cur = cur->next; ++ continue; ++ } ++ ++ if (cur->id > id) ++ { ++ cur = NULL; /* to insert after prv */ ++ sec = cur; /* in case prv == NULL */ ++ } ++ ++ break; ++ } ++ ++ if (NULL == cur) ++ { ++ /* insert after prv */ ++ result = (struct section_id_list_t *) calloc ( ++ 1, sizeof (struct section_id_list_t)); ++ BFD_ASSERT (result); /* feed me */ ++ result->id = id; ++ if (NULL != prv) ++ { ++ result->next = prv->next; ++ prv->next = result; ++ } ++ else ++ { ++ *lst_ptr = result; ++ result->next = sec; ++ } ++ } ++ } ++ ++ return result; ++} ++ ++int ++elf32_nds32_unify_relax_group (bfd *abfd, asection *asec) ++{ ++ static int next_relax_group_bias = 0; ++ ++ elf32_nds32_relax_group_t *relax_group_ptr = ++ elf32_nds32_relax_group_ptr (abfd); ++ ++ bfd_boolean result = TRUE; ++ Elf_Internal_Rela *rel; ++ Elf_Internal_Rela *relend; ++ Elf_Internal_Rela *relocs = NULL; ++ enum elf_nds32_reloc_type rtype; ++ struct section_id_list_t *node = NULL; ++ int count = 0; ++ ++ do ++ { ++ if (0 == relax_group_ptr->count) ++ break; ++ ++ /* check if this section has handled */ ++ node = elf32_nds32_lookup_section_id (asec->id, &relax_group_section_id_list); ++ if (NULL == node) ++ break; /* hit, the section id has handled. */ ++ ++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ ++ relocs = _bfd_elf_link_read_relocs (abfd, asec, NULL, NULL, ++ TRUE /* keep_memory */); ++ if (relocs == NULL) ++ { ++ BFD_ASSERT (0); /* feed me */ ++ break; ++ } ++ ++ /* allocate group id bias for this bfd! */ ++ if (0 == relax_group_ptr->init) ++ { ++ relax_group_ptr->bias = next_relax_group_bias; ++ next_relax_group_bias += relax_group_ptr->count; ++ relax_group_ptr->init = 1; ++ } ++ ++ /* reorder relax group groups */ ++ relend = relocs + asec->reloc_count; ++ for (rel = relocs; rel < relend; rel++) ++ { ++ rtype = ELF32_R_TYPE(rel->r_info); ++ if (rtype != R_NDS32_RELAX_GROUP) ++ continue; ++ ++ /* change it */ ++ rel->r_addend += relax_group_ptr->bias; ++ /* debugging count */ ++ count++; ++ } ++ } ++ while (FALSE); ++ ++ if (relocs != NULL && elf_section_data (asec)->relocs != relocs) ++ free (relocs); ++ ++ return result; ++} ++ ++int ++nds32_elf_unify_tls_model (bfd *inbfd, asection *insec, bfd_byte *incontents, ++ struct bfd_link_info *lnkinfo) ++{ ++ bfd_boolean result = TRUE; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *irelend; ++ Elf_Internal_Rela *internal_relocs; ++ unsigned long r_symndx; ++ enum elf_nds32_reloc_type r_type; ++ ++ Elf_Internal_Sym *local_syms = NULL; ++ bfd_byte *contents = NULL; ++ ++ relax_group_list_t chain = { .id = -1, .next = NULL, .next_sibling = NULL }; ++ ++ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (inbfd)->symtab_hdr; ++ struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; ++ sym_hashes = elf_sym_hashes (inbfd); ++ sym_hashes_end = ++ sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym); ++ if (!elf_bad_symtab (inbfd)) ++ sym_hashes_end -= symtab_hdr->sh_info; ++ ++ /* reorder RELAX_GROUP when command line option '-r' is applied */ ++ if (lnkinfo->relocatable) ++ { ++ elf32_nds32_unify_relax_group (inbfd, insec); ++ /* goto finish; */ ++ return result; ++ } ++ ++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ ++ internal_relocs = _bfd_elf_link_read_relocs (inbfd, insec, NULL, NULL, ++ TRUE /* keep_memory */); ++ if (internal_relocs == NULL) ++ goto error_return; ++ ++ irelend = internal_relocs + insec->reloc_count; ++ irel = find_relocs_at_address (internal_relocs, internal_relocs, ++ irelend, R_NDS32_RELAX_ENTRY); ++ if (irel == irelend) ++ goto finish; ++ ++ /* chain/remove groups */ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ r_type = ELF32_R_TYPE (irel->r_info); ++ if (r_type != R_NDS32_RELAX_GROUP) ++ continue; ++ ++ /* remove it */ ++ irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_NONE); ++ /* chain it now */ ++ if (!list_insert (&chain, irel)) ++ goto error_return; ++ } ++ ++ /* collect group relocations */ ++ /* presume relocations are sorted */ ++ relax_group_list_t *pNext = chain.next; ++ if (pNext) ++ { ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ if (irel->r_offset == pNext->relo->r_offset) ++ { ++ /* ignore Non-TLS relocation types */ ++ r_type = ELF32_R_TYPE (irel->r_info); ++ if ((R_NDS32_TLS_TPOFF > r_type) ++ || (R_NDS32_RELAX_ENTRY == r_type)) ++ continue; ++ ++ if (!list_insert_sibling (pNext, irel)) ++ goto error_return; ++ } ++ else if (irel->r_offset > pNext->relo->r_offset) ++ { ++ pNext = pNext->next; ++ if (!pNext) ++ break; ++ ++ bfd_vma current_offset = pNext->relo->r_offset; ++ if (irel->r_offset > current_offset) ++ irel = internal_relocs; /* restart from head */ ++ else ++ --irel; /* check current irel again */ ++ continue; ++ } ++ else ++ { ++ //printf("irel->off = 0x%08x, pNext->relo->off = 0x%08x (0x%08x)\n", (unsigned)irel->r_offset, (unsigned)pNext->relo->r_offset, (unsigned)first_offset); ++ } ++ } ++ } ++ ++#ifdef DUBUG_VERBOSE ++ dump_chain(&chain); ++#endif ++ ++ /* Get symbol table and section content. */ ++ if (incontents) ++ contents = incontents; ++ else if (!nds32_get_section_contents (inbfd, insec, &contents, TRUE) ++ || !nds32_get_local_syms (inbfd, insec, &local_syms)) ++ goto error_return; ++ ++ char *local_got_tls_type = elf32_nds32_local_got_tls_type (inbfd); ++ ++ /* convert TLS model each group if necessary */ ++ pNext = chain.next; ++ int cur_grp_id = -1; ++ int sethi_rt = -1; ++ int add_rt = -1; ++ enum elf_nds32_tls_type tls_type, org_tls_type, eff_tls_type; ++ tls_type = org_tls_type = eff_tls_type = 0; ++ while (pNext) ++ { ++ relax_group_list_t *pNextSig = pNext->next_sibling; ++ while (pNextSig) ++ { ++ struct elf_link_hash_entry *h = NULL; ++ irel = pNextSig->relo; ++ r_symndx = ELF32_R_SYM(irel->r_info); ++ r_type = ELF32_R_TYPE(irel->r_info); ++ ++ if (pNext->id != cur_grp_id) ++ { ++ cur_grp_id = pNext->id; ++ org_tls_type = get_tls_type (r_type, NULL); ++ if (r_symndx >= symtab_hdr->sh_info) ++ { ++ h = sym_hashes[r_symndx - symtab_hdr->sh_info]; ++ while (h->root.type == bfd_link_hash_indirect ++ || h->root.type == bfd_link_hash_warning) ++ h = (struct elf_link_hash_entry *) h->root.u.i.link; ++ tls_type = ((struct elf_nds32_link_hash_entry *) h)->tls_type; ++ } ++ else ++ { ++ /* TODO: find local symbol hash if necessary? */ ++ tls_type = local_got_tls_type ? local_got_tls_type[r_symndx] : GOT_NORMAL; ++ } ++ ++ eff_tls_type = 1 << (fls (tls_type) - 1); ++ sethi_rt = N32_RT5(bfd_getb32 (contents + irel->r_offset)); ++ } ++ ++ if (eff_tls_type != org_tls_type) ++ { ++ switch (org_tls_type) ++ { ++ case GOT_TLS_DESC: ++ switch (eff_tls_type) ++ { ++ case GOT_TLS_IE: ++ switch (r_type) ++ { ++ case R_NDS32_TLS_DESC_HI20: ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_TLS_IE_HI20); ++ break; ++ case R_NDS32_TLS_DESC_LO12: ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_TLS_IE_LO12); ++ break; ++ case R_NDS32_TLS_DESC_ADD: ++ { ++ uint32_t insn = bfd_getb32 ( ++ contents + irel->r_offset); ++ add_rt = N32_RT5 (insn); ++ insn = N32_TYPE2 (LWI, add_rt, sethi_rt, 0); ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); ++/* irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_IE_LW); ++*/ ++ } ++ break; ++ case R_NDS32_TLS_DESC_FUNC: ++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_RELAX_REMOVE); ++ break; ++ case R_NDS32_TLS_DESC_CALL: ++ { ++ uint32_t insn = N32_ALU1(ADD, REG_R0, add_rt, ++ REG_TP); ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); ++ } ++ break; ++ case R_NDS32_LOADSTORE: ++ case R_NDS32_PTR: ++ case R_NDS32_PTR_RESOLVED: ++ case R_NDS32_NONE: ++ case R_NDS32_LABEL: ++ break; ++ default: ++ BFD_ASSERT(0); ++ break; ++ } ++ break; ++ case GOT_TLS_IEGP: ++ switch (r_type) ++ { ++ case R_NDS32_TLS_DESC_HI20: ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_TLS_IEGP_HI20); ++ break; ++ case R_NDS32_TLS_DESC_LO12: ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_TLS_IEGP_LO12); ++ break; ++ case R_NDS32_TLS_DESC_ADD: ++ { ++ uint32_t insn = bfd_getb32 ( ++ contents + irel->r_offset); ++ add_rt = N32_RT5 (insn); ++ insn = N32_MEM(LW, add_rt, sethi_rt, REG_GP, 0); ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); ++/* irel->r_info = ELF32_R_INFO (r_symndx, R_NDS32_TLS_IEGP_LW); ++*/ ++ } ++ break; ++ case R_NDS32_TLS_DESC_FUNC: ++ bfd_putb32 (INSN_NOP, contents + irel->r_offset); ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_RELAX_REMOVE); ++ break; ++ case R_NDS32_TLS_DESC_CALL: ++ { ++ uint32_t insn = N32_ALU1(ADD, REG_R0, add_rt, ++ REG_TP); ++ bfd_putb32 (insn, contents + irel->r_offset); ++ ++ irel->r_info = ELF32_R_INFO(r_symndx, R_NDS32_NONE); ++ } ++ break; ++ case R_NDS32_LOADSTORE: ++ case R_NDS32_PTR: ++ case R_NDS32_PTR_RESOLVED: ++ case R_NDS32_NONE: ++ case R_NDS32_LABEL: ++ break; ++ default: ++ BFD_ASSERT(0); ++ break; ++ } ++ break; ++ default: ++#ifdef DEBUG_VERBOSE ++ printf ( ++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", ++ inbfd->filename, h ? h->root.root.string : "local", ++ (unsigned) irel->r_offset, tls_type, eff_tls_type, ++ org_tls_type); ++#endif ++ break; ++ } ++ break; ++ case GOT_TLS_IEGP: ++ switch (eff_tls_type) ++ { ++ case GOT_TLS_IE: ++ switch (r_type) ++ { ++ case R_NDS32_TLS_IEGP_HI20: ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_TLS_IE_HI20); ++ break; ++ case R_NDS32_TLS_IEGP_LO12: ++ irel->r_info = ELF32_R_INFO(r_symndx, ++ R_NDS32_TLS_IE_LO12); ++ break; ++ case R_NDS32_PTR_RESOLVED: ++ { ++ uint32_t insn = bfd_getb32 ( ++ contents + irel->r_offset); ++ add_rt = N32_RT5 (insn); ++ insn = N32_TYPE2 (LWI, add_rt, sethi_rt, 0); ++ bfd_putb32 (insn, contents + irel->r_offset); ++ } ++ break; ++ case R_NDS32_LOADSTORE: ++ case R_NDS32_PTR: ++ case R_NDS32_NONE: ++ case R_NDS32_LABEL: ++ break; ++ default: ++ BFD_ASSERT(0); ++ break; ++ } ++ break; ++ default: ++#ifdef DEBUG_VERBOSE ++ printf ( ++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", ++ inbfd->filename, h ? h->root.root.string : "local", ++ (unsigned) irel->r_offset, tls_type, eff_tls_type, ++ org_tls_type); ++#endif ++ break; ++ } ++ break; ++ default: ++#ifdef DEBUG_VERBOSE ++ printf ( ++ "SKIP: %s: %s @ 0x%08x tls_type = 0x%08x, eff_tls_type = 0x%08x, org_tls_type = 0x%08x\n", ++ inbfd->filename, h ? h->root.root.string : "local", ++ (unsigned) irel->r_offset, tls_type, eff_tls_type, ++ org_tls_type); ++#endif ++ break; ++ } ++ } ++ pNextSig = pNextSig->next_sibling; ++ } ++ ++#if 1 ++ pNext = pNext->next; ++#else ++ while (pNext) ++ { ++ if (pNext->id != cur_grp_id) ++ break; ++ pNext = pNext->next; ++ } ++#endif ++ } ++ ++finish: ++ if (incontents) ++ contents = NULL; ++ ++ if (internal_relocs != NULL ++ && elf_section_data (insec)->relocs != internal_relocs) ++ free (internal_relocs); ++ ++ if (contents != NULL ++ && elf_section_data (insec)->this_hdr.contents != contents) ++ free (contents); ++ ++ if (local_syms != NULL && symtab_hdr->contents != (bfd_byte *) local_syms) ++ free (local_syms); ++ ++ if (chain.next) ++ { ++ pNext = chain.next; ++ relax_group_list_t *pDel; ++ while (pNext) ++ { ++ pDel = pNext; ++ pNext = pNext->next; ++ free (pDel); ++ } ++ } ++ ++ return result; ++ ++error_return: ++ result = FALSE; ++ goto finish; ++} ++ ++/* Initialize ifc hash table. */ ++ ++static int ++nds32_elf_ifc_init (void) ++{ ++ static bfd_boolean done = FALSE; ++ if (done) ++ return TRUE; ++ ++ done = TRUE; ++ if (!bfd_hash_table_init (&ifc_code_table, nds32_elf_ifc_code_hash_newfunc, ++ sizeof (struct elf_nds32_ifc_code_hash_entry))) ++ { ++ (*_bfd_error_handler) (_("Ld error: cannot init ifc hash table\n")); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++/* New a unit and insert ifc hash entry. */ ++ ++static void ++nds32_elf_ifc_new_ifc_unit (struct elf_nds32_ifc_code_hash_entry *entry, ++ struct elf_nds32_ifc_code_hash_entry *pre_entry, ++ struct elf_nds32_ifc_member *child, ++ struct elf_nds32_ifc_member *pre_child) ++{ ++ struct elf_nds32_ifc_unit *ptr_unit, *temp_unit; ++ struct elf_nds32_ifc_member *ptr_member; ++ ++ if (!pre_entry || !pre_child) ++ return; ++ ++ /* Find unit in entry. */ ++ ptr_unit = pre_entry->unit; ++ temp_unit = ptr_unit; ++ while (ptr_unit && ptr_unit->hash != entry) ++ { ++ temp_unit = ptr_unit; ++ ptr_unit = ptr_unit->next; ++ } ++ if (!ptr_unit) ++ { ++ ptr_unit = bfd_malloc (sizeof (struct elf_nds32_ifc_unit)); ++ if (!pre_entry->unit) ++ pre_entry->unit = ptr_unit; ++ else ++ temp_unit->next = ptr_unit; ++ ptr_unit->times = 0; ++ ptr_unit->member = NULL; ++ ptr_unit->hash = entry; ++ ptr_unit->next = NULL; ++ ptr_unit->entry_p = pre_entry; ++ ptr_unit->done = 0; ++ } ++ pre_child->next_member = child; ++ pre_child->unit_p = ptr_unit; ++ ptr_unit->times++; ++ if (!pre_entry->max_unit ++ || pre_entry->max_unit->times < ptr_unit->times) ++ pre_entry->max_unit = ptr_unit; ++ ++ /* Insert member into unit. */ ++ ptr_member = ptr_unit->member; ++ while (ptr_member && ptr_member->next) ++ ptr_member = ptr_member->next; ++ ++ if (!ptr_member) ++ ptr_unit->member = pre_child; ++ else ++ ptr_member->next = pre_child; ++} ++ ++/* Insert the symbol and relocation barrier list. */ ++ ++static void ++nds32_elf_ifc_insert_barrier (int offset, ++ struct elf_nds32_ifc_barrier ** barrier) ++{ ++ struct elf_nds32_ifc_barrier *new_barrier; ++ struct elf_nds32_ifc_barrier *last_barrier; ++ ++ /* The symbol is in this section. */ ++ new_barrier = malloc (sizeof (struct elf_nds32_ifc_barrier)); ++ new_barrier->offset = offset; ++ new_barrier->next = NULL; ++ if (*barrier == NULL) ++ *barrier = new_barrier; ++ else ++ { ++ if (new_barrier->offset < (*barrier)->offset) ++ { ++ new_barrier->next = *barrier; ++ *barrier = new_barrier; ++ } ++ else ++ { ++ last_barrier = *barrier; ++ while (last_barrier->next ++ && last_barrier->next->offset < new_barrier->offset) ++ last_barrier = last_barrier->next; ++ new_barrier->next = last_barrier->next; ++ last_barrier->next = new_barrier; ++ } ++ } ++} ++ ++/* Build barrier list. */ ++ ++static bfd_boolean ++nds32_elf_ifc_build_barrier (bfd *abfd, asection *sec, ++ struct elf_nds32_ifc_barrier **barrier) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); ++ Elf_Internal_Shdr *hdr; ++ bfd_size_type symcount; ++ bfd_size_type extsymcount; ++ struct bfd_link_hash_entry *bh; ++ Elf_Internal_Rela *internal_relocs, *irelend, *irel; ++ unsigned int sec_shndx; ++ Elf_Internal_Shdr *symtab_hdr; ++ Elf_Internal_Sym *isym = NULL; ++ unsigned int i; ++ ++ /* Scan global symbol. */ ++ if (sym_hashes) ++ { ++ if (!(abfd->flags & DYNAMIC) || elf_dynsymtab (abfd) == 0) ++ hdr = &elf_tdata (abfd)->symtab_hdr; ++ else ++ return FALSE; ++ ++ /* Check for the symbol existence. */ ++ symcount = hdr->sh_size / bed->s->sizeof_sym; ++ extsymcount = symcount - hdr->sh_info; ++ for (i = 0; i < extsymcount; i++) ++ { ++ bh = (struct bfd_link_hash_entry *) *(sym_hashes + i); ++ if (bh->u.def.section == sec) ++ nds32_elf_ifc_insert_barrier (bh->u.def.value, barrier); ++ } ++ } ++ ++ /* Scan relocations to get the local target. */ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sec->reloc_count; ++ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ if (!nds32_get_local_syms (abfd, sec, &isym)) ++ return FALSE; ++ ++ for (i = 0; i < symtab_hdr->sh_info; i++) ++ { ++ if ((isym + i)->st_value > 0 ++ && (isym + i)->st_shndx == sec_shndx ++ && (isym + i)->st_value <= sec->size ++ && ELF32_ST_TYPE ((isym + i)->st_info) == STT_FUNC) ++ { ++ nds32_elf_ifc_insert_barrier ((isym + i)->st_value, barrier); ++ } ++ } ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ if (ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ && ELF32_R_TYPE (irel->r_info) != R_NDS32_LABEL ++ && ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx) ++ { ++ /* FIXME: DIFFxx relcoations have to be do something more. */ ++ nds32_elf_ifc_insert_barrier (irel->r_addend, barrier); ++ } ++ } ++ return TRUE; ++} ++ ++/* Trace all section and build the instruction list. */ ++/* We collect all instruction here, and put each same insntruction in ++ the same hash entry. Each entry has to save all appearance section ++ and offset. */ ++ ++static bfd_boolean ++nds32_elf_ifc_trace_code (struct bfd_link_info *link_info, ++ bfd *abfd, asection *sec) ++{ ++ Elf_Internal_Rela *internal_relocs, *irelend, *irel; ++ bfd_byte *contents = NULL; ++ unsigned int off = 0, insn_size; ++ unsigned long insn; ++ struct elf_nds32_ifc_code_hash_entry *entry, *pre_entry; ++ struct elf_nds32_ifc_member *pre_child, *child; ++ struct elf_nds32_ifc_sec_block *block; ++ struct elf_nds32_ifc_sec_member *smember, *cur_smember;; ++ char code[20]; ++ struct elf_nds32_ifc_barrier *barrier = NULL, *ptr_barrier; ++ bfd_boolean ignore, end; ++ struct elf_link_hash_entry **sym_hashes; ++ unsigned long r_symndx; ++ Elf_Internal_Shdr *symtab_hdr; ++ struct elf_link_hash_entry *h; ++ Elf_Internal_Sym *isymbuf = NULL; ++ ++ pre_entry = NULL; ++ pre_child = NULL; ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sec->reloc_count; ++ ++ /* Check the object if enable ifc. */ ++ irel = find_relocs_at_address (internal_relocs, internal_relocs, irelend, ++ R_NDS32_RELAX_ENTRY); ++ ++ /* Check this section trigger ifc relaxation. */ ++ if (irel == NULL ++ || irel >= irelend ++ || ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ || (ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY ++ && !(irel->r_addend & R_NDS32_RELAX_ENTRY_IFC_FLAG))) ++ return TRUE; ++ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) ++ return FALSE; ++ ++ elf_section_data (sec)->relocs = internal_relocs; ++ sym_hashes = elf_sym_hashes (abfd); ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ nds32_get_local_syms (abfd, sec, &isymbuf); ++ /* Backup header size and restore it after relocation because ifc ++ optimization may modify this value. */ ++ elf_nds32_tdata (abfd)->hdr_size = symtab_hdr->sh_size; ++ ++ /* Build barrier list. If there is any label or target in somewhere, ++ this instruction can not be delete. It has to traverse global symbol ++ hash table and relocations to get all possible label. */ ++ nds32_elf_ifc_build_barrier (abfd, sec, &barrier); ++ ++ /* Start to traverse content. */ ++ irel = internal_relocs; ++ ptr_barrier = barrier; ++ ++ block = malloc (sizeof (struct elf_nds32_ifc_sec_block)); ++ block->sec = sec; ++ block->smember = NULL; ++ block->next = ifc_block_head; ++ ifc_block_head = block; ++ cur_smember = NULL; ++ ++ while (off < sec->size) ++ { ++ h = NULL; ++ ignore = FALSE; ++ end = FALSE; ++ ++ while (irel != NULL && irel < irelend && irel->r_offset < off) ++ irel++; ++ while (ptr_barrier && ptr_barrier->offset < off) ++ ptr_barrier = ptr_barrier->next; ++ ++ /* Get binary code. */ ++ if (*(contents + off) & 0x80) ++ { ++ /* 16-bit instuction. */ ++ insn = bfd_getb16 (contents + off); ++ snprintf (code, sizeof (code), "%04lx", insn); ++ insn_size = 2; ++ ++ /* Clean insntruction regiter for jr5 and jral5. */ ++ switch (insn & 0xff00) ++ { ++ /* Because there is no relocation for jr5 and jral5 in case ++ longjump and longcall, it has to ignore it for ifc. */ ++ /* jr5 ret5 jral5 add5.pc ex9.it. */ ++ case INSN_JR5: ++ ignore = TRUE; ++ break; ++ default: ++ break; ++ } ++ } ++ else ++ { ++ /* 32-bit instuction. */ ++ insn = bfd_getb32 (contents + off); ++ snprintf (code, sizeof (code), "%08lx", insn); ++ insn_size = 4; ++ switch (N32_OP6 (insn)) ++ { ++ case N32_OP6_JREG: ++ /* jr and jral. */ ++ ignore = TRUE; ++ break; ++ case N32_OP6_MISC: ++ if (N32_SUB5 (insn) == N32_MISC_MTSR ++ || N32_SUB5 (insn) == N32_MISC_MFSR) ++ ignore = TRUE; ++ break; ++ case N32_OP6_ALU2: ++ if (N32_SUB6 (insn) == N32_ALU2_MTUSR ++ || N32_SUB6 (insn) == N32_ALU2_MFUSR) ++ ignore = TRUE; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Check the IFC ignored region. */ ++ if (irel && irel < irelend ++ && nds32_elf_ifc_check_region (&irel, irelend, link_info)) ++ { ++ if (irel == NULL || irel >= irelend) ++ return TRUE; ++ off = irel->r_offset; ++ off += ((*(contents + off) & 0x80) != 0 ? 2 : 4); ++ pre_entry = NULL; ++ pre_child = NULL; ++ continue; ++ } ++ /* Ignore instruction with relocation. */ ++ /* It can add instruction with relocation to ifc in the future. ++ I think only the global target can do. We may try to compare ++ post and link ifc to know what kinds of relocation are most needed ++ being done first. */ ++ else if (ignore == TRUE) ++ { ++ /* Set a new basic block. */ ++ off += insn_size; ++ pre_entry = NULL; ++ pre_child = NULL; ++ continue; ++ } ++ else if (irel < irelend && irel->r_offset == off ++ && (ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA15S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA15S0_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA12S2_DP_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA12S2_SP_RELA) ++ || (ELF32_R_TYPE (irel->r_info) >= R_NDS32_SDA16S3_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_SDA19S0_RELA))) ++ { ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Ignore local symbol, so set a new basic block. */ ++ off += insn_size; ++ pre_entry = NULL; ++ pre_child = NULL; ++ continue; ++ } ++ else ++ { ++ /* Global jump target, keep going. */ ++ bfd_boolean warned ATTRIBUTE_UNUSED; ++ bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED; ++ bfd_vma relocation; ++ asection *sym_sec; ++ ++ RELOC_FOR_GLOBAL_SYMBOL (link_info, abfd, sec, irel, ++ r_symndx, symtab_hdr, sym_hashes, ++ h, sym_sec, relocation, ++ unresolved_reloc, warned); ++ relocation += irel->r_addend; ++ /* J and JAL has to shift one bit. Here, we use absolute addresss ++ to build hash entry. */ ++ snprintf (code, sizeof (code), "%08lx%08lx", relocation, insn); ++ } ++ ++ if ((ELF32_R_TYPE (irel->r_info) == R_NDS32_25_PCREL_RELA ++ && (insn == INSN_JAL || insn == INSN_J))) ++ end = TRUE; ++ } ++ else if (irel < irelend && irel->r_offset == off ++ && ELF32_R_TYPE (irel->r_info) >= R_NDS32_9_PCREL_RELA ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_17_PCREL_RELA) ++ { ++ r_symndx = ELF32_R_SYM (irel->r_info); ++ if (r_symndx < symtab_hdr->sh_info) ++ { ++ /* Local symbol. */ ++ bfd_vma relocation; ++ int shndx = isymbuf[r_symndx].st_shndx; ++ ++ bfd_vma st_value = (isymbuf + r_symndx)->st_value; ++ asection *isec = elf_elfsections (abfd)[shndx]->bfd_section; ++ relocation = isec->output_section->vma + isec->output_offset ++ + st_value + irel->r_addend; ++ snprintf (code, sizeof (code), "%08lx%08lx", relocation, ++ (insn_size == 4) ? insn : insn << 16); ++ } ++ else ++ { ++ /* Ignore global condition branch target. */ ++ off += insn_size; ++ pre_entry = NULL; ++ pre_child = NULL; ++ continue; ++ } ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_9_PCREL_RELA ++ && (insn == INSN_J8)) ++ end = TRUE; ++ } ++ else if (irel < irelend && irel->r_offset == off) ++ { ++ while (irel < irelend && irel->r_offset == off) ++ { ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ case R_NDS32_32_RELA: ++ /* Data. */ ++ insn_size = 4; ++ break; ++ case R_NDS32_16_RELA: ++ /* Data. */ ++ insn_size = 2; ++ break; ++ case R_NDS32_DATA: ++ /* Data. */ ++ /* The least code alignment is 2. If the data is only one byte, ++ we have to shift one more byte. */ ++ if (irel->r_addend == 1) ++ insn_size = 2; ++ else ++ insn_size = irel->r_addend; ++ break; ++ default: ++ break; ++ } ++ irel++; ++ } ++ /* Set a new basic block. */ ++ off += insn_size; ++ pre_entry = NULL; ++ pre_child = NULL; ++ continue; ++ } ++ ++ if (ptr_barrier && ptr_barrier->offset == off) ++ { ++ /* If there is symbol at the instruction, this one only can be the ++ begining of basic block. We have to promise there is no jump ++ target or label in the common block, because if the block be ++ converted ifcall the label will disapear. */ ++ pre_entry = NULL; ++ pre_child = NULL; ++ } ++ ++ off += insn_size; ++ /* Hash and copy "code". */ ++ entry = (struct elf_nds32_ifc_code_hash_entry *) ++ bfd_hash_lookup (&ifc_code_table, code, TRUE, TRUE); ++ if (entry == NULL) ++ { ++ (*_bfd_error_handler) ++ (_("%P%F: failed creating ifc %s hash table: %E\n"), code); ++ return FALSE; ++ } ++ ++ entry->size = insn_size; ++ ++ /* It is hard to do ifc, when the sequence instructions are the same. */ ++ if (entry == pre_entry ++ || (h && entry->h && entry->h != h)) ++ { ++ pre_entry = NULL; ++ pre_child = NULL; ++ continue; ++ } ++ ++ entry->times++; ++ entry->h = h; ++ entry->end = end; ++ ++ /* Build list between current and previous instruction. ++ First round: generate entry A and member B. */ ++ /* List: code_hash_entry->unit->member. ++ Example: ABCAB ++ 12345 ++ {entry} [unit] (member) ++ {A} -> [B] -> (1) -> (4) */ ++ ++ child = bfd_malloc (sizeof (struct elf_nds32_ifc_member)); ++ child->offset = off; ++ child->sec = sec; ++ /* For B member, its pre_entry is null. ++ For C member, its pre_entry is A. */ ++ child->pre_entry = pre_entry; ++ child->unit_p = NULL; ++ child->next = NULL; ++ child->next_member = NULL; ++ child->pre_member = pre_child; ++ child->dead = FALSE; ++ child->bh = NULL; ++ ++ /* Build section instruction list to adjust offset ++ when increasing or decreasing later. */ ++ smember = malloc (sizeof (struct elf_nds32_ifc_sec_member)) ; ++ smember->member = child; ++ smember->next = NULL; ++ if (!cur_smember) ++ { ++ block->smember = smember; ++ cur_smember = smember; ++ } ++ else ++ { ++ cur_smember->next = smember; ++ cur_smember = smember; ++ } ++ ++ nds32_elf_ifc_new_ifc_unit (entry, pre_entry, child, pre_child); ++ if (end) ++ { ++ pre_child = NULL; ++ pre_entry = NULL; ++ } ++ else ++ { ++ pre_child = child; ++ pre_entry = entry; ++ } ++ } ++ return TRUE; ++} ++ ++/* Insert the entry in sort by its times. */ ++ ++static void ++nds32_elf_ifc_order_insn_times (struct elf_nds32_ifc_code_hash_entry *entry) ++{ ++ struct elf_nds32_ifc_code_hash_entry *ptr = ifc_insn_head; ++ ++ /* First entry. */ ++ if (!ifc_insn_head) ++ ifc_insn_head = entry; ++ else if (!entry->max_unit) ++ { ++ /* There is no max_unit in current list. */ ++ while (ptr->next) ++ ptr = ptr->next; ++ entry->next = ptr->next; ++ ptr->next = entry; ++ } ++ else ++ { ++ entry->max_times = entry->max_unit->times; ++ if (!ptr->max_unit ++ || ptr->max_unit->times < entry->max_unit->times) ++ { ++ /* The new one is the bigest one. */ ++ entry->next = ptr; ++ ifc_insn_head = entry; ++ return; ++ } ++ while (ptr->next && ptr->next->unit ++ && ptr->next->unit->times > entry->unit->times) ++ ptr = ptr->next; ++ entry->next = ptr->next; ++ ptr->next = entry; ++ } ++} ++ ++/* IFC hash table traverse function. */ ++ ++static void ++nds32_elf_ifc_code_hash_traverse (void (*func) (struct elf_nds32_ifc_code_hash_entry*)) ++{ ++ unsigned int i; ++ ++ ifc_code_table.frozen = 1; ++ for (i = 0; i < ifc_code_table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ ++ for (p = ifc_code_table.table[i]; p != NULL; p = p->next) ++ func ((struct elf_nds32_ifc_code_hash_entry *) p); ++ } ++ ifc_code_table.frozen = 0; ++} ++ ++/* Push common subexpression. */ ++ ++static void ++nds32_elf_ifc_push_stack (struct elf_nds32_ifc_insn_stack **stack, ++ struct elf_nds32_ifc_unit *unit) ++{ ++ struct elf_nds32_ifc_member *member; ++ struct elf_nds32_ifc_insn_stack *ptr; ++ struct elf_nds32_ifc_insn_member *imember, *ptr_imember; ++ ++ /* Get the first member in the same unit. */ ++ member = unit->member->unit_p->member; ++ ++ if (!*stack) ++ { ++ /* The first instruction in common subexpression. */ ++ while (member) ++ { ++ /* The newest one stack is as the head. */ ++ if (!member->dead) ++ { ++ ptr = bfd_malloc (sizeof (struct elf_nds32_ifc_insn_stack)); ++ imember = bfd_malloc (sizeof (struct elf_nds32_ifc_insn_member)); ++ imember->member = member; ++ imember->next = NULL; ++ ptr->imember = imember; ++ ptr->next = *stack; ++ ptr->live = 1; ++ ptr->extend = 0; ++ *stack = ptr; ++ } ++ member = member->next; ++ } ++ } ++ else ++ { ++ /* Initial stack state, because we have to trigger them after ++ matching new member. */ ++ ptr = *stack; ++ while (ptr) ++ { ++ ptr->choose = ptr->live; ++ ptr->live = 0; ++ ptr = ptr->next; ++ } ++ ++ while (member) ++ { ++ /* Find the same common subexpression stack and push. */ ++ ptr = *stack; ++ while (!member->dead && ptr) ++ { ++ if (ptr->live == 0 && ptr->choose == 1) ++ { ++ ptr_imember = ptr->imember; ++ /* Go to the final imember. */ ++ while (ptr_imember && ptr_imember->next) ++ ptr_imember = ptr_imember->next; ++ ++ if (ptr_imember->member->next_member == member) ++ { ++ /* When the final member next one match the new member, ++ insert it into list. */ ++ imember = bfd_malloc (sizeof (struct elf_nds32_ifc_insn_member)); ++ imember->member = member; ++ imember->next = NULL; ++ ptr->live = 1; ++ ptr_imember->next = imember; ++ break; ++ } ++ } ++ ptr = ptr->next; ++ } ++ member = member->next; ++ } ++ } ++} ++ ++/* Pop common subexpression. */ ++ ++static void ++nds32_elf_ifc_pop_stack (struct elf_nds32_ifc_insn_stack **stack, ++ struct elf_nds32_ifc_unit *unit) ++{ ++ if (!*stack) ++ return; ++ ++ struct elf_nds32_ifc_insn_stack *ptr; ++ struct elf_nds32_ifc_insn_member *imember, *temp_member; ++ struct elf_nds32_ifc_member *member; ++ ++ ptr = *stack; ++ while (ptr) ++ { ++ ptr->live = 0; ++ ptr = ptr->next; ++ } ++ ++ ptr = *stack; ++ while (ptr) ++ { ++ /* Get the first member in the same unit. */ ++ member = unit->member->unit_p->member; ++ while (member) ++ { ++ imember = ptr->imember; ++ while (imember) ++ { ++ if (imember->member == member) ++ { ++ ptr->live = 1; ++ temp_member = imember->next; ++ imember->next = NULL; ++ imember = temp_member; ++ break; ++ } ++ imember = imember->next; ++ } ++ while (imember) ++ { ++ temp_member = imember; ++ imember = imember->next; ++ free (temp_member); ++ } ++ if (ptr->live) ++ break; ++ member = member->next; ++ } ++ ptr = ptr->next; ++ } ++} ++ ++/* Find the common down. */ ++ ++static int ++nds32_elf_ifc_find_cse_recur (struct elf_nds32_ifc_unit *ptr, ++ struct elf_nds32_ifc_insn_stack **stack, ++ int total) ++{ ++ struct elf_nds32_ifc_member *member = ptr->member; ++ struct elf_nds32_ifc_unit *unit_head, *unit_current, *unit_pre = NULL; ++ struct elf_nds32_ifc_insn_stack *stack_ptr; ++ struct elf_nds32_ifc_insn_member *imember; ++ unit_head = NULL; ++ int gain, gc_size; ++ int abandon; ++ ++ /* Push current member into stack. */ ++ nds32_elf_ifc_push_stack (stack, ptr); ++ ++ if (!*stack) ++ return 0; ++ ++ /* The instruction will close ifc state. */ ++ if (ptr->hash->end) ++ return ptr->times * ptr->hash->size; ++ ++ /* Find the unit its max next instruction. */ ++ stack_ptr = *stack; ++ while (stack_ptr) ++ { ++ if (stack_ptr->live) ++ { ++ /* Get the final instruction. */ ++ imember = stack_ptr->imember; ++ while (imember->next) ++ imember = imember->next; ++ member = imember->member; ++ if (!member->next_member->dead) ++ { ++ unit_current = unit_head; ++ while (unit_current) ++ { ++ /* Check if the hash entry exist. */ ++ unit_pre = unit_current; ++ if (member->next_member->unit_p ++ && member->next_member->unit_p->hash ++ == unit_current->hash ++ && (!unit_current->hash->h ++ || unit_current->hash->h ++ == member->next_member->unit_p->hash->h)) ++ { ++ unit_current->times++; ++ break; ++ } ++ unit_current = unit_current->next; ++ } ++ /* New a unit group. */ ++ if (member->next_member->unit_p ++ && !member->next_member->unit_p->hash->round ++ && !unit_current) ++ { ++ unit_current = bfd_malloc (sizeof (struct elf_nds32_ifc_unit)); ++ unit_current->hash = member->next_member->unit_p->hash; ++ unit_current->times = 1; ++ unit_current->next = NULL; ++ unit_current->member = member->next_member; ++ unit_current->entry_p = member->next_member->unit_p->entry_p; ++ if (!unit_head) ++ unit_head = unit_current; ++ else ++ unit_pre->next = unit_current; ++ } ++ } ++ } ++ stack_ptr = stack_ptr->next; ++ } ++ ++ /* Find the max next instruction unit. */ ++ unit_current = unit_head; ++ unit_pre = unit_head; ++ while (unit_current) ++ { ++ if (unit_current->times > unit_pre->times) ++ unit_pre = unit_current; ++ unit_current = unit_current->next; ++ } ++ ++ if (!unit_pre || unit_pre->times < 2) ++ { ++ unit_current = unit_head; ++ while (unit_current) ++ { ++ unit_current = unit_current->next; ++ free (unit_head); ++ unit_head = unit_current; ++ } ++ return ptr->times * ptr->hash->size; ++ } ++ ++ /* Total code size and abandoned unit size. */ ++ total = total + ptr->hash->size; ++ abandon = unit_pre->times; ++ gc_size = total * (ptr->times - abandon); ++ ++ /* It have to estimate the longer common subexpression is profit. ++ Example: ABC ABC ABD. ++ We have to calculate ABC or AB is profit. */ ++ ++ ptr->hash->round = 1; ++ gain = nds32_elf_ifc_find_cse_recur (unit_pre, stack, total); ++ ptr->hash->round = 0; ++ ++ /* Free memory. */ ++ unit_current = unit_head; ++ while (unit_current) ++ { ++ unit_current = unit_current->next; ++ free (unit_head); ++ unit_head = unit_current; ++ } ++ ++ if (gain > gc_size ++ || gain == 0) ++ { ++ /* Return total gain if adapt this edge. */ ++ return (ptr->times - abandon) * ptr->hash->size + gain; ++ } ++ else ++ { ++ /* It is not more benifit to link deeper, and pop it. */ ++ nds32_elf_ifc_pop_stack (stack, ptr); ++ return 0; ++ } ++} ++ ++/* Reallocate section contents. */ ++ ++static void ++nds32_elf_ifc_reallocate_contents (asection *sec, int modify, ++ bfd_byte **contents) ++{ ++ /* This function is highly dangerous, but I have to implement it. */ ++ sec->size += modify; ++ bfd_byte *p = bfd_malloc (sec->size * sizeof (bfd_byte)); ++ memset (p, 0, sec->size * sizeof (bfd_byte)); ++ memcpy (p, *contents, sec->size - modify); ++ free (*contents); ++ *contents = p; ++ elf_section_data (sec)->this_hdr.contents = p; ++} ++ ++/* Insert a symbol in symbol table. */ ++ ++static int ++nds32_elf_ifc_insert_sym_hash (bfd *abfd, ++ struct bfd_link_hash_entry *bh) ++{ ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd); ++ struct elf_link_hash_entry **sym_hash; ++ bfd_size_type amt; ++ Elf_Internal_Shdr *hdr; ++ bfd_size_type symcount; ++ bfd_size_type extsymcount; ++ bfd_size_type i; ++ ++ /* No symbol hash exsitence. */ ++ if (!sym_hashes) ++ return -1; ++ ++ if (!(abfd->flags & DYNAMIC) || elf_dynsymtab (abfd) == 0) ++ hdr = &elf_tdata (abfd)->symtab_hdr; ++ else ++ return -1; ++ ++ /* Check for the symbol existance. */ ++ symcount = hdr->sh_size / bed->s->sizeof_sym; ++ extsymcount = symcount - hdr->sh_info; ++ for (i = 0; i < extsymcount; i++) ++ { ++ if ((struct bfd_link_hash_entry *) *(sym_hashes + i) == bh) ++ return i + hdr->sh_info; ++ } ++ ++ /* Add one more entry. */ ++ hdr->sh_size += bed->s->sizeof_sym; ++ ++ symcount = hdr->sh_size / bed->s->sizeof_sym; ++ if (elf_bad_symtab (abfd)) ++ extsymcount = symcount; ++ else ++ extsymcount = symcount - hdr->sh_info; ++ ++ sym_hash = NULL; ++ if (extsymcount != 0) ++ { ++ /* We store a pointer to the hash table entry for each external ++ symbol. */ ++ amt = extsymcount * sizeof (struct elf_link_hash_entry *); ++ sym_hash = bfd_malloc (amt); ++ memset (sym_hash, 0, amt); ++ if (sym_hash == NULL) ++ return -1; ++ memcpy (sym_hash, sym_hashes, ++ amt - sizeof (struct elf_link_hash_entry *)); ++ memcpy (sym_hash + extsymcount -1, &bh, ++ sizeof (struct elf_link_hash_entry *)); ++ elf_sym_hashes (abfd) = sym_hash; ++ /* TODO: Since sym_hashes is allocated by bfd_zalloc, it can not ++ be free directly. We have to record the memory allocated by ++ ourselves and free it. */ ++ return (symcount - 1); ++ } ++ else ++ return -1; ++} ++ ++/* Insert relocation. */ ++ ++static void ++nds32_elf_ifc_insert_relocation (struct bfd_link_info *info, ++ bfd *abfd, asection *sec, ++ struct bfd_link_hash_entry *bh, ++ bfd_vma offset, ++ bfd_boolean align, ++ bfd_vma clean_off) ++{ ++ /* Insert a new relocation into section rela, and this is very force ++ implementation. It may cause unknown problem. */ ++ ++ Elf_Internal_Rela *relocs, *internal_relocs, *irelend; ++ long unsigned int size, extsymcount; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ unsigned int count = 0; ++ int num = 2; ++ ++ /* If the reduction size is not 4 bytes aligment, it has to insert ++ one more relocation. */ ++ if (!align) ++ num = 3; ++ ++ /* Insert the jump target in symbol hash. */ ++ extsymcount = nds32_elf_ifc_insert_sym_hash (abfd, bh); ++ if (extsymcount <= 0) ++ return; ++ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, ++ NULL, NULL, FALSE); ++ irelend = internal_relocs + sec->reloc_count; ++ ++ /* The common block including relocation, it has to been cleaned. */ ++ relocs = internal_relocs; ++ while (relocs && relocs < irelend) ++ { ++ if (relocs->r_offset >= offset && relocs->r_offset <= clean_off) ++ relocs->r_info = ELF32_R_INFO (ELF32_R_SYM (relocs->r_info), ++ R_NDS32_NONE); ++ relocs++; ++ } ++ ++ /* We have to insert two relocations; one for ifc and ++ another is for alignment.*/ ++ sec->reloc_count += num; ++ size = sec->reloc_count; ++ size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); ++ relocs = (Elf_Internal_Rela *) bfd_malloc (size); ++ memset (relocs, 0, size); ++ elf_section_data (sec)->relocs = relocs; ++ while ((internal_relocs + count) < irelend ++ && (internal_relocs + count)->r_offset <= offset) ++ count++; ++ ++ /* Copy the front part where the offset is smaller. */ ++ memcpy (relocs, internal_relocs, ++ (bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela) * count)); ++ ++ /* Insert new relocations. */ ++ irelend = relocs + count; ++ /* Set relocation. */ ++ irelend->r_offset = offset; ++ irelend->r_info = ++ ELF32_R_INFO (extsymcount, R_NDS32_17IFC_PCREL_RELA); ++ irelend->r_addend = 0; ++ ++ irelend++; ++ /* Set relocation. */ ++ irelend->r_offset = offset; ++ irelend->r_info = ELF32_R_INFO (0, R_NDS32_INSN16); ++ irelend->r_addend = 0; ++ ++ /* One more relocation for alignment. */ ++ if (!align) ++ { ++ irelend++; ++ irelend->r_offset = offset + 4; ++ irelend->r_info = ELF32_R_INFO (0, R_NDS32_INSN16); ++ irelend->r_addend = 1; ++ /* Put offset. */ ++ } ++ ++ /* Copy the rest part. */ ++ irelend++; ++ memcpy (irelend, internal_relocs + count, ++ size - (bed->s->int_rels_per_ext_rel * ++ sizeof (Elf_Internal_Rela) * (count + num))); ++ if (!info->keep_memory) ++ free (internal_relocs); ++} ++ ++/* Adjust insntruction map offset. Variable "adjust" is recorded the size ++ after relaxing. */ ++ ++static void ++nds32_elf_ifc_adjust_block (asection *sec, bfd_vma offset, int size, int adjust) ++{ ++ struct elf_nds32_ifc_sec_block *block; ++ struct elf_nds32_ifc_sec_member *smember; ++ ++ block = ifc_block_head; ++ while (block->sec != sec) ++ block = block->next; ++ ++ smember = block->smember; ++ while (smember->member->offset < offset) ++ smember = smember->next; ++ ++ while (size < 0 ++ && smember ++ && smember->member->offset < offset - size + adjust) ++ { ++ /* The offset result may smaller than zero, so we set its value as the ++ ifcall. */ ++ smember->member->offset = offset; ++ smember = smember->next; ++ } ++ while (smember) ++ { ++ smember->member->offset += size; ++ smember = smember->next; ++ } ++} ++ ++/* Adjust relocation and symbol. */ ++ ++static void ++nds32_elf_ifc_enlarge (bfd *abfd, asection *sec, bfd_vma off, int size) ++{ ++ unsigned int sec_shndx; /* The section the be relaxed. */ ++ Elf_Internal_Shdr *symtab_hdr; /* Symbol table header of this bfd. */ ++ Elf_Internal_Sym *isym; /* Symbol table of this bfd. */ ++ Elf_Internal_Sym *isymend; /* Symbol entry iterator. */ ++ Elf_Internal_Rela *internal_relocs; ++ Elf_Internal_Rela *irel; ++ Elf_Internal_Rela *irelend; ++ unsigned int symcount; ++ struct elf_link_hash_entry **sym_hashes; ++ struct elf_link_hash_entry **end_hashes; ++ asection *sect; ++ bfd_byte *contents; ++ ++ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ isym = (Elf_Internal_Sym *) symtab_hdr->contents; ++ if (isym == NULL) ++ { ++ isym = bfd_elf_get_elf_syms (abfd, symtab_hdr, ++ symtab_hdr->sh_info, 0, NULL, NULL, NULL); ++ symtab_hdr->contents = (bfd_byte *) isym; ++ } ++ ++ if (isym == NULL || symtab_hdr->sh_info == 0) ++ return; ++ ++ for (sect = abfd->sections; sect != NULL; sect = sect->next) ++ { ++ /* Adjust all the relocs. */ ++ ++ if ((sect->flags & SEC_RELOC) == 0) ++ continue; ++ ++ /* Relocations MUST be kept in memory, because relaxation adjust them. */ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sect, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sect->reloc_count; ++ ++ if (!nds32_get_section_contents (abfd, sect, &contents, TRUE)) ++ continue; ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ if (ELF32_R_TYPE (irel->r_info) >= R_NDS32_DIFF8 ++ && ELF32_R_TYPE (irel->r_info) <= R_NDS32_DIFF32 ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx) ++ { ++ unsigned long val, mask; ++ ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ case R_NDS32_DIFF8: ++ val = bfd_get_8 (abfd, contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF16: ++ val = bfd_get_16 (abfd, contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF32: ++ val = bfd_get_32 (abfd, contents + irel->r_offset); ++ mask = 0 - (val >> 31); ++ if (mask) ++ val = (val | (mask - 0xffffffff)); ++ break; ++ default: ++ BFD_ASSERT (0); ++ } ++ ++ if ((off > irel->r_addend && off <= irel->r_addend + val) ++ || (off <= irel->r_addend && off > irel->r_addend + val)) ++ { ++ /* The offset is incresed. */ ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ /* It may overflow. */ ++ case R_NDS32_DIFF8: ++ bfd_put_8 (abfd, val + size, contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF16: ++ bfd_put_16 (abfd, val + size, contents + irel->r_offset); ++ break; ++ case R_NDS32_DIFF32: ++ bfd_put_32 (abfd, val + size, contents + irel->r_offset); ++ break; ++ } ++ } ++ } ++ else if (ELF32_R_TYPE (irel->r_info) == R_NDS32_DIFF_ULEB128 ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx) ++ { ++ bfd_vma val = 0; ++ unsigned int len = 0; ++ bfd_byte *endp, *p; ++ ++ val = read_unsigned_leb128 (abfd, contents + irel->r_offset, &len); ++ ++ if (off >= irel->r_addend ++ && off < irel->r_addend + val) ++ { ++ /* The offset is incresed. */ ++ p = contents + irel->r_offset; ++ endp = p + len -1; ++ memset (p, 0x80, len); ++ *(endp) = 0; ++ /* It may overflow. */ ++ p = write_uleb128 (p, val + size) - 1; ++ if (p < endp) ++ *p |= 0x80; ++ } ++ } ++ ++ if (sec == sect) ++ { ++ if (irel->r_offset >= off) ++ irel->r_offset += size; ++ } ++ ++ if (ELF32_R_TYPE (irel->r_info) == R_NDS32_NONE ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_LABEL ++ || ELF32_R_TYPE (irel->r_info) == R_NDS32_RELAX_ENTRY) ++ continue; ++ ++ if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx ++ && ELF_ST_TYPE (isym[ELF32_R_SYM (irel->r_info)].st_info) == STT_SECTION) ++ { ++ if (irel->r_addend <= sec->size ++ && irel->r_addend >= off) ++ irel->r_addend += size; ++ } ++ } ++ } ++ ++ /* Adjust the local symbols defined in this section. */ ++ for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++) ++ { ++ if (isym->st_shndx == sec_shndx) ++ { ++ if (isym->st_value <= sec->size) ++ { ++ if (isym->st_value >= off) ++ isym->st_value += size; ++ /* Adjust function size. */ ++ else if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC && isym->st_size > 0 ++ && (isym->st_value + isym->st_size) >= off) ++ isym->st_size += size; ++ } ++ } ++ } ++ /* Now adjust the global symbols defined in this section. */ ++ symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) ++ - symtab_hdr->sh_info); ++ sym_hashes = elf_sym_hashes (abfd); ++ end_hashes = sym_hashes + symcount; ++ for (; sym_hashes < end_hashes; sym_hashes++) ++ { ++ struct elf_link_hash_entry *sym_hash = *sym_hashes; ++ ++ if ((sym_hash->root.type == bfd_link_hash_defined ++ || sym_hash->root.type == bfd_link_hash_defweak) ++ && sym_hash->root.u.def.section == sec) ++ { ++ if (sym_hash->root.u.def.value <= sec->size) ++ { ++ if (sym_hash->root.u.def.value >= off) ++ sym_hash->root.u.def.value += size; ++ ++ /* Adjust function size. */ ++ else if (sym_hash->type == STT_FUNC ++ && (sym_hash->root.u.def.value + sym_hash->size) >= off) ++ sym_hash->size += size; ++ ++ } ++ } ++ } ++ nds32_elf_ifc_adjust_block (sec, off, size, 0); ++} ++ ++/* Check distance between branch become farer if it ++ cause relocation overfolw. */ ++ ++static bfd_boolean ++nds32_elf_ifc_check_overflow (struct elf_nds32_ifc_insn_stack *ptr) ++{ ++ struct elf_nds32_ifc_insn_member *imember; ++ struct elf_nds32_ifc_member *member; ++ asection *sec; ++ bfd_vma offset; ++ Elf_Internal_Rela *irel, *internal_relocs, *irelend; ++ unsigned int sec_shndx; ++ bfd *abfd; ++ Elf_Internal_Sym *isym = NULL; /* Symbol table of this bfd. */ ++ Elf_Internal_Shdr *symtab_hdr; ++ ++ /* Get the common block final instruction address. */ ++ imember = ptr->imember; ++ while (imember->next) ++ imember = imember->next; ++ member = imember->member; ++ /* Add the final instruction and its instruction size to get ++ the address inserted the ifret16. */ ++ offset = member->offset + member->unit_p->hash->size; ++ ++ sec = member->sec; ++ abfd = sec->owner; ++ sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); ++ ++ symtab_hdr = &elf_tdata (abfd)->symtab_hdr; ++ ++ if (!nds32_get_local_syms (abfd, sec, &isym)) ++ return FALSE; ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, ++ TRUE /* keep_memory */); ++ irelend = internal_relocs + sec->reloc_count; ++ ++ for (irel = internal_relocs; irel < irelend; irel++) ++ { ++ if (ELF32_R_TYPE (irel->r_info) != R_NDS32_RELAX_ENTRY ++ && ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info ++ && isym[ELF32_R_SYM (irel->r_info)].st_shndx == sec_shndx) ++ { ++ /* Get the distance between caller and callee. */ ++ unsigned int distance; ++ if (irel->r_offset < offset && irel->r_addend > offset) ++ distance = irel->r_addend - irel->r_offset; ++ else if (irel->r_offset > offset && irel->r_addend < offset) ++ distance = irel->r_offset - irel->r_addend; ++ else ++ continue; ++ ++ /* In current, just check pc relative jump here. It may has to ++ check more relocation in the feature. */ ++ switch (ELF32_R_TYPE (irel->r_info)) ++ { ++ /* It has to subtruct 5 since it has to ++ consider the 4 bytes for ifret. */ ++ case R_NDS32_9_PCREL_RELA: ++ if (distance > ((1 << 8) - 5)) ++ return FALSE; ++ break; ++ case R_NDS32_15_PCREL_RELA: ++ if (distance > ((1 << 14) - 5)) ++ return FALSE; ++ break; ++ default: ++ break; ++ } ++ } ++ } ++ return TRUE; ++} ++ ++ ++/* Insert a INSN16 relocation for relaxing ifret. */ ++ ++static void ++nds32_elf_ifc_insert_insn16_reloc (struct bfd_link_info *info, ++ bfd *abfd, asection *sec, ++ unsigned long int offset) ++{ ++ /* Insert a new relocation into section rela, and this is very force ++ implementation. It may cause unknown problem. */ ++ ++ Elf_Internal_Rela *relocs, *internal_relocs, *irelend; ++ long unsigned int size; ++ const struct elf_backend_data *bed = get_elf_backend_data (abfd); ++ unsigned int count = 0; ++ ++ internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, ++ NULL, NULL, FALSE); ++ irelend = internal_relocs + sec->reloc_count; ++ ++ /* We have to insert two relocations; one for ifc and ++ another is for alignment.*/ ++ sec->reloc_count += 1; ++ size = sec->reloc_count; ++ size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); ++ relocs = (Elf_Internal_Rela *) bfd_malloc (size); ++ memset (relocs, 0, size); ++ elf_section_data (sec)->relocs = relocs; ++ while ((internal_relocs + count) < irelend ++ && (internal_relocs + count)->r_offset <= offset) ++ count++; ++ ++ /* Copy the front part where the offset is smaller. */ ++ memcpy (relocs, internal_relocs, ++ (bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela) * count)); ++ ++ /* Insert new relocations. */ ++ irelend = relocs + count; ++ ++ /* Set relocation. */ ++ irelend->r_offset = offset; ++ irelend->r_info = ELF32_R_INFO (0, R_NDS32_INSN16); ++ irelend->r_addend = 0; ++ ++ irelend++; ++ /* Copy the rest part. */ ++ memcpy (irelend, internal_relocs + count, ++ size - (bed->s->int_rels_per_ext_rel * ++ sizeof (Elf_Internal_Rela) * (count + 1))); ++ if (!info->keep_memory) ++ free (internal_relocs); ++} ++ ++/* Push new element into the head of stack. */ ++ ++static void ++nds32_elf_ifc_extend_stack (struct elf_nds32_ifc_insn_stack *stack, ++ struct elf_nds32_ifc_unit *unit) ++{ ++ struct elf_nds32_ifc_insn_stack *stackP = stack; ++ struct elf_nds32_ifc_member *pre_member; ++ struct elf_nds32_ifc_insn_member *imember; ++ struct elf_nds32_ifc_code_hash_entry *hash; ++ ++ while (stackP) ++ { ++ stackP->choose = stackP->extend; ++ stackP->extend = 0; ++ stackP= stackP->next; ++ } ++ ++ hash = unit->entry_p; ++ stackP = stack; ++ while (stackP) ++ { ++ if (stackP->choose && stackP->extend == 0) ++ { ++ pre_member = stackP->imember->member->pre_member; ++ if (pre_member && !pre_member->dead ++ && pre_member->unit_p->entry_p == hash) ++ { ++ stackP->extend = 1; ++ imember = malloc (sizeof (struct elf_nds32_ifc_insn_member)); ++ imember->member = pre_member; ++ imember->next = stackP->imember; ++ stackP->imember = imember; ++ } ++ } ++ stackP = stackP->next; ++ } ++} ++ ++/* Search stack extend up. */ ++ ++static bfd_boolean ++nds32_elf_ifc_extend_up (struct elf_nds32_ifc_insn_stack *stack) ++{ ++ struct elf_nds32_ifc_insn_stack *stackP = stack; ++ struct elf_nds32_ifc_member *memberP; ++ struct elf_nds32_ifc_insn_member *imember; ++ struct elf_nds32_ifc_unit *unitP, *unit_head = NULL, *unit_tail = NULL; ++ ++ while (stackP) ++ { ++ if (stackP->extend ++ && nds32_elf_ifc_check_overflow (stackP)) ++ { ++ /* Get previos member. */ ++ unitP = unit_head; ++ memberP = stackP->imember->member->pre_member; ++ if (memberP && !memberP->dead) ++ { ++ while (unitP) ++ { ++ unit_tail = unitP; ++ if (memberP && memberP->unit_p->entry_p == unitP->entry_p ++ && (!unitP->entry_p->h ++ || unitP->entry_p->h == memberP->unit_p->entry_p->h)) ++ { ++ unitP->times++; ++ break; ++ } ++ unitP = unitP->next; ++ } ++ ++ /* Can't find matched unit so new one. */ ++ if (!unitP) ++ { ++ /* Check this instruction is not in stack. I can't find a ++ better way currently. */ ++ imember = stackP->imember; ++ while (imember) ++ { ++ if (imember->member->unit_p->hash ++ == memberP->unit_p->entry_p) ++ break; ++ imember = imember->next; ++ } ++ if (!imember) ++ { ++ unitP = malloc (sizeof (struct elf_nds32_ifc_unit)); ++ unitP->times = 1; ++ unitP->member = memberP; ++ unitP->entry_p = memberP->unit_p->entry_p; ++ unitP->hash = memberP->unit_p->hash; ++ unitP->next = NULL; ++ if (!unit_head) ++ unit_head = unitP; ++ else ++ unit_tail->next = unitP; ++ } ++ } ++ } ++ } ++ stackP = stackP->next; ++ } ++ ++ /* Find a max one unit. */ ++ unitP = unit_head; ++ unit_tail = unit_head; ++ while (unitP) ++ { ++ if (unitP->times > unit_tail->times) ++ unit_tail = unitP; ++ unitP = unitP->next; ++ } ++ if (!unit_tail || unit_tail->times < 2) ++ return FALSE; ++ else ++ { ++ nds32_elf_ifc_extend_stack (stack, unit_tail); ++ unit_tail->hash->round = 1; ++ nds32_elf_ifc_extend_up (stack); ++ unit_tail->hash->round = 0; ++ return TRUE; ++ } ++} ++ ++/* Check this stack is worth to be used. */ ++ ++static bfd_boolean ++nds32_elf_ifc_check (struct elf_nds32_ifc_insn_stack *stack, ++ struct elf_nds32_ifc_insn_stack **base, ++ bfd_boolean extend) ++{ ++ struct elf_nds32_ifc_insn_stack *ptr; ++ struct elf_nds32_ifc_insn_member *imember; ++ bfd_vma insn_sz; ++ ++ ptr = stack; ++ while (ptr) ++ { ++ if ((extend && ptr->extend) ++ || (!extend && ptr->live ++ && nds32_elf_ifc_check_overflow (ptr))) ++ break; ++ ptr = ptr->next; ++ } ++ *base = ptr; ++ ++ if (!*base) ++ return FALSE; ++ ++ /* Conform the code size can be reduced. */ ++ ptr = stack; ++ while (ptr) ++ { ++ if (ptr->live && ptr != *base) ++ break; ++ ptr = ptr->next; ++ } ++ if (!ptr) ++ return FALSE; ++ ++ /* Get the end offset of common. */ ++ imember = (*base)->imember; ++ insn_sz = imember->member->unit_p->entry_p->size; ++ insn_sz += imember->member->unit_p->hash->size; ++ while (imember->next) ++ { ++ imember = imember->next; ++ insn_sz += imember->member->unit_p->hash->size; ++ } ++ /* The ifc does not trigger, clear all stack. */ ++ if (insn_sz < 8) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++/* Insert a new ifc target symbol. */ ++ ++#define IFC_TARGET_NAME 10 ++static void ++nds32_elf_ifc_insert_target (struct elf_nds32_ifc_insn_stack *base, ++ bfd_vma off, ++ struct bfd_link_info *info, ++ struct bfd_link_hash_entry **bh) ++{ ++ static char name[45] = "$nds32ifc_a"; /* Is this enough? */ ++ int temp_num; ++ static int hash_num = IFC_TARGET_NAME; ++ asection *sec = base->imember->member->sec; ++ bfd *abfd = sec->owner; ++ ++ *bh = bfd_link_hash_lookup (info->hash, name, ++ FALSE, FALSE, TRUE); ++ /* Insert a global symbol for ifc target. */ ++ _bfd_generic_link_add_one_symbol ++ (info, info->output_bfd, name, BSF_GLOBAL, ++ sec, off, (const char *) NULL, TRUE, /* copy */ ++ get_elf_backend_data (info->output_bfd)->collect, ++ bh); ++ ++ ++ /* Adjust ifc target name for next time. */ ++ temp_num = hash_num; ++ while (name[temp_num] >= 'z' && temp_num >= IFC_TARGET_NAME) ++ { ++ temp_num--; ++ } ++ ++ if (temp_num < IFC_TARGET_NAME) ++ { ++ /* Add one more bit and reset all bits. */ ++ hash_num++; ++ temp_num = hash_num; ++ while (temp_num >= IFC_TARGET_NAME) ++ { ++ name[temp_num] = 'a'; ++ temp_num--; ++ } ++ name[hash_num + 1] = '\0'; ++ } ++ else if (temp_num == hash_num) ++ { ++ /* Add latest one bit. */ ++ name[temp_num]++; ++ } ++ else ++ { ++ /* Add carry bit and reset low significant bits. */ ++ name[temp_num]++; ++ while (temp_num < hash_num) ++ { ++ temp_num++; ++ name[temp_num] = 'a'; ++ } ++ } ++ /* Insert the global symbol into branch target bfd to adjust ++ when relaxing. */ ++ if (nds32_elf_ifc_insert_sym_hash (abfd, *bh) < 0) ++ return; ++} ++ ++/* Replace common code with ifc. In this functionm, it has to check ++ whether relocation is overflow after insert ifret16. If it is fine, ++ insert ifret16 into one common block, and replace other common with ++ ifcall and insert relocation for it. */ ++ ++static void ++nds32_elf_ifc_replace_common (struct elf_nds32_ifc_insn_stack *stack, ++ struct bfd_link_info *info) ++{ ++ struct elf_nds32_ifc_insn_stack *ptr, *base; ++ struct elf_nds32_ifc_insn_member *imember, *base_imember; ++ struct elf_nds32_ifc_member *member; ++ bfd_byte *contents = NULL; ++ bfd_vma off, insn_sz, relocation, clean_off, base_off; ++ nds32_elf_blank_t *relax_blank_list = NULL; ++ struct bfd_link_hash_entry *bh; ++ asection *sec; ++ bfd *abfd; ++ bfd_boolean align_mask, extend; ++ ++ if (!stack) ++ return; ++ ++ /* Set extend for all live stack. */ ++ ptr = stack; ++ while (ptr) ++ { ++ ptr->extend = ptr->live; ++ ptr = ptr->next; ++ } ++ extend = nds32_elf_ifc_extend_up (stack); ++ ++ if (!nds32_elf_ifc_check (stack, &base, extend)) ++ { ++ ptr = stack; ++ while (ptr) ++ { ++ ptr->live = 0; ++ ptr = ptr->next; ++ } ++ return; ++ } ++ ++ /* Get the total block size. */ ++ imember = base->imember; ++ while (imember->next) ++ { ++ imember = imember->next; ++ insn_sz += imember->member->unit_p->hash->size; ++ } ++ /* Find the base block. */ ++ member = imember->member; ++ /* Final instruction offset. */ ++ off = member->offset; ++ /* Final instruction size. */ ++ insn_sz = member->unit_p->hash->size; ++ sec = member->sec; ++ abfd = member->sec->owner; ++ ++ if (!member->unit_p->hash->end) ++ { ++ /* Stack is the ifc base. Insert ifret16 into the block. */ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) ++ return; ++ ++ /* Adjust contents. */ ++ nds32_elf_ifc_reallocate_contents (sec, 4, &contents); ++ memmove (contents + off + 4 + insn_sz, ++ contents + off + insn_sz, ++ sec->size - off - insn_sz - 4); ++ ++ /* Adjust relocation and symbols. */ ++ nds32_elf_ifc_enlarge (abfd, sec, off + insn_sz, 4); ++ ++ /* Put ifret. It insert 32-bits ret since it has to consider alignment ++ in the future. */ ++ bfd_putb32 (INSN_IFRET, contents + off + insn_sz); ++ ++ /* Insert relocation for convert to 16-bits if possible. */ ++ nds32_elf_ifc_insert_insn16_reloc (info, abfd, sec, off + insn_sz); ++ } ++ ++ ++ off = base->imember->member->offset ++ - base->imember->member->unit_p->entry_p->size; ++ ++ /* The common block address. */ ++ relocation = off + sec->output_offset + sec->output_section->vma; ++ ++ /* Others has to exchange to ifcall, and insert relocation. */ ++ ptr = stack; ++ while (ptr) ++ { ++ if (ptr->live && ptr != base) ++ { ++ insn_sz = 0; ++ imember = ptr->imember; ++ member = imember->member; ++ sec = member->sec; ++ abfd = member->sec->owner; ++ ++ /* Check the range enough for ifcall. */ ++ off = member->offset - member->unit_p->entry_p->size ++ + sec->output_offset + sec->output_section->vma; ++ /* The larget range 16s and right shift one bit. Do it conservatively, ++ so pick range 0xf000. */ ++ if ((off > relocation && (off - relocation) > 0xf000) ++ || (off < relocation && (relocation - off) > 0xf000)) ++ { ++ ptr = ptr->next; ++ continue; ++ } ++ ++ /* The first insntruction offset. */ ++ off = member->offset - member->unit_p->entry_p->size; ++ ++ /* Get the total insntruntion size of the common subexpression. */ ++ insn_sz += member->unit_p->entry_p->size; ++ while (imember && member->unit_p) ++ { ++ member = imember->member; ++ insn_sz += member->unit_p->hash->size; ++ imember = imember->next; ++ } ++ ++ if (!nds32_get_section_contents (abfd, sec, &contents, TRUE)) ++ { ++ (*_bfd_error_handler) ++ (_("Linker: relax for ifc get section contents error.\n")); ++ return; ++ } ++ ++ /* Check the total size of common if 4 bytes multiple or not. */ ++ align_mask = ((insn_sz % 4) == 0) ? TRUE : FALSE; ++ clean_off = off + insn_sz - 2; ++ ++ /* Find the member match to base block. */ ++ base_imember = base->imember; ++ imember = ptr->imember; ++ while (imember->member->unit_p != base_imember->member->unit_p) ++ base_imember = base_imember->next; ++ if (!imember) ++ { ++ (*_bfd_error_handler) ++ (_("Linker: relax for ifc error.\n")); ++ return; ++ } ++ bh = base_imember->member->bh; ++ if (!bh) ++ { ++ base_off = base_imember->member->offset ++ - base_imember->member->unit_p->entry_p->size; ++ /* Insert a global symbol for ifc target. */ ++ nds32_elf_ifc_insert_target (base, base_off, info, &bh); ++ base_imember->member->bh = bh; ++ } ++ ++ /* Insert two relocations IFCALL and INSN16. */ ++ nds32_elf_ifc_insert_relocation (info, abfd, sec, bh, off, ++ align_mask, clean_off); ++ ++ bfd_putb32 (INSN_IFCALL, contents + off); ++ ++ if (!align_mask) ++ bfd_putb16 (INSN_NOP16, contents + off + 4); ++ ++ if (align_mask && !insert_nds32_elf_blank_recalc_total ++ (&relax_blank_list, off + 4, insn_sz - 4)) ++ return; ++ else if (!align_mask && !insert_nds32_elf_blank_recalc_total ++ (&relax_blank_list, off + 6, insn_sz - 6)) ++ return; ++ if (relax_blank_list) ++ { ++ nds32_elf_relax_delete_blanks (abfd, sec, relax_blank_list); ++ relax_blank_list = NULL; ++ } ++ nds32_elf_ifc_adjust_block (sec, off, ((align_mask) ? 4 : 6) - insn_sz, ++ (align_mask) ? 4 : 6); ++ } ++ ptr = ptr->next; ++ } ++} ++ ++/* Free heap and set dead member. */ ++ ++static void ++nds32_elf_ifc_release_member (struct elf_nds32_ifc_insn_stack *stack) ++{ ++ struct elf_nds32_ifc_insn_stack *ptr, *temp_ptr; ++ struct elf_nds32_ifc_insn_member *imember, *temp; ++ ++ ptr = stack; ++ while (ptr) ++ { ++ if (ptr->live) ++ { ++ imember = ptr->imember; ++ while (imember) ++ { ++ /* Set edge dead. */ ++ imember->member->dead = TRUE; ++ imember->member->unit_p->times--; ++ /* Since the previous insntruction is used, ++ set the edge dead, too. */ ++ imember->member->next_member->dead = TRUE; ++ if (imember->member->pre_member) ++ imember->member->pre_member->dead = TRUE; ++ temp = imember; ++ imember = imember->next; ++ free (temp); ++ } ++ } ++ temp_ptr = ptr; ++ ptr = ptr->next; ++ free (temp_ptr); ++ } ++} ++ ++/* Get the new max_unit for entry. */ ++ ++static bfd_boolean ++nds32_elf_ifc_next_max (struct elf_nds32_ifc_code_hash_entry *entry) ++{ ++ struct elf_nds32_ifc_unit *unitP, *max_unit; ++ ++ unitP = entry->unit; ++ max_unit = entry->unit; ++ while (unitP) ++ { ++ if (unitP->times > max_unit->times ++ && !unitP->done) ++ max_unit = unitP; ++ unitP = unitP->next; ++ } ++ if (!max_unit->done && max_unit->times >= 2) ++ { ++ entry->max_unit = max_unit; ++ entry->max_times = max_unit->times; ++ return TRUE; ++ } ++ return FALSE; ++} ++ ++/* Find cse block here. */ ++ ++static void ++nds32_elf_ifc_find_cse (struct bfd_link_info *info) ++{ ++ /* Example: insntruction ABCABCB. In the first round we will choose B, ++ and find its next possible insntruction. In the end of this round, ++ we will know the max appearance times is 2, and the insntruction is C. */ ++ struct elf_nds32_ifc_code_hash_entry *ptr = ifc_insn_head; ++ struct elf_nds32_ifc_insn_stack *stack; ++ ++ while (ptr) ++ { ++ stack = NULL; ++ if (ptr->max_unit && ptr->max_times >= 2) ++ { ++ /* We save some infomation for ifc search back, but not ++ implement yet. It may can be done hear. */ ++ ptr->max_unit->done = 1; ++ ptr->round = 1; ++ nds32_elf_ifc_find_cse_recur (ptr->max_unit, &stack, ptr->size); ++ nds32_elf_ifc_replace_common (stack, info); ++ ptr->round = 0; ++ nds32_elf_ifc_release_member (stack); ++ if (nds32_elf_ifc_next_max (ptr)) ++ continue; ++ } ++ ptr = ptr->next; ++ } ++} ++ ++/* To find the cse and relax it. */ ++ ++static void ++nds32_elf_ifc_cse_algo (struct bfd_link_info *info) ++{ ++ /* Order the insntruction by max_unit times. */ ++ nds32_elf_ifc_code_hash_traverse (nds32_elf_ifc_order_insn_times); ++ ++ /* Find common subexpression. */ ++ nds32_elf_ifc_find_cse (info); ++} ++/* End IFC. */ ++ ++ ++/* Rom-patch table hash function. */ ++ ++static struct bfd_hash_entry * ++nds32_elf_ict_hash_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ struct elf_nds32_ict_hash_entry *ret; ++ ++ /* Allocate the structure if it has not already been allocated by a ++ subclass. */ ++ if (entry == NULL) ++ { ++ entry = (struct bfd_hash_entry *) ++ bfd_hash_allocate (table, sizeof (*ret)); ++ if (entry == NULL) ++ return entry; ++ } ++ ++ /* Call the allocation method of the superclass. */ ++ entry = bfd_hash_newfunc (entry, table, string); ++ if (entry == NULL) ++ return entry; ++ ++ ret = (struct elf_nds32_ict_hash_entry*) entry; ++ ret->order = 0; ++ return &ret->root; ++} ++ ++static void ++nds32_elf_ict_hash_init (void) ++{ ++ if (!bfd_hash_table_init_n (&indirect_call_table, nds32_elf_ict_hash_newfunc, ++ sizeof (struct elf_nds32_ict_hash_entry), ++ 1023)) ++ (*_bfd_error_handler) (_("ld error: cannot init rom patch hash table\n")); ++ return; ++} ++ ++/* Relocate for NDS32_ICT_SECTION. */ ++static void ++nds32_elf_ict_relocate (struct bfd_link_info *info) ++{ ++ static bfd_boolean done = FALSE; ++ asection *sec; ++ bfd_byte *contents = NULL; ++ uint32_t insn; ++ unsigned int i; ++ struct elf_link_hash_entry *h; ++ struct bfd_link_hash_entry *h2; ++ bfd_vma relocation, base; ++ ++ if (done) ++ return; ++ ++ done = TRUE; ++ ++ sec = nds32_elf_get_target_section (info, NDS32_ICT_SECTION); ++ h2 = bfd_link_hash_lookup (info->hash, "_INDIRECT_CALL_TABLE_BASE_", ++ FALSE, FALSE, FALSE); ++ base = ((h2->u.def.value ++ + h2->u.def.section->output_section->vma ++ + h2->u.def.section->output_offset)); ++ ++ if (!nds32_get_section_contents (sec->owner, sec, &contents, TRUE)) ++ return; ++ ++ indirect_call_table.frozen = 1; ++ for (i = 0; i < indirect_call_table.size; i++) ++ { ++ struct bfd_hash_entry *p; ++ struct elf_nds32_ict_hash_entry *entry; ++ ++ for (p = indirect_call_table.table[i]; p != NULL; p = p->next) ++ { ++ entry = (struct elf_nds32_ict_hash_entry *) p; ++ insn = INSN_J; ++ h = entry->h; ++ if ((h->root.type == bfd_link_hash_defined ++ || h->root.type == bfd_link_hash_defweak) ++ && h->root.u.def.section != NULL ++ && h->root.u.def.section->output_section != NULL) ++ { ++ ++ relocation = h->root.u.def.value + ++ h->root.u.def.section->output_section->vma + ++ h->root.u.def.section->output_offset; ++ insn |= ((relocation - base - entry->order * 4) >> 1) & 0xffffff; ++ } ++ else ++ relocation = 0; ++ ++ bfd_putb32 (insn, contents + (entry->order) * 4); ++ } ++ } ++ indirect_call_table.frozen = 0; ++} ++ ++static asection* ++nds32_elf_get_target_section (struct bfd_link_info *info, char *name) ++{ ++ asection *sec = NULL; ++ bfd *abfd; ++ ++ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) ++ { ++ sec = bfd_get_section_by_name (abfd, name); ++ if (sec != NULL) ++ break; ++ } ++ ++ return sec; ++} ++ ++ ++#define ELF_ARCH bfd_arch_nds32 ++#define ELF_MACHINE_CODE EM_NDS32 ++#define ELF_MAXPAGESIZE 0x1000 ++#define ELF_TARGET_ID NDS32_ELF_DATA ++ ++#define TARGET_BIG_SYM bfd_elf32_nds32be_vec ++#define TARGET_BIG_NAME "elf32-nds32be" ++#define TARGET_LITTLE_SYM bfd_elf32_nds32le_vec ++#define TARGET_LITTLE_NAME "elf32-nds32le" ++ ++#define elf_info_to_howto nds32_info_to_howto ++#define elf_info_to_howto_rel nds32_info_to_howto_rel ++ ++#define bfd_elf32_bfd_link_hash_table_create nds32_elf_link_hash_table_create ++#define bfd_elf32_bfd_merge_private_bfd_data nds32_elf_merge_private_bfd_data ++#define bfd_elf32_bfd_print_private_bfd_data nds32_elf_print_private_bfd_data ++#define bfd_elf32_bfd_relax_section nds32_elf_relax_section ++#define bfd_elf32_bfd_set_private_flags nds32_elf_set_private_flags ++ ++#define bfd_elf32_mkobject nds32_elf_mkobject ++#define elf_backend_action_discarded nds32_elf_action_discarded ++#define elf_backend_add_symbol_hook nds32_elf_add_symbol_hook ++#define elf_backend_check_relocs nds32_elf_check_relocs ++#define elf_backend_adjust_dynamic_symbol nds32_elf_adjust_dynamic_symbol ++#define elf_backend_create_dynamic_sections nds32_elf_create_dynamic_sections ++#define elf_backend_finish_dynamic_sections nds32_elf_finish_dynamic_sections ++#define elf_backend_finish_dynamic_symbol nds32_elf_finish_dynamic_symbol ++#define elf_backend_size_dynamic_sections nds32_elf_size_dynamic_sections ++#define elf_backend_relocate_section nds32_elf_relocate_section ++#define elf_backend_gc_mark_hook nds32_elf_gc_mark_hook ++#define elf_backend_gc_sweep_hook nds32_elf_gc_sweep_hook ++#define elf_backend_grok_prstatus nds32_elf_grok_prstatus ++#define elf_backend_grok_psinfo nds32_elf_grok_psinfo ++#define elf_backend_reloc_type_class nds32_elf_reloc_type_class ++#define elf_backend_copy_indirect_symbol nds32_elf_copy_indirect_symbol ++#define elf_backend_link_output_symbol_hook nds32_elf_output_symbol_hook ++#define elf_backend_output_arch_syms nds32_elf_output_arch_syms ++#define elf_backend_object_p nds32_elf_object_p ++#define elf_backend_final_write_processing nds32_elf_final_write_processing ++#define elf_backend_special_sections nds32_elf_special_sections ++#define bfd_elf32_bfd_get_relocated_section_contents \ ++ nds32_elf_get_relocated_section_contents ++#define bfd_elf32_bfd_is_target_special_symbol nds32_elf_is_target_special_symbol ++#define elf_backend_maybe_function_sym nds32_elf_maybe_function_sym ++ ++#define elf_backend_can_gc_sections 1 ++#define elf_backend_can_refcount 1 ++#define elf_backend_want_got_plt 1 ++#define elf_backend_plt_readonly 1 ++#define elf_backend_want_plt_sym 0 ++#define elf_backend_got_header_size 12 ++#define elf_backend_may_use_rel_p 1 ++#define elf_backend_default_use_rela_p 1 ++#define elf_backend_may_use_rela_p 1 ++ ++#include "elf32-target.h" ++ ++#undef ELF_MAXPAGESIZE ++#define ELF_MAXPAGESIZE 0x2000 ++ ++#undef TARGET_BIG_SYM ++#define TARGET_BIG_SYM bfd_elf32_nds32belin_vec ++#undef TARGET_BIG_NAME ++#define TARGET_BIG_NAME "elf32-nds32be-linux" ++#undef TARGET_LITTLE_SYM ++#define TARGET_LITTLE_SYM bfd_elf32_nds32lelin_vec ++#undef TARGET_LITTLE_NAME ++#define TARGET_LITTLE_NAME "elf32-nds32le-linux" ++#undef elf32_bed ++#define elf32_bed elf32_nds32_lin_bed ++ ++#include "elf32-target.h" +diff -Nur binutils-2.24.orig/bfd/elf32-nds32.h binutils-2.24/bfd/elf32-nds32.h +--- binutils-2.24.orig/bfd/elf32-nds32.h 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/bfd/elf32-nds32.h 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1,215 @@ ++/* NDS32-specific support for 32-bit ELF. ++ Copyright (C) 2012-2013 Free Software Foundation, Inc. ++ Contributed by Andes Technology Corporation. ++ ++ 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 3 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 ELF32_NDS32_H ++#define ELF32_NDS32_H ++ ++/* ++ * Relocation flags encoded in r_addend. ++ */ ++ ++/* Relocation flags for R_NDS32_ERLAX_ENTRY. */ ++ ++/* Set if relax on this section is done or disabled. */ ++#define R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG (1 << 31) ++/* Optimize for performance. */ ++#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG (1 << 30) ++/* Optimize for size. Branch destination 4-byte adjustment ++ may be disabled. */ ++#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG (1 << 29) ++/* To distinguish the assembly code generated by compiler ++ or written manually. */ ++#define R_NDS32_RELAX_ENTRY_VERBATIM_FLAG (1 << 28) ++/* EX9 and link-time IFC must be explicitly enabled, so we ++ won't mess up handcraft assembly code. */ ++/* Enable EX9 optimization for this section. */ ++#define R_NDS32_RELAX_ENTRY_EX9_FLAG (1 << 2) ++/* Enable IFC optimization for this section. */ ++#define R_NDS32_RELAX_ENTRY_IFC_FLAG (1 << 3) ++ ++ ++/* Relocation flags for R_NDS32_INSN16. */ ++ ++/* Tag the nop16 can be removed. */ ++#define R_NDS32_INSN16_CONVERT_FLAG (1 << 0) ++/* Convert a gp-relative access (e.g., lwi.gp) ++ to fp-as-gp access (lwi37.fp). ++ This value is used by linker internally only. ++ It's fine to change the vlaue. */ ++#define R_NDS32_INSN16_FP7U2_FLAG (1 << 1) ++ ++/* Relocation flags for R_NDS32_RELAX_REGION_OMIT_FP_START/END. */ ++ ++/* OMIT_FP_FLAG marks the region for applying fp-as-gp ++ optimization. */ ++#define R_NDS32_RELAX_REGION_OMIT_FP_FLAG (1 << 0) ++/* NOT_OMIT_FP_FLAG is set if this region is not worth ++ for fp-as-gp. */ ++#define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG (1 << 1) ++/* Suppress EX9 optimization in the region. */ ++#define R_NDS32_RELAX_REGION_NO_EX9_FLAG (1 << 2) ++/* A Innermost loop region. Some optimizations is suppressed ++ in this region due to performance drop. */ ++#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG (1 << 4) ++/* Suppress IFC optimization in the region. */ ++#define R_NDS32_RELAX_REGION_NO_IFC_FLAG (1 << 5) ++ ++/* Tag range for LOADSTORE relocation. */ ++enum ++{ ++ NDS32_LOADSTORE_NONE = 0x0, ++ NDS32_LOADSTORE_BYTE = 0x1, ++ NDS32_LOADSTORE_HALF = 0x2, ++ NDS32_LOADSTORE_WORD = 0x4, ++ NDS32_LOADSTORE_FLOAT_S = 0x8, ++ NDS32_LOADSTORE_FLOAT_D = 0x10, ++ NDS32_LOADSTORE_IMM = 0x20 ++}; ++ ++/* Relax tag for nds32_elf_relax_section, we have to specify which ++ optimization do in this round. */ ++enum ++{ ++ NDS32_RELAX_NONE_ROUND = 0, ++ NDS32_RELAX_NORMAL_ROUND, ++ NDS32_RELAX_JUMP_IFC_ROUND, ++ NDS32_RELAX_IFC_ROUND, ++ NDS32_RELAX_EX9_BUILD_ROUND, ++ NDS32_RELAX_EX9_REPLACE_ROUND, ++ NDS32_RELAX_EMPTY_ROUND ++}; ++ ++/* Security tag. */ ++enum ++{ ++ NDS32_SECURITY_NONE = 0, ++ NDS32_SECURITY_START, ++ NDS32_SECURITY_RESTART, ++ NDS32_SECURITY_END ++}; ++ ++/* There are two state in IFC optimization including general ifc (post-opt) ++ and jump ifc (j and jal). Therefore, we have to use two different mask to ++ distinguish them. */ ++/* Optimization status mask. */ ++#define NDS32_RELAX_JUMP_IFC_DONE (1 << 0) ++#define NDS32_RELAX_EX9_DONE (1 << 1) ++#define NDS32_RELAX_IFC_DONE (1 << 2) ++ ++/* Optimization turn on mask. */ ++#define NDS32_RELAX_IFC_ON (1 << 0) ++#define NDS32_RELAX_EX9_ON (1 << 1) ++ ++void nds32_insertion_sort ++ (void *base, size_t nmemb, size_t size, ++ int (*compar) (const void *lhs, const void *rhs)); ++ ++struct section_id_list_t ++{ ++ int id; ++ struct section_id_list_t *next; ++}; ++ ++struct section_id_list_t * ++ elf32_nds32_lookup_section_id (int id, struct section_id_list_t **lst_ptr); ++int elf32_nds32_check_relax_group (bfd *bfd, asection *sec); ++int elf32_nds32_unify_relax_group (bfd *abfd, asection *asec); ++int nds32_elf_unify_tls_model (bfd *inbfd, asection *insec, ++ bfd_byte *incontents, ++ struct bfd_link_info *lnkinfo); ++ ++void bfd_elf32_nds32_set_target_option (struct bfd_link_info *, int, int, ++ FILE *, int, int, int, int, FILE *, ++ FILE *, int, int, bfd_boolean, ++ bfd_boolean, bfd_boolean); ++void bfd_elf32_nds32_append_section (struct bfd_link_info*, bfd *, int); ++int nds32_convert_32_to_16 ++ (bfd *abfd, uint32_t insn, uint16_t *pinsn16, int *pinsn_type); ++int nds32_convert_16_to_32 (bfd *abfd, uint16_t insn16, uint32_t *pinsn); ++ ++#define nds32_elf_hash_table(info) \ ++ (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \ ++ == NDS32_ELF_DATA ? ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL) ++ ++#define elf32_nds32_compute_jump_table_size(htab) \ ++ ((htab)->next_tls_desc_index * 4) ++ ++#define elf32_nds32_local_tlsdesc_gotent(bfd) \ ++ (elf_nds32_tdata (bfd)->local_tlsdesc_gotent) ++ ++/* Hash table structure for target nds32. There are some members to ++ save target options passed from nds32elf.em to bfd. */ ++ ++struct elf_nds32_link_hash_table ++{ ++ struct elf_link_hash_table root; ++ ++ /* ?? Short-cuts to get to dynamic linker sections. */ ++ asection *sdynbss; ++ asection *srelbss; ++ ++ /* Small local sym to section mapping cache. */ ++ struct sym_cache sym_cache; ++ ++ /* Target dependent options. */ ++ int relax_fp_as_gp; /* --mrelax-omit-fp */ ++ int eliminate_gc_relocs; /* --meliminate-gc-relocs */ ++ FILE *sym_ld_script; /* --mgen-symbol-ld-script= */ ++ /* Disable if linking a dynamically linked executable. */ ++ int load_store_relax; ++ int target_optimize; /* Switch optimization. */ ++ int relax_status; /* Finished optimization. */ ++ int relax_round; /* Going optimization. */ ++ FILE *ex9_export_file; /* --mexport-ex9= */ ++ FILE *ex9_import_file; /* --mimport-ex9= */ ++ int update_ex9_table; /* --mupdate-ex9. */ ++ int ex9_limit; ++ bfd_boolean ex9_loop_aware; /* Ignore ex9 if inside a loop. */ ++ bfd_boolean ifc_loop_aware; /* Ignore ifc if inside a loop. */ ++ bfd_boolean hyper_relax; /* Relax for symbol not in RW sections. */ ++ ++ /* The offset into splt of the PLT entry for the TLS descriptor ++ resolver. Special values are 0, if not necessary (or not found ++ to be necessary yet), and -1 if needed but not determined ++ yet. */ ++ bfd_vma dt_tlsdesc_plt; ++ ++ /* The offset into sgot of the GOT entry used by the PLT entry ++ above. */ ++ bfd_vma dt_tlsdesc_got; ++ ++ /* Offset in .plt section of tls_nds32_trampoline. */ ++ bfd_vma tls_trampoline; ++ ++ /* The index of the next unused R_NDS32_TLS_DESC slot in .rel.plt. */ ++ bfd_vma next_tls_desc_index; ++ ++ /* How many R_NDS32_TLS_DESC relocations were generated so far. */ ++ bfd_vma num_tls_desc; ++ ++ /* The amount of space used by the reserved portion of the sgotplt ++ section, plus whatever space is used by the jump slots. */ ++ bfd_vma sgotplt_jump_table_size; ++ ++ /* True if the target uses REL relocations. */ ++ int use_rel; ++}; ++#endif +diff -Nur binutils-2.24.orig/bfd/libbfd.c binutils-2.24/bfd/libbfd.c +--- binutils-2.24.orig/bfd/libbfd.c 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/bfd/libbfd.c 2016-04-10 20:30:46.000000000 +0200 +@@ -550,11 +550,10 @@ + .*/ + + /* Sign extension to bfd_signed_vma. */ +-#define COERCE16(x) (((bfd_signed_vma) (x) ^ 0x8000) - 0x8000) +-#define COERCE32(x) (((bfd_signed_vma) (x) ^ 0x80000000) - 0x80000000) +-#define EIGHT_GAZILLION ((bfd_int64_t) 1 << 63) ++#define COERCE16(x) (((bfd_vma) (x) ^ 0x8000) - 0x8000) ++#define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000) + #define COERCE64(x) \ +- (((bfd_int64_t) (x) ^ EIGHT_GAZILLION) - EIGHT_GAZILLION) ++ (((bfd_uint64_t) (x) ^ ((bfd_uint64_t) 1 << 63)) - ((bfd_uint64_t) 1 << 63)) + + bfd_vma + bfd_getb16 (const void *p) +diff -Nur binutils-2.24.orig/bfd/libbfd.h binutils-2.24/bfd/libbfd.h +--- binutils-2.24.orig/bfd/libbfd.h 2013-11-18 09:40:15.000000000 +0100 ++++ binutils-2.24/bfd/libbfd.h 2016-04-10 20:30:46.000000000 +0200 +@@ -1746,6 +1746,141 @@ + "BFD_RELOC_M32R_GOTPC_HI_ULO", + "BFD_RELOC_M32R_GOTPC_HI_SLO", + "BFD_RELOC_M32R_GOTPC_LO", ++ "BFD_RELOC_NDS32_20", ++ "BFD_RELOC_NDS32_9_PCREL", ++ "BFD_RELOC_NDS32_WORD_9_PCREL", ++ "BFD_RELOC_NDS32_15_PCREL", ++ "BFD_RELOC_NDS32_17_PCREL", ++ "BFD_RELOC_NDS32_25_PCREL", ++ "BFD_RELOC_NDS32_HI20", ++ "BFD_RELOC_NDS32_LO12S3", ++ "BFD_RELOC_NDS32_LO12S2", ++ "BFD_RELOC_NDS32_LO12S1", ++ "BFD_RELOC_NDS32_LO12S0", ++ "BFD_RELOC_NDS32_LO12S0_ORI", ++ "BFD_RELOC_NDS32_SDA15S3", ++ "BFD_RELOC_NDS32_SDA15S2", ++ "BFD_RELOC_NDS32_SDA15S1", ++ "BFD_RELOC_NDS32_SDA15S0", ++ "BFD_RELOC_NDS32_SDA16S3", ++ "BFD_RELOC_NDS32_SDA17S2", ++ "BFD_RELOC_NDS32_SDA18S1", ++ "BFD_RELOC_NDS32_SDA19S0", ++ "BFD_RELOC_NDS32_SECURITY_16", ++ "BFD_RELOC_NDS32_GOT20", ++ "BFD_RELOC_NDS32_9_PLTREL", ++ "BFD_RELOC_NDS32_25_PLTREL", ++ "BFD_RELOC_NDS32_COPY", ++ "BFD_RELOC_NDS32_GLOB_DAT", ++ "BFD_RELOC_NDS32_JMP_SLOT", ++ "BFD_RELOC_NDS32_RELATIVE", ++ "BFD_RELOC_NDS32_GOTOFF", ++ "BFD_RELOC_NDS32_GOTOFF_HI20", ++ "BFD_RELOC_NDS32_GOTOFF_LO12", ++ "BFD_RELOC_NDS32_GOTPC20", ++ "BFD_RELOC_NDS32_GOT_HI20", ++ "BFD_RELOC_NDS32_GOT_LO12", ++ "BFD_RELOC_NDS32_GOTPC_HI20", ++ "BFD_RELOC_NDS32_GOTPC_LO12", ++ "BFD_RELOC_NDS32_INSN16", ++ "BFD_RELOC_NDS32_LABEL", ++ "BFD_RELOC_NDS32_LONGCALL1", ++ "BFD_RELOC_NDS32_LONGCALL2", ++ "BFD_RELOC_NDS32_LONGCALL3", ++ "BFD_RELOC_NDS32_LONGJUMP1", ++ "BFD_RELOC_NDS32_LONGJUMP2", ++ "BFD_RELOC_NDS32_LONGJUMP3", ++ "BFD_RELOC_NDS32_LOADSTORE", ++ "BFD_RELOC_NDS32_9_FIXED", ++ "BFD_RELOC_NDS32_15_FIXED", ++ "BFD_RELOC_NDS32_17_FIXED", ++ "BFD_RELOC_NDS32_25_FIXED", ++ "BFD_RELOC_NDS32_LONGCALL4", ++ "BFD_RELOC_NDS32_LONGCALL5", ++ "BFD_RELOC_NDS32_LONGCALL6", ++ "BFD_RELOC_NDS32_LONGJUMP4", ++ "BFD_RELOC_NDS32_LONGJUMP5", ++ "BFD_RELOC_NDS32_LONGJUMP6", ++ "BFD_RELOC_NDS32_LONGJUMP7", ++ "BFD_RELOC_NDS32_PLTREL_HI20", ++ "BFD_RELOC_NDS32_PLTREL_LO12", ++ "BFD_RELOC_NDS32_PLT_GOTREL_HI20", ++ "BFD_RELOC_NDS32_PLT_GOTREL_LO12", ++ "BFD_RELOC_NDS32_SDA12S2_DP", ++ "BFD_RELOC_NDS32_SDA12S2_SP", ++ "BFD_RELOC_NDS32_LO12S2_DP", ++ "BFD_RELOC_NDS32_LO12S2_SP", ++ "BFD_RELOC_NDS32_DWARF2_OP1", ++ "BFD_RELOC_NDS32_DWARF2_OP2", ++ "BFD_RELOC_NDS32_DWARF2_LEB", ++ "BFD_RELOC_NDS32_UPDATE_TA", ++ "BFD_RELOC_NDS32_PLT_GOTREL_LO20", ++ "BFD_RELOC_NDS32_PLT_GOTREL_LO15", ++ "BFD_RELOC_NDS32_PLT_GOTREL_LO19", ++ "BFD_RELOC_NDS32_GOT_LO15", ++ "BFD_RELOC_NDS32_GOT_LO19", ++ "BFD_RELOC_NDS32_GOTOFF_LO15", ++ "BFD_RELOC_NDS32_GOTOFF_LO19", ++ "BFD_RELOC_NDS32_GOT15S2", ++ "BFD_RELOC_NDS32_GOT17S2", ++ "BFD_RELOC_NDS32_5", ++ "BFD_RELOC_NDS32_10_UPCREL", ++ "BFD_RELOC_NDS32_SDA_FP7U2_RELA", ++ "BFD_RELOC_NDS32_RELAX_ENTRY", ++ "BFD_RELOC_NDS32_GOT_SUFF", ++ "BFD_RELOC_NDS32_GOTOFF_SUFF", ++ "BFD_RELOC_NDS32_PLT_GOT_SUFF", ++ "BFD_RELOC_NDS32_MULCALL_SUFF", ++ "BFD_RELOC_NDS32_PTR", ++ "BFD_RELOC_NDS32_PTR_COUNT", ++ "BFD_RELOC_NDS32_PTR_RESOLVED", ++ "BFD_RELOC_NDS32_PLTBLOCK", ++ "BFD_RELOC_NDS32_RELAX_REGION_BEGIN", ++ "BFD_RELOC_NDS32_RELAX_REGION_END", ++ "BFD_RELOC_NDS32_MINUEND", ++ "BFD_RELOC_NDS32_SUBTRAHEND", ++ "BFD_RELOC_NDS32_DIFF8", ++ "BFD_RELOC_NDS32_DIFF16", ++ "BFD_RELOC_NDS32_DIFF32", ++ "BFD_RELOC_NDS32_DIFF_ULEB128", ++ "BFD_RELOC_NDS32_EMPTY", ++ "BFD_RELOC_NDS32_25_ABS", ++ "BFD_RELOC_NDS32_DATA", ++ "BFD_RELOC_NDS32_TRAN", ++ "BFD_RELOC_NDS32_17IFC_PCREL", ++ "BFD_RELOC_NDS32_10IFCU_PCREL", ++ "BFD_RELOC_NDS32_TPOFF", ++ "BFD_RELOC_NDS32_GOTTPOFF", ++ "BFD_RELOC_NDS32_TLS_LE_HI20", ++ "BFD_RELOC_NDS32_TLS_LE_LO12", ++ "BFD_RELOC_NDS32_TLS_LE_20", ++ "BFD_RELOC_NDS32_TLS_LE_15S0", ++ "BFD_RELOC_NDS32_TLS_LE_15S1", ++ "BFD_RELOC_NDS32_TLS_LE_15S2", ++ "BFD_RELOC_NDS32_TLS_LE_ADD", ++ "BFD_RELOC_NDS32_TLS_LE_LS", ++ "BFD_RELOC_NDS32_TLS_IE_HI20", ++ "BFD_RELOC_NDS32_TLS_IE_LO12", ++ "BFD_RELOC_NDS32_TLS_IE_LO12S2", ++ "BFD_RELOC_NDS32_TLS_IEGP_HI20", ++ "BFD_RELOC_NDS32_TLS_IEGP_LO12", ++ "BFD_RELOC_NDS32_TLS_IEGP_LO12S2", ++ "BFD_RELOC_NDS32_TLS_IEGP_LW", ++ "BFD_RELOC_NDS32_TLS_DESC", ++ "BFD_RELOC_NDS32_TLS_DESC_HI20", ++ "BFD_RELOC_NDS32_TLS_DESC_LO12", ++ "BFD_RELOC_NDS32_TLS_DESC_20", ++ "BFD_RELOC_NDS32_TLS_DESC_SDA17S2", ++ "BFD_RELOC_NDS32_TLS_DESC_ADD", ++ "BFD_RELOC_NDS32_TLS_DESC_FUNC", ++ "BFD_RELOC_NDS32_TLS_DESC_CALL", ++ "BFD_RELOC_NDS32_TLS_DESC_MEM", ++ "BFD_RELOC_NDS32_REMOVE", ++ "BFD_RELOC_NDS32_GROUP", ++ "BFD_RELOC_NDS32_ICT", ++ "BFD_RELOC_NDS32_ICT_HI20", ++ "BFD_RELOC_NDS32_ICT_LO12", ++ "BFD_RELOC_NDS32_ICT_25PC", + "BFD_RELOC_V850_9_PCREL", + "BFD_RELOC_V850_22_PCREL", + "BFD_RELOC_V850_SDA_16_16_OFFSET", +diff -Nur binutils-2.24.orig/bfd/po/.cvsignore binutils-2.24/bfd/po/.cvsignore +--- binutils-2.24.orig/bfd/po/.cvsignore 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/bfd/po/.cvsignore 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1 @@ ++*.gmo +diff -Nur binutils-2.24.orig/bfd/reloc.c binutils-2.24/bfd/reloc.c +--- binutils-2.24.orig/bfd/reloc.c 2013-11-18 09:40:15.000000000 +0100 ++++ binutils-2.24/bfd/reloc.c 2016-04-10 20:30:46.000000000 +0200 +@@ -3839,6 +3839,366 @@ + + + ENUM ++ BFD_RELOC_NDS32_20 ++ENUMDOC ++ NDS32 relocs. ++ This is a 20 bit absolute address. ++ENUM ++ BFD_RELOC_NDS32_9_PCREL ++ENUMDOC ++ This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0. ++ENUM ++ BFD_RELOC_NDS32_WORD_9_PCREL ++ENUMDOC ++ This is a 9-bit pc-relative reloc with the right 1 bit assumed to be 0. ++ENUM ++ BFD_RELOC_NDS32_15_PCREL ++ENUMDOC ++ This is an 15-bit reloc with the right 1 bit assumed to be 0. ++ENUM ++ BFD_RELOC_NDS32_17_PCREL ++ENUMDOC ++ This is an 17-bit reloc with the right 1 bit assumed to be 0. ++ENUM ++ BFD_RELOC_NDS32_25_PCREL ++ENUMDOC ++ This is a 25-bit reloc with the right 1 bit assumed to be 0. ++ENUM ++ BFD_RELOC_NDS32_HI20 ++ENUMDOC ++ This is a 20-bit reloc containing the high 20 bits of an address ++ used with the lower 12 bits ++ENUM ++ BFD_RELOC_NDS32_LO12S3 ++ENUMDOC ++ This is a 12-bit reloc containing the lower 12 bits of an address ++ then shift right by 3. This is used with ldi,sdi... ++ENUM ++ BFD_RELOC_NDS32_LO12S2 ++ENUMDOC ++ This is a 12-bit reloc containing the lower 12 bits of an address ++ then shift left by 2. This is used with lwi,swi... ++ENUM ++ BFD_RELOC_NDS32_LO12S1 ++ENUMDOC ++ This is a 12-bit reloc containing the lower 12 bits of an address ++ then shift left by 1. This is used with lhi,shi... ++ENUM ++ BFD_RELOC_NDS32_LO12S0 ++ENUMDOC ++ This is a 12-bit reloc containing the lower 12 bits of an address ++ then shift left by 0. This is used with lbisbi... ++ENUM ++ BFD_RELOC_NDS32_LO12S0_ORI ++ENUMDOC ++ This is a 12-bit reloc containing the lower 12 bits of an address ++ then shift left by 0. This is only used with branch relaxations ++ENUM ++ BFD_RELOC_NDS32_SDA15S3 ++ENUMDOC ++ This is a 15-bit reloc containing the small data area 18-bit signed offset ++ and shift left by 3 for use in ldi, sdi... ++ENUM ++ BFD_RELOC_NDS32_SDA15S2 ++ENUMDOC ++ This is a 15-bit reloc containing the small data area 17-bit signed offset ++ and shift left by 2 for use in lwi, swi... ++ENUM ++ BFD_RELOC_NDS32_SDA15S1 ++ENUMDOC ++ This is a 15-bit reloc containing the small data area 16-bit signed offset ++ and shift left by 1 for use in lhi, shi... ++ENUM ++ BFD_RELOC_NDS32_SDA15S0 ++ENUMDOC ++ This is a 15-bit reloc containing the small data area 15-bit signed offset ++ and shift left by 0 for use in lbi, sbi... ++ENUM ++ BFD_RELOC_NDS32_SDA16S3 ++ENUMDOC ++ This is a 16-bit reloc containing the small data area 16-bit signed offset ++ and shift left by 3 ++ENUM ++ BFD_RELOC_NDS32_SDA17S2 ++ENUMDOC ++ This is a 17-bit reloc containing the small data area 17-bit signed offset ++ and shift left by 2 for use in lwi.gp, swi.gp... ++ENUM ++ BFD_RELOC_NDS32_SDA18S1 ++ENUMDOC ++ This is a 18-bit reloc containing the small data area 18-bit signed offset ++ and shift left by 1 for use in lhi.gp, shi.gp... ++ENUM ++ BFD_RELOC_NDS32_SDA19S0 ++ENUMDOC ++ This is a 19-bit reloc containing the small data area 19-bit signed offset ++ and shift left by 0 for use in lbi.gp, sbi.gp... ++ENUM ++ BFD_RELOC_NDS32_SECURITY_16 ++ENUMDOC ++ This is a 24-bit reloc for security check sum. ++ENUM ++ BFD_RELOC_NDS32_GOT20 ++ENUMX ++ BFD_RELOC_NDS32_9_PLTREL ++ENUMX ++ BFD_RELOC_NDS32_25_PLTREL ++ENUMX ++ BFD_RELOC_NDS32_COPY ++ENUMX ++ BFD_RELOC_NDS32_GLOB_DAT ++ENUMX ++ BFD_RELOC_NDS32_JMP_SLOT ++ENUMX ++ BFD_RELOC_NDS32_RELATIVE ++ENUMX ++ BFD_RELOC_NDS32_GOTOFF ++ENUMX ++ BFD_RELOC_NDS32_GOTOFF_HI20 ++ENUMX ++ BFD_RELOC_NDS32_GOTOFF_LO12 ++ENUMX ++ BFD_RELOC_NDS32_GOTPC20 ++ENUMX ++ BFD_RELOC_NDS32_GOT_HI20 ++ENUMX ++ BFD_RELOC_NDS32_GOT_LO12 ++ENUMX ++ BFD_RELOC_NDS32_GOTPC_HI20 ++ENUMX ++ BFD_RELOC_NDS32_GOTPC_LO12 ++ENUMDOC ++ for PIC ++ENUM ++ BFD_RELOC_NDS32_INSN16 ++ENUMX ++ BFD_RELOC_NDS32_LABEL ++ENUMX ++ BFD_RELOC_NDS32_LONGCALL1 ++ENUMX ++ BFD_RELOC_NDS32_LONGCALL2 ++ENUMX ++ BFD_RELOC_NDS32_LONGCALL3 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP1 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP2 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP3 ++ENUMX ++ BFD_RELOC_NDS32_LOADSTORE ++ENUMX ++ BFD_RELOC_NDS32_9_FIXED ++ENUMX ++ BFD_RELOC_NDS32_15_FIXED ++ENUMX ++ BFD_RELOC_NDS32_17_FIXED ++ENUMX ++ BFD_RELOC_NDS32_25_FIXED ++ENUMX ++ BFD_RELOC_NDS32_LONGCALL4 ++ENUMX ++ BFD_RELOC_NDS32_LONGCALL5 ++ENUMX ++ BFD_RELOC_NDS32_LONGCALL6 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP4 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP5 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP6 ++ENUMX ++ BFD_RELOC_NDS32_LONGJUMP7 ++ENUMDOC ++ for relax ++ENUM ++ BFD_RELOC_NDS32_PLTREL_HI20 ++ENUMX ++ BFD_RELOC_NDS32_PLTREL_LO12 ++ENUMX ++ BFD_RELOC_NDS32_PLT_GOTREL_HI20 ++ENUMX ++ BFD_RELOC_NDS32_PLT_GOTREL_LO12 ++ENUMDOC ++ for PIC ++ENUM ++ BFD_RELOC_NDS32_SDA12S2_DP ++ENUMX ++ BFD_RELOC_NDS32_SDA12S2_SP ++ENUMX ++ BFD_RELOC_NDS32_LO12S2_DP ++ENUMX ++ BFD_RELOC_NDS32_LO12S2_SP ++ENUMDOC ++ for floating point ++ENUM ++ BFD_RELOC_NDS32_DWARF2_OP1 ++ENUMX ++ BFD_RELOC_NDS32_DWARF2_OP2 ++ENUMX ++ BFD_RELOC_NDS32_DWARF2_LEB ++ENUMDOC ++ for dwarf2 debug_line. ++ENUM ++ BFD_RELOC_NDS32_UPDATE_TA ++ENUMDOC ++ for eliminate 16-bit instructions ++ENUM ++ BFD_RELOC_NDS32_PLT_GOTREL_LO20 ++ENUMX ++ BFD_RELOC_NDS32_PLT_GOTREL_LO15 ++ENUMX ++ BFD_RELOC_NDS32_PLT_GOTREL_LO19 ++ENUMX ++ BFD_RELOC_NDS32_GOT_LO15 ++ENUMX ++ BFD_RELOC_NDS32_GOT_LO19 ++ENUMX ++ BFD_RELOC_NDS32_GOTOFF_LO15 ++ENUMX ++ BFD_RELOC_NDS32_GOTOFF_LO19 ++ENUMX ++ BFD_RELOC_NDS32_GOT15S2 ++ENUMX ++ BFD_RELOC_NDS32_GOT17S2 ++ENUMDOC ++ for PIC object relaxation ++ENUM ++ BFD_RELOC_NDS32_5 ++ENUMDOC ++ NDS32 relocs. ++ This is a 5 bit absolute address. ++ENUM ++ BFD_RELOC_NDS32_10_UPCREL ++ENUMDOC ++ This is a 10-bit unsigned pc-relative reloc with the right 1 bit assumed to be 0. ++ENUM ++ BFD_RELOC_NDS32_SDA_FP7U2_RELA ++ENUMDOC ++ If fp were omitted, fp can used as another gp. ++ENUM ++ BFD_RELOC_NDS32_RELAX_ENTRY ++ENUMX ++ BFD_RELOC_NDS32_GOT_SUFF ++ENUMX ++ BFD_RELOC_NDS32_GOTOFF_SUFF ++ENUMX ++ BFD_RELOC_NDS32_PLT_GOT_SUFF ++ENUMX ++ BFD_RELOC_NDS32_MULCALL_SUFF ++ENUMX ++ BFD_RELOC_NDS32_PTR ++ENUMX ++ BFD_RELOC_NDS32_PTR_COUNT ++ENUMX ++ BFD_RELOC_NDS32_PTR_RESOLVED ++ENUMX ++ BFD_RELOC_NDS32_PLTBLOCK ++ENUMX ++ BFD_RELOC_NDS32_RELAX_REGION_BEGIN ++ENUMX ++ BFD_RELOC_NDS32_RELAX_REGION_END ++ENUMX ++ BFD_RELOC_NDS32_MINUEND ++ENUMX ++ BFD_RELOC_NDS32_SUBTRAHEND ++ENUMX ++ BFD_RELOC_NDS32_DIFF8 ++ENUMX ++ BFD_RELOC_NDS32_DIFF16 ++ENUMX ++ BFD_RELOC_NDS32_DIFF32 ++ENUMX ++ BFD_RELOC_NDS32_DIFF_ULEB128 ++ENUMX ++ BFD_RELOC_NDS32_EMPTY ++ENUMDOC ++ relaxation relative relocation types ++ENUM ++ BFD_RELOC_NDS32_25_ABS ++ENUMDOC ++ This is a 25 bit absolute address. ++ENUM ++ BFD_RELOC_NDS32_DATA ++ENUMX ++ BFD_RELOC_NDS32_TRAN ++ENUMX ++ BFD_RELOC_NDS32_17IFC_PCREL ++ENUMX ++ BFD_RELOC_NDS32_10IFCU_PCREL ++ENUMDOC ++ For ex9 and ifc using. ++ENUM ++ BFD_RELOC_NDS32_TPOFF ++ENUMX ++ BFD_RELOC_NDS32_GOTTPOFF ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_HI20 ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_LO12 ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_20 ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_15S0 ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_15S1 ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_15S2 ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_ADD ++ENUMX ++ BFD_RELOC_NDS32_TLS_LE_LS ++ENUMX ++ BFD_RELOC_NDS32_TLS_IE_HI20 ++ENUMX ++ BFD_RELOC_NDS32_TLS_IE_LO12 ++ENUMX ++ BFD_RELOC_NDS32_TLS_IE_LO12S2 ++ENUMX ++ BFD_RELOC_NDS32_TLS_IEGP_HI20 ++ENUMX ++ BFD_RELOC_NDS32_TLS_IEGP_LO12 ++ENUMX ++ BFD_RELOC_NDS32_TLS_IEGP_LO12S2 ++ENUMX ++ BFD_RELOC_NDS32_TLS_IEGP_LW ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_HI20 ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_LO12 ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_20 ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_SDA17S2 ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_ADD ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_FUNC ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_CALL ++ENUMX ++ BFD_RELOC_NDS32_TLS_DESC_MEM ++ENUMX ++ BFD_RELOC_NDS32_REMOVE ++ENUMX ++ BFD_RELOC_NDS32_GROUP ++ENUMDOC ++ For TLS. ++ ++ENUM ++ BFD_RELOC_NDS32_ICT ++ENUMX ++ BFD_RELOC_NDS32_ICT_HI20 ++ENUMX ++ BFD_RELOC_NDS32_ICT_LO12 ++ENUMX ++ BFD_RELOC_NDS32_ICT_25PC ++ENUMDOC ++ Jump-patch table relative relocations. ++ ++ENUM + BFD_RELOC_V850_9_PCREL + ENUMDOC + This is a 9-bit reloc +diff -Nur binutils-2.24.orig/bfd/section.c binutils-2.24/bfd/section.c +--- binutils-2.24.orig/bfd/section.c 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/bfd/section.c 2016-04-10 20:30:46.000000000 +0200 +@@ -542,6 +542,32 @@ + . int size; + .}; + . ++.{* Note: the following are provided as inline functions rather than macros ++. because not all callers use the return value. A macro implementation ++. would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some ++. compilers will complain about comma expressions that have no effect. *} ++.static inline bfd_boolean ++.bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val) ++.{ ++. ptr->userdata = val; ++. return TRUE; ++.} ++. ++.static inline bfd_boolean ++.bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val) ++.{ ++. ptr->vma = ptr->lma = val; ++. ptr->user_set_vma = TRUE; ++. return TRUE; ++.} ++. ++.static inline bfd_boolean ++.bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int val) ++.{ ++. ptr->alignment_power = val; ++. return TRUE; ++.} ++. + .{* These sections are global, and are managed by BFD. The application + . and target back end are not permitted to change the values in + . these sections. *} +diff -Nur binutils-2.24.orig/bfd/targets.c binutils-2.24/bfd/targets.c +--- binutils-2.24.orig/bfd/targets.c 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/bfd/targets.c 2016-04-10 20:30:46.000000000 +0200 +@@ -673,6 +673,10 @@ + extern const bfd_target bfd_elf32_ntradlittlemips_vec; + extern const bfd_target bfd_elf32_ntradbigmips_freebsd_vec; + extern const bfd_target bfd_elf32_ntradlittlemips_freebsd_vec; ++extern const bfd_target bfd_elf32_nds32be_vec; ++extern const bfd_target bfd_elf32_nds32le_vec; ++extern const bfd_target bfd_elf32_nds32belin_vec; ++extern const bfd_target bfd_elf32_nds32lelin_vec; + extern const bfd_target bfd_elf32_openrisc_vec; + extern const bfd_target bfd_elf32_or32_big_vec; + extern const bfd_target bfd_elf32_pj_vec; +@@ -1061,6 +1065,10 @@ + &bfd_elf32_ntradbigmips_freebsd_vec, + &bfd_elf32_ntradlittlemips_freebsd_vec, + #endif ++ &bfd_elf32_nds32be_vec, ++ &bfd_elf32_nds32le_vec, ++ &bfd_elf32_nds32belin_vec, ++ &bfd_elf32_nds32lelin_vec, + &bfd_elf32_openrisc_vec, + &bfd_elf32_or32_big_vec, + &bfd_elf32_pj_vec, +diff -Nur binutils-2.24.orig/binutils/MAINTAINERS binutils-2.24/binutils/MAINTAINERS +--- binutils-2.24.orig/binutils/MAINTAINERS 2013-11-08 11:13:48.000000000 +0100 ++++ binutils-2.24/binutils/MAINTAINERS 2016-04-10 20:30:46.000000000 +0200 +@@ -109,6 +109,8 @@ + MN10300 Alexandre Oliva + Moxie Anthony Green + MSP430 Dmitry Diky ++ NDS32 Kuan-Lin Chen ++ NDS32 Wei-Cheng Wang + NetBSD support Matt Thomas + Nios II Sandra Loosemore + Nios II Andrew Jenner +diff -Nur binutils-2.24.orig/binutils/Makefile.am binutils-2.24/binutils/Makefile.am +--- binutils-2.24.orig/binutils/Makefile.am 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/binutils/Makefile.am 2016-04-10 20:30:46.000000000 +0200 +@@ -241,7 +241,7 @@ + + objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS) + EXTRA_objdump_SOURCES = od-xcoff.c +-objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) ++objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) -ldl + + objdump.@OBJEXT@:objdump.c + if am__fastdepCC +diff -Nur binutils-2.24.orig/binutils/Makefile.in binutils-2.24/binutils/Makefile.in +--- binutils-2.24.orig/binutils/Makefile.in 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/binutils/Makefile.in 2016-04-10 20:30:46.000000000 +0200 +@@ -581,7 +581,7 @@ + nm_new_SOURCES = nm.c $(BULIBS) + objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) $(ELFLIBS) + EXTRA_objdump_SOURCES = od-xcoff.c +-objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) ++objdump_LDADD = $(OBJDUMP_PRIVATE_OFILES) $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) -ldl + cxxfilt_SOURCES = cxxfilt.c $(BULIBS) + ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \ + emul_$(EMULATION).c $(BULIBS) +diff -Nur binutils-2.24.orig/binutils/NEWS binutils-2.24/binutils/NEWS +--- binutils-2.24.orig/binutils/NEWS 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/binutils/NEWS 2016-04-10 20:30:46.000000000 +0200 +@@ -1,5 +1,7 @@ + -*- text -*- + ++* Add support for the Andes NDS32. ++ + Changes in 2.24: + + * Objcopy now supports wildcard characters in command line options that take +diff -Nur binutils-2.24.orig/binutils/arlex.c binutils-2.24/binutils/arlex.c +--- binutils-2.24.orig/binutils/arlex.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/arlex.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2036 +0,0 @@ +- +-#line 3 "arlex.c" +- +-#define YY_INT_ALIGNED short int +- +-/* A lexical scanner generated by flex */ +- +-#define FLEX_SCANNER +-#define YY_FLEX_MAJOR_VERSION 2 +-#define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 35 +-#if YY_FLEX_SUBMINOR_VERSION > 0 +-#define FLEX_BETA +-#endif +- +-/* First, we deal with platform-specific or compiler-specific issues. */ +- +-/* begin standard C headers. */ +-#include +-#include +-#include +-#include +- +-/* end standard C headers. */ +- +-/* flex integer type definitions */ +- +-#ifndef FLEXINT_H +-#define FLEXINT_H +- +-/* C99 systems have . Non-C99 systems may or may not. */ +- +-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +- +-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, +- * if you want the limit (max/min) macros for int types. +- */ +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS 1 +-#endif +- +-#include +-typedef int8_t flex_int8_t; +-typedef uint8_t flex_uint8_t; +-typedef int16_t flex_int16_t; +-typedef uint16_t flex_uint16_t; +-typedef int32_t flex_int32_t; +-typedef uint32_t flex_uint32_t; +-typedef uint64_t flex_uint64_t; +-#else +-typedef signed char flex_int8_t; +-typedef short int flex_int16_t; +-typedef int flex_int32_t; +-typedef unsigned char flex_uint8_t; +-typedef unsigned short int flex_uint16_t; +-typedef unsigned int flex_uint32_t; +-#endif /* ! C99 */ +- +-/* Limits of integral types. */ +-#ifndef INT8_MIN +-#define INT8_MIN (-128) +-#endif +-#ifndef INT16_MIN +-#define INT16_MIN (-32767-1) +-#endif +-#ifndef INT32_MIN +-#define INT32_MIN (-2147483647-1) +-#endif +-#ifndef INT8_MAX +-#define INT8_MAX (127) +-#endif +-#ifndef INT16_MAX +-#define INT16_MAX (32767) +-#endif +-#ifndef INT32_MAX +-#define INT32_MAX (2147483647) +-#endif +-#ifndef UINT8_MAX +-#define UINT8_MAX (255U) +-#endif +-#ifndef UINT16_MAX +-#define UINT16_MAX (65535U) +-#endif +-#ifndef UINT32_MAX +-#define UINT32_MAX (4294967295U) +-#endif +- +-#endif /* ! FLEXINT_H */ +- +-#ifdef __cplusplus +- +-/* The "const" storage-class-modifier is valid. */ +-#define YY_USE_CONST +- +-#else /* ! __cplusplus */ +- +-/* C99 requires __STDC__ to be defined as 1. */ +-#if defined (__STDC__) +- +-#define YY_USE_CONST +- +-#endif /* defined (__STDC__) */ +-#endif /* ! __cplusplus */ +- +-#ifdef YY_USE_CONST +-#define yyconst const +-#else +-#define yyconst +-#endif +- +-/* Returned upon end-of-file. */ +-#define YY_NULL 0 +- +-/* Promotes a possibly negative, possibly signed char to an unsigned +- * integer for use as an array index. If the signed char is negative, +- * we want to instead treat it as an 8-bit unsigned char, hence the +- * double cast. +- */ +-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +- +-/* Enter a start condition. This macro really ought to take a parameter, +- * but we do it the disgusting crufty way forced on us by the ()-less +- * definition of BEGIN. +- */ +-#define BEGIN (yy_start) = 1 + 2 * +- +-/* Translate the current start state into a value that can be later handed +- * to BEGIN to return to the state. The YYSTATE alias is for lex +- * compatibility. +- */ +-#define YY_START (((yy_start) - 1) / 2) +-#define YYSTATE YY_START +- +-/* Action number for EOF rule of a given start state. */ +-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +- +-/* Special action meaning "start processing a new file". */ +-#define YY_NEW_FILE yyrestart(yyin ) +- +-#define YY_END_OF_BUFFER_CHAR 0 +- +-/* Size of default input buffer. */ +-#ifndef YY_BUF_SIZE +-#define YY_BUF_SIZE 16384 +-#endif +- +-/* The state buf must be large enough to hold one state per character in the main buffer. +- */ +-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) +- +-#ifndef YY_TYPEDEF_YY_BUFFER_STATE +-#define YY_TYPEDEF_YY_BUFFER_STATE +-typedef struct yy_buffer_state *YY_BUFFER_STATE; +-#endif +- +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-extern yy_size_t yyleng; +- +-extern FILE *yyin, *yyout; +- +-#define EOB_ACT_CONTINUE_SCAN 0 +-#define EOB_ACT_END_OF_FILE 1 +-#define EOB_ACT_LAST_MATCH 2 +- +- #define YY_LESS_LINENO(n) +- +-/* Return all but the first "n" matched characters back to the input stream. */ +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up yytext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- *yy_cp = (yy_hold_char); \ +- YY_RESTORE_YY_MORE_OFFSET \ +- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ +- YY_DO_BEFORE_ACTION; /* set up yytext again */ \ +- } \ +- while ( 0 ) +- +-#define unput(c) yyunput( c, (yytext_ptr) ) +- +-#ifndef YY_STRUCT_YY_BUFFER_STATE +-#define YY_STRUCT_YY_BUFFER_STATE +-struct yy_buffer_state +- { +- FILE *yy_input_file; +- +- char *yy_ch_buf; /* input buffer */ +- char *yy_buf_pos; /* current position in input buffer */ +- +- /* Size of input buffer in bytes, not including room for EOB +- * characters. +- */ +- yy_size_t yy_buf_size; +- +- /* Number of characters read into yy_ch_buf, not including EOB +- * characters. +- */ +- yy_size_t yy_n_chars; +- +- /* Whether we "own" the buffer - i.e., we know we created it, +- * and can realloc() it to grow it, and should free() it to +- * delete it. +- */ +- int yy_is_our_buffer; +- +- /* Whether this is an "interactive" input source; if so, and +- * if we're using stdio for input, then we want to use getc() +- * instead of fread(), to make sure we stop fetching input after +- * each newline. +- */ +- int yy_is_interactive; +- +- /* Whether we're considered to be at the beginning of a line. +- * If so, '^' rules will be active on the next match, otherwise +- * not. +- */ +- int yy_at_bol; +- +- int yy_bs_lineno; /**< The line count. */ +- int yy_bs_column; /**< The column count. */ +- +- /* Whether to try to fill the input buffer when we reach the +- * end of it. +- */ +- int yy_fill_buffer; +- +- int yy_buffer_status; +- +-#define YY_BUFFER_NEW 0 +-#define YY_BUFFER_NORMAL 1 +- /* When an EOF's been seen but there's still some text to process +- * then we mark the buffer as YY_EOF_PENDING, to indicate that we +- * shouldn't try reading from the input source any more. We might +- * still have a bunch of tokens to match, though, because of +- * possible backing-up. +- * +- * When we actually see the EOF, we change the status to "new" +- * (via yyrestart()), so that the user can continue scanning by +- * just pointing yyin at a new input file. +- */ +-#define YY_BUFFER_EOF_PENDING 2 +- +- }; +-#endif /* !YY_STRUCT_YY_BUFFER_STATE */ +- +-/* Stack of input buffers. */ +-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +- +-/* We provide macros for accessing buffer states in case in the +- * future we want to put the buffer states in a more general +- * "scanner state". +- * +- * Returns the top of the stack, or NULL. +- */ +-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ +- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ +- : NULL) +- +-/* Same as previous macro, but useful when we know that the buffer stack is not +- * NULL or when we need an lvalue. For internal use only. +- */ +-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] +- +-/* yy_hold_char holds the character lost when yytext is formed. */ +-static char yy_hold_char; +-static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +-yy_size_t yyleng; +- +-/* Points to current character in buffer. */ +-static char *yy_c_buf_p = (char *) 0; +-static int yy_init = 0; /* whether we need to initialize */ +-static int yy_start = 0; /* start state number */ +- +-/* Flag which is used to allow yywrap()'s to do buffer switches +- * instead of setting up a fresh yyin. A bit of a hack ... +- */ +-static int yy_did_buffer_switch_on_eof; +- +-void yyrestart (FILE *input_file ); +-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +-void yy_delete_buffer (YY_BUFFER_STATE b ); +-void yy_flush_buffer (YY_BUFFER_STATE b ); +-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +-void yypop_buffer_state (void ); +- +-static void yyensure_buffer_stack (void ); +-static void yy_load_buffer_state (void ); +-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); +- +-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) +- +-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); +- +-void *yyalloc (yy_size_t ); +-void *yyrealloc (void *,yy_size_t ); +-void yyfree (void * ); +- +-#define yy_new_buffer yy_create_buffer +- +-#define yy_set_interactive(is_interactive) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){ \ +- yyensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- yy_create_buffer(yyin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ +- } +- +-#define yy_set_bol(at_bol) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){\ +- yyensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- yy_create_buffer(yyin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ +- } +- +-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) +- +-/* Begin user sect3 */ +- +-typedef unsigned char YY_CHAR; +- +-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +- +-typedef int yy_state_type; +- +-extern int yylineno; +- +-int yylineno = 1; +- +-extern char *yytext; +-#define yytext_ptr yytext +- +-static yy_state_type yy_get_previous_state (void ); +-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +-static int yy_get_next_buffer (void ); +-static void yy_fatal_error (yyconst char msg[] ); +- +-/* Done after the current pattern has been matched and before the +- * corresponding action - sets up yytext. +- */ +-#define YY_DO_BEFORE_ACTION \ +- (yytext_ptr) = yy_bp; \ +- yyleng = (yy_size_t) (yy_cp - yy_bp); \ +- (yy_hold_char) = *yy_cp; \ +- *yy_cp = '\0'; \ +- (yy_c_buf_p) = yy_cp; +- +-#define YY_NUM_RULES 40 +-#define YY_END_OF_BUFFER 41 +-/* This struct is not used in this scanner, +- but its presence is necessary. */ +-struct yy_trans_info +- { +- flex_int32_t yy_verify; +- flex_int32_t yy_nxt; +- }; +-static yyconst flex_int16_t yy_accept[177] = +- { 0, +- 0, 0, 41, 40, 39, 38, 35, 32, 33, 36, +- 40, 34, 37, 35, 35, 35, 35, 35, 35, 35, +- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +- 35, 35, 35, 35, 35, 35, 36, 31, 37, 35, +- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +- 35, 35, 7, 35, 35, 35, 35, 35, 35, 35, +- 35, 35, 35, 35, 35, 35, 22, 35, 35, 35, +- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +- +- 35, 35, 35, 10, 11, 12, 35, 15, 35, 35, +- 35, 35, 35, 35, 35, 35, 35, 25, 26, 27, +- 35, 30, 35, 35, 35, 3, 35, 35, 35, 35, +- 35, 35, 35, 35, 35, 18, 35, 35, 35, 35, +- 35, 35, 35, 1, 2, 4, 5, 35, 35, 35, +- 35, 35, 16, 17, 19, 20, 35, 35, 35, 35, +- 35, 35, 8, 9, 13, 14, 35, 23, 24, 28, +- 29, 35, 35, 6, 21, 0 +- } ; +- +-static yyconst flex_int32_t yy_ec[256] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 3, 1, 1, 1, 4, 1, 1, 1, 5, +- 6, 7, 8, 9, 4, 4, 4, 4, 4, 4, +- 4, 4, 4, 4, 4, 4, 4, 4, 10, 1, +- 1, 1, 1, 1, 11, 12, 13, 14, 15, 16, +- 4, 17, 18, 4, 4, 19, 20, 21, 22, 23, +- 4, 24, 25, 26, 27, 28, 4, 29, 30, 4, +- 1, 4, 1, 1, 4, 1, 31, 32, 33, 34, +- +- 35, 36, 4, 37, 38, 4, 4, 39, 40, 41, +- 42, 43, 4, 44, 45, 46, 47, 48, 4, 49, +- 50, 4, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1 +- } ; +- +-static yyconst flex_int32_t yy_meta[51] = +- { 0, +- 1, 2, 1, 3, 1, 1, 1, 1, 1, 1, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +- } ; +- +-static yyconst flex_int16_t yy_base[180] = +- { 0, +- 0, 0, 193, 194, 194, 194, 0, 194, 194, 0, +- 190, 194, 0, 177, 32, 37, 32, 163, 174, 170, +- 164, 171, 174, 169, 149, 15, 22, 17, 135, 146, +- 142, 136, 143, 146, 141, 0, 0, 194, 0, 161, +- 159, 158, 153, 147, 156, 143, 149, 148, 141, 150, +- 141, 135, 138, 127, 125, 124, 119, 113, 122, 109, +- 115, 114, 107, 116, 107, 101, 104, 43, 136, 135, +- 130, 129, 0, 119, 123, 118, 114, 118, 119, 122, +- 124, 25, 104, 103, 98, 97, 0, 87, 91, 86, +- 82, 86, 87, 90, 92, 105, 100, 97, 94, 93, +- +- 105, 106, 102, 0, 0, 0, 104, 0, 92, 75, +- 70, 67, 64, 63, 75, 76, 72, 0, 0, 0, +- 74, 0, 62, 91, 88, 0, 86, 85, 73, 85, +- 79, 83, 70, 62, 59, 0, 57, 56, 44, 56, +- 50, 54, 41, 0, 0, 0, 0, 63, 58, 59, +- 67, 66, 0, 0, 0, 0, 38, 33, 34, 42, +- 41, 51, 0, 0, 0, 0, 30, 0, 0, 0, +- 0, 43, 21, 0, 0, 194, 65, 66, 69 +- } ; +- +-static yyconst flex_int16_t yy_def[180] = +- { 0, +- 176, 1, 176, 176, 176, 176, 177, 176, 176, 178, +- 176, 176, 179, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 178, 176, 179, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, +- 177, 177, 177, 177, 177, 0, 176, 176, 176 +- } ; +- +-static yyconst flex_int16_t yy_nxt[245] = +- { 0, +- 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, +- 14, 7, 15, 16, 17, 18, 19, 7, 20, 7, +- 7, 21, 7, 22, 23, 7, 7, 24, 7, 7, +- 25, 7, 26, 27, 28, 29, 30, 7, 31, 7, +- 7, 32, 7, 33, 34, 7, 7, 35, 7, 7, +- 41, 43, 45, 55, 44, 42, 57, 59, 56, 58, +- 46, 96, 97, 110, 111, 60, 37, 36, 37, 39, +- 175, 39, 174, 173, 172, 171, 170, 169, 168, 167, +- 166, 165, 164, 163, 162, 161, 160, 159, 158, 157, +- 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, +- +- 146, 145, 144, 143, 142, 141, 140, 139, 138, 137, +- 136, 135, 134, 133, 132, 131, 130, 129, 128, 127, +- 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, +- 116, 115, 114, 113, 112, 109, 108, 107, 106, 105, +- 104, 103, 102, 101, 100, 99, 98, 95, 94, 93, +- 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, +- 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, +- 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, +- 62, 61, 54, 53, 52, 51, 50, 49, 48, 47, +- 40, 38, 176, 3, 176, 176, 176, 176, 176, 176, +- +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176 +- } ; +- +-static yyconst flex_int16_t yy_chk[245] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 15, 16, 17, 26, 16, 15, 27, 28, 26, 27, +- 17, 68, 68, 82, 82, 28, 178, 177, 178, 179, +- 173, 179, 172, 167, 162, 161, 160, 159, 158, 157, +- 152, 151, 150, 149, 148, 143, 142, 141, 140, 139, +- 138, 137, 135, 134, 133, 132, 131, 130, 129, 128, +- +- 127, 125, 124, 123, 121, 117, 116, 115, 114, 113, +- 112, 111, 110, 109, 107, 103, 102, 101, 100, 99, +- 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, +- 88, 86, 85, 84, 83, 81, 80, 79, 78, 77, +- 76, 75, 74, 72, 71, 70, 69, 67, 66, 65, +- 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, +- 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, +- 44, 43, 42, 41, 40, 35, 34, 33, 32, 31, +- 30, 29, 25, 24, 23, 22, 21, 20, 19, 18, +- 14, 11, 3, 176, 176, 176, 176, 176, 176, 176, +- +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, +- 176, 176, 176, 176 +- } ; +- +-static yy_state_type yy_last_accepting_state; +-static char *yy_last_accepting_cpos; +- +-extern int yy_flex_debug; +-int yy_flex_debug = 0; +- +-/* The intent behind this definition is that it'll catch +- * any uses of REJECT which flex missed. +- */ +-#define REJECT reject_used_but_not_detected +-#define yymore() yymore_used_but_not_detected +-#define YY_MORE_ADJ 0 +-#define YY_RESTORE_YY_MORE_OFFSET +-char *yytext; +-#line 1 "arlex.l" +-#define YY_NO_INPUT 1 +-#line 4 "arlex.l" +-/* arlex.l - Strange script language lexer */ +- +-/* Copyright 1992, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2011 +- Free Software Foundation, Inc. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +- +-/* Contributed by Steve Chamberlain . */ +- +-#define DONTDECLARE_MALLOC +-#include "ansidecl.h" +-#include "libiberty.h" +-#include "arparse.h" +- +-#ifndef YY_NO_UNPUT +-#define YY_NO_UNPUT +-#endif +- +-extern int yylex (void); +- +-int linenumber; +-#line 599 "arlex.c" +- +-#define INITIAL 0 +- +-#ifndef YY_NO_UNISTD_H +-/* Special case for "unistd.h", since it is non-ANSI. We include it way +- * down here because we want the user's section 1 to have been scanned first. +- * The user has a chance to override it with an option. +- */ +-#include +-#endif +- +-#ifndef YY_EXTRA_TYPE +-#define YY_EXTRA_TYPE void * +-#endif +- +-static int yy_init_globals (void ); +- +-/* Accessor methods to globals. +- These are made visible to non-reentrant scanners for convenience. */ +- +-int yylex_destroy (void ); +- +-int yyget_debug (void ); +- +-void yyset_debug (int debug_flag ); +- +-YY_EXTRA_TYPE yyget_extra (void ); +- +-void yyset_extra (YY_EXTRA_TYPE user_defined ); +- +-FILE *yyget_in (void ); +- +-void yyset_in (FILE * in_str ); +- +-FILE *yyget_out (void ); +- +-void yyset_out (FILE * out_str ); +- +-yy_size_t yyget_leng (void ); +- +-char *yyget_text (void ); +- +-int yyget_lineno (void ); +- +-void yyset_lineno (int line_number ); +- +-/* Macros after this point can all be overridden by user definitions in +- * section 1. +- */ +- +-#ifndef YY_SKIP_YYWRAP +-#ifdef __cplusplus +-extern "C" int yywrap (void ); +-#else +-extern int yywrap (void ); +-#endif +-#endif +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char *,yyconst char *,int ); +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * ); +-#endif +- +-#ifndef YY_NO_INPUT +- +-#ifdef __cplusplus +-static int yyinput (void ); +-#else +-static int input (void ); +-#endif +- +-#endif +- +-/* Amount of stuff to slurp up with each read. */ +-#ifndef YY_READ_BUF_SIZE +-#define YY_READ_BUF_SIZE 8192 +-#endif +- +-/* Copy whatever the last rule matched to the standard output. */ +-#ifndef ECHO +-/* This used to be an fputs(), but since the string might contain NUL's, +- * we now use fwrite(). +- */ +-#define ECHO fwrite( yytext, yyleng, 1, yyout ) +-#endif +- +-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, +- * is returned in "result". +- */ +-#ifndef YY_INPUT +-#define YY_INPUT(buf,result,max_size) \ +- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ +- { \ +- int c = '*'; \ +- yy_size_t n; \ +- for ( n = 0; n < max_size && \ +- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ +- buf[n] = (char) c; \ +- if ( c == '\n' ) \ +- buf[n++] = (char) c; \ +- if ( c == EOF && ferror( yyin ) ) \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- result = n; \ +- } \ +- else \ +- { \ +- errno=0; \ +- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ +- { \ +- if( errno != EINTR) \ +- { \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- break; \ +- } \ +- errno=0; \ +- clearerr(yyin); \ +- } \ +- }\ +-\ +- +-#endif +- +-/* No semi-colon after return; correct usage is to write "yyterminate();" - +- * we don't want an extra ';' after the "return" because that will cause +- * some compilers to complain about unreachable statements. +- */ +-#ifndef yyterminate +-#define yyterminate() return YY_NULL +-#endif +- +-/* Number of entries by which start-condition stack grows. */ +-#ifndef YY_START_STACK_INCR +-#define YY_START_STACK_INCR 25 +-#endif +- +-/* Report a fatal error. */ +-#ifndef YY_FATAL_ERROR +-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +-#endif +- +-/* end tables serialization structures and prototypes */ +- +-/* Default declaration of generated scanner - a define so the user can +- * easily add parameters. +- */ +-#ifndef YY_DECL +-#define YY_DECL_IS_OURS 1 +- +-extern int yylex (void); +- +-#define YY_DECL int yylex (void) +-#endif /* !YY_DECL */ +- +-/* Code executed at the beginning of each rule, after yytext and yyleng +- * have been set up. +- */ +-#ifndef YY_USER_ACTION +-#define YY_USER_ACTION +-#endif +- +-/* Code executed at the end of each rule. */ +-#ifndef YY_BREAK +-#define YY_BREAK break; +-#endif +- +-#define YY_RULE_SETUP \ +- YY_USER_ACTION +- +-/** The main scanner function which does all the work. +- */ +-YY_DECL +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp, *yy_bp; +- register int yy_act; +- +-#line 46 "arlex.l" +- +- +-#line 782 "arlex.c" +- +- if ( !(yy_init) ) +- { +- (yy_init) = 1; +- +-#ifdef YY_USER_INIT +- YY_USER_INIT; +-#endif +- +- if ( ! (yy_start) ) +- (yy_start) = 1; /* first start state */ +- +- if ( ! yyin ) +- yyin = stdin; +- +- if ( ! yyout ) +- yyout = stdout; +- +- if ( ! YY_CURRENT_BUFFER ) { +- yyensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- yy_create_buffer(yyin,YY_BUF_SIZE ); +- } +- +- yy_load_buffer_state( ); +- } +- +- while ( 1 ) /* loops until end-of-file is reached */ +- { +- yy_cp = (yy_c_buf_p); +- +- /* Support of yytext. */ +- *yy_cp = (yy_hold_char); +- +- /* yy_bp points to the position in yy_ch_buf of the start of +- * the current run. +- */ +- yy_bp = yy_cp; +- +- yy_current_state = (yy_start); +-yy_match: +- do +- { +- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 177 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- ++yy_cp; +- } +- while ( yy_base[yy_current_state] != 194 ); +- +-yy_find_action: +- yy_act = yy_accept[yy_current_state]; +- if ( yy_act == 0 ) +- { /* have to back up */ +- yy_cp = (yy_last_accepting_cpos); +- yy_current_state = (yy_last_accepting_state); +- yy_act = yy_accept[yy_current_state]; +- } +- +- YY_DO_BEFORE_ACTION; +- +-do_action: /* This label is used only to access EOF actions. */ +- +- switch ( yy_act ) +- { /* beginning of action switch */ +- case 0: /* must back up */ +- /* undo the effects of YY_DO_BEFORE_ACTION */ +- *yy_cp = (yy_hold_char); +- yy_cp = (yy_last_accepting_cpos); +- yy_current_state = (yy_last_accepting_state); +- goto yy_find_action; +- +-case 1: +-YY_RULE_SETUP +-#line 48 "arlex.l" +-{ return ADDLIB; } +- YY_BREAK +-case 2: +-YY_RULE_SETUP +-#line 49 "arlex.l" +-{ return ADDMOD; } +- YY_BREAK +-case 3: +-YY_RULE_SETUP +-#line 50 "arlex.l" +-{ return CLEAR; } +- YY_BREAK +-case 4: +-YY_RULE_SETUP +-#line 51 "arlex.l" +-{ return CREATE; } +- YY_BREAK +-case 5: +-YY_RULE_SETUP +-#line 52 "arlex.l" +-{ return DELETE; } +- YY_BREAK +-case 6: +-YY_RULE_SETUP +-#line 53 "arlex.l" +-{ return DIRECTORY; } +- YY_BREAK +-case 7: +-YY_RULE_SETUP +-#line 54 "arlex.l" +-{ return END; } +- YY_BREAK +-case 8: +-YY_RULE_SETUP +-#line 55 "arlex.l" +-{ return EXTRACT; } +- YY_BREAK +-case 9: +-YY_RULE_SETUP +-#line 56 "arlex.l" +-{ return FULLDIR; } +- YY_BREAK +-case 10: +-YY_RULE_SETUP +-#line 57 "arlex.l" +-{ return HELP; } +- YY_BREAK +-case 11: +-YY_RULE_SETUP +-#line 58 "arlex.l" +-{ return LIST; } +- YY_BREAK +-case 12: +-YY_RULE_SETUP +-#line 59 "arlex.l" +-{ return OPEN; } +- YY_BREAK +-case 13: +-YY_RULE_SETUP +-#line 60 "arlex.l" +-{ return REPLACE; } +- YY_BREAK +-case 14: +-YY_RULE_SETUP +-#line 61 "arlex.l" +-{ return VERBOSE; } +- YY_BREAK +-case 15: +-YY_RULE_SETUP +-#line 62 "arlex.l" +-{ return SAVE; } +- YY_BREAK +-case 16: +-YY_RULE_SETUP +-#line 63 "arlex.l" +-{ return ADDLIB; } +- YY_BREAK +-case 17: +-YY_RULE_SETUP +-#line 64 "arlex.l" +-{ return ADDMOD; } +- YY_BREAK +-case 18: +-YY_RULE_SETUP +-#line 65 "arlex.l" +-{ return CLEAR; } +- YY_BREAK +-case 19: +-YY_RULE_SETUP +-#line 66 "arlex.l" +-{ return CREATE; } +- YY_BREAK +-case 20: +-YY_RULE_SETUP +-#line 67 "arlex.l" +-{ return DELETE; } +- YY_BREAK +-case 21: +-YY_RULE_SETUP +-#line 68 "arlex.l" +-{ return DIRECTORY; } +- YY_BREAK +-case 22: +-YY_RULE_SETUP +-#line 69 "arlex.l" +-{ return END; } +- YY_BREAK +-case 23: +-YY_RULE_SETUP +-#line 70 "arlex.l" +-{ return EXTRACT; } +- YY_BREAK +-case 24: +-YY_RULE_SETUP +-#line 71 "arlex.l" +-{ return FULLDIR; } +- YY_BREAK +-case 25: +-YY_RULE_SETUP +-#line 72 "arlex.l" +-{ return HELP; } +- YY_BREAK +-case 26: +-YY_RULE_SETUP +-#line 73 "arlex.l" +-{ return LIST; } +- YY_BREAK +-case 27: +-YY_RULE_SETUP +-#line 74 "arlex.l" +-{ return OPEN; } +- YY_BREAK +-case 28: +-YY_RULE_SETUP +-#line 75 "arlex.l" +-{ return REPLACE; } +- YY_BREAK +-case 29: +-YY_RULE_SETUP +-#line 76 "arlex.l" +-{ return VERBOSE; } +- YY_BREAK +-case 30: +-YY_RULE_SETUP +-#line 77 "arlex.l" +-{ return SAVE; } +- YY_BREAK +-case 31: +-/* rule 31 can match eol */ +-YY_RULE_SETUP +-#line 78 "arlex.l" +-{ linenumber ++; } +- YY_BREAK +-case 32: +-YY_RULE_SETUP +-#line 79 "arlex.l" +-{ return '('; } +- YY_BREAK +-case 33: +-YY_RULE_SETUP +-#line 80 "arlex.l" +-{ return ')'; } +- YY_BREAK +-case 34: +-YY_RULE_SETUP +-#line 81 "arlex.l" +-{ return ','; } +- YY_BREAK +-case 35: +-YY_RULE_SETUP +-#line 82 "arlex.l" +-{ +- yylval.name = xstrdup (yytext); +- return FILENAME; +- } +- YY_BREAK +-case 36: +-YY_RULE_SETUP +-#line 86 "arlex.l" +-{ } +- YY_BREAK +-case 37: +-YY_RULE_SETUP +-#line 87 "arlex.l" +-{ } +- YY_BREAK +-case 38: +-YY_RULE_SETUP +-#line 88 "arlex.l" +-{ } +- YY_BREAK +-case 39: +-/* rule 39 can match eol */ +-YY_RULE_SETUP +-#line 89 "arlex.l" +-{ linenumber ++; return NEWLINE; } +- YY_BREAK +-case 40: +-YY_RULE_SETUP +-#line 91 "arlex.l" +-ECHO; +- YY_BREAK +-#line 1070 "arlex.c" +-case YY_STATE_EOF(INITIAL): +- yyterminate(); +- +- case YY_END_OF_BUFFER: +- { +- /* Amount of text matched not including the EOB char. */ +- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; +- +- /* Undo the effects of YY_DO_BEFORE_ACTION. */ +- *yy_cp = (yy_hold_char); +- YY_RESTORE_YY_MORE_OFFSET +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) +- { +- /* We're scanning a new file or input source. It's +- * possible that this happened because the user +- * just pointed yyin at a new source and called +- * yylex(). If so, then we have to assure +- * consistency between YY_CURRENT_BUFFER and our +- * globals. Here is the right place to do so, because +- * this is the first action (other than possibly a +- * back-up) that will match for the new input source. +- */ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; +- } +- +- /* Note that here we test for yy_c_buf_p "<=" to the position +- * of the first EOB in the buffer, since yy_c_buf_p will +- * already have been incremented past the NUL character +- * (since all states make transitions on EOB to the +- * end-of-buffer state). Contrast this with the test +- * in input(). +- */ +- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- { /* This was really a NUL. */ +- yy_state_type yy_next_state; +- +- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- /* Okay, we're now positioned to make the NUL +- * transition. We couldn't have +- * yy_get_previous_state() go ahead and do it +- * for us because it doesn't know how to deal +- * with the possibility of jamming (and we don't +- * want to build jamming into it because then it +- * will run more slowly). +- */ +- +- yy_next_state = yy_try_NUL_trans( yy_current_state ); +- +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- +- if ( yy_next_state ) +- { +- /* Consume the NUL. */ +- yy_cp = ++(yy_c_buf_p); +- yy_current_state = yy_next_state; +- goto yy_match; +- } +- +- else +- { +- yy_cp = (yy_c_buf_p); +- goto yy_find_action; +- } +- } +- +- else switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_END_OF_FILE: +- { +- (yy_did_buffer_switch_on_eof) = 0; +- +- if ( yywrap( ) ) +- { +- /* Note: because we've taken care in +- * yy_get_next_buffer() to have set up +- * yytext, we can now set up +- * yy_c_buf_p so that if some total +- * hoser (like flex itself) wants to +- * call the scanner after we return the +- * YY_NULL, it'll still work - another +- * YY_NULL will get returned. +- */ +- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; +- +- yy_act = YY_STATE_EOF(YY_START); +- goto do_action; +- } +- +- else +- { +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +- } +- break; +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = +- (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_match; +- +- case EOB_ACT_LAST_MATCH: +- (yy_c_buf_p) = +- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_find_action; +- } +- break; +- } +- +- default: +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--no action found" ); +- } /* end of action switch */ +- } /* end of scanning one token */ +-} /* end of yylex */ +- +-/* yy_get_next_buffer - try to read in a new buffer +- * +- * Returns a code representing an action: +- * EOB_ACT_LAST_MATCH - +- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position +- * EOB_ACT_END_OF_FILE - end of file +- */ +-static int yy_get_next_buffer (void) +-{ +- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; +- register char *source = (yytext_ptr); +- register int number_to_move, i; +- int ret_val; +- +- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--end of buffer missed" ); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) +- { /* Don't try to fill the buffer, so this is an EOF. */ +- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) +- { +- /* We matched a single character, the EOB, so +- * treat this as a final EOF. +- */ +- return EOB_ACT_END_OF_FILE; +- } +- +- else +- { +- /* We matched some text prior to the EOB, first +- * process it. +- */ +- return EOB_ACT_LAST_MATCH; +- } +- } +- +- /* Try to read more data. */ +- +- /* First move last chars to start of buffer. */ +- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; +- +- for ( i = 0; i < number_to_move; ++i ) +- *(dest++) = *(source++); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) +- /* don't do the read, it's not guaranteed to return an EOF, +- * just force an EOF +- */ +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; +- +- else +- { +- yy_size_t num_to_read = +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; +- +- while ( num_to_read <= 0 ) +- { /* Not enough room in the buffer - grow it. */ +- +- /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; +- +- int yy_c_buf_p_offset = +- (int) ((yy_c_buf_p) - b->yy_ch_buf); +- +- if ( b->yy_is_our_buffer ) +- { +- yy_size_t new_size = b->yy_buf_size * 2; +- +- if ( new_size <= 0 ) +- b->yy_buf_size += b->yy_buf_size / 8; +- else +- b->yy_buf_size *= 2; +- +- b->yy_ch_buf = (char *) +- /* Include room in for 2 EOB chars. */ +- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); +- } +- else +- /* Can't grow it, we don't own it. */ +- b->yy_ch_buf = 0; +- +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( +- "fatal error - scanner input buffer overflow" ); +- +- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; +- +- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - +- number_to_move - 1; +- +- } +- +- if ( num_to_read > YY_READ_BUF_SIZE ) +- num_to_read = YY_READ_BUF_SIZE; +- +- /* Read in more data. */ +- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), num_to_read ); +- +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- if ( (yy_n_chars) == 0 ) +- { +- if ( number_to_move == YY_MORE_ADJ ) +- { +- ret_val = EOB_ACT_END_OF_FILE; +- yyrestart(yyin ); +- } +- +- else +- { +- ret_val = EOB_ACT_LAST_MATCH; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = +- YY_BUFFER_EOF_PENDING; +- } +- } +- +- else +- ret_val = EOB_ACT_CONTINUE_SCAN; +- +- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { +- /* Extend the array by 50%, plus the number we really need. */ +- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); +- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); +- } +- +- (yy_n_chars) += number_to_move; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; +- +- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; +- +- return ret_val; +-} +- +-/* yy_get_previous_state - get the state just before the EOB char was reached */ +- +- static yy_state_type yy_get_previous_state (void) +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp; +- +- yy_current_state = (yy_start); +- +- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) +- { +- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 177 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- } +- +- return yy_current_state; +-} +- +-/* yy_try_NUL_trans - try to make a transition on the NUL character +- * +- * synopsis +- * next_state = yy_try_NUL_trans( current_state ); +- */ +- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +-{ +- register int yy_is_jam; +- register char *yy_cp = (yy_c_buf_p); +- +- register YY_CHAR yy_c = 1; +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 177 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 176); +- +- return yy_is_jam ? 0 : yy_current_state; +-} +- +-#ifndef YY_NO_INPUT +-#ifdef __cplusplus +- static int yyinput (void) +-#else +- static int input (void) +-#endif +- +-{ +- int c; +- +- *(yy_c_buf_p) = (yy_hold_char); +- +- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) +- { +- /* yy_c_buf_p now points to the character we want to return. +- * If this occurs *before* the EOB characters, then it's a +- * valid NUL; if not, then we've hit the end of the buffer. +- */ +- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- /* This was really a NUL. */ +- *(yy_c_buf_p) = '\0'; +- +- else +- { /* need more input */ +- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); +- ++(yy_c_buf_p); +- +- switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_LAST_MATCH: +- /* This happens because yy_g_n_b() +- * sees that we've accumulated a +- * token and flags that we need to +- * try matching the token before +- * proceeding. But for input(), +- * there's no matching to consider. +- * So convert the EOB_ACT_LAST_MATCH +- * to EOB_ACT_END_OF_FILE. +- */ +- +- /* Reset buffer status. */ +- yyrestart(yyin ); +- +- /*FALLTHROUGH*/ +- +- case EOB_ACT_END_OF_FILE: +- { +- if ( yywrap( ) ) +- return 0; +- +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +-#ifdef __cplusplus +- return yyinput(); +-#else +- return input(); +-#endif +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = (yytext_ptr) + offset; +- break; +- } +- } +- } +- +- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ +- *(yy_c_buf_p) = '\0'; /* preserve yytext */ +- (yy_hold_char) = *++(yy_c_buf_p); +- +- return c; +-} +-#endif /* ifndef YY_NO_INPUT */ +- +-/** Immediately switch to a different input stream. +- * @param input_file A readable stream. +- * +- * @note This function does not reset the start condition to @c INITIAL . +- */ +- void yyrestart (FILE * input_file ) +-{ +- +- if ( ! YY_CURRENT_BUFFER ){ +- yyensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- yy_create_buffer(yyin,YY_BUF_SIZE ); +- } +- +- yy_init_buffer(YY_CURRENT_BUFFER,input_file ); +- yy_load_buffer_state( ); +-} +- +-/** Switch to a different input buffer. +- * @param new_buffer The new input buffer. +- * +- */ +- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +-{ +- +- /* TODO. We should be able to replace this entire function body +- * with +- * yypop_buffer_state(); +- * yypush_buffer_state(new_buffer); +- */ +- yyensure_buffer_stack (); +- if ( YY_CURRENT_BUFFER == new_buffer ) +- return; +- +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- yy_load_buffer_state( ); +- +- /* We don't actually know whether we did this switch during +- * EOF (yywrap()) processing, but the only time this flag +- * is looked at is after yywrap() is called, so it's safe +- * to go ahead and always set it. +- */ +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-static void yy_load_buffer_state (void) +-{ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; +- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; +- (yy_hold_char) = *(yy_c_buf_p); +-} +- +-/** Allocate and initialize an input buffer state. +- * @param file A readable stream. +- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. +- * +- * @return the allocated buffer state. +- */ +- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +-{ +- YY_BUFFER_STATE b; +- +- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); +- +- b->yy_buf_size = size; +- +- /* yy_ch_buf has to be 2 characters longer than the size given because +- * we need to put in 2 end-of-buffer characters. +- */ +- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); +- +- b->yy_is_our_buffer = 1; +- +- yy_init_buffer(b,file ); +- +- return b; +-} +- +-/** Destroy the buffer. +- * @param b a buffer created with yy_create_buffer() +- * +- */ +- void yy_delete_buffer (YY_BUFFER_STATE b ) +-{ +- +- if ( ! b ) +- return; +- +- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ +- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; +- +- if ( b->yy_is_our_buffer ) +- yyfree((void *) b->yy_ch_buf ); +- +- yyfree((void *) b ); +-} +- +-#ifndef __cplusplus +-extern int isatty (int ); +-#endif /* __cplusplus */ +- +-/* Initializes or reinitializes a buffer. +- * This function is sometimes called more than once on the same buffer, +- * such as during a yyrestart() or at EOF. +- */ +- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) +- +-{ +- int oerrno = errno; +- +- yy_flush_buffer(b ); +- +- b->yy_input_file = file; +- b->yy_fill_buffer = 1; +- +- /* If b is the current buffer, then yy_init_buffer was _probably_ +- * called from yyrestart() or through yy_get_next_buffer. +- * In that case, we don't want to reset the lineno or column. +- */ +- if (b != YY_CURRENT_BUFFER){ +- b->yy_bs_lineno = 1; +- b->yy_bs_column = 0; +- } +- +- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +- +- errno = oerrno; +-} +- +-/** Discard all buffered characters. On the next scan, YY_INPUT will be called. +- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. +- * +- */ +- void yy_flush_buffer (YY_BUFFER_STATE b ) +-{ +- if ( ! b ) +- return; +- +- b->yy_n_chars = 0; +- +- /* We always need two end-of-buffer characters. The first causes +- * a transition to the end-of-buffer state. The second causes +- * a jam in that state. +- */ +- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; +- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; +- +- b->yy_buf_pos = &b->yy_ch_buf[0]; +- +- b->yy_at_bol = 1; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- if ( b == YY_CURRENT_BUFFER ) +- yy_load_buffer_state( ); +-} +- +-/** Pushes the new state onto the stack. The new state becomes +- * the current state. This function will allocate the stack +- * if necessary. +- * @param new_buffer The new state. +- * +- */ +-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +-{ +- if (new_buffer == NULL) +- return; +- +- yyensure_buffer_stack(); +- +- /* This block is copied from yy_switch_to_buffer. */ +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- /* Only push if top exists. Otherwise, replace top. */ +- if (YY_CURRENT_BUFFER) +- (yy_buffer_stack_top)++; +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- +- /* copied from yy_switch_to_buffer. */ +- yy_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-/** Removes and deletes the top of the stack, if present. +- * The next element becomes the new top. +- * +- */ +-void yypop_buffer_state (void) +-{ +- if (!YY_CURRENT_BUFFER) +- return; +- +- yy_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- if ((yy_buffer_stack_top) > 0) +- --(yy_buffer_stack_top); +- +- if (YY_CURRENT_BUFFER) { +- yy_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +- } +-} +- +-/* Allocates the stack if it does not exist. +- * Guarantees space for at least one push. +- */ +-static void yyensure_buffer_stack (void) +-{ +- yy_size_t num_to_alloc; +- +- if (!(yy_buffer_stack)) { +- +- /* First allocation is just for 2 elements, since we don't know if this +- * scanner will even need a stack. We use 2 instead of 1 to avoid an +- * immediate realloc on the next call. +- */ +- num_to_alloc = 1; +- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc +- (num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- +- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); +- +- (yy_buffer_stack_max) = num_to_alloc; +- (yy_buffer_stack_top) = 0; +- return; +- } +- +- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ +- +- /* Increase the buffer to prepare for a possible push. */ +- int grow_size = 8 /* arbitrary grow size */; +- +- num_to_alloc = (yy_buffer_stack_max) + grow_size; +- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc +- ((yy_buffer_stack), +- num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- +- /* zero only the new slots.*/ +- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); +- (yy_buffer_stack_max) = num_to_alloc; +- } +-} +- +-/** Setup the input buffer state to scan directly from a user-specified character buffer. +- * @param base the character buffer +- * @param size the size in bytes of the character buffer +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +-{ +- YY_BUFFER_STATE b; +- +- if ( size < 2 || +- base[size-2] != YY_END_OF_BUFFER_CHAR || +- base[size-1] != YY_END_OF_BUFFER_CHAR ) +- /* They forgot to leave room for the EOB's. */ +- return 0; +- +- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); +- +- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ +- b->yy_buf_pos = b->yy_ch_buf = base; +- b->yy_is_our_buffer = 0; +- b->yy_input_file = 0; +- b->yy_n_chars = b->yy_buf_size; +- b->yy_is_interactive = 0; +- b->yy_at_bol = 1; +- b->yy_fill_buffer = 0; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- yy_switch_to_buffer(b ); +- +- return b; +-} +- +-/** Setup the input buffer state to scan a string. The next call to yylex() will +- * scan from a @e copy of @a str. +- * @param yystr a NUL-terminated string to scan +- * +- * @return the newly allocated buffer state object. +- * @note If you want to scan bytes that may contain NUL values, then use +- * yy_scan_bytes() instead. +- */ +-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +-{ +- +- return yy_scan_bytes(yystr,strlen(yystr) ); +-} +- +-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will +- * scan from a @e copy of @a bytes. +- * @param bytes the byte buffer to scan +- * @param len the number of bytes in the buffer pointed to by @a bytes. +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +-{ +- YY_BUFFER_STATE b; +- char *buf; +- yy_size_t n, i; +- +- /* Get memory for full buffer, including space for trailing EOB's. */ +- n = _yybytes_len + 2; +- buf = (char *) yyalloc(n ); +- if ( ! buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); +- +- for ( i = 0; i < _yybytes_len; ++i ) +- buf[i] = yybytes[i]; +- +- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; +- +- b = yy_scan_buffer(buf,n ); +- if ( ! b ) +- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); +- +- /* It's okay to grow etc. this buffer, and we should throw it +- * away when we're done. +- */ +- b->yy_is_our_buffer = 1; +- +- return b; +-} +- +-#ifndef YY_EXIT_FAILURE +-#define YY_EXIT_FAILURE 2 +-#endif +- +-static void yy_fatal_error (yyconst char* msg ) +-{ +- (void) fprintf( stderr, "%s\n", msg ); +- exit( YY_EXIT_FAILURE ); +-} +- +-/* Redefine yyless() so it works in section 3 code. */ +- +-#undef yyless +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up yytext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- yytext[yyleng] = (yy_hold_char); \ +- (yy_c_buf_p) = yytext + yyless_macro_arg; \ +- (yy_hold_char) = *(yy_c_buf_p); \ +- *(yy_c_buf_p) = '\0'; \ +- yyleng = yyless_macro_arg; \ +- } \ +- while ( 0 ) +- +-/* Accessor methods (get/set functions) to struct members. */ +- +-/** Get the current line number. +- * +- */ +-int yyget_lineno (void) +-{ +- +- return yylineno; +-} +- +-/** Get the input stream. +- * +- */ +-FILE *yyget_in (void) +-{ +- return yyin; +-} +- +-/** Get the output stream. +- * +- */ +-FILE *yyget_out (void) +-{ +- return yyout; +-} +- +-/** Get the length of the current token. +- * +- */ +-yy_size_t yyget_leng (void) +-{ +- return yyleng; +-} +- +-/** Get the current token. +- * +- */ +- +-char *yyget_text (void) +-{ +- return yytext; +-} +- +-/** Set the current line number. +- * @param line_number +- * +- */ +-void yyset_lineno (int line_number ) +-{ +- +- yylineno = line_number; +-} +- +-/** Set the input stream. This does not discard the current +- * input buffer. +- * @param in_str A readable stream. +- * +- * @see yy_switch_to_buffer +- */ +-void yyset_in (FILE * in_str ) +-{ +- yyin = in_str ; +-} +- +-void yyset_out (FILE * out_str ) +-{ +- yyout = out_str ; +-} +- +-int yyget_debug (void) +-{ +- return yy_flex_debug; +-} +- +-void yyset_debug (int bdebug ) +-{ +- yy_flex_debug = bdebug ; +-} +- +-static int yy_init_globals (void) +-{ +- /* Initialization is the same as for the non-reentrant scanner. +- * This function is called from yylex_destroy(), so don't allocate here. +- */ +- +- (yy_buffer_stack) = 0; +- (yy_buffer_stack_top) = 0; +- (yy_buffer_stack_max) = 0; +- (yy_c_buf_p) = (char *) 0; +- (yy_init) = 0; +- (yy_start) = 0; +- +-/* Defined in main.c */ +-#ifdef YY_STDINIT +- yyin = stdin; +- yyout = stdout; +-#else +- yyin = (FILE *) 0; +- yyout = (FILE *) 0; +-#endif +- +- /* For future reference: Set errno on error, since we are called by +- * yylex_init() +- */ +- return 0; +-} +- +-/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +-int yylex_destroy (void) +-{ +- +- /* Pop the buffer stack, destroying each element. */ +- while(YY_CURRENT_BUFFER){ +- yy_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- yypop_buffer_state(); +- } +- +- /* Destroy the stack itself. */ +- yyfree((yy_buffer_stack) ); +- (yy_buffer_stack) = NULL; +- +- /* Reset the globals. This is important in a non-reentrant scanner so the next time +- * yylex() is called, initialization will occur. */ +- yy_init_globals( ); +- +- return 0; +-} +- +-/* +- * Internal utility routines. +- */ +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +-{ +- register int i; +- for ( i = 0; i < n; ++i ) +- s1[i] = s2[i]; +-} +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * s ) +-{ +- register int n; +- for ( n = 0; s[n]; ++n ) +- ; +- +- return n; +-} +-#endif +- +-void *yyalloc (yy_size_t size ) +-{ +- return (void *) malloc( size ); +-} +- +-void *yyrealloc (void * ptr, yy_size_t size ) +-{ +- /* The cast to (char *) in the following accommodates both +- * implementations that use char* generic pointers, and those +- * that use void* generic pointers. It works with the latter +- * because both ANSI C and C++ allow castless assignment from +- * any pointer type to void*, and deal with argument conversions +- * as though doing an assignment. +- */ +- return (void *) realloc( (char *) ptr, size ); +-} +- +-void yyfree (void * ptr ) +-{ +- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +-} +- +-#define YYTABLES_NAME "yytables" +- +-#line 91 "arlex.l" +- +- +-#ifndef yywrap +-/* Needed for lex, though not flex. */ +-int yywrap(void) { return 1; } +-#endif +- +diff -Nur binutils-2.24.orig/binutils/arparse.c binutils-2.24/binutils/arparse.c +--- binutils-2.24.orig/binutils/arparse.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/arparse.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1770 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton implementation for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "2.3" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Using locations. */ +-#define YYLSP_NEEDED 0 +- +- +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- NEWLINE = 258, +- VERBOSE = 259, +- FILENAME = 260, +- ADDLIB = 261, +- LIST = 262, +- ADDMOD = 263, +- CLEAR = 264, +- CREATE = 265, +- DELETE = 266, +- DIRECTORY = 267, +- END = 268, +- EXTRACT = 269, +- FULLDIR = 270, +- HELP = 271, +- QUIT = 272, +- REPLACE = 273, +- SAVE = 274, +- OPEN = 275 +- }; +-#endif +-/* Tokens. */ +-#define NEWLINE 258 +-#define VERBOSE 259 +-#define FILENAME 260 +-#define ADDLIB 261 +-#define LIST 262 +-#define ADDMOD 263 +-#define CLEAR 264 +-#define CREATE 265 +-#define DELETE 266 +-#define DIRECTORY 267 +-#define END 268 +-#define EXTRACT 269 +-#define FULLDIR 270 +-#define HELP 271 +-#define QUIT 272 +-#define REPLACE 273 +-#define SAVE 274 +-#define OPEN 275 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 1 "arparse.y" +- +-/* arparse.y - Stange script language parser */ +- +-/* Copyright 1992, 1993, 1995, 1997, 1999, 2002, 2003, 2005, 2007 +- Free Software Foundation, Inc. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +- +-/* Contributed by Steve Chamberlain +- sac@cygnus.com +- +-*/ +-#define DONTDECLARE_MALLOC +-#include "sysdep.h" +-#include "bfd.h" +-#include "arsup.h" +-extern int verbose; +-extern int yylex (void); +-static int yyerror (const char *); +- +- +-/* Enabling traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* Enabling the token table. */ +-#ifndef YYTOKEN_TABLE +-# define YYTOKEN_TABLE 0 +-#endif +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 38 "arparse.y" +-{ +- char *name; +-struct list *list ; +- +-} +-/* Line 193 of yacc.c. */ +-#line 179 "arparse.c" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +- +- +-/* Copy the second part of user declarations. */ +- +- +-/* Line 216 of yacc.c. */ +-#line 192 "arparse.c" +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; +-#else +-typedef short int yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(msgid) dgettext ("bison-runtime", msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(msgid) msgid +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(e) ((void) (e)) +-#else +-# define YYUSE(e) /* empty */ +-#endif +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(n) (n) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int i) +-#else +-static int +-YYID (i) +- int i; +-#endif +-{ +- return i; +-} +-#endif +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined _STDLIB_H \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss; +- YYSTYPE yyvs; +- }; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-/* Copy COUNT objects from FROM to TO. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(To, From, Count) \ +- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +-# else +-# define YYCOPY(To, From, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (To)[yyi] = (From)[yyi]; \ +- } \ +- while (YYID (0)) +-# endif +-# endif +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack, Stack, yysize); \ +- Stack = &yyptr->Stack; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) +- +-#endif +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 3 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 34 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 24 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 22 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 42 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 53 +- +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 275 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 21, 22, 2, 2, 23, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20 +-}; +- +-#if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint8 yyprhs[] = +-{ +- 0, 0, 3, 4, 7, 10, 11, 14, 16, 18, +- 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, +- 40, 42, 44, 45, 48, 51, 53, 56, 59, 61, +- 63, 66, 69, 73, 78, 80, 81, 85, 86, 90, +- 91, 93, 94 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int8 yyrhs[] = +-{ +- 25, 0, -1, -1, 26, 27, -1, 27, 28, -1, +- -1, 29, 3, -1, 37, -1, 38, -1, 45, -1, +- 40, -1, 39, -1, 32, -1, 34, -1, 36, -1, +- 30, -1, 31, -1, 33, -1, 35, -1, 13, -1, +- 1, -1, 5, -1, -1, 14, 43, -1, 18, 43, +- -1, 9, -1, 11, 43, -1, 8, 43, -1, 7, +- -1, 19, -1, 20, 5, -1, 10, 5, -1, 6, +- 5, 42, -1, 12, 5, 42, 41, -1, 5, -1, +- -1, 21, 43, 22, -1, -1, 43, 44, 5, -1, +- -1, 23, -1, -1, 4, -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const yytype_uint8 yyrline[] = +-{ +- 0, 69, 69, 69, 73, 74, 78, 82, 83, 84, +- 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, +- 95, 96, 97, 102, 107, 112, 117, 121, 126, 131, +- 138, 143, 149, 153, 160, 162, 166, 169, 173, 179, +- 184, 185, 190 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "NEWLINE", "VERBOSE", "FILENAME", +- "ADDLIB", "LIST", "ADDMOD", "CLEAR", "CREATE", "DELETE", "DIRECTORY", +- "END", "EXTRACT", "FULLDIR", "HELP", "QUIT", "REPLACE", "SAVE", "OPEN", +- "'('", "')'", "','", "$accept", "start", "@1", "session", "command_line", +- "command", "extract_command", "replace_command", "clear_command", +- "delete_command", "addmod_command", "list_command", "save_command", +- "open_command", "create_command", "addlib_command", "directory_command", +- "optional_filename", "modulelist", "modulename", "optcomma", +- "verbose_command", 0 +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 40, 41, 44 +-}; +-# endif +- +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 24, 26, 25, 27, 27, 28, 29, 29, 29, +- 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +- 29, 29, 29, 30, 31, 32, 33, 34, 35, 36, +- 37, 38, 39, 40, 41, 41, 42, 42, 43, 43, +- 44, 44, 45 +-}; +- +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 0, 2, 2, 0, 2, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 0, 2, 2, 1, 2, 2, 1, 1, +- 2, 2, 3, 4, 1, 0, 3, 0, 3, 0, +- 1, 0, 1 +-}; +- +-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state +- STATE-NUM when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 2, 0, 5, 1, 0, 20, 42, 21, 0, 28, +- 39, 25, 0, 39, 0, 19, 39, 39, 29, 0, +- 4, 0, 15, 16, 12, 17, 13, 18, 14, 7, +- 8, 11, 10, 9, 37, 27, 31, 26, 37, 23, +- 24, 30, 6, 39, 32, 40, 0, 35, 41, 38, +- 34, 33, 36 +-}; +- +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int8 yydefgoto[] = +-{ +- -1, 1, 2, 4, 20, 21, 22, 23, 24, 25, +- 26, 27, 28, 29, 30, 31, 32, 51, 44, 35, +- 46, 33 +-}; +- +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -14 +-static const yytype_int8 yypact[] = +-{ +- -14, 1, -14, -14, 5, -14, -14, -14, 2, -14, +- -14, -14, 21, -14, 22, -14, -14, -14, -14, 23, +- -14, 26, -14, -14, -14, -14, -14, -14, -14, -14, +- -14, -14, -14, -14, 10, -3, -14, -3, 10, -3, +- -3, -14, -14, -14, -14, -14, 27, 28, -1, -14, +- -14, -14, -14 +-}; +- +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = +-{ +- -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, +- -14, -14, -14, -14, -14, -14, -14, -14, -4, -13, +- -14, -14 +-}; +- +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If zero, do what YYDEFACT says. +- If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -42 +-static const yytype_int8 yytable[] = +-{ +- 37, 3, -41, 39, 40, -3, 5, 34, -22, 6, +- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, +- 45, 52, 45, 17, 18, 19, 36, 38, 41, 42, +- 48, 43, 49, 50, 47 +-}; +- +-static const yytype_uint8 yycheck[] = +-{ +- 13, 0, 5, 16, 17, 0, 1, 5, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 23, 22, 23, 18, 19, 20, 5, 5, 5, 3, +- 43, 21, 5, 5, 38 +-}; +- +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 25, 26, 0, 27, 1, 4, 5, 6, 7, +- 8, 9, 10, 11, 12, 13, 14, 18, 19, 20, +- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +- 38, 39, 40, 45, 5, 43, 5, 43, 5, 43, +- 43, 5, 3, 21, 42, 23, 44, 42, 43, 5, +- 5, 41, 22 +-}; +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. */ +- +-#define YYFAIL goto yyerrlab +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY && yylen == 1) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK (1); \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) +- +- +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +- If N is 0, then set CURRENT to the empty location which ends +- the previous symbol: RHS[0] (always defined). */ +- +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +-#ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (YYID (N)) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (YYID (0)) +-#endif +- +- +-/* YY_LOCATION_PRINT -- Print the location on the stream. +- This macro was not mandated originally: define only if we know +- we won't break user code: when these are the locations we know. */ +- +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +-# define YY_LOCATION_PRINT(File, Loc) \ +- fprintf (File, "%d.%d-%d.%d", \ +- (Loc).first_line, (Loc).first_column, \ +- (Loc).last_line, (Loc).last_column) +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif +- +- +-/* YYLEX -- calling `yylex' with the right arguments. */ +- +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); +-# endif +- switch (yytype) +- { +- default: +- break; +- } +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +-#else +-static void +-yy_stack_print (bottom, top) +- yytype_int16 *bottom; +- yytype_int16 *top; +-#endif +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; bottom <= top; ++bottom) +- YYFPRINTF (stderr, " %d", *bottom); +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif +-{ +- int yynrhs = yyr2[yyrule]; +- int yyi; +- unsigned long int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- fprintf (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- fprintf (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static YYSIZE_T +-yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into YYRESULT an error message about the unexpected token +- YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not +- copy anything; just return the number of bytes that would be +- copied. As a special case, return 0 if an ordinary "syntax error" +- message will do. Return YYSIZE_MAXIMUM if overflow occurs during +- size calculation. */ +-static YYSIZE_T +-yysyntax_error (char *yyresult, int yystate, int yychar) +-{ +- int yyn = yypact[yystate]; +- +- if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) +- return 0; +- else +- { +- int yytype = YYTRANSLATE (yychar); +- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); +- YYSIZE_T yysize = yysize0; +- YYSIZE_T yysize1; +- int yysize_overflow = 0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- int yyx; +- +-# if 0 +- /* This is so xgettext sees the translatable formats that are +- constructed on the fly. */ +- YY_("syntax error, unexpected %s"); +- YY_("syntax error, unexpected %s, expecting %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +-# endif +- char *yyfmt; +- char const *yyf; +- static char const yyunexpected[] = "syntax error, unexpected %s"; +- static char const yyexpecting[] = ", expecting %s"; +- static char const yyor[] = " or %s"; +- char yyformat[sizeof yyunexpected +- + sizeof yyexpecting - 1 +- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) +- * (sizeof yyor - 1))]; +- char const *yyprefix = yyexpecting; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 1; +- +- yyarg[0] = yytname[yytype]; +- yyfmt = yystpcpy (yyformat, yyunexpected); +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- yyformat[sizeof yyunexpected - 1] = '\0'; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- yysize1 = yysize + yytnamerr (0, yytname[yyx]); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- yyfmt = yystpcpy (yyfmt, yyprefix); +- yyprefix = yyor; +- } +- +- yyf = YY_(yyformat); +- yysize1 = yysize + yystrlen (yyf); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- +- if (yysize_overflow) +- return YYSIZE_MAXIMUM; +- +- if (yyresult) +- { +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- char *yyp = yyresult; +- int yyi = 0; +- while ((*yyp = *yyf) != '\0') +- { +- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyf += 2; +- } +- else +- { +- yyp++; +- yyf++; +- } +- } +- } +- return yysize; +- } +-} +-#endif /* YYERROR_VERBOSE */ +- +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif +-{ +- YYUSE (yyvaluep); +- +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- switch (yytype) +- { +- +- default: +- break; +- } +-} +- +- +-/* Prevent warnings from -Wmissing-prototypes. */ +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ +- +- +- +-/* The look-ahead symbol. */ +-int yychar; +- +-/* The semantic value of the look-ahead symbol. */ +-YYSTYPE yylval; +- +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif +-{ +- +- int yystate; +- int yyn; +- int yyresult; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- /* Look-ahead token as an internal (translated) token number. */ +- int yytoken = 0; +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +- /* Three stacks and their tools: +- `yyss': related to states, +- `yyvs': related to semantic values, +- `yyls': related to locations. +- +- Refer to the stacks thru separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss = yyssa; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs = yyvsa; +- YYSTYPE *yyvsp; +- +- +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- YYSIZE_T yystacksize = YYINITDEPTH; +- +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- +- /* Initialize stack pointers. +- Waste one element of value and location stack +- so that they stay on the same level as the state stack. +- The wasted elements are never initialized. */ +- +- yyssp = yyss; +- yyvsp = yyvs; +- +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss); +- YYSTACK_RELOCATE (yyvs); +- +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- look-ahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to look-ahead token. */ +- yyn = yypact[yystate]; +- if (yyn == YYPACT_NINF) +- goto yydefault; +- +- /* Not known => get a look-ahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yyn == 0 || yyn == YYTABLE_NINF) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the look-ahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- yystate = yyn; +- *++yyvsp = yylval; +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 2: +-#line 69 "arparse.y" +- { prompt(); } +- break; +- +- case 6: +-#line 78 "arparse.y" +- { prompt(); } +- break; +- +- case 19: +-#line 94 "arparse.y" +- { ar_end(); return 0; } +- break; +- +- case 21: +-#line 96 "arparse.y" +- { yyerror("foo"); } +- break; +- +- case 23: +-#line 103 "arparse.y" +- { ar_extract((yyvsp[(2) - (2)].list)); } +- break; +- +- case 24: +-#line 108 "arparse.y" +- { ar_replace((yyvsp[(2) - (2)].list)); } +- break; +- +- case 25: +-#line 113 "arparse.y" +- { ar_clear(); } +- break; +- +- case 26: +-#line 118 "arparse.y" +- { ar_delete((yyvsp[(2) - (2)].list)); } +- break; +- +- case 27: +-#line 122 "arparse.y" +- { ar_addmod((yyvsp[(2) - (2)].list)); } +- break; +- +- case 28: +-#line 127 "arparse.y" +- { ar_list(); } +- break; +- +- case 29: +-#line 132 "arparse.y" +- { ar_save(); } +- break; +- +- case 30: +-#line 139 "arparse.y" +- { ar_open((yyvsp[(2) - (2)].name),0); } +- break; +- +- case 31: +-#line 144 "arparse.y" +- { ar_open((yyvsp[(2) - (2)].name),1); } +- break; +- +- case 32: +-#line 150 "arparse.y" +- { ar_addlib((yyvsp[(2) - (3)].name),(yyvsp[(3) - (3)].list)); } +- break; +- +- case 33: +-#line 154 "arparse.y" +- { ar_directory((yyvsp[(2) - (4)].name), (yyvsp[(3) - (4)].list), (yyvsp[(4) - (4)].name)); } +- break; +- +- case 34: +-#line 161 "arparse.y" +- { (yyval.name) = (yyvsp[(1) - (1)].name); } +- break; +- +- case 35: +-#line 162 "arparse.y" +- { (yyval.name) = 0; } +- break; +- +- case 36: +-#line 167 "arparse.y" +- { (yyval.list) = (yyvsp[(2) - (3)].list); } +- break; +- +- case 37: +-#line 169 "arparse.y" +- { (yyval.list) = 0; } +- break; +- +- case 38: +-#line 174 "arparse.y" +- { struct list *n = (struct list *) malloc(sizeof(struct list)); +- n->next = (yyvsp[(1) - (3)].list); +- n->name = (yyvsp[(3) - (3)].name); +- (yyval.list) = n; +- } +- break; +- +- case 39: +-#line 179 "arparse.y" +- { (yyval.list) = 0; } +- break; +- +- case 42: +-#line 191 "arparse.y" +- { verbose = !verbose; } +- break; +- +- +-/* Line 1267 of yacc.c. */ +-#line 1546 "arparse.c" +- default: break; +- } +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- +- /* Now `shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ +-yyerrlab: +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +- { +- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); +- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) +- { +- YYSIZE_T yyalloc = 2 * yysize; +- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) +- yyalloc = YYSTACK_ALLOC_MAXIMUM; +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yyalloc); +- if (yymsg) +- yymsg_alloc = yyalloc; +- else +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- } +- } +- +- if (0 < yysize && yysize <= yymsg_alloc) +- { +- (void) yysyntax_error (yymsg, yystate, yychar); +- yyerror (yymsg); +- } +- else +- { +- yyerror (YY_("syntax error")); +- if (yysize != 0) +- goto yyexhaustedlab; +- } +- } +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse look-ahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse look-ahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule which action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (yyn != YYPACT_NINF) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- *++yyvsp = yylval; +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#ifndef yyoverflow +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEOF && yychar != YYEMPTY) +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- /* Do not reclaim the symbols of the rule which action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); +-} +- +- +-#line 195 "arparse.y" +- +- +-static int +-yyerror (const char *x ATTRIBUTE_UNUSED) +-{ +- extern int linenumber; +- +- printf (_("Syntax error in archive script, line %d\n"), linenumber + 1); +- return 0; +-} +- +diff -Nur binutils-2.24.orig/binutils/arparse.h binutils-2.24/binutils/arparse.h +--- binutils-2.24.orig/binutils/arparse.h 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/arparse.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,102 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton interface for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- NEWLINE = 258, +- VERBOSE = 259, +- FILENAME = 260, +- ADDLIB = 261, +- LIST = 262, +- ADDMOD = 263, +- CLEAR = 264, +- CREATE = 265, +- DELETE = 266, +- DIRECTORY = 267, +- END = 268, +- EXTRACT = 269, +- FULLDIR = 270, +- HELP = 271, +- QUIT = 272, +- REPLACE = 273, +- SAVE = 274, +- OPEN = 275 +- }; +-#endif +-/* Tokens. */ +-#define NEWLINE 258 +-#define VERBOSE 259 +-#define FILENAME 260 +-#define ADDLIB 261 +-#define LIST 262 +-#define ADDMOD 263 +-#define CLEAR 264 +-#define CREATE 265 +-#define DELETE 266 +-#define DIRECTORY 267 +-#define END 268 +-#define EXTRACT 269 +-#define FULLDIR 270 +-#define HELP 271 +-#define QUIT 272 +-#define REPLACE 273 +-#define SAVE 274 +-#define OPEN 275 +- +- +- +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 38 "arparse.y" +-{ +- char *name; +-struct list *list ; +- +-} +-/* Line 1529 of yacc.c. */ +-#line 95 "arparse.h" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +-extern YYSTYPE yylval; +- +diff -Nur binutils-2.24.orig/binutils/deflex.c binutils-2.24/binutils/deflex.c +--- binutils-2.24.orig/binutils/deflex.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/deflex.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2105 +0,0 @@ +- +-#line 3 "deflex.c" +- +-#define YY_INT_ALIGNED short int +- +-/* A lexical scanner generated by flex */ +- +-#define FLEX_SCANNER +-#define YY_FLEX_MAJOR_VERSION 2 +-#define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 35 +-#if YY_FLEX_SUBMINOR_VERSION > 0 +-#define FLEX_BETA +-#endif +- +-/* First, we deal with platform-specific or compiler-specific issues. */ +- +-/* begin standard C headers. */ +-#include +-#include +-#include +-#include +- +-/* end standard C headers. */ +- +-/* flex integer type definitions */ +- +-#ifndef FLEXINT_H +-#define FLEXINT_H +- +-/* C99 systems have . Non-C99 systems may or may not. */ +- +-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +- +-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, +- * if you want the limit (max/min) macros for int types. +- */ +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS 1 +-#endif +- +-#include +-typedef int8_t flex_int8_t; +-typedef uint8_t flex_uint8_t; +-typedef int16_t flex_int16_t; +-typedef uint16_t flex_uint16_t; +-typedef int32_t flex_int32_t; +-typedef uint32_t flex_uint32_t; +-typedef uint64_t flex_uint64_t; +-#else +-typedef signed char flex_int8_t; +-typedef short int flex_int16_t; +-typedef int flex_int32_t; +-typedef unsigned char flex_uint8_t; +-typedef unsigned short int flex_uint16_t; +-typedef unsigned int flex_uint32_t; +-#endif /* ! C99 */ +- +-/* Limits of integral types. */ +-#ifndef INT8_MIN +-#define INT8_MIN (-128) +-#endif +-#ifndef INT16_MIN +-#define INT16_MIN (-32767-1) +-#endif +-#ifndef INT32_MIN +-#define INT32_MIN (-2147483647-1) +-#endif +-#ifndef INT8_MAX +-#define INT8_MAX (127) +-#endif +-#ifndef INT16_MAX +-#define INT16_MAX (32767) +-#endif +-#ifndef INT32_MAX +-#define INT32_MAX (2147483647) +-#endif +-#ifndef UINT8_MAX +-#define UINT8_MAX (255U) +-#endif +-#ifndef UINT16_MAX +-#define UINT16_MAX (65535U) +-#endif +-#ifndef UINT32_MAX +-#define UINT32_MAX (4294967295U) +-#endif +- +-#endif /* ! FLEXINT_H */ +- +-#ifdef __cplusplus +- +-/* The "const" storage-class-modifier is valid. */ +-#define YY_USE_CONST +- +-#else /* ! __cplusplus */ +- +-/* C99 requires __STDC__ to be defined as 1. */ +-#if defined (__STDC__) +- +-#define YY_USE_CONST +- +-#endif /* defined (__STDC__) */ +-#endif /* ! __cplusplus */ +- +-#ifdef YY_USE_CONST +-#define yyconst const +-#else +-#define yyconst +-#endif +- +-/* Returned upon end-of-file. */ +-#define YY_NULL 0 +- +-/* Promotes a possibly negative, possibly signed char to an unsigned +- * integer for use as an array index. If the signed char is negative, +- * we want to instead treat it as an 8-bit unsigned char, hence the +- * double cast. +- */ +-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +- +-/* Enter a start condition. This macro really ought to take a parameter, +- * but we do it the disgusting crufty way forced on us by the ()-less +- * definition of BEGIN. +- */ +-#define BEGIN (yy_start) = 1 + 2 * +- +-/* Translate the current start state into a value that can be later handed +- * to BEGIN to return to the state. The YYSTATE alias is for lex +- * compatibility. +- */ +-#define YY_START (((yy_start) - 1) / 2) +-#define YYSTATE YY_START +- +-/* Action number for EOF rule of a given start state. */ +-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +- +-/* Special action meaning "start processing a new file". */ +-#define YY_NEW_FILE yyrestart(yyin ) +- +-#define YY_END_OF_BUFFER_CHAR 0 +- +-/* Size of default input buffer. */ +-#ifndef YY_BUF_SIZE +-#define YY_BUF_SIZE 16384 +-#endif +- +-/* The state buf must be large enough to hold one state per character in the main buffer. +- */ +-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) +- +-#ifndef YY_TYPEDEF_YY_BUFFER_STATE +-#define YY_TYPEDEF_YY_BUFFER_STATE +-typedef struct yy_buffer_state *YY_BUFFER_STATE; +-#endif +- +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-extern yy_size_t yyleng; +- +-extern FILE *yyin, *yyout; +- +-#define EOB_ACT_CONTINUE_SCAN 0 +-#define EOB_ACT_END_OF_FILE 1 +-#define EOB_ACT_LAST_MATCH 2 +- +- #define YY_LESS_LINENO(n) +- +-/* Return all but the first "n" matched characters back to the input stream. */ +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up yytext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- *yy_cp = (yy_hold_char); \ +- YY_RESTORE_YY_MORE_OFFSET \ +- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ +- YY_DO_BEFORE_ACTION; /* set up yytext again */ \ +- } \ +- while ( 0 ) +- +-#define unput(c) yyunput( c, (yytext_ptr) ) +- +-#ifndef YY_STRUCT_YY_BUFFER_STATE +-#define YY_STRUCT_YY_BUFFER_STATE +-struct yy_buffer_state +- { +- FILE *yy_input_file; +- +- char *yy_ch_buf; /* input buffer */ +- char *yy_buf_pos; /* current position in input buffer */ +- +- /* Size of input buffer in bytes, not including room for EOB +- * characters. +- */ +- yy_size_t yy_buf_size; +- +- /* Number of characters read into yy_ch_buf, not including EOB +- * characters. +- */ +- yy_size_t yy_n_chars; +- +- /* Whether we "own" the buffer - i.e., we know we created it, +- * and can realloc() it to grow it, and should free() it to +- * delete it. +- */ +- int yy_is_our_buffer; +- +- /* Whether this is an "interactive" input source; if so, and +- * if we're using stdio for input, then we want to use getc() +- * instead of fread(), to make sure we stop fetching input after +- * each newline. +- */ +- int yy_is_interactive; +- +- /* Whether we're considered to be at the beginning of a line. +- * If so, '^' rules will be active on the next match, otherwise +- * not. +- */ +- int yy_at_bol; +- +- int yy_bs_lineno; /**< The line count. */ +- int yy_bs_column; /**< The column count. */ +- +- /* Whether to try to fill the input buffer when we reach the +- * end of it. +- */ +- int yy_fill_buffer; +- +- int yy_buffer_status; +- +-#define YY_BUFFER_NEW 0 +-#define YY_BUFFER_NORMAL 1 +- /* When an EOF's been seen but there's still some text to process +- * then we mark the buffer as YY_EOF_PENDING, to indicate that we +- * shouldn't try reading from the input source any more. We might +- * still have a bunch of tokens to match, though, because of +- * possible backing-up. +- * +- * When we actually see the EOF, we change the status to "new" +- * (via yyrestart()), so that the user can continue scanning by +- * just pointing yyin at a new input file. +- */ +-#define YY_BUFFER_EOF_PENDING 2 +- +- }; +-#endif /* !YY_STRUCT_YY_BUFFER_STATE */ +- +-/* Stack of input buffers. */ +-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +- +-/* We provide macros for accessing buffer states in case in the +- * future we want to put the buffer states in a more general +- * "scanner state". +- * +- * Returns the top of the stack, or NULL. +- */ +-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ +- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ +- : NULL) +- +-/* Same as previous macro, but useful when we know that the buffer stack is not +- * NULL or when we need an lvalue. For internal use only. +- */ +-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] +- +-/* yy_hold_char holds the character lost when yytext is formed. */ +-static char yy_hold_char; +-static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +-yy_size_t yyleng; +- +-/* Points to current character in buffer. */ +-static char *yy_c_buf_p = (char *) 0; +-static int yy_init = 0; /* whether we need to initialize */ +-static int yy_start = 0; /* start state number */ +- +-/* Flag which is used to allow yywrap()'s to do buffer switches +- * instead of setting up a fresh yyin. A bit of a hack ... +- */ +-static int yy_did_buffer_switch_on_eof; +- +-void yyrestart (FILE *input_file ); +-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +-void yy_delete_buffer (YY_BUFFER_STATE b ); +-void yy_flush_buffer (YY_BUFFER_STATE b ); +-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +-void yypop_buffer_state (void ); +- +-static void yyensure_buffer_stack (void ); +-static void yy_load_buffer_state (void ); +-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); +- +-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) +- +-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); +- +-void *yyalloc (yy_size_t ); +-void *yyrealloc (void *,yy_size_t ); +-void yyfree (void * ); +- +-#define yy_new_buffer yy_create_buffer +- +-#define yy_set_interactive(is_interactive) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){ \ +- yyensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- yy_create_buffer(yyin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ +- } +- +-#define yy_set_bol(at_bol) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){\ +- yyensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- yy_create_buffer(yyin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ +- } +- +-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) +- +-/* Begin user sect3 */ +- +-typedef unsigned char YY_CHAR; +- +-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +- +-typedef int yy_state_type; +- +-extern int yylineno; +- +-int yylineno = 1; +- +-extern char *yytext; +-#define yytext_ptr yytext +- +-static yy_state_type yy_get_previous_state (void ); +-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +-static int yy_get_next_buffer (void ); +-static void yy_fatal_error (yyconst char msg[] ); +- +-/* Done after the current pattern has been matched and before the +- * corresponding action - sets up yytext. +- */ +-#define YY_DO_BEFORE_ACTION \ +- (yytext_ptr) = yy_bp; \ +- yyleng = (yy_size_t) (yy_cp - yy_bp); \ +- (yy_hold_char) = *yy_cp; \ +- *yy_cp = '\0'; \ +- (yy_c_buf_p) = yy_cp; +- +-#define YY_NUM_RULES 42 +-#define YY_END_OF_BUFFER 43 +-/* This struct is not used in this scanner, +- but its presence is necessary. */ +-struct yy_trans_info +- { +- flex_int32_t yy_verify; +- flex_int32_t yy_nxt; +- }; +-static yyconst flex_int16_t yy_accept[199] = +- { 0, +- 0, 0, 43, 42, 34, 36, 35, 33, 42, 28, +- 42, 31, 41, 39, 27, 32, 38, 40, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 0, 29, 28, 0, 30, 31, 27, +- 32, 37, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 12, 6, 28, +- 7, 28, 28, 28, 28, 28, 28, 28, 28, 1, +- +- 28, 28, 28, 16, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 17, 28, 28, 28, 28, 28, 28, 28, 28, +- 28, 28, 14, 28, 28, 28, 19, 21, 28, 28, +- 28, 28, 28, 28, 18, 9, 28, 10, 28, 28, +- 2, 28, 28, 15, 28, 28, 28, 28, 11, 13, +- 28, 5, 28, 28, 22, 28, 8, 28, 28, 28, +- 28, 28, 28, 20, 4, 28, 28, 28, 24, 28, +- 26, 28, 3, 28, 28, 23, 25, 0 +- +- } ; +- +-static yyconst flex_int32_t yy_ec[256] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, +- 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 5, 1, 6, 1, 7, 1, 1, 8, 1, +- 1, 9, 1, 10, 7, 11, 12, 13, 13, 13, +- 13, 13, 13, 13, 13, 13, 13, 7, 14, 12, +- 15, 12, 7, 16, 17, 18, 19, 20, 21, 22, +- 23, 24, 25, 7, 26, 27, 28, 29, 30, 31, +- 7, 32, 33, 34, 35, 36, 37, 38, 39, 40, +- 1, 1, 1, 1, 7, 1, 22, 22, 22, 22, +- +- 22, 22, 7, 7, 7, 7, 7, 7, 7, 7, +- 7, 7, 7, 7, 7, 7, 7, 7, 7, 22, +- 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1 +- } ; +- +-static yyconst flex_int32_t yy_meta[41] = +- { 0, +- 1, 1, 2, 1, 1, 1, 3, 1, 1, 1, +- 1, 4, 5, 1, 1, 4, 6, 6, 6, 6, +- 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, +- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 +- } ; +- +-static yyconst flex_int16_t yy_base[206] = +- { 0, +- 0, 0, 230, 231, 231, 231, 231, 231, 223, 0, +- 220, 0, 231, 231, 0, 0, 212, 0, 209, 195, +- 24, 186, 202, 14, 197, 186, 27, 188, 198, 25, +- 197, 196, 184, 209, 231, 0, 206, 231, 0, 0, +- 0, 231, 0, 180, 27, 178, 178, 27, 193, 178, +- 183, 189, 179, 177, 175, 178, 185, 182, 183, 170, +- 181, 165, 164, 170, 173, 172, 159, 174, 171, 170, +- 158, 156, 156, 151, 152, 149, 161, 34, 145, 160, +- 145, 146, 154, 157, 147, 141, 139, 0, 0, 138, +- 0, 139, 135, 137, 135, 135, 29, 149, 140, 0, +- +- 136, 139, 145, 0, 136, 139, 132, 132, 30, 132, +- 135, 138, 129, 119, 118, 126, 116, 122, 119, 115, +- 115, 124, 127, 109, 112, 121, 119, 106, 111, 108, +- 106, 0, 106, 103, 112, 99, 91, 97, 99, 95, +- 88, 99, 0, 93, 103, 94, 0, 0, 97, 91, +- 87, 90, 84, 83, 0, 0, 95, 0, 97, 80, +- 0, 92, 91, 0, 78, 70, 91, 74, 0, 0, +- 82, 0, 89, 88, 0, 84, 0, 82, 85, 83, +- 69, 66, 56, 0, 0, 39, 36, 35, 0, 44, +- 0, 43, 0, 40, 39, 0, 0, 231, 67, 71, +- +- 77, 83, 85, 91, 95 +- } ; +- +-static yyconst flex_int16_t yy_def[206] = +- { 0, +- 198, 1, 198, 198, 198, 198, 198, 198, 199, 200, +- 201, 202, 198, 198, 203, 204, 198, 205, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 199, 198, 200, 201, 198, 202, 203, +- 204, 198, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, +- 200, 200, 200, 200, 200, 200, 200, 0, 198, 198, +- +- 198, 198, 198, 198, 198 +- } ; +- +-static yyconst flex_int16_t yy_nxt[272] = +- { 0, +- 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, +- 14, 4, 15, 16, 17, 18, 10, 19, 20, 21, +- 22, 10, 10, 23, 24, 10, 25, 26, 27, 10, +- 28, 29, 30, 31, 10, 32, 33, 10, 10, 10, +- 46, 50, 51, 54, 47, 58, 66, 70, 59, 60, +- 101, 118, 129, 119, 130, 67, 55, 71, 61, 197, +- 196, 195, 194, 193, 192, 191, 102, 34, 34, 34, +- 34, 34, 34, 36, 36, 36, 36, 37, 37, 37, +- 37, 37, 37, 39, 190, 39, 39, 39, 39, 40, +- 40, 41, 189, 41, 41, 41, 41, 43, 188, 187, +- +- 43, 186, 185, 184, 183, 182, 181, 180, 179, 178, +- 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, +- 167, 166, 165, 164, 163, 162, 161, 160, 159, 158, +- 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, +- 147, 146, 145, 144, 143, 142, 141, 140, 139, 138, +- 137, 136, 135, 134, 133, 132, 131, 128, 127, 126, +- 125, 124, 123, 122, 121, 120, 117, 116, 115, 114, +- 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, +- 103, 100, 99, 98, 97, 96, 95, 94, 93, 92, +- 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, +- +- 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, +- 69, 68, 65, 38, 35, 64, 63, 62, 57, 56, +- 53, 52, 49, 48, 45, 44, 42, 38, 35, 198, +- 3, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198 +- } ; +- +-static yyconst flex_int16_t yy_chk[272] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 21, 24, 24, 27, 21, 30, 45, 48, 30, 30, +- 78, 97, 109, 97, 109, 45, 27, 48, 30, 195, +- 194, 192, 190, 188, 187, 186, 78, 199, 199, 199, +- 199, 199, 199, 200, 200, 200, 200, 201, 201, 201, +- 201, 201, 201, 202, 183, 202, 202, 202, 202, 203, +- 203, 204, 182, 204, 204, 204, 204, 205, 181, 180, +- +- 205, 179, 178, 176, 174, 173, 171, 168, 167, 166, +- 165, 163, 162, 160, 159, 157, 154, 153, 152, 151, +- 150, 149, 146, 145, 144, 142, 141, 140, 139, 138, +- 137, 136, 135, 134, 133, 131, 130, 129, 128, 127, +- 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, +- 116, 115, 114, 113, 112, 111, 110, 108, 107, 106, +- 105, 103, 102, 101, 99, 98, 96, 95, 94, 93, +- 92, 90, 87, 86, 85, 84, 83, 82, 81, 80, +- 79, 77, 76, 75, 74, 73, 72, 71, 70, 69, +- 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, +- +- 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, +- 47, 46, 44, 37, 34, 33, 32, 31, 29, 28, +- 26, 25, 23, 22, 20, 19, 17, 11, 9, 3, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, +- 198 +- } ; +- +-static yy_state_type yy_last_accepting_state; +-static char *yy_last_accepting_cpos; +- +-extern int yy_flex_debug; +-int yy_flex_debug = 0; +- +-/* The intent behind this definition is that it'll catch +- * any uses of REJECT which flex missed. +- */ +-#define REJECT reject_used_but_not_detected +-#define yymore() yymore_used_but_not_detected +-#define YY_MORE_ADJ 0 +-#define YY_RESTORE_YY_MORE_OFFSET +-char *yytext; +-#line 1 "deflex.l" +-#line 2 "deflex.l" +- +-/* Copyright 1995, 1997, 1998, 1999, 2002, 2003, 2004, 2005, 2007 +- Free Software Foundation, Inc. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +- +-/* Contributed by Steve Chamberlain: sac@cygnus.com */ +- +-#define DONTDECLARE_MALLOC +-#include "libiberty.h" +-#include "defparse.h" +-#include "dlltool.h" +- +-#define YY_NO_UNPUT +- +-int linenumber; +- +-#line 610 "deflex.c" +- +-#define INITIAL 0 +- +-#ifndef YY_NO_UNISTD_H +-/* Special case for "unistd.h", since it is non-ANSI. We include it way +- * down here because we want the user's section 1 to have been scanned first. +- * The user has a chance to override it with an option. +- */ +-#include +-#endif +- +-#ifndef YY_EXTRA_TYPE +-#define YY_EXTRA_TYPE void * +-#endif +- +-static int yy_init_globals (void ); +- +-/* Accessor methods to globals. +- These are made visible to non-reentrant scanners for convenience. */ +- +-int yylex_destroy (void ); +- +-int yyget_debug (void ); +- +-void yyset_debug (int debug_flag ); +- +-YY_EXTRA_TYPE yyget_extra (void ); +- +-void yyset_extra (YY_EXTRA_TYPE user_defined ); +- +-FILE *yyget_in (void ); +- +-void yyset_in (FILE * in_str ); +- +-FILE *yyget_out (void ); +- +-void yyset_out (FILE * out_str ); +- +-yy_size_t yyget_leng (void ); +- +-char *yyget_text (void ); +- +-int yyget_lineno (void ); +- +-void yyset_lineno (int line_number ); +- +-/* Macros after this point can all be overridden by user definitions in +- * section 1. +- */ +- +-#ifndef YY_SKIP_YYWRAP +-#ifdef __cplusplus +-extern "C" int yywrap (void ); +-#else +-extern int yywrap (void ); +-#endif +-#endif +- +- static void yyunput (int c,char *buf_ptr ); +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char *,yyconst char *,int ); +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * ); +-#endif +- +-#ifndef YY_NO_INPUT +- +-#ifdef __cplusplus +-static int yyinput (void ); +-#else +-static int input (void ); +-#endif +- +-#endif +- +-/* Amount of stuff to slurp up with each read. */ +-#ifndef YY_READ_BUF_SIZE +-#define YY_READ_BUF_SIZE 8192 +-#endif +- +-/* Copy whatever the last rule matched to the standard output. */ +-#ifndef ECHO +-/* This used to be an fputs(), but since the string might contain NUL's, +- * we now use fwrite(). +- */ +-#define ECHO fwrite( yytext, yyleng, 1, yyout ) +-#endif +- +-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, +- * is returned in "result". +- */ +-#ifndef YY_INPUT +-#define YY_INPUT(buf,result,max_size) \ +- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ +- { \ +- int c = '*'; \ +- yy_size_t n; \ +- for ( n = 0; n < max_size && \ +- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ +- buf[n] = (char) c; \ +- if ( c == '\n' ) \ +- buf[n++] = (char) c; \ +- if ( c == EOF && ferror( yyin ) ) \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- result = n; \ +- } \ +- else \ +- { \ +- errno=0; \ +- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ +- { \ +- if( errno != EINTR) \ +- { \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- break; \ +- } \ +- errno=0; \ +- clearerr(yyin); \ +- } \ +- }\ +-\ +- +-#endif +- +-/* No semi-colon after return; correct usage is to write "yyterminate();" - +- * we don't want an extra ';' after the "return" because that will cause +- * some compilers to complain about unreachable statements. +- */ +-#ifndef yyterminate +-#define yyterminate() return YY_NULL +-#endif +- +-/* Number of entries by which start-condition stack grows. */ +-#ifndef YY_START_STACK_INCR +-#define YY_START_STACK_INCR 25 +-#endif +- +-/* Report a fatal error. */ +-#ifndef YY_FATAL_ERROR +-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +-#endif +- +-/* end tables serialization structures and prototypes */ +- +-/* Default declaration of generated scanner - a define so the user can +- * easily add parameters. +- */ +-#ifndef YY_DECL +-#define YY_DECL_IS_OURS 1 +- +-extern int yylex (void); +- +-#define YY_DECL int yylex (void) +-#endif /* !YY_DECL */ +- +-/* Code executed at the beginning of each rule, after yytext and yyleng +- * have been set up. +- */ +-#ifndef YY_USER_ACTION +-#define YY_USER_ACTION +-#endif +- +-/* Code executed at the end of each rule. */ +-#ifndef YY_BREAK +-#define YY_BREAK break; +-#endif +- +-#define YY_RULE_SETUP \ +- YY_USER_ACTION +- +-/** The main scanner function which does all the work. +- */ +-YY_DECL +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp, *yy_bp; +- register int yy_act; +- +-#line 36 "deflex.l" +- +-#line 794 "deflex.c" +- +- if ( !(yy_init) ) +- { +- (yy_init) = 1; +- +-#ifdef YY_USER_INIT +- YY_USER_INIT; +-#endif +- +- if ( ! (yy_start) ) +- (yy_start) = 1; /* first start state */ +- +- if ( ! yyin ) +- yyin = stdin; +- +- if ( ! yyout ) +- yyout = stdout; +- +- if ( ! YY_CURRENT_BUFFER ) { +- yyensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- yy_create_buffer(yyin,YY_BUF_SIZE ); +- } +- +- yy_load_buffer_state( ); +- } +- +- while ( 1 ) /* loops until end-of-file is reached */ +- { +- yy_cp = (yy_c_buf_p); +- +- /* Support of yytext. */ +- *yy_cp = (yy_hold_char); +- +- /* yy_bp points to the position in yy_ch_buf of the start of +- * the current run. +- */ +- yy_bp = yy_cp; +- +- yy_current_state = (yy_start); +-yy_match: +- do +- { +- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 199 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- ++yy_cp; +- } +- while ( yy_base[yy_current_state] != 231 ); +- +-yy_find_action: +- yy_act = yy_accept[yy_current_state]; +- if ( yy_act == 0 ) +- { /* have to back up */ +- yy_cp = (yy_last_accepting_cpos); +- yy_current_state = (yy_last_accepting_state); +- yy_act = yy_accept[yy_current_state]; +- } +- +- YY_DO_BEFORE_ACTION; +- +-do_action: /* This label is used only to access EOF actions. */ +- +- switch ( yy_act ) +- { /* beginning of action switch */ +- case 0: /* must back up */ +- /* undo the effects of YY_DO_BEFORE_ACTION */ +- *yy_cp = (yy_hold_char); +- yy_cp = (yy_last_accepting_cpos); +- yy_current_state = (yy_last_accepting_state); +- goto yy_find_action; +- +-case 1: +-YY_RULE_SETUP +-#line 37 "deflex.l" +-{ return NAME;} +- YY_BREAK +-case 2: +-YY_RULE_SETUP +-#line 38 "deflex.l" +-{ return LIBRARY;} +- YY_BREAK +-case 3: +-YY_RULE_SETUP +-#line 39 "deflex.l" +-{ return DESCRIPTION;} +- YY_BREAK +-case 4: +-YY_RULE_SETUP +-#line 40 "deflex.l" +-{ return STACKSIZE;} +- YY_BREAK +-case 5: +-YY_RULE_SETUP +-#line 41 "deflex.l" +-{ return HEAPSIZE;} +- YY_BREAK +-case 6: +-YY_RULE_SETUP +-#line 42 "deflex.l" +-{ return CODE;} +- YY_BREAK +-case 7: +-YY_RULE_SETUP +-#line 43 "deflex.l" +-{ return DATA;} +- YY_BREAK +-case 8: +-YY_RULE_SETUP +-#line 44 "deflex.l" +-{ return SECTIONS;} +- YY_BREAK +-case 9: +-YY_RULE_SETUP +-#line 45 "deflex.l" +-{ return EXPORTS;} +- YY_BREAK +-case 10: +-YY_RULE_SETUP +-#line 46 "deflex.l" +-{ return IMPORTS;} +- YY_BREAK +-case 11: +-YY_RULE_SETUP +-#line 47 "deflex.l" +-{ return VERSIONK;} +- YY_BREAK +-case 12: +-YY_RULE_SETUP +-#line 48 "deflex.l" +-{ return BASE;} +- YY_BREAK +-case 13: +-YY_RULE_SETUP +-#line 49 "deflex.l" +-{ return CONSTANT; } +- YY_BREAK +-case 14: +-YY_RULE_SETUP +-#line 50 "deflex.l" +-{ return NONAME; } +- YY_BREAK +-case 15: +-YY_RULE_SETUP +-#line 51 "deflex.l" +-{ return PRIVATE; } +- YY_BREAK +-case 16: +-YY_RULE_SETUP +-#line 52 "deflex.l" +-{ return READ;} +- YY_BREAK +-case 17: +-YY_RULE_SETUP +-#line 53 "deflex.l" +-{ return WRITE;} +- YY_BREAK +-case 18: +-YY_RULE_SETUP +-#line 54 "deflex.l" +-{ return EXECUTE;} +- YY_BREAK +-case 19: +-YY_RULE_SETUP +-#line 55 "deflex.l" +-{ return SHARED;} +- YY_BREAK +-case 20: +-YY_RULE_SETUP +-#line 56 "deflex.l" +-{ return NONSHARED;} +- YY_BREAK +-case 21: +-YY_RULE_SETUP +-#line 57 "deflex.l" +-{ return SINGLE;} +- YY_BREAK +-case 22: +-YY_RULE_SETUP +-#line 58 "deflex.l" +-{ return MULTIPLE;} +- YY_BREAK +-case 23: +-YY_RULE_SETUP +-#line 59 "deflex.l" +-{ return INITINSTANCE;} +- YY_BREAK +-case 24: +-YY_RULE_SETUP +-#line 60 "deflex.l" +-{ return INITGLOBAL;} +- YY_BREAK +-case 25: +-YY_RULE_SETUP +-#line 61 "deflex.l" +-{ return TERMINSTANCE;} +- YY_BREAK +-case 26: +-YY_RULE_SETUP +-#line 62 "deflex.l" +-{ return TERMGLOBAL;} +- YY_BREAK +-case 27: +-YY_RULE_SETUP +-#line 64 "deflex.l" +-{ yylval.number = strtol (yytext,0,0); +- return NUMBER; } +- YY_BREAK +-case 28: +-YY_RULE_SETUP +-#line 67 "deflex.l" +-{ +- yylval.id = xstrdup (yytext); +- return ID; +- } +- YY_BREAK +-case 29: +-/* rule 29 can match eol */ +-YY_RULE_SETUP +-#line 72 "deflex.l" +-{ +- yylval.id = xstrdup (yytext+1); +- yylval.id[yyleng-2] = 0; +- return ID; +- } +- YY_BREAK +-case 30: +-/* rule 30 can match eol */ +-YY_RULE_SETUP +-#line 78 "deflex.l" +-{ +- yylval.id = xstrdup (yytext+1); +- yylval.id[yyleng-2] = 0; +- return ID; +- } +- YY_BREAK +-case 31: +-YY_RULE_SETUP +-#line 83 "deflex.l" +-{ } +- YY_BREAK +-case 32: +-YY_RULE_SETUP +-#line 84 "deflex.l" +-{ } +- YY_BREAK +-case 33: +-YY_RULE_SETUP +-#line 85 "deflex.l" +-{ } +- YY_BREAK +-case 34: +-YY_RULE_SETUP +-#line 86 "deflex.l" +-{ } +- YY_BREAK +-case 35: +-YY_RULE_SETUP +-#line 87 "deflex.l" +-{ } +- YY_BREAK +-case 36: +-/* rule 36 can match eol */ +-YY_RULE_SETUP +-#line 88 "deflex.l" +-{ linenumber ++ ;} +- YY_BREAK +-case 37: +-YY_RULE_SETUP +-#line 89 "deflex.l" +-{ return EQUAL;} +- YY_BREAK +-case 38: +-YY_RULE_SETUP +-#line 90 "deflex.l" +-{ return '=';} +- YY_BREAK +-case 39: +-YY_RULE_SETUP +-#line 91 "deflex.l" +-{ return '.';} +- YY_BREAK +-case 40: +-YY_RULE_SETUP +-#line 92 "deflex.l" +-{ return '@';} +- YY_BREAK +-case 41: +-YY_RULE_SETUP +-#line 93 "deflex.l" +-{ return ',';} +- YY_BREAK +-case 42: +-YY_RULE_SETUP +-#line 94 "deflex.l" +-ECHO; +- YY_BREAK +-#line 1102 "deflex.c" +-case YY_STATE_EOF(INITIAL): +- yyterminate(); +- +- case YY_END_OF_BUFFER: +- { +- /* Amount of text matched not including the EOB char. */ +- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; +- +- /* Undo the effects of YY_DO_BEFORE_ACTION. */ +- *yy_cp = (yy_hold_char); +- YY_RESTORE_YY_MORE_OFFSET +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) +- { +- /* We're scanning a new file or input source. It's +- * possible that this happened because the user +- * just pointed yyin at a new source and called +- * yylex(). If so, then we have to assure +- * consistency between YY_CURRENT_BUFFER and our +- * globals. Here is the right place to do so, because +- * this is the first action (other than possibly a +- * back-up) that will match for the new input source. +- */ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; +- } +- +- /* Note that here we test for yy_c_buf_p "<=" to the position +- * of the first EOB in the buffer, since yy_c_buf_p will +- * already have been incremented past the NUL character +- * (since all states make transitions on EOB to the +- * end-of-buffer state). Contrast this with the test +- * in input(). +- */ +- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- { /* This was really a NUL. */ +- yy_state_type yy_next_state; +- +- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- /* Okay, we're now positioned to make the NUL +- * transition. We couldn't have +- * yy_get_previous_state() go ahead and do it +- * for us because it doesn't know how to deal +- * with the possibility of jamming (and we don't +- * want to build jamming into it because then it +- * will run more slowly). +- */ +- +- yy_next_state = yy_try_NUL_trans( yy_current_state ); +- +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- +- if ( yy_next_state ) +- { +- /* Consume the NUL. */ +- yy_cp = ++(yy_c_buf_p); +- yy_current_state = yy_next_state; +- goto yy_match; +- } +- +- else +- { +- yy_cp = (yy_c_buf_p); +- goto yy_find_action; +- } +- } +- +- else switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_END_OF_FILE: +- { +- (yy_did_buffer_switch_on_eof) = 0; +- +- if ( yywrap( ) ) +- { +- /* Note: because we've taken care in +- * yy_get_next_buffer() to have set up +- * yytext, we can now set up +- * yy_c_buf_p so that if some total +- * hoser (like flex itself) wants to +- * call the scanner after we return the +- * YY_NULL, it'll still work - another +- * YY_NULL will get returned. +- */ +- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; +- +- yy_act = YY_STATE_EOF(YY_START); +- goto do_action; +- } +- +- else +- { +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +- } +- break; +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = +- (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_match; +- +- case EOB_ACT_LAST_MATCH: +- (yy_c_buf_p) = +- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_find_action; +- } +- break; +- } +- +- default: +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--no action found" ); +- } /* end of action switch */ +- } /* end of scanning one token */ +-} /* end of yylex */ +- +-/* yy_get_next_buffer - try to read in a new buffer +- * +- * Returns a code representing an action: +- * EOB_ACT_LAST_MATCH - +- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position +- * EOB_ACT_END_OF_FILE - end of file +- */ +-static int yy_get_next_buffer (void) +-{ +- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; +- register char *source = (yytext_ptr); +- register int number_to_move, i; +- int ret_val; +- +- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--end of buffer missed" ); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) +- { /* Don't try to fill the buffer, so this is an EOF. */ +- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) +- { +- /* We matched a single character, the EOB, so +- * treat this as a final EOF. +- */ +- return EOB_ACT_END_OF_FILE; +- } +- +- else +- { +- /* We matched some text prior to the EOB, first +- * process it. +- */ +- return EOB_ACT_LAST_MATCH; +- } +- } +- +- /* Try to read more data. */ +- +- /* First move last chars to start of buffer. */ +- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; +- +- for ( i = 0; i < number_to_move; ++i ) +- *(dest++) = *(source++); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) +- /* don't do the read, it's not guaranteed to return an EOF, +- * just force an EOF +- */ +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; +- +- else +- { +- yy_size_t num_to_read = +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; +- +- while ( num_to_read <= 0 ) +- { /* Not enough room in the buffer - grow it. */ +- +- /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; +- +- int yy_c_buf_p_offset = +- (int) ((yy_c_buf_p) - b->yy_ch_buf); +- +- if ( b->yy_is_our_buffer ) +- { +- yy_size_t new_size = b->yy_buf_size * 2; +- +- if ( new_size <= 0 ) +- b->yy_buf_size += b->yy_buf_size / 8; +- else +- b->yy_buf_size *= 2; +- +- b->yy_ch_buf = (char *) +- /* Include room in for 2 EOB chars. */ +- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); +- } +- else +- /* Can't grow it, we don't own it. */ +- b->yy_ch_buf = 0; +- +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( +- "fatal error - scanner input buffer overflow" ); +- +- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; +- +- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - +- number_to_move - 1; +- +- } +- +- if ( num_to_read > YY_READ_BUF_SIZE ) +- num_to_read = YY_READ_BUF_SIZE; +- +- /* Read in more data. */ +- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), num_to_read ); +- +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- if ( (yy_n_chars) == 0 ) +- { +- if ( number_to_move == YY_MORE_ADJ ) +- { +- ret_val = EOB_ACT_END_OF_FILE; +- yyrestart(yyin ); +- } +- +- else +- { +- ret_val = EOB_ACT_LAST_MATCH; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = +- YY_BUFFER_EOF_PENDING; +- } +- } +- +- else +- ret_val = EOB_ACT_CONTINUE_SCAN; +- +- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { +- /* Extend the array by 50%, plus the number we really need. */ +- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); +- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); +- } +- +- (yy_n_chars) += number_to_move; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; +- +- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; +- +- return ret_val; +-} +- +-/* yy_get_previous_state - get the state just before the EOB char was reached */ +- +- static yy_state_type yy_get_previous_state (void) +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp; +- +- yy_current_state = (yy_start); +- +- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) +- { +- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 199 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- } +- +- return yy_current_state; +-} +- +-/* yy_try_NUL_trans - try to make a transition on the NUL character +- * +- * synopsis +- * next_state = yy_try_NUL_trans( current_state ); +- */ +- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +-{ +- register int yy_is_jam; +- register char *yy_cp = (yy_c_buf_p); +- +- register YY_CHAR yy_c = 1; +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 199 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 198); +- +- return yy_is_jam ? 0 : yy_current_state; +-} +- +- static void yyunput (int c, register char * yy_bp ) +-{ +- register char *yy_cp; +- +- yy_cp = (yy_c_buf_p); +- +- /* undo effects of setting up yytext */ +- *yy_cp = (yy_hold_char); +- +- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) +- { /* need to shift things up to make room */ +- /* +2 for EOB chars. */ +- register yy_size_t number_to_move = (yy_n_chars) + 2; +- register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; +- register char *source = +- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; +- +- while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) +- *--dest = *--source; +- +- yy_cp += (int) (dest - source); +- yy_bp += (int) (dest - source); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; +- +- if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) +- YY_FATAL_ERROR( "flex scanner push-back overflow" ); +- } +- +- *--yy_cp = (char) c; +- +- (yytext_ptr) = yy_bp; +- (yy_hold_char) = *yy_cp; +- (yy_c_buf_p) = yy_cp; +-} +- +-#ifndef YY_NO_INPUT +-#ifdef __cplusplus +- static int yyinput (void) +-#else +- static int input (void) +-#endif +- +-{ +- int c; +- +- *(yy_c_buf_p) = (yy_hold_char); +- +- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) +- { +- /* yy_c_buf_p now points to the character we want to return. +- * If this occurs *before* the EOB characters, then it's a +- * valid NUL; if not, then we've hit the end of the buffer. +- */ +- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- /* This was really a NUL. */ +- *(yy_c_buf_p) = '\0'; +- +- else +- { /* need more input */ +- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); +- ++(yy_c_buf_p); +- +- switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_LAST_MATCH: +- /* This happens because yy_g_n_b() +- * sees that we've accumulated a +- * token and flags that we need to +- * try matching the token before +- * proceeding. But for input(), +- * there's no matching to consider. +- * So convert the EOB_ACT_LAST_MATCH +- * to EOB_ACT_END_OF_FILE. +- */ +- +- /* Reset buffer status. */ +- yyrestart(yyin ); +- +- /*FALLTHROUGH*/ +- +- case EOB_ACT_END_OF_FILE: +- { +- if ( yywrap( ) ) +- return 0; +- +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +-#ifdef __cplusplus +- return yyinput(); +-#else +- return input(); +-#endif +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = (yytext_ptr) + offset; +- break; +- } +- } +- } +- +- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ +- *(yy_c_buf_p) = '\0'; /* preserve yytext */ +- (yy_hold_char) = *++(yy_c_buf_p); +- +- return c; +-} +-#endif /* ifndef YY_NO_INPUT */ +- +-/** Immediately switch to a different input stream. +- * @param input_file A readable stream. +- * +- * @note This function does not reset the start condition to @c INITIAL . +- */ +- void yyrestart (FILE * input_file ) +-{ +- +- if ( ! YY_CURRENT_BUFFER ){ +- yyensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- yy_create_buffer(yyin,YY_BUF_SIZE ); +- } +- +- yy_init_buffer(YY_CURRENT_BUFFER,input_file ); +- yy_load_buffer_state( ); +-} +- +-/** Switch to a different input buffer. +- * @param new_buffer The new input buffer. +- * +- */ +- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +-{ +- +- /* TODO. We should be able to replace this entire function body +- * with +- * yypop_buffer_state(); +- * yypush_buffer_state(new_buffer); +- */ +- yyensure_buffer_stack (); +- if ( YY_CURRENT_BUFFER == new_buffer ) +- return; +- +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- yy_load_buffer_state( ); +- +- /* We don't actually know whether we did this switch during +- * EOF (yywrap()) processing, but the only time this flag +- * is looked at is after yywrap() is called, so it's safe +- * to go ahead and always set it. +- */ +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-static void yy_load_buffer_state (void) +-{ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; +- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; +- (yy_hold_char) = *(yy_c_buf_p); +-} +- +-/** Allocate and initialize an input buffer state. +- * @param file A readable stream. +- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. +- * +- * @return the allocated buffer state. +- */ +- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +-{ +- YY_BUFFER_STATE b; +- +- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); +- +- b->yy_buf_size = size; +- +- /* yy_ch_buf has to be 2 characters longer than the size given because +- * we need to put in 2 end-of-buffer characters. +- */ +- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); +- +- b->yy_is_our_buffer = 1; +- +- yy_init_buffer(b,file ); +- +- return b; +-} +- +-/** Destroy the buffer. +- * @param b a buffer created with yy_create_buffer() +- * +- */ +- void yy_delete_buffer (YY_BUFFER_STATE b ) +-{ +- +- if ( ! b ) +- return; +- +- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ +- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; +- +- if ( b->yy_is_our_buffer ) +- yyfree((void *) b->yy_ch_buf ); +- +- yyfree((void *) b ); +-} +- +-#ifndef __cplusplus +-extern int isatty (int ); +-#endif /* __cplusplus */ +- +-/* Initializes or reinitializes a buffer. +- * This function is sometimes called more than once on the same buffer, +- * such as during a yyrestart() or at EOF. +- */ +- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) +- +-{ +- int oerrno = errno; +- +- yy_flush_buffer(b ); +- +- b->yy_input_file = file; +- b->yy_fill_buffer = 1; +- +- /* If b is the current buffer, then yy_init_buffer was _probably_ +- * called from yyrestart() or through yy_get_next_buffer. +- * In that case, we don't want to reset the lineno or column. +- */ +- if (b != YY_CURRENT_BUFFER){ +- b->yy_bs_lineno = 1; +- b->yy_bs_column = 0; +- } +- +- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +- +- errno = oerrno; +-} +- +-/** Discard all buffered characters. On the next scan, YY_INPUT will be called. +- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. +- * +- */ +- void yy_flush_buffer (YY_BUFFER_STATE b ) +-{ +- if ( ! b ) +- return; +- +- b->yy_n_chars = 0; +- +- /* We always need two end-of-buffer characters. The first causes +- * a transition to the end-of-buffer state. The second causes +- * a jam in that state. +- */ +- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; +- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; +- +- b->yy_buf_pos = &b->yy_ch_buf[0]; +- +- b->yy_at_bol = 1; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- if ( b == YY_CURRENT_BUFFER ) +- yy_load_buffer_state( ); +-} +- +-/** Pushes the new state onto the stack. The new state becomes +- * the current state. This function will allocate the stack +- * if necessary. +- * @param new_buffer The new state. +- * +- */ +-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +-{ +- if (new_buffer == NULL) +- return; +- +- yyensure_buffer_stack(); +- +- /* This block is copied from yy_switch_to_buffer. */ +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- /* Only push if top exists. Otherwise, replace top. */ +- if (YY_CURRENT_BUFFER) +- (yy_buffer_stack_top)++; +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- +- /* copied from yy_switch_to_buffer. */ +- yy_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-/** Removes and deletes the top of the stack, if present. +- * The next element becomes the new top. +- * +- */ +-void yypop_buffer_state (void) +-{ +- if (!YY_CURRENT_BUFFER) +- return; +- +- yy_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- if ((yy_buffer_stack_top) > 0) +- --(yy_buffer_stack_top); +- +- if (YY_CURRENT_BUFFER) { +- yy_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +- } +-} +- +-/* Allocates the stack if it does not exist. +- * Guarantees space for at least one push. +- */ +-static void yyensure_buffer_stack (void) +-{ +- yy_size_t num_to_alloc; +- +- if (!(yy_buffer_stack)) { +- +- /* First allocation is just for 2 elements, since we don't know if this +- * scanner will even need a stack. We use 2 instead of 1 to avoid an +- * immediate realloc on the next call. +- */ +- num_to_alloc = 1; +- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc +- (num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- +- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); +- +- (yy_buffer_stack_max) = num_to_alloc; +- (yy_buffer_stack_top) = 0; +- return; +- } +- +- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ +- +- /* Increase the buffer to prepare for a possible push. */ +- int grow_size = 8 /* arbitrary grow size */; +- +- num_to_alloc = (yy_buffer_stack_max) + grow_size; +- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc +- ((yy_buffer_stack), +- num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- +- /* zero only the new slots.*/ +- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); +- (yy_buffer_stack_max) = num_to_alloc; +- } +-} +- +-/** Setup the input buffer state to scan directly from a user-specified character buffer. +- * @param base the character buffer +- * @param size the size in bytes of the character buffer +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +-{ +- YY_BUFFER_STATE b; +- +- if ( size < 2 || +- base[size-2] != YY_END_OF_BUFFER_CHAR || +- base[size-1] != YY_END_OF_BUFFER_CHAR ) +- /* They forgot to leave room for the EOB's. */ +- return 0; +- +- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); +- +- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ +- b->yy_buf_pos = b->yy_ch_buf = base; +- b->yy_is_our_buffer = 0; +- b->yy_input_file = 0; +- b->yy_n_chars = b->yy_buf_size; +- b->yy_is_interactive = 0; +- b->yy_at_bol = 1; +- b->yy_fill_buffer = 0; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- yy_switch_to_buffer(b ); +- +- return b; +-} +- +-/** Setup the input buffer state to scan a string. The next call to yylex() will +- * scan from a @e copy of @a str. +- * @param yystr a NUL-terminated string to scan +- * +- * @return the newly allocated buffer state object. +- * @note If you want to scan bytes that may contain NUL values, then use +- * yy_scan_bytes() instead. +- */ +-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +-{ +- +- return yy_scan_bytes(yystr,strlen(yystr) ); +-} +- +-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will +- * scan from a @e copy of @a bytes. +- * @param bytes the byte buffer to scan +- * @param len the number of bytes in the buffer pointed to by @a bytes. +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +-{ +- YY_BUFFER_STATE b; +- char *buf; +- yy_size_t n, i; +- +- /* Get memory for full buffer, including space for trailing EOB's. */ +- n = _yybytes_len + 2; +- buf = (char *) yyalloc(n ); +- if ( ! buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); +- +- for ( i = 0; i < _yybytes_len; ++i ) +- buf[i] = yybytes[i]; +- +- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; +- +- b = yy_scan_buffer(buf,n ); +- if ( ! b ) +- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); +- +- /* It's okay to grow etc. this buffer, and we should throw it +- * away when we're done. +- */ +- b->yy_is_our_buffer = 1; +- +- return b; +-} +- +-#ifndef YY_EXIT_FAILURE +-#define YY_EXIT_FAILURE 2 +-#endif +- +-static void yy_fatal_error (yyconst char* msg ) +-{ +- (void) fprintf( stderr, "%s\n", msg ); +- exit( YY_EXIT_FAILURE ); +-} +- +-/* Redefine yyless() so it works in section 3 code. */ +- +-#undef yyless +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up yytext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- yytext[yyleng] = (yy_hold_char); \ +- (yy_c_buf_p) = yytext + yyless_macro_arg; \ +- (yy_hold_char) = *(yy_c_buf_p); \ +- *(yy_c_buf_p) = '\0'; \ +- yyleng = yyless_macro_arg; \ +- } \ +- while ( 0 ) +- +-/* Accessor methods (get/set functions) to struct members. */ +- +-/** Get the current line number. +- * +- */ +-int yyget_lineno (void) +-{ +- +- return yylineno; +-} +- +-/** Get the input stream. +- * +- */ +-FILE *yyget_in (void) +-{ +- return yyin; +-} +- +-/** Get the output stream. +- * +- */ +-FILE *yyget_out (void) +-{ +- return yyout; +-} +- +-/** Get the length of the current token. +- * +- */ +-yy_size_t yyget_leng (void) +-{ +- return yyleng; +-} +- +-/** Get the current token. +- * +- */ +- +-char *yyget_text (void) +-{ +- return yytext; +-} +- +-/** Set the current line number. +- * @param line_number +- * +- */ +-void yyset_lineno (int line_number ) +-{ +- +- yylineno = line_number; +-} +- +-/** Set the input stream. This does not discard the current +- * input buffer. +- * @param in_str A readable stream. +- * +- * @see yy_switch_to_buffer +- */ +-void yyset_in (FILE * in_str ) +-{ +- yyin = in_str ; +-} +- +-void yyset_out (FILE * out_str ) +-{ +- yyout = out_str ; +-} +- +-int yyget_debug (void) +-{ +- return yy_flex_debug; +-} +- +-void yyset_debug (int bdebug ) +-{ +- yy_flex_debug = bdebug ; +-} +- +-static int yy_init_globals (void) +-{ +- /* Initialization is the same as for the non-reentrant scanner. +- * This function is called from yylex_destroy(), so don't allocate here. +- */ +- +- (yy_buffer_stack) = 0; +- (yy_buffer_stack_top) = 0; +- (yy_buffer_stack_max) = 0; +- (yy_c_buf_p) = (char *) 0; +- (yy_init) = 0; +- (yy_start) = 0; +- +-/* Defined in main.c */ +-#ifdef YY_STDINIT +- yyin = stdin; +- yyout = stdout; +-#else +- yyin = (FILE *) 0; +- yyout = (FILE *) 0; +-#endif +- +- /* For future reference: Set errno on error, since we are called by +- * yylex_init() +- */ +- return 0; +-} +- +-/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +-int yylex_destroy (void) +-{ +- +- /* Pop the buffer stack, destroying each element. */ +- while(YY_CURRENT_BUFFER){ +- yy_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- yypop_buffer_state(); +- } +- +- /* Destroy the stack itself. */ +- yyfree((yy_buffer_stack) ); +- (yy_buffer_stack) = NULL; +- +- /* Reset the globals. This is important in a non-reentrant scanner so the next time +- * yylex() is called, initialization will occur. */ +- yy_init_globals( ); +- +- return 0; +-} +- +-/* +- * Internal utility routines. +- */ +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +-{ +- register int i; +- for ( i = 0; i < n; ++i ) +- s1[i] = s2[i]; +-} +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * s ) +-{ +- register int n; +- for ( n = 0; s[n]; ++n ) +- ; +- +- return n; +-} +-#endif +- +-void *yyalloc (yy_size_t size ) +-{ +- return (void *) malloc( size ); +-} +- +-void *yyrealloc (void * ptr, yy_size_t size ) +-{ +- /* The cast to (char *) in the following accommodates both +- * implementations that use char* generic pointers, and those +- * that use void* generic pointers. It works with the latter +- * because both ANSI C and C++ allow castless assignment from +- * any pointer type to void*, and deal with argument conversions +- * as though doing an assignment. +- */ +- return (void *) realloc( (char *) ptr, size ); +-} +- +-void yyfree (void * ptr ) +-{ +- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +-} +- +-#define YYTABLES_NAME "yytables" +- +-#line 94 "deflex.l" +- +- +-#ifndef yywrap +-/* Needed for lex, though not flex. */ +-int yywrap(void) { return 1; } +-#endif +- +diff -Nur binutils-2.24.orig/binutils/defparse.c binutils-2.24/binutils/defparse.c +--- binutils-2.24.orig/binutils/defparse.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/defparse.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2142 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton implementation for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "2.3" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Using locations. */ +-#define YYLSP_NEEDED 0 +- +- +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- NAME = 258, +- LIBRARY = 259, +- DESCRIPTION = 260, +- STACKSIZE = 261, +- HEAPSIZE = 262, +- CODE = 263, +- DATA = 264, +- SECTIONS = 265, +- EXPORTS = 266, +- IMPORTS = 267, +- VERSIONK = 268, +- BASE = 269, +- CONSTANT = 270, +- READ = 271, +- WRITE = 272, +- EXECUTE = 273, +- SHARED = 274, +- NONSHARED = 275, +- NONAME = 276, +- PRIVATE = 277, +- SINGLE = 278, +- MULTIPLE = 279, +- INITINSTANCE = 280, +- INITGLOBAL = 281, +- TERMINSTANCE = 282, +- TERMGLOBAL = 283, +- EQUAL = 284, +- ID = 285, +- NUMBER = 286 +- }; +-#endif +-/* Tokens. */ +-#define NAME 258 +-#define LIBRARY 259 +-#define DESCRIPTION 260 +-#define STACKSIZE 261 +-#define HEAPSIZE 262 +-#define CODE 263 +-#define DATA 264 +-#define SECTIONS 265 +-#define EXPORTS 266 +-#define IMPORTS 267 +-#define VERSIONK 268 +-#define BASE 269 +-#define CONSTANT 270 +-#define READ 271 +-#define WRITE 272 +-#define EXECUTE 273 +-#define SHARED 274 +-#define NONSHARED 275 +-#define NONAME 276 +-#define PRIVATE 277 +-#define SINGLE 278 +-#define MULTIPLE 279 +-#define INITINSTANCE 280 +-#define INITGLOBAL 281 +-#define TERMINSTANCE 282 +-#define TERMGLOBAL 283 +-#define EQUAL 284 +-#define ID 285 +-#define NUMBER 286 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 1 "defparse.y" +- /* defparse.y - parser for .def files */ +- +-/* Copyright 1995, 1997, 1998, 1999, 2001, 2004, 2005, 2007 +- Free Software Foundation, Inc. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +-#include "sysdep.h" +-#include "bfd.h" +-#include "libiberty.h" +-#include "dlltool.h" +- +- +-/* Enabling traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* Enabling the token table. */ +-#ifndef YYTOKEN_TABLE +-# define YYTOKEN_TABLE 0 +-#endif +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 29 "defparse.y" +-{ +- char *id; +- const char *id_const; +- int number; +-} +-/* Line 193 of yacc.c. */ +-#line 192 "defparse.c" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +- +- +-/* Copy the second part of user declarations. */ +- +- +-/* Line 216 of yacc.c. */ +-#line 205 "defparse.c" +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; +-#else +-typedef short int yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(msgid) dgettext ("bison-runtime", msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(msgid) msgid +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(e) ((void) (e)) +-#else +-# define YYUSE(e) /* empty */ +-#endif +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(n) (n) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int i) +-#else +-static int +-YYID (i) +- int i; +-#endif +-{ +- return i; +-} +-#endif +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined _STDLIB_H \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss; +- YYSTYPE yyvs; +- }; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-/* Copy COUNT objects from FROM to TO. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(To, From, Count) \ +- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +-# else +-# define YYCOPY(To, From, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (To)[yyi] = (From)[yyi]; \ +- } \ +- while (YYID (0)) +-# endif +-# endif +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack, Stack, yysize); \ +- Stack = &yyptr->Stack; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) +- +-#endif +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 66 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 141 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 36 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 26 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 98 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 139 +- +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 286 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 34, 2, 32, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 33, 2, 2, 35, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +- 25, 26, 27, 28, 29, 30, 31 +-}; +- +-#if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint16 yyprhs[] = +-{ +- 0, 0, 3, 6, 8, 12, 17, 20, 23, 27, +- 31, 34, 37, 40, 43, 46, 51, 52, 55, 64, +- 67, 69, 78, 87, 94, 101, 108, 115, 120, 125, +- 128, 130, 133, 137, 139, 141, 142, 145, 146, 148, +- 150, 152, 154, 156, 158, 160, 162, 163, 165, 166, +- 168, 169, 171, 172, 174, 176, 178, 180, 182, 184, +- 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, +- 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, +- 227, 230, 234, 238, 240, 241, 244, 245, 248, 249, +- 252, 253, 257, 258, 259, 263, 265, 267, 269 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int8 yyrhs[] = +-{ +- 37, 0, -1, 37, 38, -1, 38, -1, 3, 55, +- 59, -1, 4, 55, 59, 60, -1, 11, 39, -1, +- 5, 30, -1, 6, 31, 47, -1, 7, 31, 47, +- -1, 8, 45, -1, 9, 45, -1, 10, 43, -1, +- 12, 41, -1, 13, 31, -1, 13, 31, 32, 31, +- -1, -1, 39, 40, -1, 30, 58, 56, 50, 49, +- 51, 52, 57, -1, 41, 42, -1, 42, -1, 30, +- 33, 30, 32, 30, 32, 30, 57, -1, 30, 33, +- 30, 32, 30, 32, 31, 57, -1, 30, 33, 30, +- 32, 30, 57, -1, 30, 33, 30, 32, 31, 57, +- -1, 30, 32, 30, 32, 30, 57, -1, 30, 32, +- 30, 32, 31, 57, -1, 30, 32, 30, 57, -1, +- 30, 32, 31, 57, -1, 43, 44, -1, 44, -1, +- 30, 45, -1, 45, 46, 48, -1, 48, -1, 34, +- -1, -1, 34, 31, -1, -1, 16, -1, 17, -1, +- 18, -1, 19, -1, 20, -1, 23, -1, 24, -1, +- 15, -1, -1, 21, -1, -1, 9, -1, -1, 22, +- -1, -1, 3, -1, 5, -1, 6, -1, 7, -1, +- 8, -1, 9, -1, 10, -1, 11, -1, 12, -1, +- 13, -1, 14, -1, 15, -1, 21, -1, 22, -1, +- 16, -1, 17, -1, 18, -1, 19, -1, 20, -1, +- 23, -1, 24, -1, 25, -1, 26, -1, 27, -1, +- 28, -1, 30, -1, 32, 53, -1, 32, 54, -1, +- 53, 32, 54, -1, 30, 32, 54, -1, 54, -1, +- -1, 35, 31, -1, -1, 29, 54, -1, -1, 33, +- 54, -1, -1, 14, 33, 31, -1, -1, -1, 60, +- 46, 61, -1, 25, -1, 26, -1, 27, -1, 28, +- -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const yytype_uint8 yyrline[] = +-{ +- 0, 49, 49, 50, 54, 55, 56, 57, 58, 59, +- 60, 61, 62, 63, 64, 65, 69, 71, 75, 80, +- 81, 85, 87, 89, 91, 93, 95, 97, 99, 104, +- 105, 109, 113, 114, 118, 119, 121, 122, 126, 127, +- 128, 129, 130, 131, 132, 136, 137, 141, 142, 146, +- 147, 151, 152, 155, 160, 161, 162, 163, 164, 165, +- 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, +- 176, 177, 178, 179, 180, 181, 182, 183, 186, 187, +- 193, 199, 205, 212, 213, 217, 218, 222, 223, 227, +- 228, 231, 232, 235, 237, 241, 242, 243, 244 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "NAME", "LIBRARY", "DESCRIPTION", +- "STACKSIZE", "HEAPSIZE", "CODE", "DATA", "SECTIONS", "EXPORTS", +- "IMPORTS", "VERSIONK", "BASE", "CONSTANT", "READ", "WRITE", "EXECUTE", +- "SHARED", "NONSHARED", "NONAME", "PRIVATE", "SINGLE", "MULTIPLE", +- "INITINSTANCE", "INITGLOBAL", "TERMINSTANCE", "TERMGLOBAL", "EQUAL", +- "ID", "NUMBER", "'.'", "'='", "','", "'@'", "$accept", "start", +- "command", "explist", "expline", "implist", "impline", "seclist", +- "secline", "attr_list", "opt_comma", "opt_number", "attr", +- "opt_CONSTANT", "opt_NONAME", "opt_DATA", "opt_PRIVATE", +- "keyword_as_name", "opt_name2", "opt_name", "opt_ordinal", +- "opt_import_name", "opt_equal_name", "opt_base", "option_list", "option", 0 +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, +- 285, 286, 46, 61, 44, 64 +-}; +-# endif +- +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 36, 37, 37, 38, 38, 38, 38, 38, 38, +- 38, 38, 38, 38, 38, 38, 39, 39, 40, 41, +- 41, 42, 42, 42, 42, 42, 42, 42, 42, 43, +- 43, 44, 45, 45, 46, 46, 47, 47, 48, 48, +- 48, 48, 48, 48, 48, 49, 49, 50, 50, 51, +- 51, 52, 52, 53, 53, 53, 53, 53, 53, 53, +- 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, +- 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, +- 54, 54, 54, 55, 55, 56, 56, 57, 57, 58, +- 58, 59, 59, 60, 60, 61, 61, 61, 61 +-}; +- +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 2, 1, 3, 4, 2, 2, 3, 3, +- 2, 2, 2, 2, 2, 4, 0, 2, 8, 2, +- 1, 8, 8, 6, 6, 6, 6, 4, 4, 2, +- 1, 2, 3, 1, 1, 0, 2, 0, 1, 1, +- 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, +- 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, +- 2, 3, 3, 1, 0, 2, 0, 2, 0, 2, +- 0, 3, 0, 0, 3, 1, 1, 1, 1 +-}; +- +-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state +- STATE-NUM when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 0, 84, 84, 0, 0, 0, 0, 0, 0, 16, +- 0, 0, 0, 3, 53, 54, 55, 56, 57, 58, +- 59, 60, 61, 62, 63, 64, 67, 68, 69, 70, +- 71, 65, 66, 72, 73, 74, 75, 76, 77, 78, +- 0, 0, 83, 92, 92, 7, 37, 37, 38, 39, +- 40, 41, 42, 43, 44, 10, 33, 11, 0, 12, +- 30, 6, 0, 13, 20, 14, 1, 2, 0, 79, +- 80, 0, 0, 4, 93, 0, 8, 9, 34, 0, +- 31, 29, 90, 17, 0, 0, 19, 0, 82, 81, +- 0, 5, 36, 32, 0, 86, 88, 88, 0, 15, +- 91, 0, 89, 0, 48, 0, 0, 27, 28, 0, +- 95, 96, 97, 98, 94, 85, 47, 46, 87, 88, +- 88, 88, 88, 45, 50, 25, 26, 0, 23, 24, +- 49, 52, 88, 88, 51, 88, 21, 22, 18 +-}; +- +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int16 yydefgoto[] = +-{ +- -1, 12, 13, 61, 83, 63, 64, 59, 60, 55, +- 79, 76, 56, 124, 117, 131, 135, 41, 42, 43, +- 104, 107, 95, 73, 91, 114 +-}; +- +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -96 +-static const yytype_int8 yypact[] = +-{ +- 38, 61, 61, -22, -1, 8, 39, 39, -7, -96, +- 23, 59, 92, -96, -96, -96, -96, -96, -96, -96, +- -96, -96, -96, -96, -96, -96, -96, -96, -96, -96, +- -96, -96, -96, -96, -96, -96, -96, -96, -96, 62, +- 61, 79, -96, 96, 96, -96, 80, 80, -96, -96, +- -96, -96, -96, -96, -96, -13, -96, -13, 39, -7, +- -96, 82, 1, 23, -96, 81, -96, -96, 61, 79, +- -96, 61, 83, -96, -96, 84, -96, -96, -96, 39, +- -13, -96, 85, -96, 5, 87, -96, 88, -96, -96, +- 89, -12, -96, -96, 61, 86, -20, 93, 91, -96, +- -96, -8, -96, 94, 103, 61, 30, -96, -96, 76, +- -96, -96, -96, -96, -96, -96, -96, 111, -96, 93, +- 93, 0, 93, -96, 118, -96, -96, 78, -96, -96, +- -96, 106, 93, 93, -96, 93, -96, -96, -96 +-}; +- +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int16 yypgoto[] = +-{ +- -96, -96, 117, -96, -96, -96, 67, -96, 72, -6, +- 41, 90, 54, -96, -96, -96, -96, 95, -40, 132, +- -96, -95, -96, 97, -96, -96 +-}; +- +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If zero, do what YYDEFACT says. +- If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -36 +-static const yytype_int16 yytable[] = +-{ +- 70, 57, 108, -35, -35, -35, -35, -35, 45, 105, +- -35, -35, 106, -35, -35, -35, -35, 110, 111, 112, +- 113, 78, 78, 58, 125, 126, 128, 129, 88, 105, +- 46, 89, 127, 84, 85, 96, 97, 136, 137, 47, +- 138, 1, 2, 3, 4, 5, 6, 7, 8, 9, +- 10, 11, 80, 62, 102, 48, 49, 50, 51, 52, +- 119, 120, 53, 54, 14, 118, 15, 16, 17, 18, +- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, +- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, +- 65, 39, 66, 40, 68, 1, 2, 3, 4, 5, +- 6, 7, 8, 9, 10, 11, 121, 122, 132, 133, +- 72, 71, 82, 87, 75, 92, 90, 98, 94, 99, +- 100, 103, 105, 109, 116, 115, 123, 130, 134, 67, +- 86, 81, 101, 93, 44, 69, 0, 77, 0, 0, +- 0, 74 +-}; +- +-static const yytype_int16 yycheck[] = +-{ +- 40, 7, 97, 16, 17, 18, 19, 20, 30, 29, +- 23, 24, 32, 25, 26, 27, 28, 25, 26, 27, +- 28, 34, 34, 30, 119, 120, 121, 122, 68, 29, +- 31, 71, 32, 32, 33, 30, 31, 132, 133, 31, +- 135, 3, 4, 5, 6, 7, 8, 9, 10, 11, +- 12, 13, 58, 30, 94, 16, 17, 18, 19, 20, +- 30, 31, 23, 24, 3, 105, 5, 6, 7, 8, +- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, +- 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, +- 31, 30, 0, 32, 32, 3, 4, 5, 6, 7, +- 8, 9, 10, 11, 12, 13, 30, 31, 30, 31, +- 14, 32, 30, 32, 34, 31, 33, 30, 33, 31, +- 31, 35, 29, 32, 21, 31, 15, 9, 22, 12, +- 63, 59, 91, 79, 2, 40, -1, 47, -1, -1, +- -1, 44 +-}; +- +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, +- 12, 13, 37, 38, 3, 5, 6, 7, 8, 9, +- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +- 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, +- 32, 53, 54, 55, 55, 30, 31, 31, 16, 17, +- 18, 19, 20, 23, 24, 45, 48, 45, 30, 43, +- 44, 39, 30, 41, 42, 31, 0, 38, 32, 53, +- 54, 32, 14, 59, 59, 34, 47, 47, 34, 46, +- 45, 44, 30, 40, 32, 33, 42, 32, 54, 54, +- 33, 60, 31, 48, 33, 58, 30, 31, 30, 31, +- 31, 46, 54, 35, 56, 29, 32, 57, 57, 32, +- 25, 26, 27, 28, 61, 31, 21, 50, 54, 30, +- 31, 30, 31, 15, 49, 57, 57, 32, 57, 57, +- 9, 51, 30, 31, 22, 52, 57, 57, 57 +-}; +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. */ +- +-#define YYFAIL goto yyerrlab +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY && yylen == 1) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK (1); \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) +- +- +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +- If N is 0, then set CURRENT to the empty location which ends +- the previous symbol: RHS[0] (always defined). */ +- +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +-#ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (YYID (N)) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (YYID (0)) +-#endif +- +- +-/* YY_LOCATION_PRINT -- Print the location on the stream. +- This macro was not mandated originally: define only if we know +- we won't break user code: when these are the locations we know. */ +- +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +-# define YY_LOCATION_PRINT(File, Loc) \ +- fprintf (File, "%d.%d-%d.%d", \ +- (Loc).first_line, (Loc).first_column, \ +- (Loc).last_line, (Loc).last_column) +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif +- +- +-/* YYLEX -- calling `yylex' with the right arguments. */ +- +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); +-# endif +- switch (yytype) +- { +- default: +- break; +- } +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +-#else +-static void +-yy_stack_print (bottom, top) +- yytype_int16 *bottom; +- yytype_int16 *top; +-#endif +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; bottom <= top; ++bottom) +- YYFPRINTF (stderr, " %d", *bottom); +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif +-{ +- int yynrhs = yyr2[yyrule]; +- int yyi; +- unsigned long int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- fprintf (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- fprintf (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static YYSIZE_T +-yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into YYRESULT an error message about the unexpected token +- YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not +- copy anything; just return the number of bytes that would be +- copied. As a special case, return 0 if an ordinary "syntax error" +- message will do. Return YYSIZE_MAXIMUM if overflow occurs during +- size calculation. */ +-static YYSIZE_T +-yysyntax_error (char *yyresult, int yystate, int yychar) +-{ +- int yyn = yypact[yystate]; +- +- if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) +- return 0; +- else +- { +- int yytype = YYTRANSLATE (yychar); +- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); +- YYSIZE_T yysize = yysize0; +- YYSIZE_T yysize1; +- int yysize_overflow = 0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- int yyx; +- +-# if 0 +- /* This is so xgettext sees the translatable formats that are +- constructed on the fly. */ +- YY_("syntax error, unexpected %s"); +- YY_("syntax error, unexpected %s, expecting %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +-# endif +- char *yyfmt; +- char const *yyf; +- static char const yyunexpected[] = "syntax error, unexpected %s"; +- static char const yyexpecting[] = ", expecting %s"; +- static char const yyor[] = " or %s"; +- char yyformat[sizeof yyunexpected +- + sizeof yyexpecting - 1 +- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) +- * (sizeof yyor - 1))]; +- char const *yyprefix = yyexpecting; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 1; +- +- yyarg[0] = yytname[yytype]; +- yyfmt = yystpcpy (yyformat, yyunexpected); +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- yyformat[sizeof yyunexpected - 1] = '\0'; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- yysize1 = yysize + yytnamerr (0, yytname[yyx]); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- yyfmt = yystpcpy (yyfmt, yyprefix); +- yyprefix = yyor; +- } +- +- yyf = YY_(yyformat); +- yysize1 = yysize + yystrlen (yyf); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- +- if (yysize_overflow) +- return YYSIZE_MAXIMUM; +- +- if (yyresult) +- { +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- char *yyp = yyresult; +- int yyi = 0; +- while ((*yyp = *yyf) != '\0') +- { +- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyf += 2; +- } +- else +- { +- yyp++; +- yyf++; +- } +- } +- } +- return yysize; +- } +-} +-#endif /* YYERROR_VERBOSE */ +- +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif +-{ +- YYUSE (yyvaluep); +- +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- switch (yytype) +- { +- +- default: +- break; +- } +-} +- +- +-/* Prevent warnings from -Wmissing-prototypes. */ +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ +- +- +- +-/* The look-ahead symbol. */ +-int yychar; +- +-/* The semantic value of the look-ahead symbol. */ +-YYSTYPE yylval; +- +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif +-{ +- +- int yystate; +- int yyn; +- int yyresult; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- /* Look-ahead token as an internal (translated) token number. */ +- int yytoken = 0; +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +- /* Three stacks and their tools: +- `yyss': related to states, +- `yyvs': related to semantic values, +- `yyls': related to locations. +- +- Refer to the stacks thru separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss = yyssa; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs = yyvsa; +- YYSTYPE *yyvsp; +- +- +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- YYSIZE_T yystacksize = YYINITDEPTH; +- +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- +- /* Initialize stack pointers. +- Waste one element of value and location stack +- so that they stay on the same level as the state stack. +- The wasted elements are never initialized. */ +- +- yyssp = yyss; +- yyvsp = yyvs; +- +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss); +- YYSTACK_RELOCATE (yyvs); +- +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- look-ahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to look-ahead token. */ +- yyn = yypact[yystate]; +- if (yyn == YYPACT_NINF) +- goto yydefault; +- +- /* Not known => get a look-ahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yyn == 0 || yyn == YYTABLE_NINF) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the look-ahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- yystate = yyn; +- *++yyvsp = yylval; +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 4: +-#line 54 "defparse.y" +- { def_name ((yyvsp[(2) - (3)].id), (yyvsp[(3) - (3)].number)); } +- break; +- +- case 5: +-#line 55 "defparse.y" +- { def_library ((yyvsp[(2) - (4)].id), (yyvsp[(3) - (4)].number)); } +- break; +- +- case 7: +-#line 57 "defparse.y" +- { def_description ((yyvsp[(2) - (2)].id));} +- break; +- +- case 8: +-#line 58 "defparse.y" +- { def_stacksize ((yyvsp[(2) - (3)].number), (yyvsp[(3) - (3)].number));} +- break; +- +- case 9: +-#line 59 "defparse.y" +- { def_heapsize ((yyvsp[(2) - (3)].number), (yyvsp[(3) - (3)].number));} +- break; +- +- case 10: +-#line 60 "defparse.y" +- { def_code ((yyvsp[(2) - (2)].number));} +- break; +- +- case 11: +-#line 61 "defparse.y" +- { def_data ((yyvsp[(2) - (2)].number));} +- break; +- +- case 14: +-#line 64 "defparse.y" +- { def_version ((yyvsp[(2) - (2)].number),0);} +- break; +- +- case 15: +-#line 65 "defparse.y" +- { def_version ((yyvsp[(2) - (4)].number),(yyvsp[(4) - (4)].number));} +- break; +- +- case 18: +-#line 77 "defparse.y" +- { def_exports ((yyvsp[(1) - (8)].id), (yyvsp[(2) - (8)].id), (yyvsp[(3) - (8)].number), (yyvsp[(4) - (8)].number), (yyvsp[(5) - (8)].number), (yyvsp[(6) - (8)].number), (yyvsp[(7) - (8)].number), (yyvsp[(8) - (8)].id));} +- break; +- +- case 21: +-#line 86 "defparse.y" +- { def_import ((yyvsp[(1) - (8)].id),(yyvsp[(3) - (8)].id),(yyvsp[(5) - (8)].id),(yyvsp[(7) - (8)].id), 0, (yyvsp[(8) - (8)].id)); } +- break; +- +- case 22: +-#line 88 "defparse.y" +- { def_import ((yyvsp[(1) - (8)].id),(yyvsp[(3) - (8)].id),(yyvsp[(5) - (8)].id), 0,(yyvsp[(7) - (8)].number), (yyvsp[(8) - (8)].id)); } +- break; +- +- case 23: +-#line 90 "defparse.y" +- { def_import ((yyvsp[(1) - (6)].id),(yyvsp[(3) - (6)].id), 0,(yyvsp[(5) - (6)].id), 0, (yyvsp[(6) - (6)].id)); } +- break; +- +- case 24: +-#line 92 "defparse.y" +- { def_import ((yyvsp[(1) - (6)].id),(yyvsp[(3) - (6)].id), 0, 0,(yyvsp[(5) - (6)].number), (yyvsp[(6) - (6)].id)); } +- break; +- +- case 25: +-#line 94 "defparse.y" +- { def_import ( 0,(yyvsp[(1) - (6)].id),(yyvsp[(3) - (6)].id),(yyvsp[(5) - (6)].id), 0, (yyvsp[(6) - (6)].id)); } +- break; +- +- case 26: +-#line 96 "defparse.y" +- { def_import ( 0,(yyvsp[(1) - (6)].id),(yyvsp[(3) - (6)].id), 0,(yyvsp[(5) - (6)].number), (yyvsp[(6) - (6)].id)); } +- break; +- +- case 27: +-#line 98 "defparse.y" +- { def_import ( 0,(yyvsp[(1) - (4)].id), 0,(yyvsp[(3) - (4)].id), 0, (yyvsp[(4) - (4)].id)); } +- break; +- +- case 28: +-#line 100 "defparse.y" +- { def_import ( 0,(yyvsp[(1) - (4)].id), 0, 0,(yyvsp[(3) - (4)].number), (yyvsp[(4) - (4)].id)); } +- break; +- +- case 31: +-#line 109 "defparse.y" +- { def_section ((yyvsp[(1) - (2)].id),(yyvsp[(2) - (2)].number));} +- break; +- +- case 36: +-#line 121 "defparse.y" +- { (yyval.number)=(yyvsp[(2) - (2)].number);} +- break; +- +- case 37: +-#line 122 "defparse.y" +- { (yyval.number)=-1;} +- break; +- +- case 38: +-#line 126 "defparse.y" +- { (yyval.number) = 1; } +- break; +- +- case 39: +-#line 127 "defparse.y" +- { (yyval.number) = 2; } +- break; +- +- case 40: +-#line 128 "defparse.y" +- { (yyval.number) = 4; } +- break; +- +- case 41: +-#line 129 "defparse.y" +- { (yyval.number) = 8; } +- break; +- +- case 42: +-#line 130 "defparse.y" +- { (yyval.number) = 0; } +- break; +- +- case 43: +-#line 131 "defparse.y" +- { (yyval.number) = 0; } +- break; +- +- case 44: +-#line 132 "defparse.y" +- { (yyval.number) = 0; } +- break; +- +- case 45: +-#line 136 "defparse.y" +- {(yyval.number)=1;} +- break; +- +- case 46: +-#line 137 "defparse.y" +- {(yyval.number)=0;} +- break; +- +- case 47: +-#line 141 "defparse.y" +- {(yyval.number)=1;} +- break; +- +- case 48: +-#line 142 "defparse.y" +- {(yyval.number)=0;} +- break; +- +- case 49: +-#line 146 "defparse.y" +- { (yyval.number) = 1; } +- break; +- +- case 50: +-#line 147 "defparse.y" +- { (yyval.number) = 0; } +- break; +- +- case 51: +-#line 151 "defparse.y" +- { (yyval.number) = 1; } +- break; +- +- case 52: +-#line 152 "defparse.y" +- { (yyval.number) = 0; } +- break; +- +- case 53: +-#line 155 "defparse.y" +- { (yyval.id_const) = "NAME"; } +- break; +- +- case 54: +-#line 160 "defparse.y" +- { (yyval.id_const) = "DESCRIPTION"; } +- break; +- +- case 55: +-#line 161 "defparse.y" +- { (yyval.id_const) = "STACKSIZE"; } +- break; +- +- case 56: +-#line 162 "defparse.y" +- { (yyval.id_const) = "HEAPSIZE"; } +- break; +- +- case 57: +-#line 163 "defparse.y" +- { (yyval.id_const) = "CODE"; } +- break; +- +- case 58: +-#line 164 "defparse.y" +- { (yyval.id_const) = "DATA"; } +- break; +- +- case 59: +-#line 165 "defparse.y" +- { (yyval.id_const) = "SECTIONS"; } +- break; +- +- case 60: +-#line 166 "defparse.y" +- { (yyval.id_const) = "EXPORTS"; } +- break; +- +- case 61: +-#line 167 "defparse.y" +- { (yyval.id_const) = "IMPORTS"; } +- break; +- +- case 62: +-#line 168 "defparse.y" +- { (yyval.id_const) = "VERSION"; } +- break; +- +- case 63: +-#line 169 "defparse.y" +- { (yyval.id_const) = "BASE"; } +- break; +- +- case 64: +-#line 170 "defparse.y" +- { (yyval.id_const) = "CONSTANT"; } +- break; +- +- case 65: +-#line 171 "defparse.y" +- { (yyval.id_const) = "NONAME"; } +- break; +- +- case 66: +-#line 172 "defparse.y" +- { (yyval.id_const) = "PRIVATE"; } +- break; +- +- case 67: +-#line 173 "defparse.y" +- { (yyval.id_const) = "READ"; } +- break; +- +- case 68: +-#line 174 "defparse.y" +- { (yyval.id_const) = "WRITE"; } +- break; +- +- case 69: +-#line 175 "defparse.y" +- { (yyval.id_const) = "EXECUTE"; } +- break; +- +- case 70: +-#line 176 "defparse.y" +- { (yyval.id_const) = "SHARED"; } +- break; +- +- case 71: +-#line 177 "defparse.y" +- { (yyval.id_const) = "NONSHARED"; } +- break; +- +- case 72: +-#line 178 "defparse.y" +- { (yyval.id_const) = "SINGLE"; } +- break; +- +- case 73: +-#line 179 "defparse.y" +- { (yyval.id_const) = "MULTIPLE"; } +- break; +- +- case 74: +-#line 180 "defparse.y" +- { (yyval.id_const) = "INITINSTANCE"; } +- break; +- +- case 75: +-#line 181 "defparse.y" +- { (yyval.id_const) = "INITGLOBAL"; } +- break; +- +- case 76: +-#line 182 "defparse.y" +- { (yyval.id_const) = "TERMINSTANCE"; } +- break; +- +- case 77: +-#line 183 "defparse.y" +- { (yyval.id_const) = "TERMGLOBAL"; } +- break; +- +- case 78: +-#line 186 "defparse.y" +- { (yyval.id) = (yyvsp[(1) - (1)].id); } +- break; +- +- case 79: +-#line 188 "defparse.y" +- { +- char *name = xmalloc (strlen ((yyvsp[(2) - (2)].id_const)) + 2); +- sprintf (name, ".%s", (yyvsp[(2) - (2)].id_const)); +- (yyval.id) = name; +- } +- break; +- +- case 80: +-#line 194 "defparse.y" +- { +- char *name = xmalloc (strlen ((yyvsp[(2) - (2)].id)) + 2); +- sprintf (name, ".%s", (yyvsp[(2) - (2)].id)); +- (yyval.id) = name; +- } +- break; +- +- case 81: +-#line 200 "defparse.y" +- { +- char *name = xmalloc (strlen ((yyvsp[(1) - (3)].id_const)) + 1 + strlen ((yyvsp[(3) - (3)].id)) + 1); +- sprintf (name, "%s.%s", (yyvsp[(1) - (3)].id_const), (yyvsp[(3) - (3)].id)); +- (yyval.id) = name; +- } +- break; +- +- case 82: +-#line 206 "defparse.y" +- { +- char *name = xmalloc (strlen ((yyvsp[(1) - (3)].id)) + 1 + strlen ((yyvsp[(3) - (3)].id)) + 1); +- sprintf (name, "%s.%s", (yyvsp[(1) - (3)].id), (yyvsp[(3) - (3)].id)); +- (yyval.id) = name; +- } +- break; +- +- case 83: +-#line 212 "defparse.y" +- { (yyval.id) =(yyvsp[(1) - (1)].id); } +- break; +- +- case 84: +-#line 213 "defparse.y" +- { (yyval.id)=""; } +- break; +- +- case 85: +-#line 217 "defparse.y" +- { (yyval.number)=(yyvsp[(2) - (2)].number);} +- break; +- +- case 86: +-#line 218 "defparse.y" +- { (yyval.number)=-1;} +- break; +- +- case 87: +-#line 222 "defparse.y" +- { (yyval.id) = (yyvsp[(2) - (2)].id); } +- break; +- +- case 88: +-#line 223 "defparse.y" +- { (yyval.id) = 0; } +- break; +- +- case 89: +-#line 227 "defparse.y" +- { (yyval.id) = (yyvsp[(2) - (2)].id); } +- break; +- +- case 90: +-#line 228 "defparse.y" +- { (yyval.id) = 0; } +- break; +- +- case 91: +-#line 231 "defparse.y" +- { (yyval.number)= (yyvsp[(3) - (3)].number);} +- break; +- +- case 92: +-#line 232 "defparse.y" +- { (yyval.number)=-1;} +- break; +- +- +-/* Line 1267 of yacc.c. */ +-#line 1929 "defparse.c" +- default: break; +- } +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- +- /* Now `shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ +-yyerrlab: +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +- { +- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); +- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) +- { +- YYSIZE_T yyalloc = 2 * yysize; +- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) +- yyalloc = YYSTACK_ALLOC_MAXIMUM; +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yyalloc); +- if (yymsg) +- yymsg_alloc = yyalloc; +- else +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- } +- } +- +- if (0 < yysize && yysize <= yymsg_alloc) +- { +- (void) yysyntax_error (yymsg, yystate, yychar); +- yyerror (yymsg); +- } +- else +- { +- yyerror (YY_("syntax error")); +- if (yysize != 0) +- goto yyexhaustedlab; +- } +- } +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse look-ahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse look-ahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule which action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (yyn != YYPACT_NINF) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- *++yyvsp = yylval; +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#ifndef yyoverflow +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEOF && yychar != YYEMPTY) +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- /* Do not reclaim the symbols of the rule which action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); +-} +- +- +- +diff -Nur binutils-2.24.orig/binutils/defparse.h binutils-2.24/binutils/defparse.h +--- binutils-2.24.orig/binutils/defparse.h 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/defparse.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,124 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton interface for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- NAME = 258, +- LIBRARY = 259, +- DESCRIPTION = 260, +- STACKSIZE = 261, +- HEAPSIZE = 262, +- CODE = 263, +- DATA = 264, +- SECTIONS = 265, +- EXPORTS = 266, +- IMPORTS = 267, +- VERSIONK = 268, +- BASE = 269, +- CONSTANT = 270, +- READ = 271, +- WRITE = 272, +- EXECUTE = 273, +- SHARED = 274, +- NONSHARED = 275, +- NONAME = 276, +- PRIVATE = 277, +- SINGLE = 278, +- MULTIPLE = 279, +- INITINSTANCE = 280, +- INITGLOBAL = 281, +- TERMINSTANCE = 282, +- TERMGLOBAL = 283, +- EQUAL = 284, +- ID = 285, +- NUMBER = 286 +- }; +-#endif +-/* Tokens. */ +-#define NAME 258 +-#define LIBRARY 259 +-#define DESCRIPTION 260 +-#define STACKSIZE 261 +-#define HEAPSIZE 262 +-#define CODE 263 +-#define DATA 264 +-#define SECTIONS 265 +-#define EXPORTS 266 +-#define IMPORTS 267 +-#define VERSIONK 268 +-#define BASE 269 +-#define CONSTANT 270 +-#define READ 271 +-#define WRITE 272 +-#define EXECUTE 273 +-#define SHARED 274 +-#define NONSHARED 275 +-#define NONAME 276 +-#define PRIVATE 277 +-#define SINGLE 278 +-#define MULTIPLE 279 +-#define INITINSTANCE 280 +-#define INITGLOBAL 281 +-#define TERMINSTANCE 282 +-#define TERMGLOBAL 283 +-#define EQUAL 284 +-#define ID 285 +-#define NUMBER 286 +- +- +- +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 29 "defparse.y" +-{ +- char *id; +- const char *id_const; +- int number; +-} +-/* Line 1529 of yacc.c. */ +-#line 117 "defparse.h" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +-extern YYSTYPE yylval; +- +diff -Nur binutils-2.24.orig/binutils/doc/addr2line.1 binutils-2.24/binutils/doc/addr2line.1 +--- binutils-2.24.orig/binutils/doc/addr2line.1 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/doc/addr2line.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,299 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "ADDR2LINE 1" +-.TH ADDR2LINE 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-addr2line \- convert addresses into file names and line numbers. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-addr2line [\fB\-a\fR|\fB\-\-addresses\fR] +- [\fB\-b\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] +- [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR]] +- [\fB\-e\fR \fIfilename\fR|\fB\-\-exe=\fR\fIfilename\fR] +- [\fB\-f\fR|\fB\-\-functions\fR] [\fB\-s\fR|\fB\-\-basename\fR] +- [\fB\-i\fR|\fB\-\-inlines\fR] +- [\fB\-p\fR|\fB\-\-pretty\-print\fR] +- [\fB\-j\fR|\fB\-\-section=\fR\fIname\fR] +- [\fB\-H\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] +- [addr addr ...] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBaddr2line\fR translates addresses into file names and line numbers. +-Given an address in an executable or an offset in a section of a relocatable +-object, it uses the debugging information to figure out which file name and +-line number are associated with it. +-.PP +-The executable or relocatable object to use is specified with the \fB\-e\fR +-option. The default is the file \fIa.out\fR. The section in the relocatable +-object to use is specified with the \fB\-j\fR option. +-.PP +-\&\fBaddr2line\fR has two modes of operation. +-.PP +-In the first, hexadecimal addresses are specified on the command line, +-and \fBaddr2line\fR displays the file name and line number for each +-address. +-.PP +-In the second, \fBaddr2line\fR reads hexadecimal addresses from +-standard input, and prints the file name and line number for each +-address on standard output. In this mode, \fBaddr2line\fR may be used +-in a pipe to convert dynamically chosen addresses. +-.PP +-The format of the output is \fB\s-1FILENAME:LINENO\s0\fR. The file name and +-line number for each input address is printed on separate lines. +-.PP +-If the \fB\-f\fR option is used, then each \fB\s-1FILENAME:LINENO\s0\fR +-line is preceded by \fB\s-1FUNCTIONNAME\s0\fR which is the name of the +-function containing the address. +-.PP +-If the \fB\-i\fR option is used and the code at the given address is +-present there because of inlining by the compiler then the +-\&\fB{\s-1FUNCTIONNAME\s0} \s-1FILENAME:LINENO\s0\fR information for the inlining +-function will be displayed afterwards. This continues recursively +-until there is no more inlining to report. +-.PP +-If the \fB\-a\fR option is used then the output is prefixed by the +-input address. +-.PP +-If the \fB\-p\fR option is used then the output for each input +-address is displayed on one, possibly quite long, line. If +-\&\fB\-p\fR is not used then the output is broken up into multiple +-lines, based on the paragraphs above. +-.PP +-If the file name or function name can not be determined, +-\&\fBaddr2line\fR will print two question marks in their place. If the +-line number can not be determined, \fBaddr2line\fR will print 0. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The long and short forms of options, shown here as alternatives, are +-equivalent. +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-addresses\fR" 4 +-.IX Item "--addresses" +-.PD +-Display the address before the function name, file and line number +-information. The address is printed with a \fB0x\fR prefix to easily +-identify it. +-.IP "\fB\-b\fR \fIbfdname\fR" 4 +-.IX Item "-b bfdname" +-.PD 0 +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-.PD +-Specify that the object-code format for the object files is +-\&\fIbfdname\fR. +-.IP "\fB\-C\fR" 4 +-.IX Item "-C" +-.PD 0 +-.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 +-.IX Item "--demangle[=style]" +-.PD +-Decode (\fIdemangle\fR) low-level symbol names into user-level names. +-Besides removing any initial underscore prepended by the system, this +-makes \*(C+ function names readable. Different compilers have different +-mangling styles. The optional demangling style argument can be used to +-choose an appropriate demangling style for your compiler. +-.IP "\fB\-e\fR \fIfilename\fR" 4 +-.IX Item "-e filename" +-.PD 0 +-.IP "\fB\-\-exe=\fR\fIfilename\fR" 4 +-.IX Item "--exe=filename" +-.PD +-Specify the name of the executable for which addresses should be +-translated. The default file is \fIa.out\fR. +-.IP "\fB\-f\fR" 4 +-.IX Item "-f" +-.PD 0 +-.IP "\fB\-\-functions\fR" 4 +-.IX Item "--functions" +-.PD +-Display function names as well as file and line number information. +-.IP "\fB\-s\fR" 4 +-.IX Item "-s" +-.PD 0 +-.IP "\fB\-\-basenames\fR" 4 +-.IX Item "--basenames" +-.PD +-Display only the base of each file name. +-.IP "\fB\-i\fR" 4 +-.IX Item "-i" +-.PD 0 +-.IP "\fB\-\-inlines\fR" 4 +-.IX Item "--inlines" +-.PD +-If the address belongs to a function that was inlined, the source +-information for all enclosing scopes back to the first non-inlined +-function will also be printed. For example, if \f(CW\*(C`main\*(C'\fR inlines +-\&\f(CW\*(C`callee1\*(C'\fR which inlines \f(CW\*(C`callee2\*(C'\fR, and address is from +-\&\f(CW\*(C`callee2\*(C'\fR, the source information for \f(CW\*(C`callee1\*(C'\fR and \f(CW\*(C`main\*(C'\fR +-will also be printed. +-.IP "\fB\-j\fR" 4 +-.IX Item "-j" +-.PD 0 +-.IP "\fB\-\-section\fR" 4 +-.IX Item "--section" +-.PD +-Read offsets relative to the specified section instead of absolute addresses. +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-pretty\-print\fR" 4 +-.IX Item "--pretty-print" +-.PD +-Make the output more human friendly: each location are printed on one line. +-If option \fB\-i\fR is specified, lines for all enclosing scopes are +-prefixed with \fB(inlined by)\fR. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/ar.1 binutils-2.24/binutils/doc/ar.1 +--- binutils-2.24.orig/binutils/doc/ar.1 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/doc/ar.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,461 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "AR 1" +-.TH AR 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-ar \- create, modify, and extract from archives +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-ar [\fB\-\-plugin\fR \fIname\fR] [\fB\-X32_64\fR] [\fB\-\fR]\fIp\fR[\fImod\fR [\fIrelpos\fR] [\fIcount\fR]] [\fB\-\-target\fR \fIbfdname\fR] \fIarchive\fR [\fImember\fR...] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-The \s-1GNU\s0 \fBar\fR program creates, modifies, and extracts from +-archives. An \fIarchive\fR is a single file holding a collection of +-other files in a structure that makes it possible to retrieve +-the original individual files (called \fImembers\fR of the archive). +-.PP +-The original files' contents, mode (permissions), timestamp, owner, and +-group are preserved in the archive, and can be restored on +-extraction. +-.PP +-\&\s-1GNU\s0 \fBar\fR can maintain archives whose members have names of any +-length; however, depending on how \fBar\fR is configured on your +-system, a limit on member-name length may be imposed for compatibility +-with archive formats maintained with other tools. If it exists, the +-limit is often 15 characters (typical of formats related to a.out) or 16 +-characters (typical of formats related to coff). +-.PP +-\&\fBar\fR is considered a binary utility because archives of this sort +-are most often used as \fIlibraries\fR holding commonly needed +-subroutines. +-.PP +-\&\fBar\fR creates an index to the symbols defined in relocatable +-object modules in the archive when you specify the modifier \fBs\fR. +-Once created, this index is updated in the archive whenever \fBar\fR +-makes a change to its contents (save for the \fBq\fR update operation). +-An archive with such an index speeds up linking to the library, and +-allows routines in the library to call each other without regard to +-their placement in the archive. +-.PP +-You may use \fBnm \-s\fR or \fBnm \-\-print\-armap\fR to list this index +-table. If an archive lacks the table, another form of \fBar\fR called +-\&\fBranlib\fR can be used to add just the table. +-.PP +-\&\s-1GNU\s0 \fBar\fR can optionally create a \fIthin\fR archive, +-which contains a symbol index and references to the original copies +-of the member files of the archive. This is useful for building +-libraries for use within a local build tree, where the relocatable +-objects are expected to remain available, and copying the contents of +-each object would only waste time and space. +-.PP +-An archive can either be \fIthin\fR or it can be normal. It cannot +-be both at the same time. Once an archive is created its format +-cannot be changed without first deleting it and then creating a new +-archive in its place. +-.PP +-Thin archives are also \fIflattened\fR, so that adding one thin +-archive to another thin archive does not nest it, as would happen with +-a normal archive. Instead the elements of the first archive are added +-individually to the second archive. +-.PP +-The paths to the elements of the archive are stored relative to the +-archive itself. +-.PP +-\&\s-1GNU\s0 \fBar\fR is designed to be compatible with two different +-facilities. You can control its activity using command-line options, +-like the different varieties of \fBar\fR on Unix systems; or, if you +-specify the single command-line option \fB\-M\fR, you can control it +-with a script supplied via standard input, like the \s-1MRI\s0 \*(L"librarian\*(R" +-program. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-\&\s-1GNU\s0 \fBar\fR allows you to mix the operation code \fIp\fR and modifier +-flags \fImod\fR in any order, within the first command-line argument. +-.PP +-If you wish, you may begin the first command-line argument with a +-dash. +-.PP +-The \fIp\fR keyletter specifies what operation to execute; it may be +-any of the following, but you must specify only one of them: +-.IP "\fBd\fR" 4 +-.IX Item "d" +-\&\fIDelete\fR modules from the archive. Specify the names of modules to +-be deleted as \fImember\fR...; the archive is untouched if you +-specify no files to delete. +-.Sp +-If you specify the \fBv\fR modifier, \fBar\fR lists each module +-as it is deleted. +-.IP "\fBm\fR" 4 +-.IX Item "m" +-Use this operation to \fImove\fR members in an archive. +-.Sp +-The ordering of members in an archive can make a difference in how +-programs are linked using the library, if a symbol is defined in more +-than one member. +-.Sp +-If no modifiers are used with \f(CW\*(C`m\*(C'\fR, any members you name in the +-\&\fImember\fR arguments are moved to the \fIend\fR of the archive; +-you can use the \fBa\fR, \fBb\fR, or \fBi\fR modifiers to move them to a +-specified place instead. +-.IP "\fBp\fR" 4 +-.IX Item "p" +-\&\fIPrint\fR the specified members of the archive, to the standard +-output file. If the \fBv\fR modifier is specified, show the member +-name before copying its contents to standard output. +-.Sp +-If you specify no \fImember\fR arguments, all the files in the archive are +-printed. +-.IP "\fBq\fR" 4 +-.IX Item "q" +-\&\fIQuick append\fR; Historically, add the files \fImember\fR... to the end of +-\&\fIarchive\fR, without checking for replacement. +-.Sp +-The modifiers \fBa\fR, \fBb\fR, and \fBi\fR do \fInot\fR affect this +-operation; new members are always placed at the end of the archive. +-.Sp +-The modifier \fBv\fR makes \fBar\fR list each file as it is appended. +-.Sp +-Since the point of this operation is speed, implementations of +-\&\fBar\fR have the option of not updating the archive's symbol +-table if one exists. Too many different systems however assume that +-symbol tables are always up-to-date, so \s-1GNU\s0 \fBar\fR will +-rebuild the table even with a quick append. +-.Sp +-Note \- \s-1GNU\s0 \fBar\fR treats the command \fBqs\fR as a +-synonym for \fBr\fR \- replacing already existing files in the +-archive and appending new ones at the end. +-.IP "\fBr\fR" 4 +-.IX Item "r" +-Insert the files \fImember\fR... into \fIarchive\fR (with +-\&\fIreplacement\fR). This operation differs from \fBq\fR in that any +-previously existing members are deleted if their names match those being +-added. +-.Sp +-If one of the files named in \fImember\fR... does not exist, \fBar\fR +-displays an error message, and leaves undisturbed any existing members +-of the archive matching that name. +-.Sp +-By default, new members are added at the end of the file; but you may +-use one of the modifiers \fBa\fR, \fBb\fR, or \fBi\fR to request +-placement relative to some existing member. +-.Sp +-The modifier \fBv\fR used with this operation elicits a line of +-output for each file inserted, along with one of the letters \fBa\fR or +-\&\fBr\fR to indicate whether the file was appended (no old member +-deleted) or replaced. +-.IP "\fBs\fR" 4 +-.IX Item "s" +-Add an index to the archive, or update it if it already exists. Note +-this command is an exception to the rule that there can only be one +-command letter, as it is possible to use it as either a command or a +-modifier. In either case it does the same thing. +-.IP "\fBt\fR" 4 +-.IX Item "t" +-Display a \fItable\fR listing the contents of \fIarchive\fR, or those +-of the files listed in \fImember\fR... that are present in the +-archive. Normally only the member name is shown; if you also want to +-see the modes (permissions), timestamp, owner, group, and size, you can +-request that by also specifying the \fBv\fR modifier. +-.Sp +-If you do not specify a \fImember\fR, all files in the archive +-are listed. +-.Sp +-If there is more than one file with the same name (say, \fBfie\fR) in +-an archive (say \fBb.a\fR), \fBar t b.a fie\fR lists only the +-first instance; to see them all, you must ask for a complete +-listing\-\-\-in our example, \fBar t b.a\fR. +-.IP "\fBx\fR" 4 +-.IX Item "x" +-\&\fIExtract\fR members (named \fImember\fR) from the archive. You can +-use the \fBv\fR modifier with this operation, to request that +-\&\fBar\fR list each name as it extracts it. +-.Sp +-If you do not specify a \fImember\fR, all files in the archive +-are extracted. +-.Sp +-Files cannot be extracted from a thin archive. +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-Displays the list of command line options supported by \fBar\fR +-and then exits. +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-Displays the version information of \fBar\fR and then exits. +-.PP +-A number of modifiers (\fImod\fR) may immediately follow the \fIp\fR +-keyletter, to specify variations on an operation's behavior: +-.IP "\fBa\fR" 4 +-.IX Item "a" +-Add new files \fIafter\fR an existing member of the +-archive. If you use the modifier \fBa\fR, the name of an existing archive +-member must be present as the \fIrelpos\fR argument, before the +-\&\fIarchive\fR specification. +-.IP "\fBb\fR" 4 +-.IX Item "b" +-Add new files \fIbefore\fR an existing member of the +-archive. If you use the modifier \fBb\fR, the name of an existing archive +-member must be present as the \fIrelpos\fR argument, before the +-\&\fIarchive\fR specification. (same as \fBi\fR). +-.IP "\fBc\fR" 4 +-.IX Item "c" +-\&\fICreate\fR the archive. The specified \fIarchive\fR is always +-created if it did not exist, when you request an update. But a warning is +-issued unless you specify in advance that you expect to create it, by +-using this modifier. +-.IP "\fBD\fR" 4 +-.IX Item "D" +-Operate in \fIdeterministic\fR mode. When adding files and the archive +-index use zero for UIDs, GIDs, timestamps, and use consistent file modes +-for all files. When this option is used, if \fBar\fR is used with +-identical options and identical input files, multiple runs will create +-identical output files regardless of the input files' owners, groups, +-file modes, or modification times. +-.Sp +-If \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR, then this mode is on by default. +-It can be disabled with the \fBU\fR modifier, below. +-.IP "\fBf\fR" 4 +-.IX Item "f" +-Truncate names in the archive. \s-1GNU\s0 \fBar\fR will normally permit file +-names of any length. This will cause it to create archives which are +-not compatible with the native \fBar\fR program on some systems. If +-this is a concern, the \fBf\fR modifier may be used to truncate file +-names when putting them in the archive. +-.IP "\fBi\fR" 4 +-.IX Item "i" +-Insert new files \fIbefore\fR an existing member of the +-archive. If you use the modifier \fBi\fR, the name of an existing archive +-member must be present as the \fIrelpos\fR argument, before the +-\&\fIarchive\fR specification. (same as \fBb\fR). +-.IP "\fBl\fR" 4 +-.IX Item "l" +-This modifier is accepted but not used. +-.IP "\fBN\fR" 4 +-.IX Item "N" +-Uses the \fIcount\fR parameter. This is used if there are multiple +-entries in the archive with the same name. Extract or delete instance +-\&\fIcount\fR of the given name from the archive. +-.IP "\fBo\fR" 4 +-.IX Item "o" +-Preserve the \fIoriginal\fR dates of members when extracting them. If +-you do not specify this modifier, files extracted from the archive +-are stamped with the time of extraction. +-.IP "\fBP\fR" 4 +-.IX Item "P" +-Use the full path name when matching names in the archive. \s-1GNU\s0 +-\&\fBar\fR can not create an archive with a full path name (such archives +-are not \s-1POSIX\s0 complaint), but other archive creators can. This option +-will cause \s-1GNU\s0 \fBar\fR to match file names using a complete path +-name, which can be convenient when extracting a single file from an +-archive created by another tool. +-.IP "\fBs\fR" 4 +-.IX Item "s" +-Write an object-file index into the archive, or update an existing one, +-even if no other change is made to the archive. You may use this modifier +-flag either with any operation, or alone. Running \fBar s\fR on an +-archive is equivalent to running \fBranlib\fR on it. +-.IP "\fBS\fR" 4 +-.IX Item "S" +-Do not generate an archive symbol table. This can speed up building a +-large library in several steps. The resulting archive can not be used +-with the linker. In order to build a symbol table, you must omit the +-\&\fBS\fR modifier on the last execution of \fBar\fR, or you must run +-\&\fBranlib\fR on the archive. +-.IP "\fBT\fR" 4 +-.IX Item "T" +-Make the specified \fIarchive\fR a \fIthin\fR archive. If it already +-exists and is a regular archive, the existing members must be present +-in the same directory as \fIarchive\fR. +-.IP "\fBu\fR" 4 +-.IX Item "u" +-Normally, \fBar r\fR... inserts all files +-listed into the archive. If you would like to insert \fIonly\fR those +-of the files you list that are newer than existing members of the same +-names, use this modifier. The \fBu\fR modifier is allowed only for the +-operation \fBr\fR (replace). In particular, the combination \fBqu\fR is +-not allowed, since checking the timestamps would lose any speed +-advantage from the operation \fBq\fR. +-.IP "\fBU\fR" 4 +-.IX Item "U" +-Do \fInot\fR operate in \fIdeterministic\fR mode. This is the inverse +-of the \fBD\fR modifier, above: added files and the archive index will +-get their actual \s-1UID\s0, \s-1GID\s0, timestamp, and file mode values. +-.Sp +-This is the default unless \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR. +-.IP "\fBv\fR" 4 +-.IX Item "v" +-This modifier requests the \fIverbose\fR version of an operation. Many +-operations display additional information, such as filenames processed, +-when the modifier \fBv\fR is appended. +-.IP "\fBV\fR" 4 +-.IX Item "V" +-This modifier shows the version number of \fBar\fR. +-.PP +-\&\fBar\fR ignores an initial option spelt \fB\-X32_64\fR, for +-compatibility with \s-1AIX\s0. The behaviour produced by this option is the +-default for \s-1GNU\s0 \fBar\fR. \fBar\fR does not support any of the other +-\&\fB\-X\fR options; in particular, it does not support \fB\-X32\fR +-which is the default for \s-1AIX\s0 \fBar\fR. +-.PP +-The optional command line switch \fB\-\-plugin\fR \fIname\fR causes +-\&\fBar\fR to load the plugin called \fIname\fR which adds support +-for more file formats. This option is only available if the toolchain +-has been built with plugin support enabled. +-.PP +-The optional command line switch \fB\-\-target\fR \fIbfdname\fR +-specifies that the archive members are in an object code format +-different from your system's default format. See +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fInm\fR\|(1), \fIranlib\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/binutils.info binutils-2.24/binutils/doc/binutils.info +--- binutils-2.24.orig/binutils/doc/binutils.info 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/doc/binutils.info 1970-01-01 01:00:00.000000000 +0100 +@@ -1,4898 +0,0 @@ +-This is binutils.info, produced by makeinfo version 4.8 from +-binutils.texi. +- +- Copyright (C) 1991-2013 Free Software Foundation, Inc. +- +- Permission is granted to copy, distribute and/or modify this document +-under the terms of the GNU Free Documentation License, Version 1.3 or +-any later version published by the Free Software Foundation; with no +-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +-Texts. A copy of the license is included in the section entitled "GNU +-Free Documentation License". +- +-INFO-DIR-SECTION Software development +-START-INFO-DIR-ENTRY +-* Binutils: (binutils). The GNU binary utilities. +-END-INFO-DIR-ENTRY +- +-INFO-DIR-SECTION Individual utilities +-START-INFO-DIR-ENTRY +-* addr2line: (binutils)addr2line. Convert addresses to file and line. +-* ar: (binutils)ar. Create, modify, and extract from archives. +-* c++filt: (binutils)c++filt. Filter to demangle encoded C++ symbols. +-* cxxfilt: (binutils)c++filt. MS-DOS name for c++filt. +-* dlltool: (binutils)dlltool. Create files needed to build and use DLLs. +-* nlmconv: (binutils)nlmconv. Converts object code into an NLM. +-* nm: (binutils)nm. List symbols from object files. +-* objcopy: (binutils)objcopy. Copy and translate object files. +-* objdump: (binutils)objdump. Display information from object files. +-* ranlib: (binutils)ranlib. Generate index to archive contents. +-* readelf: (binutils)readelf. Display the contents of ELF format files. +-* size: (binutils)size. List section sizes and total size. +-* strings: (binutils)strings. List printable strings from files. +-* strip: (binutils)strip. Discard symbols. +-* elfedit: (binutils)elfedit. Update the ELF header of ELF files. +-* windmc: (binutils)windmc. Generator for Windows message resources. +-* windres: (binutils)windres. Manipulate Windows resources. +-END-INFO-DIR-ENTRY +- +- +-File: binutils.info, Node: Top, Next: ar, Up: (dir) +- +-Introduction +-************ +- +-This brief manual contains documentation for the GNU binary utilities +-(GNU Binutils) version 2.23.91: +- +- This document is distributed under the terms of the GNU Free +-Documentation License version 1.3. A copy of the license is included +-in the section entitled "GNU Free Documentation License". +- +-* Menu: +- +-* ar:: Create, modify, and extract from archives +-* nm:: List symbols from object files +-* objcopy:: Copy and translate object files +-* objdump:: Display information from object files +-* ranlib:: Generate index to archive contents +-* size:: List section sizes and total size +-* strings:: List printable strings from files +-* strip:: Discard symbols +-* c++filt:: Filter to demangle encoded C++ symbols +-* cxxfilt: c++filt. MS-DOS name for c++filt +-* addr2line:: Convert addresses to file and line +-* nlmconv:: Converts object code into an NLM +-* windmc:: Generator for Windows message resources +-* windres:: Manipulate Windows resources +-* dlltool:: Create files needed to build and use DLLs +-* readelf:: Display the contents of ELF format files +-* elfedit:: Update the ELF header of ELF files +-* Common Options:: Command-line options for all utilities +-* Selecting the Target System:: How these utilities determine the target +-* Reporting Bugs:: Reporting Bugs +-* GNU Free Documentation License:: GNU Free Documentation License +-* Binutils Index:: Binutils Index +- +- +-File: binutils.info, Node: ar, Next: nm, Prev: Top, Up: Top +- +-1 ar +-**** +- +- ar [`--plugin' NAME] [-]P[MOD [RELPOS] [COUNT]] [`--target' BFDNAME] ARCHIVE [MEMBER...] +- ar -M [ '), and continues executing even after errors. If you +-redirect standard input to a script file, no prompts are issued, and +-`ar' abandons execution (with a nonzero exit code) on any error. +- +- The `ar' command language is _not_ designed to be equivalent to the +-command-line options; in fact, it provides somewhat less control over +-archives. The only purpose of the command language is to ease the +-transition to GNU `ar' for developers who already have scripts written +-for the MRI "librarian" program. +- +- The syntax for the `ar' command language is straightforward: +- * commands are recognized in upper or lower case; for example, `LIST' +- is the same as `list'. In the following descriptions, commands are +- shown in upper case for clarity. +- +- * a single command may appear on each line; it is the first word on +- the line. +- +- * empty lines are allowed, and have no effect. +- +- * comments are allowed; text after either of the characters `*' or +- `;' is ignored. +- +- * Whenever you use a list of names as part of the argument to an `ar' +- command, you can separate the individual names with either commas +- or blanks. Commas are shown in the explanations below, for +- clarity. +- +- * `+' is used as a line continuation character; if `+' appears at +- the end of a line, the text on the following line is considered +- part of the current command. +- +- Here are the commands you can use in `ar' scripts, or when using +-`ar' interactively. Three of them have special significance: +- +- `OPEN' or `CREATE' specify a "current archive", which is a temporary +-file required for most of the other commands. +- +- `SAVE' commits the changes so far specified by the script. Prior to +-`SAVE', commands affect only the temporary copy of the current archive. +- +-`ADDLIB ARCHIVE' +-`ADDLIB ARCHIVE (MODULE, MODULE, ... MODULE)' +- Add all the contents of ARCHIVE (or, if specified, each named +- MODULE from ARCHIVE) to the current archive. +- +- Requires prior use of `OPEN' or `CREATE'. +- +-`ADDMOD MEMBER, MEMBER, ... MEMBER' +- Add each named MEMBER as a module in the current archive. +- +- Requires prior use of `OPEN' or `CREATE'. +- +-`CLEAR' +- Discard the contents of the current archive, canceling the effect +- of any operations since the last `SAVE'. May be executed (with no +- effect) even if no current archive is specified. +- +-`CREATE ARCHIVE' +- Creates an archive, and makes it the current archive (required for +- many other commands). The new archive is created with a temporary +- name; it is not actually saved as ARCHIVE until you use `SAVE'. +- You can overwrite existing archives; similarly, the contents of any +- existing file named ARCHIVE will not be destroyed until `SAVE'. +- +-`DELETE MODULE, MODULE, ... MODULE' +- Delete each listed MODULE from the current archive; equivalent to +- `ar -d ARCHIVE MODULE ... MODULE'. +- +- Requires prior use of `OPEN' or `CREATE'. +- +-`DIRECTORY ARCHIVE (MODULE, ... MODULE)' +-`DIRECTORY ARCHIVE (MODULE, ... MODULE) OUTPUTFILE' +- List each named MODULE present in ARCHIVE. The separate command +- `VERBOSE' specifies the form of the output: when verbose output is +- off, output is like that of `ar -t ARCHIVE MODULE...'. When +- verbose output is on, the listing is like `ar -tv ARCHIVE +- MODULE...'. +- +- Output normally goes to the standard output stream; however, if you +- specify OUTPUTFILE as a final argument, `ar' directs the output to +- that file. +- +-`END' +- Exit from `ar', with a `0' exit code to indicate successful +- completion. This command does not save the output file; if you +- have changed the current archive since the last `SAVE' command, +- those changes are lost. +- +-`EXTRACT MODULE, MODULE, ... MODULE' +- Extract each named MODULE from the current archive, writing them +- into the current directory as separate files. Equivalent to `ar -x +- ARCHIVE MODULE...'. +- +- Requires prior use of `OPEN' or `CREATE'. +- +-`LIST' +- Display full contents of the current archive, in "verbose" style +- regardless of the state of `VERBOSE'. The effect is like `ar tv +- ARCHIVE'. (This single command is a GNU `ar' enhancement, rather +- than present for MRI compatibility.) +- +- Requires prior use of `OPEN' or `CREATE'. +- +-`OPEN ARCHIVE' +- Opens an existing archive for use as the current archive (required +- for many other commands). Any changes as the result of subsequent +- commands will not actually affect ARCHIVE until you next use +- `SAVE'. +- +-`REPLACE MODULE, MODULE, ... MODULE' +- In the current archive, replace each existing MODULE (named in the +- `REPLACE' arguments) from files in the current working directory. +- To execute this command without errors, both the file, and the +- module in the current archive, must exist. +- +- Requires prior use of `OPEN' or `CREATE'. +- +-`VERBOSE' +- Toggle an internal flag governing the output from `DIRECTORY'. +- When the flag is on, `DIRECTORY' output matches output from `ar +- -tv '.... +- +-`SAVE' +- Commit your changes to the current archive, and actually save it +- as a file with the name specified in the last `CREATE' or `OPEN' +- command. +- +- Requires prior use of `OPEN' or `CREATE'. +- +- +- +-File: binutils.info, Node: nm, Next: objcopy, Prev: ar, Up: Top +- +-2 nm +-**** +- +- nm [`-A'|`-o'|`--print-file-name'] [`-a'|`--debug-syms'] +- [`-B'|`--format=bsd'] [`-C'|`--demangle'[=STYLE]] +- [`-D'|`--dynamic'] [`-f'FORMAT|`--format='FORMAT] +- [`-g'|`--extern-only'] [`-h'|`--help'] +- [`-l'|`--line-numbers'] [`-n'|`-v'|`--numeric-sort'] +- [`-P'|`--portability'] [`-p'|`--no-sort'] +- [`-r'|`--reverse-sort'] [`-S'|`--print-size'] +- [`-s'|`--print-armap'] [`-t' RADIX|`--radix='RADIX] +- [`-u'|`--undefined-only'] [`-V'|`--version'] +- [`-X 32_64'] [`--defined-only'] [`--no-demangle'] +- [`--plugin' NAME] [`--size-sort'] [`--special-syms'] +- [`--synthetic'] [`--target='BFDNAME] +- [OBJFILE...] +- +- GNU `nm' lists the symbols from object files OBJFILE.... If no +-object files are listed as arguments, `nm' assumes the file `a.out'. +- +- For each symbol, `nm' shows: +- +- * The symbol value, in the radix selected by options (see below), or +- hexadecimal by default. +- +- * The symbol type. At least the following types are used; others +- are, as well, depending on the object file format. If lowercase, +- the symbol is usually local; if uppercase, the symbol is global +- (external). There are however a few lowercase symbols that are +- shown for special global symbols (`u', `v' and `w'). +- +- `A' +- The symbol's value is absolute, and will not be changed by +- further linking. +- +- `B' +- `b' +- The symbol is in the uninitialized data section (known as +- BSS). +- +- `C' +- The symbol is common. Common symbols are uninitialized data. +- When linking, multiple common symbols may appear with the +- same name. If the symbol is defined anywhere, the common +- symbols are treated as undefined references. For more +- details on common symbols, see the discussion of -warn-common +- in *Note Linker options: (ld.info)Options. +- +- `D' +- `d' +- The symbol is in the initialized data section. +- +- `G' +- `g' +- The symbol is in an initialized data section for small +- objects. Some object file formats permit more efficient +- access to small data objects, such as a global int variable +- as opposed to a large global array. +- +- `i' +- For PE format files this indicates that the symbol is in a +- section specific to the implementation of DLLs. For ELF +- format files this indicates that the symbol is an indirect +- function. This is a GNU extension to the standard set of ELF +- symbol types. It indicates a symbol which if referenced by a +- relocation does not evaluate to its address, but instead must +- be invoked at runtime. The runtime execution will then +- return the value to be used in the relocation. +- +- `I' +- The symbol is an indirect reference to another symbol. +- +- `N' +- The symbol is a debugging symbol. +- +- `p' +- The symbols is in a stack unwind section. +- +- `R' +- `r' +- The symbol is in a read only data section. +- +- `S' +- `s' +- The symbol is in an uninitialized data section for small +- objects. +- +- `T' +- `t' +- The symbol is in the text (code) section. +- +- `U' +- The symbol is undefined. +- +- `u' +- The symbol is a unique global symbol. This is a GNU +- extension to the standard set of ELF symbol bindings. For +- such a symbol the dynamic linker will make sure that in the +- entire process there is just one symbol with this name and +- type in use. +- +- `V' +- `v' +- The symbol is a weak object. When a weak defined symbol is +- linked with a normal defined symbol, the normal defined +- symbol is used with no error. When a weak undefined symbol +- is linked and the symbol is not defined, the value of the +- weak symbol becomes zero with no error. On some systems, +- uppercase indicates that a default value has been specified. +- +- `W' +- `w' +- The symbol is a weak symbol that has not been specifically +- tagged as a weak object symbol. When a weak defined symbol +- is linked with a normal defined symbol, the normal defined +- symbol is used with no error. When a weak undefined symbol +- is linked and the symbol is not defined, the value of the +- symbol is determined in a system-specific manner without +- error. On some systems, uppercase indicates that a default +- value has been specified. +- +- `-' +- The symbol is a stabs symbol in an a.out object file. In +- this case, the next values printed are the stabs other field, +- the stabs desc field, and the stab type. Stabs symbols are +- used to hold debugging information. +- +- `?' +- The symbol type is unknown, or object file format specific. +- +- * The symbol name. +- +- The long and short forms of options, shown here as alternatives, are +-equivalent. +- +-`-A' +-`-o' +-`--print-file-name' +- Precede each symbol by the name of the input file (or archive +- member) in which it was found, rather than identifying the input +- file once only, before all of its symbols. +- +-`-a' +-`--debug-syms' +- Display all symbols, even debugger-only symbols; normally these +- are not listed. +- +-`-B' +- The same as `--format=bsd' (for compatibility with the MIPS `nm'). +- +-`-C' +-`--demangle[=STYLE]' +- Decode ("demangle") low-level symbol names into user-level names. +- Besides removing any initial underscore prepended by the system, +- this makes C++ function names readable. Different compilers have +- different mangling styles. The optional demangling style argument +- can be used to choose an appropriate demangling style for your +- compiler. *Note c++filt::, for more information on demangling. +- +-`--no-demangle' +- Do not demangle low-level symbol names. This is the default. +- +-`-D' +-`--dynamic' +- Display the dynamic symbols rather than the normal symbols. This +- is only meaningful for dynamic objects, such as certain types of +- shared libraries. +- +-`-f FORMAT' +-`--format=FORMAT' +- Use the output format FORMAT, which can be `bsd', `sysv', or +- `posix'. The default is `bsd'. Only the first character of +- FORMAT is significant; it can be either upper or lower case. +- +-`-g' +-`--extern-only' +- Display only external symbols. +- +-`-h' +-`--help' +- Show a summary of the options to `nm' and exit. +- +-`-l' +-`--line-numbers' +- For each symbol, use debugging information to try to find a +- filename and line number. For a defined symbol, look for the line +- number of the address of the symbol. For an undefined symbol, +- look for the line number of a relocation entry which refers to the +- symbol. If line number information can be found, print it after +- the other symbol information. +- +-`-n' +-`-v' +-`--numeric-sort' +- Sort symbols numerically by their addresses, rather than +- alphabetically by their names. +- +-`-p' +-`--no-sort' +- Do not bother to sort the symbols in any order; print them in the +- order encountered. +- +-`-P' +-`--portability' +- Use the POSIX.2 standard output format instead of the default +- format. Equivalent to `-f posix'. +- +-`-r' +-`--reverse-sort' +- Reverse the order of the sort (whether numeric or alphabetic); let +- the last come first. +- +-`-S' +-`--print-size' +- Print both value and size of defined symbols for the `bsd' output +- style. This option has no effect for object formats that do not +- record symbol sizes, unless `--size-sort' is also used in which +- case a calculated size is displayed. +- +-`-s' +-`--print-armap' +- When listing symbols from archive members, include the index: a +- mapping (stored in the archive by `ar' or `ranlib') of which +- modules contain definitions for which names. +- +-`-t RADIX' +-`--radix=RADIX' +- Use RADIX as the radix for printing the symbol values. It must be +- `d' for decimal, `o' for octal, or `x' for hexadecimal. +- +-`-u' +-`--undefined-only' +- Display only undefined symbols (those external to each object +- file). +- +-`-V' +-`--version' +- Show the version number of `nm' and exit. +- +-`-X' +- This option is ignored for compatibility with the AIX version of +- `nm'. It takes one parameter which must be the string `32_64'. +- The default mode of AIX `nm' corresponds to `-X 32', which is not +- supported by GNU `nm'. +- +-`--defined-only' +- Display only defined symbols for each object file. +- +-`--plugin NAME' +- Load the plugin called NAME to add support for extra target types. +- This option is only available if the toolchain has been built +- with plugin support enabled. +- +-`--size-sort' +- Sort symbols by size. The size is computed as the difference +- between the value of the symbol and the value of the symbol with +- the next higher value. If the `bsd' output format is used the +- size of the symbol is printed, rather than the value, and `-S' +- must be used in order both size and value to be printed. +- +-`--special-syms' +- Display symbols which have a target-specific special meaning. +- These symbols are usually used by the target for some special +- processing and are not normally helpful when included in the +- normal symbol lists. For example for ARM targets this option +- would skip the mapping symbols used to mark transitions between +- ARM code, THUMB code and data. +- +-`--synthetic' +- Include synthetic symbols in the output. These are special symbols +- created by the linker for various purposes. They are not shown by +- default since they are not part of the binary's original source +- code. +- +-`--target=BFDNAME' +- Specify an object code format other than your system's default +- format. *Note Target Selection::, for more information. +- +- +- +-File: binutils.info, Node: objcopy, Next: objdump, Prev: nm, Up: Top +- +-3 objcopy +-********* +- +- objcopy [`-F' BFDNAME|`--target='BFDNAME] +- [`-I' BFDNAME|`--input-target='BFDNAME] +- [`-O' BFDNAME|`--output-target='BFDNAME] +- [`-B' BFDARCH|`--binary-architecture='BFDARCH] +- [`-S'|`--strip-all'] +- [`-g'|`--strip-debug'] +- [`-K' SYMBOLNAME|`--keep-symbol='SYMBOLNAME] +- [`-N' SYMBOLNAME|`--strip-symbol='SYMBOLNAME] +- [`--strip-unneeded-symbol='SYMBOLNAME] +- [`-G' SYMBOLNAME|`--keep-global-symbol='SYMBOLNAME] +- [`--localize-hidden'] +- [`-L' SYMBOLNAME|`--localize-symbol='SYMBOLNAME] +- [`--globalize-symbol='SYMBOLNAME] +- [`-W' SYMBOLNAME|`--weaken-symbol='SYMBOLNAME] +- [`-w'|`--wildcard'] +- [`-x'|`--discard-all'] +- [`-X'|`--discard-locals'] +- [`-b' BYTE|`--byte='BYTE] +- [`-i' [BREADTH]|`--interleave'[=BREADTH]] +- [`--interleave-width='WIDTH] +- [`-j' SECTIONPATTERN|`--only-section='SECTIONPATTERN] +- [`-R' SECTIONPATTERN|`--remove-section='SECTIONPATTERN] +- [`-p'|`--preserve-dates'] +- [`-D'|`--enable-deterministic-archives'] +- [`-U'|`--disable-deterministic-archives'] +- [`--debugging'] +- [`--gap-fill='VAL] +- [`--pad-to='ADDRESS] +- [`--set-start='VAL] +- [`--adjust-start='INCR] +- [`--change-addresses='INCR] +- [`--change-section-address' SECTIONPATTERN{=,+,-}VAL] +- [`--change-section-lma' SECTIONPATTERN{=,+,-}VAL] +- [`--change-section-vma' SECTIONPATTERN{=,+,-}VAL] +- [`--change-warnings'] [`--no-change-warnings'] +- [`--set-section-flags' SECTIONPATTERN=FLAGS] +- [`--add-section' SECTIONNAME=FILENAME] +- [`--rename-section' OLDNAME=NEWNAME[,FLAGS]] +- [`--long-section-names' {enable,disable,keep}] +- [`--change-leading-char'] [`--remove-leading-char'] +- [`--reverse-bytes='NUM] +- [`--srec-len='IVAL] [`--srec-forceS3'] +- [`--redefine-sym' OLD=NEW] +- [`--redefine-syms='FILENAME] +- [`--weaken'] +- [`--keep-symbols='FILENAME] +- [`--strip-symbols='FILENAME] +- [`--strip-unneeded-symbols='FILENAME] +- [`--keep-global-symbols='FILENAME] +- [`--localize-symbols='FILENAME] +- [`--globalize-symbols='FILENAME] +- [`--weaken-symbols='FILENAME] +- [`--alt-machine-code='INDEX] +- [`--prefix-symbols='STRING] +- [`--prefix-sections='STRING] +- [`--prefix-alloc-sections='STRING] +- [`--add-gnu-debuglink='PATH-TO-FILE] +- [`--keep-file-symbols'] +- [`--only-keep-debug'] +- [`--strip-dwo'] +- [`--extract-dwo'] +- [`--extract-symbol'] +- [`--writable-text'] +- [`--readonly-text'] +- [`--pure'] +- [`--impure'] +- [`--file-alignment='NUM] +- [`--heap='SIZE] +- [`--image-base='ADDRESS] +- [`--section-alignment='NUM] +- [`--stack='SIZE] +- [`--subsystem='WHICH:MAJOR.MINOR] +- [`--compress-debug-sections'] +- [`--decompress-debug-sections'] +- [`--dwarf-depth=N'] +- [`--dwarf-start=N'] +- [`-v'|`--verbose'] +- [`-V'|`--version'] +- [`--help'] [`--info'] +- INFILE [OUTFILE] +- +- The GNU `objcopy' utility copies the contents of an object file to +-another. `objcopy' uses the GNU BFD Library to read and write the +-object files. It can write the destination object file in a format +-different from that of the source object file. The exact behavior of +-`objcopy' is controlled by command-line options. Note that `objcopy' +-should be able to copy a fully linked file between any two formats. +-However, copying a relocatable object file between any two formats may +-not work as expected. +- +- `objcopy' creates temporary files to do its translations and deletes +-them afterward. `objcopy' uses BFD to do all its translation work; it +-has access to all the formats described in BFD and thus is able to +-recognize most formats without being told explicitly. *Note BFD: +-(ld.info)BFD. +- +- `objcopy' can be used to generate S-records by using an output +-target of `srec' (e.g., use `-O srec'). +- +- `objcopy' can be used to generate a raw binary file by using an +-output target of `binary' (e.g., use `-O binary'). When `objcopy' +-generates a raw binary file, it will essentially produce a memory dump +-of the contents of the input object file. All symbols and relocation +-information will be discarded. The memory dump will start at the load +-address of the lowest section copied into the output file. +- +- When generating an S-record or a raw binary file, it may be helpful +-to use `-S' to remove sections containing debugging information. In +-some cases `-R' will be useful to remove sections which contain +-information that is not needed by the binary file. +- +- Note--`objcopy' is not able to change the endianness of its input +-files. If the input format has an endianness (some formats do not), +-`objcopy' can only copy the inputs into file formats that have the same +-endianness or which have no endianness (e.g., `srec'). (However, see +-the `--reverse-bytes' option.) +- +-`INFILE' +-`OUTFILE' +- The input and output files, respectively. If you do not specify +- OUTFILE, `objcopy' creates a temporary file and destructively +- renames the result with the name of INFILE. +- +-`-I BFDNAME' +-`--input-target=BFDNAME' +- Consider the source file's object format to be BFDNAME, rather than +- attempting to deduce it. *Note Target Selection::, for more +- information. +- +-`-O BFDNAME' +-`--output-target=BFDNAME' +- Write the output file using the object format BFDNAME. *Note +- Target Selection::, for more information. +- +-`-F BFDNAME' +-`--target=BFDNAME' +- Use BFDNAME as the object format for both the input and the output +- file; i.e., simply transfer data from source to destination with no +- translation. *Note Target Selection::, for more information. +- +-`-B BFDARCH' +-`--binary-architecture=BFDARCH' +- Useful when transforming a architecture-less input file into an +- object file. In this case the output architecture can be set to +- BFDARCH. This option will be ignored if the input file has a +- known BFDARCH. You can access this binary data inside a program +- by referencing the special symbols that are created by the +- conversion process. These symbols are called +- _binary_OBJFILE_start, _binary_OBJFILE_end and +- _binary_OBJFILE_size. e.g. you can transform a picture file into +- an object file and then access it in your code using these symbols. +- +-`-j SECTIONPATTERN' +-`--only-section=SECTIONPATTERN' +- Copy only the indicated sections from the input file to the output +- file. This option may be given more than once. Note that using +- this option inappropriately may make the output file unusable. +- Wildcard characters are accepted in SECTIONPATTERN. +- +-`-R SECTIONPATTERN' +-`--remove-section=SECTIONPATTERN' +- Remove any section matching SECTIONPATTERN from the output file. +- This option may be given more than once. Note that using this +- option inappropriately may make the output file unusable. Wildcard +- characters are accepted in SECTIONPATTERN. Using both the `-j' +- and `-R' options together results in undefined behaviour. +- +-`-S' +-`--strip-all' +- Do not copy relocation and symbol information from the source file. +- +-`-g' +-`--strip-debug' +- Do not copy debugging symbols or sections from the source file. +- +-`--strip-unneeded' +- Strip all symbols that are not needed for relocation processing. +- +-`-K SYMBOLNAME' +-`--keep-symbol=SYMBOLNAME' +- When stripping symbols, keep symbol SYMBOLNAME even if it would +- normally be stripped. This option may be given more than once. +- +-`-N SYMBOLNAME' +-`--strip-symbol=SYMBOLNAME' +- Do not copy symbol SYMBOLNAME from the source file. This option +- may be given more than once. +- +-`--strip-unneeded-symbol=SYMBOLNAME' +- Do not copy symbol SYMBOLNAME from the source file unless it is +- needed by a relocation. This option may be given more than once. +- +-`-G SYMBOLNAME' +-`--keep-global-symbol=SYMBOLNAME' +- Keep only symbol SYMBOLNAME global. Make all other symbols local +- to the file, so that they are not visible externally. This option +- may be given more than once. +- +-`--localize-hidden' +- In an ELF object, mark all symbols that have hidden or internal +- visibility as local. This option applies on top of +- symbol-specific localization options such as `-L'. +- +-`-L SYMBOLNAME' +-`--localize-symbol=SYMBOLNAME' +- Make symbol SYMBOLNAME local to the file, so that it is not +- visible externally. This option may be given more than once. +- +-`-W SYMBOLNAME' +-`--weaken-symbol=SYMBOLNAME' +- Make symbol SYMBOLNAME weak. This option may be given more than +- once. +- +-`--globalize-symbol=SYMBOLNAME' +- Give symbol SYMBOLNAME global scoping so that it is visible +- outside of the file in which it is defined. This option may be +- given more than once. +- +-`-w' +-`--wildcard' +- Permit regular expressions in SYMBOLNAMEs used in other command +- line options. The question mark (?), asterisk (*), backslash (\) +- and square brackets ([]) operators can be used anywhere in the +- symbol name. If the first character of the symbol name is the +- exclamation point (!) then the sense of the switch is reversed for +- that symbol. For example: +- +- -w -W !foo -W fo* +- +- would cause objcopy to weaken all symbols that start with "fo" +- except for the symbol "foo". +- +-`-x' +-`--discard-all' +- Do not copy non-global symbols from the source file. +- +-`-X' +-`--discard-locals' +- Do not copy compiler-generated local symbols. (These usually +- start with `L' or `.'.) +- +-`-b BYTE' +-`--byte=BYTE' +- If interleaving has been enabled via the `--interleave' option +- then start the range of bytes to keep at the BYTEth byte. BYTE +- can be in the range from 0 to BREADTH-1, where BREADTH is the +- value given by the `--interleave' option. +- +-`-i [BREADTH]' +-`--interleave[=BREADTH]' +- Only copy a range out of every BREADTH bytes. (Header data is not +- affected). Select which byte in the range begins the copy with +- the `--byte' option. Select the width of the range with the +- `--interleave-width' option. +- +- This option is useful for creating files to program ROM. It is +- typically used with an `srec' output target. Note that `objcopy' +- will complain if you do not specify the `--byte' option as well. +- +- The default interleave breadth is 4, so with `--byte' set to 0, +- `objcopy' would copy the first byte out of every four bytes from +- the input to the output. +- +-`--interleave-width=WIDTH' +- When used with the `--interleave' option, copy WIDTH bytes at a +- time. The start of the range of bytes to be copied is set by the +- `--byte' option, and the extent of the range is set with the +- `--interleave' option. +- +- The default value for this option is 1. The value of WIDTH plus +- the BYTE value set by the `--byte' option must not exceed the +- interleave breadth set by the `--interleave' option. +- +- This option can be used to create images for two 16-bit flashes +- interleaved in a 32-bit bus by passing `-b 0 -i 4 +- --interleave-width=2' and `-b 2 -i 4 --interleave-width=2' to two +- `objcopy' commands. If the input was '12345678' then the outputs +- would be '1256' and '3478' respectively. +- +-`-p' +-`--preserve-dates' +- Set the access and modification dates of the output file to be the +- same as those of the input file. +- +-`-D' +-`--enable-deterministic-archives' +- Operate in _deterministic_ mode. When copying archive members and +- writing the archive index, use zero for UIDs, GIDs, timestamps, +- and use consistent file modes for all files. +- +- If `binutils' was configured with +- `--enable-deterministic-archives', then this mode is on by default. +- It can be disabled with the `-U' option, below. +- +-`-U' +-`--disable-deterministic-archives' +- Do _not_ operate in _deterministic_ mode. This is the inverse of +- the `-D' option, above: when copying archive members and writing +- the archive index, use their actual UID, GID, timestamp, and file +- mode values. +- +- This is the default unless `binutils' was configured with +- `--enable-deterministic-archives'. +- +-`--debugging' +- Convert debugging information, if possible. This is not the +- default because only certain debugging formats are supported, and +- the conversion process can be time consuming. +- +-`--gap-fill VAL' +- Fill gaps between sections with VAL. This operation applies to +- the _load address_ (LMA) of the sections. It is done by increasing +- the size of the section with the lower address, and filling in the +- extra space created with VAL. +- +-`--pad-to ADDRESS' +- Pad the output file up to the load address ADDRESS. This is done +- by increasing the size of the last section. The extra space is +- filled in with the value specified by `--gap-fill' (default zero). +- +-`--set-start VAL' +- Set the start address of the new file to VAL. Not all object file +- formats support setting the start address. +- +-`--change-start INCR' +-`--adjust-start INCR' +- Change the start address by adding INCR. Not all object file +- formats support setting the start address. +- +-`--change-addresses INCR' +-`--adjust-vma INCR' +- Change the VMA and LMA addresses of all sections, as well as the +- start address, by adding INCR. Some object file formats do not +- permit section addresses to be changed arbitrarily. Note that +- this does not relocate the sections; if the program expects +- sections to be loaded at a certain address, and this option is +- used to change the sections such that they are loaded at a +- different address, the program may fail. +- +-`--change-section-address SECTIONPATTERN{=,+,-}VAL' +-`--adjust-section-vma SECTIONPATTERN{=,+,-}VAL' +- Set or change both the VMA address and the LMA address of any +- section matching SECTIONPATTERN. If `=' is used, the section +- address is set to VAL. Otherwise, VAL is added to or subtracted +- from the section address. See the comments under +- `--change-addresses', above. If SECTIONPATTERN does not match any +- sections in the input file, a warning will be issued, unless +- `--no-change-warnings' is used. +- +-`--change-section-lma SECTIONPATTERN{=,+,-}VAL' +- Set or change the LMA address of any sections matching +- SECTIONPATTERN. The LMA address is the address where the section +- will be loaded into memory at program load time. Normally this is +- the same as the VMA address, which is the address of the section +- at program run time, but on some systems, especially those where a +- program is held in ROM, the two can be different. If `=' is used, +- the section address is set to VAL. Otherwise, VAL is added to or +- subtracted from the section address. See the comments under +- `--change-addresses', above. If SECTIONPATTERN does not match any +- sections in the input file, a warning will be issued, unless +- `--no-change-warnings' is used. +- +-`--change-section-vma SECTIONPATTERN{=,+,-}VAL' +- Set or change the VMA address of any section matching +- SECTIONPATTERN. The VMA address is the address where the section +- will be located once the program has started executing. Normally +- this is the same as the LMA address, which is the address where +- the section will be loaded into memory, but on some systems, +- especially those where a program is held in ROM, the two can be +- different. If `=' is used, the section address is set to VAL. +- Otherwise, VAL is added to or subtracted from the section address. +- See the comments under `--change-addresses', above. If +- SECTIONPATTERN does not match any sections in the input file, a +- warning will be issued, unless `--no-change-warnings' is used. +- +-`--change-warnings' +-`--adjust-warnings' +- If `--change-section-address' or `--change-section-lma' or +- `--change-section-vma' is used, and the section pattern does not +- match any sections, issue a warning. This is the default. +- +-`--no-change-warnings' +-`--no-adjust-warnings' +- Do not issue a warning if `--change-section-address' or +- `--adjust-section-lma' or `--adjust-section-vma' is used, even if +- the section pattern does not match any sections. +- +-`--set-section-flags SECTIONPATTERN=FLAGS' +- Set the flags for any sections matching SECTIONPATTERN. The FLAGS +- argument is a comma separated string of flag names. The +- recognized names are `alloc', `contents', `load', `noload', +- `readonly', `code', `data', `rom', `share', and `debug'. You can +- set the `contents' flag for a section which does not have +- contents, but it is not meaningful to clear the `contents' flag of +- a section which does have contents-just remove the section +- instead. Not all flags are meaningful for all object file formats. +- +-`--add-section SECTIONNAME=FILENAME' +- Add a new section named SECTIONNAME while copying the file. The +- contents of the new section are taken from the file FILENAME. The +- size of the section will be the size of the file. This option only +- works on file formats which can support sections with arbitrary +- names. +- +-`--rename-section OLDNAME=NEWNAME[,FLAGS]' +- Rename a section from OLDNAME to NEWNAME, optionally changing the +- section's flags to FLAGS in the process. This has the advantage +- over usng a linker script to perform the rename in that the output +- stays as an object file and does not become a linked executable. +- +- This option is particularly helpful when the input format is +- binary, since this will always create a section called .data. If +- for example, you wanted instead to create a section called .rodata +- containing binary data you could use the following command line to +- achieve it: +- +- objcopy -I binary -O -B \ +- --rename-section .data=.rodata,alloc,load,readonly,data,contents \ +- +- +-`--long-section-names {enable,disable,keep}' +- Controls the handling of long section names when processing `COFF' +- and `PE-COFF' object formats. The default behaviour, `keep', is +- to preserve long section names if any are present in the input +- file. The `enable' and `disable' options forcibly enable or +- disable the use of long section names in the output object; when +- `disable' is in effect, any long section names in the input object +- will be truncated. The `enable' option will only emit long +- section names if any are present in the inputs; this is mostly the +- same as `keep', but it is left undefined whether the `enable' +- option might force the creation of an empty string table in the +- output file. +- +-`--change-leading-char' +- Some object file formats use special characters at the start of +- symbols. The most common such character is underscore, which +- compilers often add before every symbol. This option tells +- `objcopy' to change the leading character of every symbol when it +- converts between object file formats. If the object file formats +- use the same leading character, this option has no effect. +- Otherwise, it will add a character, or remove a character, or +- change a character, as appropriate. +- +-`--remove-leading-char' +- If the first character of a global symbol is a special symbol +- leading character used by the object file format, remove the +- character. The most common symbol leading character is +- underscore. This option will remove a leading underscore from all +- global symbols. This can be useful if you want to link together +- objects of different file formats with different conventions for +- symbol names. This is different from `--change-leading-char' +- because it always changes the symbol name when appropriate, +- regardless of the object file format of the output file. +- +-`--reverse-bytes=NUM' +- Reverse the bytes in a section with output contents. A section +- length must be evenly divisible by the value given in order for +- the swap to be able to take place. Reversing takes place before +- the interleaving is performed. +- +- This option is used typically in generating ROM images for +- problematic target systems. For example, on some target boards, +- the 32-bit words fetched from 8-bit ROMs are re-assembled in +- little-endian byte order regardless of the CPU byte order. +- Depending on the programming model, the endianness of the ROM may +- need to be modified. +- +- Consider a simple file with a section containing the following +- eight bytes: `12345678'. +- +- Using `--reverse-bytes=2' for the above example, the bytes in the +- output file would be ordered `21436587'. +- +- Using `--reverse-bytes=4' for the above example, the bytes in the +- output file would be ordered `43218765'. +- +- By using `--reverse-bytes=2' for the above example, followed by +- `--reverse-bytes=4' on the output file, the bytes in the second +- output file would be ordered `34127856'. +- +-`--srec-len=IVAL' +- Meaningful only for srec output. Set the maximum length of the +- Srecords being produced to IVAL. This length covers both address, +- data and crc fields. +- +-`--srec-forceS3' +- Meaningful only for srec output. Avoid generation of S1/S2 +- records, creating S3-only record format. +- +-`--redefine-sym OLD=NEW' +- Change the name of a symbol OLD, to NEW. This can be useful when +- one is trying link two things together for which you have no +- source, and there are name collisions. +- +-`--redefine-syms=FILENAME' +- Apply `--redefine-sym' to each symbol pair "OLD NEW" listed in the +- file FILENAME. FILENAME is simply a flat file, with one symbol +- pair per line. Line comments may be introduced by the hash +- character. This option may be given more than once. +- +-`--weaken' +- Change all global symbols in the file to be weak. This can be +- useful when building an object which will be linked against other +- objects using the `-R' option to the linker. This option is only +- effective when using an object file format which supports weak +- symbols. +- +-`--keep-symbols=FILENAME' +- Apply `--keep-symbol' option to each symbol listed in the file +- FILENAME. FILENAME is simply a flat file, with one symbol name +- per line. Line comments may be introduced by the hash character. +- This option may be given more than once. +- +-`--strip-symbols=FILENAME' +- Apply `--strip-symbol' option to each symbol listed in the file +- FILENAME. FILENAME is simply a flat file, with one symbol name +- per line. Line comments may be introduced by the hash character. +- This option may be given more than once. +- +-`--strip-unneeded-symbols=FILENAME' +- Apply `--strip-unneeded-symbol' option to each symbol listed in +- the file FILENAME. FILENAME is simply a flat file, with one +- symbol name per line. Line comments may be introduced by the hash +- character. This option may be given more than once. +- +-`--keep-global-symbols=FILENAME' +- Apply `--keep-global-symbol' option to each symbol listed in the +- file FILENAME. FILENAME is simply a flat file, with one symbol +- name per line. Line comments may be introduced by the hash +- character. This option may be given more than once. +- +-`--localize-symbols=FILENAME' +- Apply `--localize-symbol' option to each symbol listed in the file +- FILENAME. FILENAME is simply a flat file, with one symbol name +- per line. Line comments may be introduced by the hash character. +- This option may be given more than once. +- +-`--globalize-symbols=FILENAME' +- Apply `--globalize-symbol' option to each symbol listed in the file +- FILENAME. FILENAME is simply a flat file, with one symbol name +- per line. Line comments may be introduced by the hash character. +- This option may be given more than once. +- +-`--weaken-symbols=FILENAME' +- Apply `--weaken-symbol' option to each symbol listed in the file +- FILENAME. FILENAME is simply a flat file, with one symbol name +- per line. Line comments may be introduced by the hash character. +- This option may be given more than once. +- +-`--alt-machine-code=INDEX' +- If the output architecture has alternate machine codes, use the +- INDEXth code instead of the default one. This is useful in case a +- machine is assigned an official code and the tool-chain adopts the +- new code, but other applications still depend on the original code +- being used. For ELF based architectures if the INDEX alternative +- does not exist then the value is treated as an absolute number to +- be stored in the e_machine field of the ELF header. +- +-`--writable-text' +- Mark the output text as writable. This option isn't meaningful +- for all object file formats. +- +-`--readonly-text' +- Make the output text write protected. This option isn't +- meaningful for all object file formats. +- +-`--pure' +- Mark the output file as demand paged. This option isn't +- meaningful for all object file formats. +- +-`--impure' +- Mark the output file as impure. This option isn't meaningful for +- all object file formats. +- +-`--prefix-symbols=STRING' +- Prefix all symbols in the output file with STRING. +- +-`--prefix-sections=STRING' +- Prefix all section names in the output file with STRING. +- +-`--prefix-alloc-sections=STRING' +- Prefix all the names of all allocated sections in the output file +- with STRING. +- +-`--add-gnu-debuglink=PATH-TO-FILE' +- Creates a .gnu_debuglink section which contains a reference to +- PATH-TO-FILE and adds it to the output file. +- +-`--keep-file-symbols' +- When stripping a file, perhaps with `--strip-debug' or +- `--strip-unneeded', retain any symbols specifying source file +- names, which would otherwise get stripped. +- +-`--only-keep-debug' +- Strip a file, removing contents of any sections that would not be +- stripped by `--strip-debug' and leaving the debugging sections +- intact. In ELF files, this preserves all note sections in the +- output. +- +- The intention is that this option will be used in conjunction with +- `--add-gnu-debuglink' to create a two part executable. One a +- stripped binary which will occupy less space in RAM and in a +- distribution and the second a debugging information file which is +- only needed if debugging abilities are required. The suggested +- procedure to create these files is as follows: +- +- 1. Link the executable as normal. Assuming that is is called +- `foo' then... +- +- 2. Run `objcopy --only-keep-debug foo foo.dbg' to create a file +- containing the debugging info. +- +- 3. Run `objcopy --strip-debug foo' to create a stripped +- executable. +- +- 4. Run `objcopy --add-gnu-debuglink=foo.dbg foo' to add a link +- to the debugging info into the stripped executable. +- +- Note--the choice of `.dbg' as an extension for the debug info file +- is arbitrary. Also the `--only-keep-debug' step is optional. You +- could instead do this: +- +- 1. Link the executable as normal. +- +- 2. Copy `foo' to `foo.full' +- +- 3. Run `objcopy --strip-debug foo' +- +- 4. Run `objcopy --add-gnu-debuglink=foo.full foo' +- +- i.e., the file pointed to by the `--add-gnu-debuglink' can be the +- full executable. It does not have to be a file created by the +- `--only-keep-debug' switch. +- +- Note--this switch is only intended for use on fully linked files. +- It does not make sense to use it on object files where the +- debugging information may be incomplete. Besides the +- gnu_debuglink feature currently only supports the presence of one +- filename containing debugging information, not multiple filenames +- on a one-per-object-file basis. +- +-`--strip-dwo' +- Remove the contents of all DWARF .dwo sections, leaving the +- remaining debugging sections and all symbols intact. This option +- is intended for use by the compiler as part of the `-gsplit-dwarf' +- option, which splits debug information between the .o file and a +- separate .dwo file. The compiler generates all debug information +- in the same file, then uses the `--extract-dwo' option to copy the +- .dwo sections to the .dwo file, then the `--strip-dwo' option to +- remove those sections from the original .o file. +- +-`--extract-dwo' +- Extract the contents of all DWARF .dwo sections. See the +- `--strip-dwo' option for more information. +- +-`--file-alignment NUM' +- Specify the file alignment. Sections in the file will always +- begin at file offsets which are multiples of this number. This +- defaults to 512. [This option is specific to PE targets.] +- +-`--heap RESERVE' +-`--heap RESERVE,COMMIT' +- Specify the number of bytes of memory to reserve (and optionally +- commit) to be used as heap for this program. [This option is +- specific to PE targets.] +- +-`--image-base VALUE' +- Use VALUE as the base address of your program or dll. This is the +- lowest memory location that will be used when your program or dll +- is loaded. To reduce the need to relocate and improve performance +- of your dlls, each should have a unique base address and not +- overlap any other dlls. The default is 0x400000 for executables, +- and 0x10000000 for dlls. [This option is specific to PE targets.] +- +-`--section-alignment NUM' +- Sets the section alignment. Sections in memory will always begin +- at addresses which are a multiple of this number. Defaults to +- 0x1000. [This option is specific to PE targets.] +- +-`--stack RESERVE' +-`--stack RESERVE,COMMIT' +- Specify the number of bytes of memory to reserve (and optionally +- commit) to be used as stack for this program. [This option is +- specific to PE targets.] +- +-`--subsystem WHICH' +-`--subsystem WHICH:MAJOR' +-`--subsystem WHICH:MAJOR.MINOR' +- Specifies the subsystem under which your program will execute. The +- legal values for WHICH are `native', `windows', `console', +- `posix', `efi-app', `efi-bsd', `efi-rtd', `sal-rtd', and `xbox'. +- You may optionally set the subsystem version also. Numeric values +- are also accepted for WHICH. [This option is specific to PE +- targets.] +- +-`--extract-symbol' +- Keep the file's section flags and symbols but remove all section +- data. Specifically, the option: +- +- * removes the contents of all sections; +- +- * sets the size of every section to zero; and +- +- * sets the file's start address to zero. +- +- This option is used to build a `.sym' file for a VxWorks kernel. +- It can also be a useful way of reducing the size of a +- `--just-symbols' linker input file. +- +-`--compress-debug-sections' +- Compress DWARF debug sections using zlib. +- +-`--decompress-debug-sections' +- Decompress DWARF debug sections using zlib. +- +-`-V' +-`--version' +- Show the version number of `objcopy'. +- +-`-v' +-`--verbose' +- Verbose output: list all object files modified. In the case of +- archives, `objcopy -V' lists all members of the archive. +- +-`--help' +- Show a summary of the options to `objcopy'. +- +-`--info' +- Display a list showing all architectures and object formats +- available. +- +- +-File: binutils.info, Node: objdump, Next: ranlib, Prev: objcopy, Up: Top +- +-4 objdump +-********* +- +- objdump [`-a'|`--archive-headers'] +- [`-b' BFDNAME|`--target=BFDNAME'] +- [`-C'|`--demangle'[=STYLE] ] +- [`-d'|`--disassemble'] +- [`-D'|`--disassemble-all'] +- [`-z'|`--disassemble-zeroes'] +- [`-EB'|`-EL'|`--endian='{big | little }] +- [`-f'|`--file-headers'] +- [`-F'|`--file-offsets'] +- [`--file-start-context'] +- [`-g'|`--debugging'] +- [`-e'|`--debugging-tags'] +- [`-h'|`--section-headers'|`--headers'] +- [`-i'|`--info'] +- [`-j' SECTION|`--section='SECTION] +- [`-l'|`--line-numbers'] +- [`-S'|`--source'] +- [`-m' MACHINE|`--architecture='MACHINE] +- [`-M' OPTIONS|`--disassembler-options='OPTIONS] +- [`-p'|`--private-headers'] +- [`-P' OPTIONS|`--private='OPTIONS] +- [`-r'|`--reloc'] +- [`-R'|`--dynamic-reloc'] +- [`-s'|`--full-contents'] +- [`-W[lLiaprmfFsoRt]'| +- `--dwarf'[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] +- [`-G'|`--stabs'] +- [`-t'|`--syms'] +- [`-T'|`--dynamic-syms'] +- [`-x'|`--all-headers'] +- [`-w'|`--wide'] +- [`--start-address='ADDRESS] +- [`--stop-address='ADDRESS] +- [`--prefix-addresses'] +- [`--[no-]show-raw-insn'] +- [`--adjust-vma='OFFSET] +- [`--special-syms'] +- [`--prefix='PREFIX] +- [`--prefix-strip='LEVEL] +- [`--insn-width='WIDTH] +- [`-V'|`--version'] +- [`-H'|`--help'] +- OBJFILE... +- +- `objdump' displays information about one or more object files. The +-options control what particular information to display. This +-information is mostly useful to programmers who are working on the +-compilation tools, as opposed to programmers who just want their +-program to compile and work. +- +- OBJFILE... are the object files to be examined. When you specify +-archives, `objdump' shows information on each of the member object +-files. +- +- The long and short forms of options, shown here as alternatives, are +-equivalent. At least one option from the list +-`-a,-d,-D,-e,-f,-g,-G,-h,-H,-p,-P,-r,-R,-s,-S,-t,-T,-V,-x' must be +-given. +- +-`-a' +-`--archive-header' +- If any of the OBJFILE files are archives, display the archive +- header information (in a format similar to `ls -l'). Besides the +- information you could list with `ar tv', `objdump -a' shows the +- object file format of each archive member. +- +-`--adjust-vma=OFFSET' +- When dumping information, first add OFFSET to all the section +- addresses. This is useful if the section addresses do not +- correspond to the symbol table, which can happen when putting +- sections at particular addresses when using a format which can not +- represent section addresses, such as a.out. +- +-`-b BFDNAME' +-`--target=BFDNAME' +- Specify that the object-code format for the object files is +- BFDNAME. This option may not be necessary; OBJDUMP can +- automatically recognize many formats. +- +- For example, +- objdump -b oasys -m vax -h fu.o +- displays summary information from the section headers (`-h') of +- `fu.o', which is explicitly identified (`-m') as a VAX object file +- in the format produced by Oasys compilers. You can list the +- formats available with the `-i' option. *Note Target Selection::, +- for more information. +- +-`-C' +-`--demangle[=STYLE]' +- Decode ("demangle") low-level symbol names into user-level names. +- Besides removing any initial underscore prepended by the system, +- this makes C++ function names readable. Different compilers have +- different mangling styles. The optional demangling style argument +- can be used to choose an appropriate demangling style for your +- compiler. *Note c++filt::, for more information on demangling. +- +-`-g' +-`--debugging' +- Display debugging information. This attempts to parse STABS and +- IEEE debugging format information stored in the file and print it +- out using a C like syntax. If neither of these formats are found +- this option falls back on the `-W' option to print any DWARF +- information in the file. +- +-`-e' +-`--debugging-tags' +- Like `-g', but the information is generated in a format compatible +- with ctags tool. +- +-`-d' +-`--disassemble' +- Display the assembler mnemonics for the machine instructions from +- OBJFILE. This option only disassembles those sections which are +- expected to contain instructions. +- +-`-D' +-`--disassemble-all' +- Like `-d', but disassemble the contents of all sections, not just +- those expected to contain instructions. +- +- If the target is an ARM architecture this switch also has the +- effect of forcing the disassembler to decode pieces of data found +- in code sections as if they were instructions. +- +-`--prefix-addresses' +- When disassembling, print the complete address on each line. This +- is the older disassembly format. +- +-`-EB' +-`-EL' +-`--endian={big|little}' +- Specify the endianness of the object files. This only affects +- disassembly. This can be useful when disassembling a file format +- which does not describe endianness information, such as S-records. +- +-`-f' +-`--file-headers' +- Display summary information from the overall header of each of the +- OBJFILE files. +- +-`-F' +-`--file-offsets' +- When disassembling sections, whenever a symbol is displayed, also +- display the file offset of the region of data that is about to be +- dumped. If zeroes are being skipped, then when disassembly +- resumes, tell the user how many zeroes were skipped and the file +- offset of the location from where the disassembly resumes. When +- dumping sections, display the file offset of the location from +- where the dump starts. +- +-`--file-start-context' +- Specify that when displaying interlisted source code/disassembly +- (assumes `-S') from a file that has not yet been displayed, extend +- the context to the start of the file. +- +-`-h' +-`--section-headers' +-`--headers' +- Display summary information from the section headers of the object +- file. +- +- File segments may be relocated to nonstandard addresses, for +- example by using the `-Ttext', `-Tdata', or `-Tbss' options to +- `ld'. However, some object file formats, such as a.out, do not +- store the starting address of the file segments. In those +- situations, although `ld' relocates the sections correctly, using +- `objdump -h' to list the file section headers cannot show the +- correct addresses. Instead, it shows the usual addresses, which +- are implicit for the target. +- +-`-H' +-`--help' +- Print a summary of the options to `objdump' and exit. +- +-`-i' +-`--info' +- Display a list showing all architectures and object formats +- available for specification with `-b' or `-m'. +- +-`-j NAME' +-`--section=NAME' +- Display information only for section NAME. +- +-`-l' +-`--line-numbers' +- Label the display (using debugging information) with the filename +- and source line numbers corresponding to the object code or relocs +- shown. Only useful with `-d', `-D', or `-r'. +- +-`-m MACHINE' +-`--architecture=MACHINE' +- Specify the architecture to use when disassembling object files. +- This can be useful when disassembling object files which do not +- describe architecture information, such as S-records. You can +- list the available architectures with the `-i' option. +- +- If the target is an ARM architecture then this switch has an +- additional effect. It restricts the disassembly to only those +- instructions supported by the architecture specified by MACHINE. +- If it is necessary to use this switch because the input file does +- not contain any architecture information, but it is also desired to +- disassemble all the instructions use `-marm'. +- +-`-M OPTIONS' +-`--disassembler-options=OPTIONS' +- Pass target specific information to the disassembler. Only +- supported on some targets. If it is necessary to specify more +- than one disassembler option then multiple `-M' options can be +- used or can be placed together into a comma separated list. +- +- If the target is an ARM architecture then this switch can be used +- to select which register name set is used during disassembler. +- Specifying `-M reg-names-std' (the default) will select the +- register names as used in ARM's instruction set documentation, but +- with register 13 called 'sp', register 14 called 'lr' and register +- 15 called 'pc'. Specifying `-M reg-names-apcs' will select the +- name set used by the ARM Procedure Call Standard, whilst +- specifying `-M reg-names-raw' will just use `r' followed by the +- register number. +- +- There are also two variants on the APCS register naming scheme +- enabled by `-M reg-names-atpcs' and `-M reg-names-special-atpcs' +- which use the ARM/Thumb Procedure Call Standard naming +- conventions. (Either with the normal register names or the +- special register names). +- +- This option can also be used for ARM architectures to force the +- disassembler to interpret all instructions as Thumb instructions by +- using the switch `--disassembler-options=force-thumb'. This can be +- useful when attempting to disassemble thumb code produced by other +- compilers. +- +- For the x86, some of the options duplicate functions of the `-m' +- switch, but allow finer grained control. Multiple selections from +- the following may be specified as a comma separated string. +- `x86-64', `i386' and `i8086' select disassembly for the given +- architecture. `intel' and `att' select between intel syntax mode +- and AT&T syntax mode. `intel-mnemonic' and `att-mnemonic' select +- between intel mnemonic mode and AT&T mnemonic mode. +- `intel-mnemonic' implies `intel' and `att-mnemonic' implies `att'. +- `addr64', `addr32', `addr16', `data32' and `data16' specify the +- default address size and operand size. These four options will be +- overridden if `x86-64', `i386' or `i8086' appear later in the +- option string. Lastly, `suffix', when in AT&T mode, instructs the +- disassembler to print a mnemonic suffix even when the suffix could +- be inferred by the operands. +- +- For PowerPC, `booke' controls the disassembly of BookE +- instructions. `32' and `64' select PowerPC and PowerPC64 +- disassembly, respectively. `e300' selects disassembly for the +- e300 family. `440' selects disassembly for the PowerPC 440. +- `ppcps' selects disassembly for the paired single instructions of +- the PPC750CL. +- +- For MIPS, this option controls the printing of instruction mnemonic +- names and register names in disassembled instructions. Multiple +- selections from the following may be specified as a comma separated +- string, and invalid options are ignored: +- +- `no-aliases' +- Print the 'raw' instruction mnemonic instead of some pseudo +- instruction mnemonic. I.e., print 'daddu' or 'or' instead of +- 'move', 'sll' instead of 'nop', etc. +- +- `virt' +- Disassemble the virtualization ASE instructions. +- +- `gpr-names=ABI' +- Print GPR (general-purpose register) names as appropriate for +- the specified ABI. By default, GPR names are selected +- according to the ABI of the binary being disassembled. +- +- `fpr-names=ABI' +- Print FPR (floating-point register) names as appropriate for +- the specified ABI. By default, FPR numbers are printed +- rather than names. +- +- `cp0-names=ARCH' +- Print CP0 (system control coprocessor; coprocessor 0) +- register names as appropriate for the CPU or architecture +- specified by ARCH. By default, CP0 register names are +- selected according to the architecture and CPU of the binary +- being disassembled. +- +- `hwr-names=ARCH' +- Print HWR (hardware register, used by the `rdhwr' +- instruction) names as appropriate for the CPU or architecture +- specified by ARCH. By default, HWR names are selected +- according to the architecture and CPU of the binary being +- disassembled. +- +- `reg-names=ABI' +- Print GPR and FPR names as appropriate for the selected ABI. +- +- `reg-names=ARCH' +- Print CPU-specific register names (CP0 register and HWR names) +- as appropriate for the selected CPU or architecture. +- +- For any of the options listed above, ABI or ARCH may be specified +- as `numeric' to have numbers printed rather than names, for the +- selected types of registers. You can list the available values of +- ABI and ARCH using the `--help' option. +- +- For VAX, you can specify function entry addresses with `-M +- entry:0xf00ba'. You can use this multiple times to properly +- disassemble VAX binary files that don't contain symbol tables (like +- ROM dumps). In these cases, the function entry mask would +- otherwise be decoded as VAX instructions, which would probably +- lead the rest of the function being wrongly disassembled. +- +-`-p' +-`--private-headers' +- Print information that is specific to the object file format. The +- exact information printed depends upon the object file format. +- For some object file formats, no additional information is printed. +- +-`-P OPTIONS' +-`--private=OPTIONS' +- Print information that is specific to the object file format. The +- argument OPTIONS is a comma separated list that depends on the +- format (the lists of options is displayed with the help). +- +- For XCOFF, the available options are: `header', `aout', +- `sections', `syms', `relocs', `lineno', `loader', `except', +- `typchk', `traceback', `toc' and `ldinfo'. +- +-`-r' +-`--reloc' +- Print the relocation entries of the file. If used with `-d' or +- `-D', the relocations are printed interspersed with the +- disassembly. +- +-`-R' +-`--dynamic-reloc' +- Print the dynamic relocation entries of the file. This is only +- meaningful for dynamic objects, such as certain types of shared +- libraries. As for `-r', if used with `-d' or `-D', the +- relocations are printed interspersed with the disassembly. +- +-`-s' +-`--full-contents' +- Display the full contents of any sections requested. By default +- all non-empty sections are displayed. +- +-`-S' +-`--source' +- Display source code intermixed with disassembly, if possible. +- Implies `-d'. +- +-`--prefix=PREFIX' +- Specify PREFIX to add to the absolute paths when used with `-S'. +- +-`--prefix-strip=LEVEL' +- Indicate how many initial directory names to strip off the +- hardwired absolute paths. It has no effect without +- `--prefix='PREFIX. +- +-`--show-raw-insn' +- When disassembling instructions, print the instruction in hex as +- well as in symbolic form. This is the default except when +- `--prefix-addresses' is used. +- +-`--no-show-raw-insn' +- When disassembling instructions, do not print the instruction +- bytes. This is the default when `--prefix-addresses' is used. +- +-`--insn-width=WIDTH' +- Display WIDTH bytes on a single line when disassembling +- instructions. +- +-`-W[lLiaprmfFsoRt]' +-`--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]' +- Displays the contents of the debug sections in the file, if any are +- present. If one of the optional letters or words follows the +- switch then only data found in those specific sections will be +- dumped. +- +- Note that there is no single letter option to display the content +- of trace sections or .gdb_index. +- +- Note: the output from the `=info' option can also be affected by +- the options `--dwarf-depth', the `--dwarf-start' and the +- `--dwarf-check'. +- +-`--dwarf-depth=N' +- Limit the dump of the `.debug_info' section to N children. This +- is only useful with `--dwarf=info'. The default is to print all +- DIEs; the special value 0 for N will also have this effect. +- +- With a non-zero value for N, DIEs at or deeper than N levels will +- not be printed. The range for N is zero-based. +- +-`--dwarf-start=N' +- Print only DIEs beginning with the DIE numbered N. This is only +- useful with `--dwarf=info'. +- +- If specified, this option will suppress printing of any header +- information and all DIEs before the DIE numbered N. Only siblings +- and children of the specified DIE will be printed. +- +- This can be used in conjunction with `--dwarf-depth'. +- +-`--dwarf-check' +- Enable additional checks for consistency of Dwarf information. +- +-`-G' +-`--stabs' +- Display the full contents of any sections requested. Display the +- contents of the .stab and .stab.index and .stab.excl sections from +- an ELF file. This is only useful on systems (such as Solaris 2.0) +- in which `.stab' debugging symbol-table entries are carried in an +- ELF section. In most other file formats, debugging symbol-table +- entries are interleaved with linkage symbols, and are visible in +- the `--syms' output. +- +-`--start-address=ADDRESS' +- Start displaying data at the specified address. This affects the +- output of the `-d', `-r' and `-s' options. +- +-`--stop-address=ADDRESS' +- Stop displaying data at the specified address. This affects the +- output of the `-d', `-r' and `-s' options. +- +-`-t' +-`--syms' +- Print the symbol table entries of the file. This is similar to +- the information provided by the `nm' program, although the display +- format is different. The format of the output depends upon the +- format of the file being dumped, but there are two main types. +- One looks like this: +- +- [ 4](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss +- [ 6](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 fred +- +- where the number inside the square brackets is the number of the +- entry in the symbol table, the SEC number is the section number, +- the FL value are the symbol's flag bits, the TY number is the +- symbol's type, the SCL number is the symbol's storage class and +- the NX value is the number of auxilary entries associated with the +- symbol. The last two fields are the symbol's value and its name. +- +- The other common output format, usually seen with ELF based files, +- looks like this: +- +- 00000000 l d .bss 00000000 .bss +- 00000000 g .text 00000000 fred +- +- Here the first number is the symbol's value (sometimes refered to +- as its address). The next field is actually a set of characters +- and spaces indicating the flag bits that are set on the symbol. +- These characters are described below. Next is the section with +- which the symbol is associated or _*ABS*_ if the section is +- absolute (ie not connected with any section), or _*UND*_ if the +- section is referenced in the file being dumped, but not defined +- there. +- +- After the section name comes another field, a number, which for +- common symbols is the alignment and for other symbol is the size. +- Finally the symbol's name is displayed. +- +- The flag characters are divided into 7 groups as follows: +- `l' +- `g' +- `u' +- `!' +- The symbol is a local (l), global (g), unique global (u), +- neither global nor local (a space) or both global and local +- (!). A symbol can be neither local or global for a variety +- of reasons, e.g., because it is used for debugging, but it is +- probably an indication of a bug if it is ever both local and +- global. Unique global symbols are a GNU extension to the +- standard set of ELF symbol bindings. For such a symbol the +- dynamic linker will make sure that in the entire process +- there is just one symbol with this name and type in use. +- +- `w' +- The symbol is weak (w) or strong (a space). +- +- `C' +- The symbol denotes a constructor (C) or an ordinary symbol (a +- space). +- +- `W' +- The symbol is a warning (W) or a normal symbol (a space). A +- warning symbol's name is a message to be displayed if the +- symbol following the warning symbol is ever referenced. +- +- `I' +- +- `i' +- The symbol is an indirect reference to another symbol (I), a +- function to be evaluated during reloc processing (i) or a +- normal symbol (a space). +- +- `d' +- `D' +- The symbol is a debugging symbol (d) or a dynamic symbol (D) +- or a normal symbol (a space). +- +- `F' +- +- `f' +- +- `O' +- The symbol is the name of a function (F) or a file (f) or an +- object (O) or just a normal symbol (a space). +- +-`-T' +-`--dynamic-syms' +- Print the dynamic symbol table entries of the file. This is only +- meaningful for dynamic objects, such as certain types of shared +- libraries. This is similar to the information provided by the `nm' +- program when given the `-D' (`--dynamic') option. +- +-`--special-syms' +- When displaying symbols include those which the target considers +- to be special in some way and which would not normally be of +- interest to the user. +- +-`-V' +-`--version' +- Print the version number of `objdump' and exit. +- +-`-x' +-`--all-headers' +- Display all available header information, including the symbol +- table and relocation entries. Using `-x' is equivalent to +- specifying all of `-a -f -h -p -r -t'. +- +-`-w' +-`--wide' +- Format some lines for output devices that have more than 80 +- columns. Also do not truncate symbol names when they are +- displayed. +- +-`-z' +-`--disassemble-zeroes' +- Normally the disassembly output will skip blocks of zeroes. This +- option directs the disassembler to disassemble those blocks, just +- like any other data. +- +- +-File: binutils.info, Node: ranlib, Next: size, Prev: objdump, Up: Top +- +-5 ranlib +-******** +- +- ranlib [`--plugin' NAME] [`-DhHvVt'] ARCHIVE +- +- `ranlib' generates an index to the contents of an archive and stores +-it in the archive. The index lists each symbol defined by a member of +-an archive that is a relocatable object file. +- +- You may use `nm -s' or `nm --print-armap' to list this index. +- +- An archive with such an index speeds up linking to the library and +-allows routines in the library to call each other without regard to +-their placement in the archive. +- +- The GNU `ranlib' program is another form of GNU `ar'; running +-`ranlib' is completely equivalent to executing `ar -s'. *Note ar::. +- +-`-h' +-`-H' +-`--help' +- Show usage information for `ranlib'. +- +-`-v' +-`-V' +-`--version' +- Show the version number of `ranlib'. +- +-`-D' +- Operate in _deterministic_ mode. The symbol map archive member's +- header will show zero for the UID, GID, and timestamp. When this +- option is used, multiple runs will produce identical output files. +- +- If `binutils' was configured with +- `--enable-deterministic-archives', then this mode is on by +- default. It can be disabled with the `-U' option, described below. +- +-`-t' +- Update the timestamp of the symbol map of an archive. +- +-`-U' +- Do _not_ operate in _deterministic_ mode. This is the inverse of +- the `-D' option, above: the archive index will get actual UID, +- GID, timestamp, and file mode values. +- +- If `binutils' was configured _without_ +- `--enable-deterministic-archives', then this mode is on by default. +- +- +- +-File: binutils.info, Node: size, Next: strings, Prev: ranlib, Up: Top +- +-6 size +-****** +- +- size [`-A'|`-B'|`--format='COMPATIBILITY] +- [`--help'] +- [`-d'|`-o'|`-x'|`--radix='NUMBER] +- [`--common'] +- [`-t'|`--totals'] +- [`--target='BFDNAME] [`-V'|`--version'] +- [OBJFILE...] +- +- The GNU `size' utility lists the section sizes--and the total +-size--for each of the object or archive files OBJFILE in its argument +-list. By default, one line of output is generated for each object file +-or each module in an archive. +- +- OBJFILE... are the object files to be examined. If none are +-specified, the file `a.out' will be used. +- +- The command line options have the following meanings: +- +-`-A' +-`-B' +-`--format=COMPATIBILITY' +- Using one of these options, you can choose whether the output from +- GNU `size' resembles output from System V `size' (using `-A', or +- `--format=sysv'), or Berkeley `size' (using `-B', or +- `--format=berkeley'). The default is the one-line format similar +- to Berkeley's. +- +- Here is an example of the Berkeley (default) format of output from +- `size': +- $ size --format=Berkeley ranlib size +- text data bss dec hex filename +- 294880 81920 11592 388392 5ed28 ranlib +- 294880 81920 11888 388688 5ee50 size +- +- This is the same data, but displayed closer to System V +- conventions: +- +- $ size --format=SysV ranlib size +- ranlib : +- section size addr +- .text 294880 8192 +- .data 81920 303104 +- .bss 11592 385024 +- Total 388392 +- +- +- size : +- section size addr +- .text 294880 8192 +- .data 81920 303104 +- .bss 11888 385024 +- Total 388688 +- +-`--help' +- Show a summary of acceptable arguments and options. +- +-`-d' +-`-o' +-`-x' +-`--radix=NUMBER' +- Using one of these options, you can control whether the size of +- each section is given in decimal (`-d', or `--radix=10'); octal +- (`-o', or `--radix=8'); or hexadecimal (`-x', or `--radix=16'). +- In `--radix=NUMBER', only the three values (8, 10, 16) are +- supported. The total size is always given in two radices; decimal +- and hexadecimal for `-d' or `-x' output, or octal and hexadecimal +- if you're using `-o'. +- +-`--common' +- Print total size of common symbols in each file. When using +- Berkeley format these are included in the bss size. +- +-`-t' +-`--totals' +- Show totals of all objects listed (Berkeley format listing mode +- only). +- +-`--target=BFDNAME' +- Specify that the object-code format for OBJFILE is BFDNAME. This +- option may not be necessary; `size' can automatically recognize +- many formats. *Note Target Selection::, for more information. +- +-`-V' +-`--version' +- Display the version number of `size'. +- +- +-File: binutils.info, Node: strings, Next: strip, Prev: size, Up: Top +- +-7 strings +-********* +- +- strings [`-afovV'] [`-'MIN-LEN] +- [`-n' MIN-LEN] [`--bytes='MIN-LEN] +- [`-t' RADIX] [`--radix='RADIX] +- [`-e' ENCODING] [`--encoding='ENCODING] +- [`-'] [`--all'] [`--print-file-name'] +- [`-T' BFDNAME] [`--target='BFDNAME] +- [`--help'] [`--version'] FILE... +- +- For each FILE given, GNU `strings' prints the printable character +-sequences that are at least 4 characters long (or the number given with +-the options below) and are followed by an unprintable character. By +-default, it only prints the strings from the initialized and loaded +-sections of object files; for other types of files, it prints the +-strings from the whole file. +- +- `strings' is mainly useful for determining the contents of non-text +-files. +- +-`-a' +-`--all' +-`-' +- Do not scan only the initialized and loaded sections of object +- files; scan the whole files. +- +-`-f' +-`--print-file-name' +- Print the name of the file before each string. +- +-`--help' +- Print a summary of the program usage on the standard output and +- exit. +- +-`-MIN-LEN' +-`-n MIN-LEN' +-`--bytes=MIN-LEN' +- Print sequences of characters that are at least MIN-LEN characters +- long, instead of the default 4. +- +-`-o' +- Like `-t o'. Some other versions of `strings' have `-o' act like +- `-t d' instead. Since we can not be compatible with both ways, we +- simply chose one. +- +-`-t RADIX' +-`--radix=RADIX' +- Print the offset within the file before each string. The single +- character argument specifies the radix of the offset--`o' for +- octal, `x' for hexadecimal, or `d' for decimal. +- +-`-e ENCODING' +-`--encoding=ENCODING' +- Select the character encoding of the strings that are to be found. +- Possible values for ENCODING are: `s' = single-7-bit-byte +- characters (ASCII, ISO 8859, etc., default), `S' = +- single-8-bit-byte characters, `b' = 16-bit bigendian, `l' = 16-bit +- littleendian, `B' = 32-bit bigendian, `L' = 32-bit littleendian. +- Useful for finding wide character strings. (`l' and `b' apply to, +- for example, Unicode UTF-16/UCS-2 encodings). +- +-`-T BFDNAME' +-`--target=BFDNAME' +- Specify an object code format other than your system's default +- format. *Note Target Selection::, for more information. +- +-`-v' +-`-V' +-`--version' +- Print the program version number on the standard output and exit. +- +- +-File: binutils.info, Node: strip, Next: c++filt, Prev: strings, Up: Top +- +-8 strip +-******* +- +- strip [`-F' BFDNAME |`--target='BFDNAME] +- [`-I' BFDNAME |`--input-target='BFDNAME] +- [`-O' BFDNAME |`--output-target='BFDNAME] +- [`-s'|`--strip-all'] +- [`-S'|`-g'|`-d'|`--strip-debug'] +- [`--strip-dwo'] +- [`-K' SYMBOLNAME |`--keep-symbol='SYMBOLNAME] +- [`-N' SYMBOLNAME |`--strip-symbol='SYMBOLNAME] +- [`-w'|`--wildcard'] +- [`-x'|`--discard-all'] [`-X' |`--discard-locals'] +- [`-R' SECTIONNAME |`--remove-section='SECTIONNAME] +- [`-o' FILE] [`-p'|`--preserve-dates'] +- [`-D'|`--enable-deterministic-archives'] +- [`-U'|`--disable-deterministic-archives'] +- [`--keep-file-symbols'] +- [`--only-keep-debug'] +- [`-v' |`--verbose'] [`-V'|`--version'] +- [`--help'] [`--info'] +- OBJFILE... +- +- GNU `strip' discards all symbols from object files OBJFILE. The +-list of object files may include archives. At least one object file +-must be given. +- +- `strip' modifies the files named in its argument, rather than +-writing modified copies under different names. +- +-`-F BFDNAME' +-`--target=BFDNAME' +- Treat the original OBJFILE as a file with the object code format +- BFDNAME, and rewrite it in the same format. *Note Target +- Selection::, for more information. +- +-`--help' +- Show a summary of the options to `strip' and exit. +- +-`--info' +- Display a list showing all architectures and object formats +- available. +- +-`-I BFDNAME' +-`--input-target=BFDNAME' +- Treat the original OBJFILE as a file with the object code format +- BFDNAME. *Note Target Selection::, for more information. +- +-`-O BFDNAME' +-`--output-target=BFDNAME' +- Replace OBJFILE with a file in the output format BFDNAME. *Note +- Target Selection::, for more information. +- +-`-R SECTIONNAME' +-`--remove-section=SECTIONNAME' +- Remove any section named SECTIONNAME from the output file. This +- option may be given more than once. Note that using this option +- inappropriately may make the output file unusable. The wildcard +- character `*' may be given at the end of SECTIONNAME. If so, then +- any section starting with SECTIONNAME will be removed. +- +-`-s' +-`--strip-all' +- Remove all symbols. +- +-`-g' +-`-S' +-`-d' +-`--strip-debug' +- Remove debugging symbols only. +- +-`--strip-dwo' +- Remove the contents of all DWARF .dwo sections, leaving the +- remaining debugging sections and all symbols intact. See the +- description of this option in the `objcopy' section for more +- information. +- +-`--strip-unneeded' +- Remove all symbols that are not needed for relocation processing. +- +-`-K SYMBOLNAME' +-`--keep-symbol=SYMBOLNAME' +- When stripping symbols, keep symbol SYMBOLNAME even if it would +- normally be stripped. This option may be given more than once. +- +-`-N SYMBOLNAME' +-`--strip-symbol=SYMBOLNAME' +- Remove symbol SYMBOLNAME from the source file. This option may be +- given more than once, and may be combined with strip options other +- than `-K'. +- +-`-o FILE' +- Put the stripped output in FILE, rather than replacing the +- existing file. When this argument is used, only one OBJFILE +- argument may be specified. +- +-`-p' +-`--preserve-dates' +- Preserve the access and modification dates of the file. +- +-`-D' +-`--enable-deterministic-archives' +- Operate in _deterministic_ mode. When copying archive members and +- writing the archive index, use zero for UIDs, GIDs, timestamps, +- and use consistent file modes for all files. +- +- If `binutils' was configured with +- `--enable-deterministic-archives', then this mode is on by default. +- It can be disabled with the `-U' option, below. +- +-`-U' +-`--disable-deterministic-archives' +- Do _not_ operate in _deterministic_ mode. This is the inverse of +- the `-D' option, above: when copying archive members and writing +- the archive index, use their actual UID, GID, timestamp, and file +- mode values. +- +- This is the default unless `binutils' was configured with +- `--enable-deterministic-archives'. +- +-`-w' +-`--wildcard' +- Permit regular expressions in SYMBOLNAMEs used in other command +- line options. The question mark (?), asterisk (*), backslash (\) +- and square brackets ([]) operators can be used anywhere in the +- symbol name. If the first character of the symbol name is the +- exclamation point (!) then the sense of the switch is reversed for +- that symbol. For example: +- +- -w -K !foo -K fo* +- +- would cause strip to only keep symbols that start with the letters +- "fo", but to discard the symbol "foo". +- +-`-x' +-`--discard-all' +- Remove non-global symbols. +- +-`-X' +-`--discard-locals' +- Remove compiler-generated local symbols. (These usually start +- with `L' or `.'.) +- +-`--keep-file-symbols' +- When stripping a file, perhaps with `--strip-debug' or +- `--strip-unneeded', retain any symbols specifying source file +- names, which would otherwise get stripped. +- +-`--only-keep-debug' +- Strip a file, removing contents of any sections that would not be +- stripped by `--strip-debug' and leaving the debugging sections +- intact. In ELF files, this preserves all note sections in the +- output. +- +- The intention is that this option will be used in conjunction with +- `--add-gnu-debuglink' to create a two part executable. One a +- stripped binary which will occupy less space in RAM and in a +- distribution and the second a debugging information file which is +- only needed if debugging abilities are required. The suggested +- procedure to create these files is as follows: +- +- 1. Link the executable as normal. Assuming that is is called +- `foo' then... +- +- 2. Run `objcopy --only-keep-debug foo foo.dbg' to create a file +- containing the debugging info. +- +- 3. Run `objcopy --strip-debug foo' to create a stripped +- executable. +- +- 4. Run `objcopy --add-gnu-debuglink=foo.dbg foo' to add a link +- to the debugging info into the stripped executable. +- +- Note--the choice of `.dbg' as an extension for the debug info file +- is arbitrary. Also the `--only-keep-debug' step is optional. You +- could instead do this: +- +- 1. Link the executable as normal. +- +- 2. Copy `foo' to `foo.full' +- +- 3. Run `strip --strip-debug foo' +- +- 4. Run `objcopy --add-gnu-debuglink=foo.full foo' +- +- i.e., the file pointed to by the `--add-gnu-debuglink' can be the +- full executable. It does not have to be a file created by the +- `--only-keep-debug' switch. +- +- Note--this switch is only intended for use on fully linked files. +- It does not make sense to use it on object files where the +- debugging information may be incomplete. Besides the +- gnu_debuglink feature currently only supports the presence of one +- filename containing debugging information, not multiple filenames +- on a one-per-object-file basis. +- +-`-V' +-`--version' +- Show the version number for `strip'. +- +-`-v' +-`--verbose' +- Verbose output: list all object files modified. In the case of +- archives, `strip -v' lists all members of the archive. +- +- +-File: binutils.info, Node: c++filt, Next: addr2line, Prev: strip, Up: Top +- +-9 c++filt +-********* +- +- c++filt [`-_'|`--strip-underscore'] +- [`-n'|`--no-strip-underscore'] +- [`-p'|`--no-params'] +- [`-t'|`--types'] +- [`-i'|`--no-verbose'] +- [`-s' FORMAT|`--format='FORMAT] +- [`--help'] [`--version'] [SYMBOL...] +- +- The C++ and Java languages provide function overloading, which means +-that you can write many functions with the same name, providing that +-each function takes parameters of different types. In order to be able +-to distinguish these similarly named functions C++ and Java encode them +-into a low-level assembler name which uniquely identifies each +-different version. This process is known as "mangling". The `c++filt' +-(1) program does the inverse mapping: it decodes ("demangles") low-level +-names into user-level names so that they can be read. +- +- Every alphanumeric word (consisting of letters, digits, underscores, +-dollars, or periods) seen in the input is a potential mangled name. If +-the name decodes into a C++ name, the C++ name replaces the low-level +-name in the output, otherwise the original word is output. In this way +-you can pass an entire assembler source file, containing mangled names, +-through `c++filt' and see the same source file containing demangled +-names. +- +- You can also use `c++filt' to decipher individual symbols by passing +-them on the command line: +- +- c++filt SYMBOL +- +- If no SYMBOL arguments are given, `c++filt' reads symbol names from +-the standard input instead. All the results are printed on the +-standard output. The difference between reading names from the command +-line versus reading names from the standard input is that command line +-arguments are expected to be just mangled names and no checking is +-performed to separate them from surrounding text. Thus for example: +- +- c++filt -n _Z1fv +- +- will work and demangle the name to "f()" whereas: +- +- c++filt -n _Z1fv, +- +- will not work. (Note the extra comma at the end of the mangled name +-which makes it invalid). This command however will work: +- +- echo _Z1fv, | c++filt -n +- +- and will display "f(),", i.e., the demangled name followed by a +-trailing comma. This behaviour is because when the names are read from +-the standard input it is expected that they might be part of an +-assembler source file where there might be extra, extraneous characters +-trailing after a mangled name. For example: +- +- .type _Z1fv, @function +- +-`-_' +-`--strip-underscore' +- On some systems, both the C and C++ compilers put an underscore in +- front of every name. For example, the C name `foo' gets the +- low-level name `_foo'. This option removes the initial +- underscore. Whether `c++filt' removes the underscore by default +- is target dependent. +- +-`-n' +-`--no-strip-underscore' +- Do not remove the initial underscore. +- +-`-p' +-`--no-params' +- When demangling the name of a function, do not display the types of +- the function's parameters. +- +-`-t' +-`--types' +- Attempt to demangle types as well as function names. This is +- disabled by default since mangled types are normally only used +- internally in the compiler, and they can be confused with +- non-mangled names. For example, a function called "a" treated as +- a mangled type name would be demangled to "signed char". +- +-`-i' +-`--no-verbose' +- Do not include implementation details (if any) in the demangled +- output. +- +-`-s FORMAT' +-`--format=FORMAT' +- `c++filt' can decode various methods of mangling, used by +- different compilers. The argument to this option selects which +- method it uses: +- +- `auto' +- Automatic selection based on executable (the default method) +- +- `gnu' +- the one used by the GNU C++ compiler (g++) +- +- `lucid' +- the one used by the Lucid compiler (lcc) +- +- `arm' +- the one specified by the C++ Annotated Reference Manual +- +- `hp' +- the one used by the HP compiler (aCC) +- +- `edg' +- the one used by the EDG compiler +- +- `gnu-v3' +- the one used by the GNU C++ compiler (g++) with the V3 ABI. +- +- `java' +- the one used by the GNU Java compiler (gcj) +- +- `gnat' +- the one used by the GNU Ada compiler (GNAT). +- +-`--help' +- Print a summary of the options to `c++filt' and exit. +- +-`--version' +- Print the version number of `c++filt' and exit. +- +- _Warning:_ `c++filt' is a new utility, and the details of its user +- interface are subject to change in future releases. In particular, +- a command-line option may be required in the future to decode a +- name passed as an argument on the command line; in other words, +- +- c++filt SYMBOL +- +- may in a future release become +- +- c++filt OPTION SYMBOL +- +- ---------- Footnotes ---------- +- +- (1) MS-DOS does not allow `+' characters in file names, so on MS-DOS +-this program is named `CXXFILT'. +- +- +-File: binutils.info, Node: addr2line, Next: nlmconv, Prev: c++filt, Up: Top +- +-10 addr2line +-************ +- +- addr2line [`-a'|`--addresses'] +- [`-b' BFDNAME|`--target='BFDNAME] +- [`-C'|`--demangle'[=STYLE]] +- [`-e' FILENAME|`--exe='FILENAME] +- [`-f'|`--functions'] [`-s'|`--basename'] +- [`-i'|`--inlines'] +- [`-p'|`--pretty-print'] +- [`-j'|`--section='NAME] +- [`-H'|`--help'] [`-V'|`--version'] +- [addr addr ...] +- +- `addr2line' translates addresses into file names and line numbers. +-Given an address in an executable or an offset in a section of a +-relocatable object, it uses the debugging information to figure out +-which file name and line number are associated with it. +- +- The executable or relocatable object to use is specified with the +-`-e' option. The default is the file `a.out'. The section in the +-relocatable object to use is specified with the `-j' option. +- +- `addr2line' has two modes of operation. +- +- In the first, hexadecimal addresses are specified on the command +-line, and `addr2line' displays the file name and line number for each +-address. +- +- In the second, `addr2line' reads hexadecimal addresses from standard +-input, and prints the file name and line number for each address on +-standard output. In this mode, `addr2line' may be used in a pipe to +-convert dynamically chosen addresses. +- +- The format of the output is `FILENAME:LINENO'. The file name and +-line number for each input address is printed on separate lines. +- +- If the `-f' option is used, then each `FILENAME:LINENO' line is +-preceded by `FUNCTIONNAME' which is the name of the function containing +-the address. +- +- If the `-i' option is used and the code at the given address is +-present there because of inlining by the compiler then the +-`{FUNCTIONNAME} FILENAME:LINENO' information for the inlining function +-will be displayed afterwards. This continues recursively until there +-is no more inlining to report. +- +- If the `-a' option is used then the output is prefixed by the input +-address. +- +- If the `-p' option is used then the output for each input address is +-displayed on one, possibly quite long, line. If `-p' is not used then +-the output is broken up into multiple lines, based on the paragraphs +-above. +- +- If the file name or function name can not be determined, `addr2line' +-will print two question marks in their place. If the line number can +-not be determined, `addr2line' will print 0. +- +- The long and short forms of options, shown here as alternatives, are +-equivalent. +- +-`-a' +-`--addresses' +- Display the address before the function name, file and line number +- information. The address is printed with a `0x' prefix to easily +- identify it. +- +-`-b BFDNAME' +-`--target=BFDNAME' +- Specify that the object-code format for the object files is +- BFDNAME. +- +-`-C' +-`--demangle[=STYLE]' +- Decode ("demangle") low-level symbol names into user-level names. +- Besides removing any initial underscore prepended by the system, +- this makes C++ function names readable. Different compilers have +- different mangling styles. The optional demangling style argument +- can be used to choose an appropriate demangling style for your +- compiler. *Note c++filt::, for more information on demangling. +- +-`-e FILENAME' +-`--exe=FILENAME' +- Specify the name of the executable for which addresses should be +- translated. The default file is `a.out'. +- +-`-f' +-`--functions' +- Display function names as well as file and line number information. +- +-`-s' +-`--basenames' +- Display only the base of each file name. +- +-`-i' +-`--inlines' +- If the address belongs to a function that was inlined, the source +- information for all enclosing scopes back to the first non-inlined +- function will also be printed. For example, if `main' inlines +- `callee1' which inlines `callee2', and address is from `callee2', +- the source information for `callee1' and `main' will also be +- printed. +- +-`-j' +-`--section' +- Read offsets relative to the specified section instead of absolute +- addresses. +- +-`-p' +-`--pretty-print' +- Make the output more human friendly: each location are printed on +- one line. If option `-i' is specified, lines for all enclosing +- scopes are prefixed with `(inlined by)'. +- +- +-File: binutils.info, Node: nlmconv, Next: windmc, Prev: addr2line, Up: Top +- +-11 nlmconv +-********** +- +-`nlmconv' converts a relocatable object file into a NetWare Loadable +-Module. +- +- _Warning:_ `nlmconv' is not always built as part of the binary +- utilities, since it is only useful for NLM targets. +- +- nlmconv [`-I' BFDNAME|`--input-target='BFDNAME] +- [`-O' BFDNAME|`--output-target='BFDNAME] +- [`-T' HEADERFILE|`--header-file='HEADERFILE] +- [`-d'|`--debug'] [`-l' LINKER|`--linker='LINKER] +- [`-h'|`--help'] [`-V'|`--version'] +- INFILE OUTFILE +- +- `nlmconv' converts the relocatable `i386' object file INFILE into +-the NetWare Loadable Module OUTFILE, optionally reading HEADERFILE for +-NLM header information. For instructions on writing the NLM command +-file language used in header files, see the `linkers' section, +-`NLMLINK' in particular, of the `NLM Development and Tools Overview', +-which is part of the NLM Software Developer's Kit ("NLM SDK"), +-available from Novell, Inc. `nlmconv' uses the GNU Binary File +-Descriptor library to read INFILE; see *Note BFD: (ld.info)BFD, for +-more information. +- +- `nlmconv' can perform a link step. In other words, you can list +-more than one object file for input if you list them in the definitions +-file (rather than simply specifying one input file on the command line). +-In this case, `nlmconv' calls the linker for you. +- +-`-I BFDNAME' +-`--input-target=BFDNAME' +- Object format of the input file. `nlmconv' can usually determine +- the format of a given file (so no default is necessary). *Note +- Target Selection::, for more information. +- +-`-O BFDNAME' +-`--output-target=BFDNAME' +- Object format of the output file. `nlmconv' infers the output +- format based on the input format, e.g. for a `i386' input file the +- output format is `nlm32-i386'. *Note Target Selection::, for more +- information. +- +-`-T HEADERFILE' +-`--header-file=HEADERFILE' +- Reads HEADERFILE for NLM header information. For instructions on +- writing the NLM command file language used in header files, see +- see the `linkers' section, of the `NLM Development and Tools +- Overview', which is part of the NLM Software Developer's Kit, +- available from Novell, Inc. +- +-`-d' +-`--debug' +- Displays (on standard error) the linker command line used by +- `nlmconv'. +- +-`-l LINKER' +-`--linker=LINKER' +- Use LINKER for any linking. LINKER can be an absolute or a +- relative pathname. +- +-`-h' +-`--help' +- Prints a usage summary. +- +-`-V' +-`--version' +- Prints the version number for `nlmconv'. +- +- +-File: binutils.info, Node: windmc, Next: windres, Prev: nlmconv, Up: Top +- +-12 windmc +-********* +- +-`windmc' may be used to generator Windows message resources. +- +- _Warning:_ `windmc' is not always built as part of the binary +- utilities, since it is only useful for Windows targets. +- +- windmc [options] input-file +- +- `windmc' reads message definitions from an input file (.mc) and +-translate them into a set of output files. The output files may be of +-four kinds: +- +-`h' +- A C header file containing the message definitions. +- +-`rc' +- A resource file compilable by the `windres' tool. +- +-`bin' +- One or more binary files containing the resource data for a +- specific message language. +- +-`dbg' +- A C include file that maps message id's to their symbolic name. +- +- The exact description of these different formats is available in +-documentation from Microsoft. +- +- When `windmc' converts from the `mc' format to the `bin' format, +-`rc', `h', and optional `dbg' it is acting like the Windows Message +-Compiler. +- +-`-a' +-`--ascii_in' +- Specifies that the input file specified is ASCII. This is the +- default behaviour. +- +-`-A' +-`--ascii_out' +- Specifies that messages in the output `bin' files should be in +- ASCII format. +- +-`-b' +-`--binprefix' +- Specifies that `bin' filenames should have to be prefixed by the +- basename of the source file. +- +-`-c' +-`--customflag' +- Sets the customer bit in all message id's. +- +-`-C CODEPAGE' +-`--codepage_in CODEPAGE' +- Sets the default codepage to be used to convert input file to +- UTF16. The default is ocdepage 1252. +- +-`-d' +-`--decimal_values' +- Outputs the constants in the header file in decimal. Default is +- using hexadecimal output. +- +-`-e EXT' +-`--extension EXT' +- The extension for the header file. The default is .h extension. +- +-`-F TARGET' +-`--target TARGET' +- Specify the BFD format to use for a bin file as output. This is a +- BFD target name; you can use the `--help' option to see a list of +- supported targets. Normally `windmc' will use the default format, +- which is the first one listed by the `--help' option. *Note +- Target Selection::. +- +-`-h PATH' +-`--headerdir PATH' +- The target directory of the generated header file. The default is +- the current directory. +- +-`-H' +-`--help' +- Displays a list of command line options and then exits. +- +-`-m CHARACTERS' +-`--maxlength CHARACTERS' +- Instructs `windmc' to generate a warning if the length of any +- message exceeds the number specified. +- +-`-n' +-`--nullterminate' +- Terminate message text in `bin' files by zero. By default they are +- terminated by CR/LF. +- +-`-o' +-`--hresult_use' +- Not yet implemented. Instructs `windmc' to generate an OLE2 header +- file, using HRESULT definitions. Status codes are used if the flag +- is not specified. +- +-`-O CODEPAGE' +-`--codepage_out CODEPAGE' +- Sets the default codepage to be used to output text files. The +- default is ocdepage 1252. +- +-`-r PATH' +-`--rcdir PATH' +- The target directory for the generated `rc' script and the +- generated `bin' files that the resource compiler script includes. +- The default is the current directory. +- +-`-u' +-`--unicode_in' +- Specifies that the input file is UTF16. +- +-`-U' +-`--unicode_out' +- Specifies that messages in the output `bin' file should be in UTF16 +- format. This is the default behaviour. +- +-`-v' +- +-`--verbose' +- Enable verbose mode. +- +-`-V' +- +-`--version' +- Prints the version number for `windmc'. +- +-`-x PATH' +-`--xdgb PATH' +- The path of the `dbg' C include file that maps message id's to the +- symbolic name. No such file is generated without specifying the +- switch. +- +- +-File: binutils.info, Node: windres, Next: dlltool, Prev: windmc, Up: Top +- +-13 windres +-********** +- +-`windres' may be used to manipulate Windows resources. +- +- _Warning:_ `windres' is not always built as part of the binary +- utilities, since it is only useful for Windows targets. +- +- windres [options] [input-file] [output-file] +- +- `windres' reads resources from an input file and copies them into an +-output file. Either file may be in one of three formats: +- +-`rc' +- A text format read by the Resource Compiler. +- +-`res' +- A binary format generated by the Resource Compiler. +- +-`coff' +- A COFF object or executable. +- +- The exact description of these different formats is available in +-documentation from Microsoft. +- +- When `windres' converts from the `rc' format to the `res' format, it +-is acting like the Windows Resource Compiler. When `windres' converts +-from the `res' format to the `coff' format, it is acting like the +-Windows `CVTRES' program. +- +- When `windres' generates an `rc' file, the output is similar but not +-identical to the format expected for the input. When an input `rc' +-file refers to an external filename, an output `rc' file will instead +-include the file contents. +- +- If the input or output format is not specified, `windres' will guess +-based on the file name, or, for the input file, the file contents. A +-file with an extension of `.rc' will be treated as an `rc' file, a file +-with an extension of `.res' will be treated as a `res' file, and a file +-with an extension of `.o' or `.exe' will be treated as a `coff' file. +- +- If no output file is specified, `windres' will print the resources +-in `rc' format to standard output. +- +- The normal use is for you to write an `rc' file, use `windres' to +-convert it to a COFF object file, and then link the COFF file into your +-application. This will make the resources described in the `rc' file +-available to Windows. +- +-`-i FILENAME' +-`--input FILENAME' +- The name of the input file. If this option is not used, then +- `windres' will use the first non-option argument as the input file +- name. If there are no non-option arguments, then `windres' will +- read from standard input. `windres' can not read a COFF file from +- standard input. +- +-`-o FILENAME' +-`--output FILENAME' +- The name of the output file. If this option is not used, then +- `windres' will use the first non-option argument, after any used +- for the input file name, as the output file name. If there is no +- non-option argument, then `windres' will write to standard output. +- `windres' can not write a COFF file to standard output. Note, for +- compatibility with `rc' the option `-fo' is also accepted, but its +- use is not recommended. +- +-`-J FORMAT' +-`--input-format FORMAT' +- The input format to read. FORMAT may be `res', `rc', or `coff'. +- If no input format is specified, `windres' will guess, as +- described above. +- +-`-O FORMAT' +-`--output-format FORMAT' +- The output format to generate. FORMAT may be `res', `rc', or +- `coff'. If no output format is specified, `windres' will guess, +- as described above. +- +-`-F TARGET' +-`--target TARGET' +- Specify the BFD format to use for a COFF file as input or output. +- This is a BFD target name; you can use the `--help' option to see +- a list of supported targets. Normally `windres' will use the +- default format, which is the first one listed by the `--help' +- option. *Note Target Selection::. +- +-`--preprocessor PROGRAM' +- When `windres' reads an `rc' file, it runs it through the C +- preprocessor first. This option may be used to specify the +- preprocessor to use, including any leading arguments. The default +- preprocessor argument is `gcc -E -xc-header -DRC_INVOKED'. +- +-`--preprocessor-arg OPTION' +- When `windres' reads an `rc' file, it runs it through the C +- preprocessor first. This option may be used to specify additional +- text to be passed to preprocessor on its command line. This +- option can be used multiple times to add multiple options to the +- preprocessor command line. +- +-`-I DIRECTORY' +-`--include-dir DIRECTORY' +- Specify an include directory to use when reading an `rc' file. +- `windres' will pass this to the preprocessor as an `-I' option. +- `windres' will also search this directory when looking for files +- named in the `rc' file. If the argument passed to this command +- matches any of the supported FORMATS (as described in the `-J' +- option), it will issue a deprecation warning, and behave just like +- the `-J' option. New programs should not use this behaviour. If a +- directory happens to match a FORMAT, simple prefix it with `./' to +- disable the backward compatibility. +- +-`-D TARGET' +-`--define SYM[=VAL]' +- Specify a `-D' option to pass to the preprocessor when reading an +- `rc' file. +- +-`-U TARGET' +-`--undefine SYM' +- Specify a `-U' option to pass to the preprocessor when reading an +- `rc' file. +- +-`-r' +- Ignored for compatibility with rc. +- +-`-v' +- Enable verbose mode. This tells you what the preprocessor is if +- you didn't specify one. +- +-`-c VAL' +- +-`--codepage VAL' +- Specify the default codepage to use when reading an `rc' file. +- VAL should be a hexadecimal prefixed by `0x' or decimal codepage +- code. The valid range is from zero up to 0xffff, but the validity +- of the codepage is host and configuration dependent. +- +-`-l VAL' +- +-`--language VAL' +- Specify the default language to use when reading an `rc' file. +- VAL should be a hexadecimal language code. The low eight bits are +- the language, and the high eight bits are the sublanguage. +- +-`--use-temp-file' +- Use a temporary file to instead of using popen to read the output +- of the preprocessor. Use this option if the popen implementation +- is buggy on the host (eg., certain non-English language versions +- of Windows 95 and Windows 98 are known to have buggy popen where +- the output will instead go the console). +- +-`--no-use-temp-file' +- Use popen, not a temporary file, to read the output of the +- preprocessor. This is the default behaviour. +- +-`-h' +- +-`--help' +- Prints a usage summary. +- +-`-V' +- +-`--version' +- Prints the version number for `windres'. +- +-`--yydebug' +- If `windres' is compiled with `YYDEBUG' defined as `1', this will +- turn on parser debugging. +- +- +-File: binutils.info, Node: dlltool, Next: readelf, Prev: windres, Up: Top +- +-14 dlltool +-********** +- +-`dlltool' is used to create the files needed to create dynamic link +-libraries (DLLs) on systems which understand PE format image files such +-as Windows. A DLL contains an export table which contains information +-that the runtime loader needs to resolve references from a referencing +-program. +- +- The export table is generated by this program by reading in a `.def' +-file or scanning the `.a' and `.o' files which will be in the DLL. A +-`.o' file can contain information in special `.drectve' sections with +-export information. +- +- _Note:_ `dlltool' is not always built as part of the binary +- utilities, since it is only useful for those targets which support +- DLLs. +- +- dlltool [`-d'|`--input-def' DEF-FILE-NAME] +- [`-b'|`--base-file' BASE-FILE-NAME] +- [`-e'|`--output-exp' EXPORTS-FILE-NAME] +- [`-z'|`--output-def' DEF-FILE-NAME] +- [`-l'|`--output-lib' LIBRARY-FILE-NAME] +- [`-y'|`--output-delaylib' LIBRARY-FILE-NAME] +- [`--export-all-symbols'] [`--no-export-all-symbols'] +- [`--exclude-symbols' LIST] +- [`--no-default-excludes'] +- [`-S'|`--as' PATH-TO-ASSEMBLER] [`-f'|`--as-flags' OPTIONS] +- [`-D'|`--dllname' NAME] [`-m'|`--machine' MACHINE] +- [`-a'|`--add-indirect'] +- [`-U'|`--add-underscore'] [`--add-stdcall-underscore'] +- [`-k'|`--kill-at'] [`-A'|`--add-stdcall-alias'] +- [`-p'|`--ext-prefix-alias' PREFIX] +- [`-x'|`--no-idata4'] [`-c'|`--no-idata5'] +- [`--use-nul-prefixed-import-tables'] +- [`-I'|`--identify' LIBRARY-FILE-NAME] [`--identify-strict'] +- [`-i'|`--interwork'] +- [`-n'|`--nodelete'] [`-t'|`--temp-prefix' PREFIX] +- [`-v'|`--verbose'] +- [`-h'|`--help'] [`-V'|`--version'] +- [`--no-leading-underscore'] [`--leading-underscore'] +- [object-file ...] +- +- `dlltool' reads its inputs, which can come from the `-d' and `-b' +-options as well as object files specified on the command line. It then +-processes these inputs and if the `-e' option has been specified it +-creates a exports file. If the `-l' option has been specified it +-creates a library file and if the `-z' option has been specified it +-creates a def file. Any or all of the `-e', `-l' and `-z' options can +-be present in one invocation of dlltool. +- +- When creating a DLL, along with the source for the DLL, it is +-necessary to have three other files. `dlltool' can help with the +-creation of these files. +- +- The first file is a `.def' file which specifies which functions are +-exported from the DLL, which functions the DLL imports, and so on. This +-is a text file and can be created by hand, or `dlltool' can be used to +-create it using the `-z' option. In this case `dlltool' will scan the +-object files specified on its command line looking for those functions +-which have been specially marked as being exported and put entries for +-them in the `.def' file it creates. +- +- In order to mark a function as being exported from a DLL, it needs to +-have an `-export:' entry in the `.drectve' section of +-the object file. This can be done in C by using the asm() operator: +- +- asm (".section .drectve"); +- asm (".ascii \"-export:my_func\""); +- +- int my_func (void) { ... } +- +- The second file needed for DLL creation is an exports file. This +-file is linked with the object files that make up the body of the DLL +-and it handles the interface between the DLL and the outside world. +-This is a binary file and it can be created by giving the `-e' option to +-`dlltool' when it is creating or reading in a `.def' file. +- +- The third file needed for DLL creation is the library file that +-programs will link with in order to access the functions in the DLL (an +-`import library'). This file can be created by giving the `-l' option +-to dlltool when it is creating or reading in a `.def' file. +- +- If the `-y' option is specified, dlltool generates a delay-import +-library that can be used instead of the normal import library to allow +-a program to link to the dll only as soon as an imported function is +-called for the first time. The resulting executable will need to be +-linked to the static delayimp library containing __delayLoadHelper2(), +-which in turn will import LoadLibraryA and GetProcAddress from kernel32. +- +- `dlltool' builds the library file by hand, but it builds the exports +-file by creating temporary files containing assembler statements and +-then assembling these. The `-S' command line option can be used to +-specify the path to the assembler that dlltool will use, and the `-f' +-option can be used to pass specific flags to that assembler. The `-n' +-can be used to prevent dlltool from deleting these temporary assembler +-files when it is done, and if `-n' is specified twice then this will +-prevent dlltool from deleting the temporary object files it used to +-build the library. +- +- Here is an example of creating a DLL from a source file `dll.c' and +-also creating a program (from an object file called `program.o') that +-uses that DLL: +- +- gcc -c dll.c +- dlltool -e exports.o -l dll.lib dll.o +- gcc dll.o exports.o -o dll.dll +- gcc program.o dll.lib -o program +- +- `dlltool' may also be used to query an existing import library to +-determine the name of the DLL to which it is associated. See the +-description of the `-I' or `--identify' option. +- +- The command line options have the following meanings: +- +-`-d FILENAME' +-`--input-def FILENAME' +- Specifies the name of a `.def' file to be read in and processed. +- +-`-b FILENAME' +-`--base-file FILENAME' +- Specifies the name of a base file to be read in and processed. The +- contents of this file will be added to the relocation section in +- the exports file generated by dlltool. +- +-`-e FILENAME' +-`--output-exp FILENAME' +- Specifies the name of the export file to be created by dlltool. +- +-`-z FILENAME' +-`--output-def FILENAME' +- Specifies the name of the `.def' file to be created by dlltool. +- +-`-l FILENAME' +-`--output-lib FILENAME' +- Specifies the name of the library file to be created by dlltool. +- +-`-y FILENAME' +-`--output-delaylib FILENAME' +- Specifies the name of the delay-import library file to be created +- by dlltool. +- +-`--export-all-symbols' +- Treat all global and weak defined symbols found in the input object +- files as symbols to be exported. There is a small list of symbols +- which are not exported by default; see the `--no-default-excludes' +- option. You may add to the list of symbols to not export by using +- the `--exclude-symbols' option. +- +-`--no-export-all-symbols' +- Only export symbols explicitly listed in an input `.def' file or in +- `.drectve' sections in the input object files. This is the default +- behaviour. The `.drectve' sections are created by `dllexport' +- attributes in the source code. +- +-`--exclude-symbols LIST' +- Do not export the symbols in LIST. This is a list of symbol names +- separated by comma or colon characters. The symbol names should +- not contain a leading underscore. This is only meaningful when +- `--export-all-symbols' is used. +- +-`--no-default-excludes' +- When `--export-all-symbols' is used, it will by default avoid +- exporting certain special symbols. The current list of symbols to +- avoid exporting is `DllMain@12', `DllEntryPoint@0', `impure_ptr'. +- You may use the `--no-default-excludes' option to go ahead and +- export these special symbols. This is only meaningful when +- `--export-all-symbols' is used. +- +-`-S PATH' +-`--as PATH' +- Specifies the path, including the filename, of the assembler to be +- used to create the exports file. +- +-`-f OPTIONS' +-`--as-flags OPTIONS' +- Specifies any specific command line options to be passed to the +- assembler when building the exports file. This option will work +- even if the `-S' option is not used. This option only takes one +- argument, and if it occurs more than once on the command line, +- then later occurrences will override earlier occurrences. So if +- it is necessary to pass multiple options to the assembler they +- should be enclosed in double quotes. +- +-`-D NAME' +-`--dll-name NAME' +- Specifies the name to be stored in the `.def' file as the name of +- the DLL when the `-e' option is used. If this option is not +- present, then the filename given to the `-e' option will be used +- as the name of the DLL. +- +-`-m MACHINE' +-`-machine MACHINE' +- Specifies the type of machine for which the library file should be +- built. `dlltool' has a built in default type, depending upon how +- it was created, but this option can be used to override that. +- This is normally only useful when creating DLLs for an ARM +- processor, when the contents of the DLL are actually encode using +- Thumb instructions. +- +-`-a' +-`--add-indirect' +- Specifies that when `dlltool' is creating the exports file it +- should add a section which allows the exported functions to be +- referenced without using the import library. Whatever the hell +- that means! +- +-`-U' +-`--add-underscore' +- Specifies that when `dlltool' is creating the exports file it +- should prepend an underscore to the names of _all_ exported +- symbols. +- +-`--no-leading-underscore' +- +-`--leading-underscore' +- Specifies whether standard symbol should be forced to be prefixed, +- or not. +- +-`--add-stdcall-underscore' +- Specifies that when `dlltool' is creating the exports file it +- should prepend an underscore to the names of exported _stdcall_ +- functions. Variable names and non-stdcall function names are not +- modified. This option is useful when creating GNU-compatible +- import libs for third party DLLs that were built with MS-Windows +- tools. +- +-`-k' +-`--kill-at' +- Specifies that when `dlltool' is creating the exports file it +- should not append the string `@ '. These numbers are +- called ordinal numbers and they represent another way of accessing +- the function in a DLL, other than by name. +- +-`-A' +-`--add-stdcall-alias' +- Specifies that when `dlltool' is creating the exports file it +- should add aliases for stdcall symbols without `@ ' in +- addition to the symbols with `@ '. +- +-`-p' +-`--ext-prefix-alias PREFIX' +- Causes `dlltool' to create external aliases for all DLL imports +- with the specified prefix. The aliases are created for both +- external and import symbols with no leading underscore. +- +-`-x' +-`--no-idata4' +- Specifies that when `dlltool' is creating the exports and library +- files it should omit the `.idata4' section. This is for +- compatibility with certain operating systems. +- +-`--use-nul-prefixed-import-tables' +- Specifies that when `dlltool' is creating the exports and library +- files it should prefix the `.idata4' and `.idata5' by zero an +- element. This emulates old gnu import library generation of +- `dlltool'. By default this option is turned off. +- +-`-c' +-`--no-idata5' +- Specifies that when `dlltool' is creating the exports and library +- files it should omit the `.idata5' section. This is for +- compatibility with certain operating systems. +- +-`-I FILENAME' +-`--identify FILENAME' +- Specifies that `dlltool' should inspect the import library +- indicated by FILENAME and report, on `stdout', the name(s) of the +- associated DLL(s). This can be performed in addition to any other +- operations indicated by the other options and arguments. +- `dlltool' fails if the import library does not exist or is not +- actually an import library. See also `--identify-strict'. +- +-`--identify-strict' +- Modifies the behavior of the `--identify' option, such that an +- error is reported if FILENAME is associated with more than one DLL. +- +-`-i' +-`--interwork' +- Specifies that `dlltool' should mark the objects in the library +- file and exports file that it produces as supporting interworking +- between ARM and Thumb code. +- +-`-n' +-`--nodelete' +- Makes `dlltool' preserve the temporary assembler files it used to +- create the exports file. If this option is repeated then dlltool +- will also preserve the temporary object files it uses to create +- the library file. +- +-`-t PREFIX' +-`--temp-prefix PREFIX' +- Makes `dlltool' use PREFIX when constructing the names of +- temporary assembler and object files. By default, the temp file +- prefix is generated from the pid. +- +-`-v' +-`--verbose' +- Make dlltool describe what it is doing. +- +-`-h' +-`--help' +- Displays a list of command line options and then exits. +- +-`-V' +-`--version' +- Displays dlltool's version number and then exits. +- +- +-* Menu: +- +-* def file format:: The format of the dlltool `.def' file +- +- +-File: binutils.info, Node: def file format, Up: dlltool +- +-14.1 The format of the `dlltool' `.def' file +-============================================ +- +-A `.def' file contains any number of the following commands: +- +-`NAME' NAME `[ ,' BASE `]' +- The result is going to be named NAME`.exe'. +- +-`LIBRARY' NAME `[ ,' BASE `]' +- The result is going to be named NAME`.dll'. Note: If you want to +- use LIBRARY as name then you need to quote. Otherwise this will +- fail due a necessary hack for libtool (see PR binutils/13710 for +- more details). +- +-`EXPORTS ( ( (' NAME1 `[ = ' NAME2 `] ) | ( ' NAME1 `=' MODULE-NAME `.' EXTERNAL-NAME `) ) [ == ' ITS_NAME `]' +- +-`[' INTEGER `] [ NONAME ] [ CONSTANT ] [ DATA ] [ PRIVATE ] ) *' +- Declares NAME1 as an exported symbol from the DLL, with optional +- ordinal number INTEGER, or declares NAME1 as an alias (forward) of +- the function EXTERNAL-NAME in the DLL. If ITS_NAME is specified, +- this name is used as string in export table. MODULE-NAME. Note: +- The `EXPORTS' has to be the last command in .def file, as keywords +- are treated - beside `LIBRARY' - as simple name-identifiers. If +- you want to use LIBRARY as name then you need to quote it. +- +-`IMPORTS ( (' INTERNAL-NAME `=' MODULE-NAME `.' INTEGER `) | [' INTERNAL-NAME `= ]' MODULE-NAME `.' EXTERNAL-NAME `) [ == ) ITS_NAME `]' *' +- Declares that EXTERNAL-NAME or the exported function whose ordinal +- number is INTEGER is to be imported from the file MODULE-NAME. If +- INTERNAL-NAME is specified then this is the name that the imported +- function will be referred to in the body of the DLL. If ITS_NAME +- is specified, this name is used as string in import table. Note: +- The `IMPORTS' has to be the last command in .def file, as keywords +- are treated - beside `LIBRARY' - as simple name-identifiers. If +- you want to use LIBRARY as name then you need to quote it. +- +-`DESCRIPTION' STRING +- Puts STRING into the output `.exp' file in the `.rdata' section. +- +-`STACKSIZE' NUMBER-RESERVE `[, ' NUMBER-COMMIT `]' +- +-`HEAPSIZE' NUMBER-RESERVE `[, ' NUMBER-COMMIT `]' +- Generates `--stack' or `--heap' NUMBER-RESERVE,NUMBER-COMMIT in +- the output `.drectve' section. The linker will see this and act +- upon it. +- +-`CODE' ATTR `+' +- +-`DATA' ATTR `+' +- +-`SECTIONS (' SECTION-NAME ATTR` + ) *' +- Generates `--attr' SECTION-NAME ATTR in the output `.drectve' +- section, where ATTR is one of `READ', `WRITE', `EXECUTE' or +- `SHARED'. The linker will see this and act upon it. +- +- +- +-File: binutils.info, Node: readelf, Next: elfedit, Prev: dlltool, Up: Top +- +-15 readelf +-********** +- +- readelf [`-a'|`--all'] +- [`-h'|`--file-header'] +- [`-l'|`--program-headers'|`--segments'] +- [`-S'|`--section-headers'|`--sections'] +- [`-g'|`--section-groups'] +- [`-t'|`--section-details'] +- [`-e'|`--headers'] +- [`-s'|`--syms'|`--symbols'] +- [`--dyn-syms'] +- [`-n'|`--notes'] +- [`-r'|`--relocs'] +- [`-u'|`--unwind'] +- [`-d'|`--dynamic'] +- [`-V'|`--version-info'] +- [`-A'|`--arch-specific'] +- [`-D'|`--use-dynamic'] +- [`-x' |`--hex-dump='] +- [`-p' |`--string-dump='] +- [`-R' |`--relocated-dump='] +- [`-c'|`--archive-index'] +- [`-w[lLiaprmfFsoRt]'| +- `--debug-dump'[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] +- [`--dwarf-depth=N'] +- [`--dwarf-start=N'] +- [`-I'|`--histogram'] +- [`-v'|`--version'] +- [`-W'|`--wide'] +- [`-H'|`--help'] +- ELFFILE... +- +- `readelf' displays information about one or more ELF format object +-files. The options control what particular information to display. +- +- ELFFILE... are the object files to be examined. 32-bit and 64-bit +-ELF files are supported, as are archives containing ELF files. +- +- This program performs a similar function to `objdump' but it goes +-into more detail and it exists independently of the BFD library, so if +-there is a bug in BFD then readelf will not be affected. +- +- The long and short forms of options, shown here as alternatives, are +-equivalent. At least one option besides `-v' or `-H' must be given. +- +-`-a' +-`--all' +- Equivalent to specifying `--file-header', `--program-headers', +- `--sections', `--symbols', `--relocs', `--dynamic', `--notes' and +- `--version-info'. +- +-`-h' +-`--file-header' +- Displays the information contained in the ELF header at the start +- of the file. +- +-`-l' +-`--program-headers' +-`--segments' +- Displays the information contained in the file's segment headers, +- if it has any. +- +-`-S' +-`--sections' +-`--section-headers' +- Displays the information contained in the file's section headers, +- if it has any. +- +-`-g' +-`--section-groups' +- Displays the information contained in the file's section groups, +- if it has any. +- +-`-t' +-`--section-details' +- Displays the detailed section information. Implies `-S'. +- +-`-s' +-`--symbols' +-`--syms' +- Displays the entries in symbol table section of the file, if it +- has one. +- +-`--dyn-syms' +- Displays the entries in dynamic symbol table section of the file, +- if it has one. +- +-`-e' +-`--headers' +- Display all the headers in the file. Equivalent to `-h -l -S'. +- +-`-n' +-`--notes' +- Displays the contents of the NOTE segments and/or sections, if any. +- +-`-r' +-`--relocs' +- Displays the contents of the file's relocation section, if it has +- one. +- +-`-u' +-`--unwind' +- Displays the contents of the file's unwind section, if it has one. +- Only the unwind sections for IA64 ELF files, as well as ARM +- unwind tables (`.ARM.exidx' / `.ARM.extab') are currently +- supported. +- +-`-d' +-`--dynamic' +- Displays the contents of the file's dynamic section, if it has one. +- +-`-V' +-`--version-info' +- Displays the contents of the version sections in the file, it they +- exist. +- +-`-A' +-`--arch-specific' +- Displays architecture-specific information in the file, if there +- is any. +- +-`-D' +-`--use-dynamic' +- When displaying symbols, this option makes `readelf' use the +- symbol hash tables in the file's dynamic section, rather than the +- symbol table sections. +- +-`-x ' +-`--hex-dump=' +- Displays the contents of the indicated section as a hexadecimal +- bytes. A number identifies a particular section by index in the +- section table; any other string identifies all sections with that +- name in the object file. +- +-`-R ' +-`--relocated-dump=' +- Displays the contents of the indicated section as a hexadecimal +- bytes. A number identifies a particular section by index in the +- section table; any other string identifies all sections with that +- name in the object file. The contents of the section will be +- relocated before they are displayed. +- +-`-p ' +-`--string-dump=' +- Displays the contents of the indicated section as printable +- strings. A number identifies a particular section by index in the +- section table; any other string identifies all sections with that +- name in the object file. +- +-`-c' +-`--archive-index' +- Displays the file symbol index information contained in the header +- part of binary archives. Performs the same function as the `t' +- command to `ar', but without using the BFD library. *Note ar::. +- +-`-w[lLiaprmfFsoRt]' +-`--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]' +- Displays the contents of the debug sections in the file, if any are +- present. If one of the optional letters or words follows the +- switch then only data found in those specific sections will be +- dumped. +- +- Note that there is no single letter option to display the content +- of trace sections or .gdb_index. +- +- Note: the `=decodedline' option will display the interpreted +- contents of a .debug_line section whereas the `=rawline' option +- dumps the contents in a raw format. +- +- Note: the `=frames-interp' option will display the interpreted +- contents of a .debug_frame section whereas the `=frames' option +- dumps the contents in a raw format. +- +- Note: the output from the `=info' option can also be affected by +- the options `--dwarf-depth' and `--dwarf-start'. +- +-`--dwarf-depth=N' +- Limit the dump of the `.debug_info' section to N children. This +- is only useful with `--debug-dump=info'. The default is to print +- all DIEs; the special value 0 for N will also have this effect. +- +- With a non-zero value for N, DIEs at or deeper than N levels will +- not be printed. The range for N is zero-based. +- +-`--dwarf-start=N' +- Print only DIEs beginning with the DIE numbered N. This is only +- useful with `--debug-dump=info'. +- +- If specified, this option will suppress printing of any header +- information and all DIEs before the DIE numbered N. Only siblings +- and children of the specified DIE will be printed. +- +- This can be used in conjunction with `--dwarf-depth'. +- +-`-I' +-`--histogram' +- Display a histogram of bucket list lengths when displaying the +- contents of the symbol tables. +- +-`-v' +-`--version' +- Display the version number of readelf. +- +-`-W' +-`--wide' +- Don't break output lines to fit into 80 columns. By default +- `readelf' breaks section header and segment listing lines for +- 64-bit ELF files, so that they fit into 80 columns. This option +- causes `readelf' to print each section header resp. each segment +- one a single line, which is far more readable on terminals wider +- than 80 columns. +- +-`-H' +-`--help' +- Display the command line options understood by `readelf'. +- +- +- +-File: binutils.info, Node: elfedit, Next: Common Options, Prev: readelf, Up: Top +- +-16 elfedit +-********** +- +- elfedit [`--input-mach='MACHINE] +- [`--input-type='TYPE] +- [`--input-osabi='OSABI] +- `--output-mach='MACHINE +- `--output-type='TYPE +- `--output-osabi='OSABI +- [`-v'|`--version'] +- [`-h'|`--help'] +- ELFFILE... +- +- `elfedit' updates the ELF header of ELF files which have the +-matching ELF machine and file types. The options control how and which +-fields in the ELF header should be updated. +- +- ELFFILE... are the ELF files to be updated. 32-bit and 64-bit ELF +-files are supported, as are archives containing ELF files. +- +- The long and short forms of options, shown here as alternatives, are +-equivalent. At least one of the `--output-mach', `--output-type' and +-`--output-osabi' options must be given. +- +-`--input-mach=MACHINE' +- Set the matching input ELF machine type to MACHINE. If +- `--input-mach' isn't specified, it will match any ELF machine +- types. +- +- The supported ELF machine types are, L1OM, K1OM and X86-64. +- +-`--output-mach=MACHINE' +- Change the ELF machine type in the ELF header to MACHINE. The +- supported ELF machine types are the same as `--input-mach'. +- +-`--input-type=TYPE' +- Set the matching input ELF file type to TYPE. If `--input-type' +- isn't specified, it will match any ELF file types. +- +- The supported ELF file types are, REL, EXEC and DYN. +- +-`--output-type=TYPE' +- Change the ELF file type in the ELF header to TYPE. The supported +- ELF types are the same as `--input-type'. +- +-`--input-osabi=OSABI' +- Set the matching input ELF file OSABI to OSABI. If +- `--input-osabi' isn't specified, it will match any ELF OSABIs. +- +- The supported ELF OSABIs are, NONE, HPUX, NETBSD, GNU, LINUX +- (alias for GNU), SOLARIS, AIX, IRIX, FREEBSD, TRU64, MODESTO, +- OPENBSD, OPENVMS, NSK, AROS and FENIXOS. +- +-`--output-osabi=OSABI' +- Change the ELF OSABI in the ELF header to OSABI. The supported +- ELF OSABI are the same as `--input-osabi'. +- +-`-v' +-`--version' +- Display the version number of `elfedit'. +- +-`-h' +-`--help' +- Display the command line options understood by `elfedit'. +- +- +- +-File: binutils.info, Node: Common Options, Next: Selecting the Target System, Prev: elfedit, Up: Top +- +-17 Common Options +-***************** +- +-The following command-line options are supported by all of the programs +-described in this manual. +- +-`@FILE' +- Read command-line options from FILE. The options read are +- inserted in place of the original @FILE option. If FILE does not +- exist, or cannot be read, then the option will be treated +- literally, and not removed. +- +- Options in FILE are separated by whitespace. A whitespace +- character may be included in an option by surrounding the entire +- option in either single or double quotes. Any character +- (including a backslash) may be included by prefixing the character +- to be included with a backslash. The FILE may itself contain +- additional @FILE options; any such options will be processed +- recursively. +- +-`--help' +- Display the command-line options supported by the program. +- +-`--version' +- Display the version number of the program. +- +- +- +-File: binutils.info, Node: Selecting the Target System, Next: Reporting Bugs, Prev: Common Options, Up: Top +- +-18 Selecting the Target System +-****************************** +- +-You can specify two aspects of the target system to the GNU binary file +-utilities, each in several ways: +- +- * the target +- +- * the architecture +- +- In the following summaries, the lists of ways to specify values are +-in order of decreasing precedence. The ways listed first override those +-listed later. +- +- The commands to list valid values only list the values for which the +-programs you are running were configured. If they were configured with +-`--enable-targets=all', the commands list most of the available values, +-but a few are left out; not all targets can be configured in at once +-because some of them can only be configured "native" (on hosts with the +-same type as the target system). +- +-* Menu: +- +-* Target Selection:: +-* Architecture Selection:: +- +- +-File: binutils.info, Node: Target Selection, Next: Architecture Selection, Up: Selecting the Target System +- +-18.1 Target Selection +-===================== +- +-A "target" is an object file format. A given target may be supported +-for multiple architectures (*note Architecture Selection::). A target +-selection may also have variations for different operating systems or +-architectures. +- +- The command to list valid target values is `objdump -i' (the first +-column of output contains the relevant information). +- +- Some sample values are: `a.out-hp300bsd', `ecoff-littlemips', +-`a.out-sunos-big'. +- +- You can also specify a target using a configuration triplet. This is +-the same sort of name that is passed to `configure' to specify a +-target. When you use a configuration triplet as an argument, it must be +-fully canonicalized. You can see the canonical version of a triplet by +-running the shell script `config.sub' which is included with the +-sources. +- +- Some sample configuration triplets are: `m68k-hp-bsd', +-`mips-dec-ultrix', `sparc-sun-sunos'. +- +-`objdump' Target +----------------- +- +-Ways to specify: +- +- 1. command line option: `-b' or `--target' +- +- 2. environment variable `GNUTARGET' +- +- 3. deduced from the input file +- +-`objcopy' and `strip' Input Target +----------------------------------- +- +-Ways to specify: +- +- 1. command line options: `-I' or `--input-target', or `-F' or +- `--target' +- +- 2. environment variable `GNUTARGET' +- +- 3. deduced from the input file +- +-`objcopy' and `strip' Output Target +------------------------------------ +- +-Ways to specify: +- +- 1. command line options: `-O' or `--output-target', or `-F' or +- `--target' +- +- 2. the input target (see "`objcopy' and `strip' Input Target" above) +- +- 3. environment variable `GNUTARGET' +- +- 4. deduced from the input file +- +-`nm', `size', and `strings' Target +----------------------------------- +- +-Ways to specify: +- +- 1. command line option: `--target' +- +- 2. environment variable `GNUTARGET' +- +- 3. deduced from the input file +- +- +-File: binutils.info, Node: Architecture Selection, Prev: Target Selection, Up: Selecting the Target System +- +-18.2 Architecture Selection +-=========================== +- +-An "architecture" is a type of CPU on which an object file is to run. +-Its name may contain a colon, separating the name of the processor +-family from the name of the particular CPU. +- +- The command to list valid architecture values is `objdump -i' (the +-second column contains the relevant information). +- +- Sample values: `m68k:68020', `mips:3000', `sparc'. +- +-`objdump' Architecture +----------------------- +- +-Ways to specify: +- +- 1. command line option: `-m' or `--architecture' +- +- 2. deduced from the input file +- +-`objcopy', `nm', `size', `strings' Architecture +------------------------------------------------ +- +-Ways to specify: +- +- 1. deduced from the input file +- +- +-File: binutils.info, Node: Reporting Bugs, Next: GNU Free Documentation License, Prev: Selecting the Target System, Up: Top +- +-19 Reporting Bugs +-***************** +- +-Your bug reports play an essential role in making the binary utilities +-reliable. +- +- Reporting a bug may help you by bringing a solution to your problem, +-or it may not. But in any case the principal function of a bug report +-is to help the entire community by making the next version of the binary +-utilities work better. Bug reports are your contribution to their +-maintenance. +- +- In order for a bug report to serve its purpose, you must include the +-information that enables us to fix the bug. +- +-* Menu: +- +-* Bug Criteria:: Have you found a bug? +-* Bug Reporting:: How to report bugs +- +- +-File: binutils.info, Node: Bug Criteria, Next: Bug Reporting, Up: Reporting Bugs +- +-19.1 Have You Found a Bug? +-========================== +- +-If you are not sure whether you have found a bug, here are some +-guidelines: +- +- * If a binary utility gets a fatal signal, for any input whatever, +- that is a bug. Reliable utilities never crash. +- +- * If a binary utility produces an error message for valid input, +- that is a bug. +- +- * If you are an experienced user of binary utilities, your +- suggestions for improvement are welcome in any case. +- +- +-File: binutils.info, Node: Bug Reporting, Prev: Bug Criteria, Up: Reporting Bugs +- +-19.2 How to Report Bugs +-======================= +- +-A number of companies and individuals offer support for GNU products. +-If you obtained the binary utilities from a support organization, we +-recommend you contact that organization first. +- +- You can find contact information for many support companies and +-individuals in the file `etc/SERVICE' in the GNU Emacs distribution. +- +- In any event, we also recommend that you send bug reports for the +-binary utilities to `http://www.sourceware.org/bugzilla/'. +- +- The fundamental principle of reporting bugs usefully is this: +-*report all the facts*. If you are not sure whether to state a fact or +-leave it out, state it! +- +- Often people omit facts because they think they know what causes the +-problem and assume that some details do not matter. Thus, you might +-assume that the name of a file you use in an example does not matter. +-Well, probably it does not, but one cannot be sure. Perhaps the bug is +-a stray memory reference which happens to fetch from the location where +-that pathname is stored in memory; perhaps, if the pathname were +-different, the contents of that location would fool the utility into +-doing the right thing despite the bug. Play it safe and give a +-specific, complete example. That is the easiest thing for you to do, +-and the most helpful. +- +- Keep in mind that the purpose of a bug report is to enable us to fix +-the bug if it is new to us. Therefore, always write your bug reports +-on the assumption that the bug has not been reported previously. +- +- Sometimes people give a few sketchy facts and ask, "Does this ring a +-bell?" This cannot help us fix a bug, so it is basically useless. We +-respond by asking for enough details to enable us to investigate. You +-might as well expedite matters by sending them to begin with. +- +- To enable us to fix the bug, you should include all these things: +- +- * The version of the utility. Each utility announces it if you +- start it with the `--version' argument. +- +- Without this, we will not know whether there is any point in +- looking for the bug in the current version of the binary utilities. +- +- * Any patches you may have applied to the source, including any +- patches made to the `BFD' library. +- +- * The type of machine you are using, and the operating system name +- and version number. +- +- * What compiler (and its version) was used to compile the +- utilities--e.g. "`gcc-2.7'". +- +- * The command arguments you gave the utility to observe the bug. To +- guarantee you will not omit something important, list them all. A +- copy of the Makefile (or the output from make) is sufficient. +- +- If we were to try to guess the arguments, we would probably guess +- wrong and then we might not encounter the bug. +- +- * A complete input file, or set of input files, that will reproduce +- the bug. If the utility is reading an object file or files, then +- it is generally most helpful to send the actual object files. +- +- If the source files were produced exclusively using GNU programs +- (e.g., `gcc', `gas', and/or the GNU `ld'), then it may be OK to +- send the source files rather than the object files. In this case, +- be sure to say exactly what version of `gcc', or whatever, was +- used to produce the object files. Also say how `gcc', or +- whatever, was configured. +- +- * A description of what behavior you observe that you believe is +- incorrect. For example, "It gets a fatal signal." +- +- Of course, if the bug is that the utility gets a fatal signal, +- then we will certainly notice it. But if the bug is incorrect +- output, we might not notice unless it is glaringly wrong. You +- might as well not give us a chance to make a mistake. +- +- Even if the problem you experience is a fatal signal, you should +- still say so explicitly. Suppose something strange is going on, +- such as your copy of the utility is out of sync, or you have +- encountered a bug in the C library on your system. (This has +- happened!) Your copy might crash and ours would not. If you told +- us to expect a crash, then when ours fails to crash, we would know +- that the bug was not happening for us. If you had not told us to +- expect a crash, then we would not be able to draw any conclusion +- from our observations. +- +- * If you wish to suggest changes to the source, send us context +- diffs, as generated by `diff' with the `-u', `-c', or `-p' option. +- Always send diffs from the old file to the new file. If you wish +- to discuss something in the `ld' source, refer to it by context, +- not by line number. +- +- The line numbers in our development sources will not match those +- in your sources. Your line numbers would convey no useful +- information to us. +- +- Here are some things that are not necessary: +- +- * A description of the envelope of the bug. +- +- Often people who encounter a bug spend a lot of time investigating +- which changes to the input file will make the bug go away and which +- changes will not affect it. +- +- This is often time consuming and not very useful, because the way +- we will find the bug is by running a single example under the +- debugger with breakpoints, not by pure deduction from a series of +- examples. We recommend that you save your time for something else. +- +- Of course, if you can find a simpler example to report _instead_ +- of the original one, that is a convenience for us. Errors in the +- output will be easier to spot, running under the debugger will take +- less time, and so on. +- +- However, simplification is not vital; if you do not want to do +- this, report the bug anyway and send us the entire test case you +- used. +- +- * A patch for the bug. +- +- A patch for the bug does help us if it is a good one. But do not +- omit the necessary information, such as the test case, on the +- assumption that a patch is all we need. We might see problems +- with your patch and decide to fix the problem another way, or we +- might not understand it at all. +- +- Sometimes with programs as complicated as the binary utilities it +- is very hard to construct an example that will make the program +- follow a certain path through the code. If you do not send us the +- example, we will not be able to construct one, so we will not be +- able to verify that the bug is fixed. +- +- And if we cannot understand what bug you are trying to fix, or why +- your patch should be an improvement, we will not install it. A +- test case will help us to understand. +- +- * A guess about what the bug is or what it depends on. +- +- Such guesses are usually wrong. Even we cannot guess right about +- such things without first using the debugger to find the facts. +- +- +-File: binutils.info, Node: GNU Free Documentation License, Next: Binutils Index, Prev: Reporting Bugs, Up: Top +- +-Appendix A GNU Free Documentation License +-***************************************** +- +- Version 1.3, 3 November 2008 +- +- Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +- `http://fsf.org/' +- +- Everyone is permitted to copy and distribute verbatim copies +- of this license document, but changing it is not allowed. +- +- 0. PREAMBLE +- +- The purpose of this License is to make a manual, textbook, or other +- functional and useful document "free" in the sense of freedom: to +- assure everyone the effective freedom to copy and redistribute it, +- with or without modifying it, either commercially or +- noncommercially. Secondarily, this License preserves for the +- author and publisher a way to get credit for their work, while not +- being considered responsible for modifications made by others. +- +- This License is a kind of "copyleft", which means that derivative +- works of the document must themselves be free in the same sense. +- It complements the GNU General Public License, which is a copyleft +- license designed for free software. +- +- We have designed this License in order to use it for manuals for +- free software, because free software needs free documentation: a +- free program should come with manuals providing the same freedoms +- that the software does. But this License is not limited to +- software manuals; it can be used for any textual work, regardless +- of subject matter or whether it is published as a printed book. +- We recommend this License principally for works whose purpose is +- instruction or reference. +- +- 1. APPLICABILITY AND DEFINITIONS +- +- This License applies to any manual or other work, in any medium, +- that contains a notice placed by the copyright holder saying it +- can be distributed under the terms of this License. Such a notice +- grants a world-wide, royalty-free license, unlimited in duration, +- to use that work under the conditions stated herein. The +- "Document", below, refers to any such manual or work. Any member +- of the public is a licensee, and is addressed as "you". You +- accept the license if you copy, modify or distribute the work in a +- way requiring permission under copyright law. +- +- A "Modified Version" of the Document means any work containing the +- Document or a portion of it, either copied verbatim, or with +- modifications and/or translated into another language. +- +- A "Secondary Section" is a named appendix or a front-matter section +- of the Document that deals exclusively with the relationship of the +- publishers or authors of the Document to the Document's overall +- subject (or to related matters) and contains nothing that could +- fall directly within that overall subject. (Thus, if the Document +- is in part a textbook of mathematics, a Secondary Section may not +- explain any mathematics.) The relationship could be a matter of +- historical connection with the subject or with related matters, or +- of legal, commercial, philosophical, ethical or political position +- regarding them. +- +- The "Invariant Sections" are certain Secondary Sections whose +- titles are designated, as being those of Invariant Sections, in +- the notice that says that the Document is released under this +- License. If a section does not fit the above definition of +- Secondary then it is not allowed to be designated as Invariant. +- The Document may contain zero Invariant Sections. If the Document +- does not identify any Invariant Sections then there are none. +- +- The "Cover Texts" are certain short passages of text that are +- listed, as Front-Cover Texts or Back-Cover Texts, in the notice +- that says that the Document is released under this License. A +- Front-Cover Text may be at most 5 words, and a Back-Cover Text may +- be at most 25 words. +- +- A "Transparent" copy of the Document means a machine-readable copy, +- represented in a format whose specification is available to the +- general public, that is suitable for revising the document +- straightforwardly with generic text editors or (for images +- composed of pixels) generic paint programs or (for drawings) some +- widely available drawing editor, and that is suitable for input to +- text formatters or for automatic translation to a variety of +- formats suitable for input to text formatters. A copy made in an +- otherwise Transparent file format whose markup, or absence of +- markup, has been arranged to thwart or discourage subsequent +- modification by readers is not Transparent. An image format is +- not Transparent if used for any substantial amount of text. A +- copy that is not "Transparent" is called "Opaque". +- +- Examples of suitable formats for Transparent copies include plain +- ASCII without markup, Texinfo input format, LaTeX input format, +- SGML or XML using a publicly available DTD, and +- standard-conforming simple HTML, PostScript or PDF designed for +- human modification. Examples of transparent image formats include +- PNG, XCF and JPG. Opaque formats include proprietary formats that +- can be read and edited only by proprietary word processors, SGML or +- XML for which the DTD and/or processing tools are not generally +- available, and the machine-generated HTML, PostScript or PDF +- produced by some word processors for output purposes only. +- +- The "Title Page" means, for a printed book, the title page itself, +- plus such following pages as are needed to hold, legibly, the +- material this License requires to appear in the title page. For +- works in formats which do not have any title page as such, "Title +- Page" means the text near the most prominent appearance of the +- work's title, preceding the beginning of the body of the text. +- +- The "publisher" means any person or entity that distributes copies +- of the Document to the public. +- +- A section "Entitled XYZ" means a named subunit of the Document +- whose title either is precisely XYZ or contains XYZ in parentheses +- following text that translates XYZ in another language. (Here XYZ +- stands for a specific section name mentioned below, such as +- "Acknowledgements", "Dedications", "Endorsements", or "History".) +- To "Preserve the Title" of such a section when you modify the +- Document means that it remains a section "Entitled XYZ" according +- to this definition. +- +- The Document may include Warranty Disclaimers next to the notice +- which states that this License applies to the Document. These +- Warranty Disclaimers are considered to be included by reference in +- this License, but only as regards disclaiming warranties: any other +- implication that these Warranty Disclaimers may have is void and +- has no effect on the meaning of this License. +- +- 2. VERBATIM COPYING +- +- You may copy and distribute the Document in any medium, either +- commercially or noncommercially, provided that this License, the +- copyright notices, and the license notice saying this License +- applies to the Document are reproduced in all copies, and that you +- add no other conditions whatsoever to those of this License. You +- may not use technical measures to obstruct or control the reading +- or further copying of the copies you make or distribute. However, +- you may accept compensation in exchange for copies. If you +- distribute a large enough number of copies you must also follow +- the conditions in section 3. +- +- You may also lend copies, under the same conditions stated above, +- and you may publicly display copies. +- +- 3. COPYING IN QUANTITY +- +- If you publish printed copies (or copies in media that commonly +- have printed covers) of the Document, numbering more than 100, and +- the Document's license notice requires Cover Texts, you must +- enclose the copies in covers that carry, clearly and legibly, all +- these Cover Texts: Front-Cover Texts on the front cover, and +- Back-Cover Texts on the back cover. Both covers must also clearly +- and legibly identify you as the publisher of these copies. The +- front cover must present the full title with all words of the +- title equally prominent and visible. You may add other material +- on the covers in addition. Copying with changes limited to the +- covers, as long as they preserve the title of the Document and +- satisfy these conditions, can be treated as verbatim copying in +- other respects. +- +- If the required texts for either cover are too voluminous to fit +- legibly, you should put the first ones listed (as many as fit +- reasonably) on the actual cover, and continue the rest onto +- adjacent pages. +- +- If you publish or distribute Opaque copies of the Document +- numbering more than 100, you must either include a +- machine-readable Transparent copy along with each Opaque copy, or +- state in or with each Opaque copy a computer-network location from +- which the general network-using public has access to download +- using public-standard network protocols a complete Transparent +- copy of the Document, free of added material. If you use the +- latter option, you must take reasonably prudent steps, when you +- begin distribution of Opaque copies in quantity, to ensure that +- this Transparent copy will remain thus accessible at the stated +- location until at least one year after the last time you +- distribute an Opaque copy (directly or through your agents or +- retailers) of that edition to the public. +- +- It is requested, but not required, that you contact the authors of +- the Document well before redistributing any large number of +- copies, to give them a chance to provide you with an updated +- version of the Document. +- +- 4. MODIFICATIONS +- +- You may copy and distribute a Modified Version of the Document +- under the conditions of sections 2 and 3 above, provided that you +- release the Modified Version under precisely this License, with +- the Modified Version filling the role of the Document, thus +- licensing distribution and modification of the Modified Version to +- whoever possesses a copy of it. In addition, you must do these +- things in the Modified Version: +- +- A. Use in the Title Page (and on the covers, if any) a title +- distinct from that of the Document, and from those of +- previous versions (which should, if there were any, be listed +- in the History section of the Document). You may use the +- same title as a previous version if the original publisher of +- that version gives permission. +- +- B. List on the Title Page, as authors, one or more persons or +- entities responsible for authorship of the modifications in +- the Modified Version, together with at least five of the +- principal authors of the Document (all of its principal +- authors, if it has fewer than five), unless they release you +- from this requirement. +- +- C. State on the Title page the name of the publisher of the +- Modified Version, as the publisher. +- +- D. Preserve all the copyright notices of the Document. +- +- E. Add an appropriate copyright notice for your modifications +- adjacent to the other copyright notices. +- +- F. Include, immediately after the copyright notices, a license +- notice giving the public permission to use the Modified +- Version under the terms of this License, in the form shown in +- the Addendum below. +- +- G. Preserve in that license notice the full lists of Invariant +- Sections and required Cover Texts given in the Document's +- license notice. +- +- H. Include an unaltered copy of this License. +- +- I. Preserve the section Entitled "History", Preserve its Title, +- and add to it an item stating at least the title, year, new +- authors, and publisher of the Modified Version as given on +- the Title Page. If there is no section Entitled "History" in +- the Document, create one stating the title, year, authors, +- and publisher of the Document as given on its Title Page, +- then add an item describing the Modified Version as stated in +- the previous sentence. +- +- J. Preserve the network location, if any, given in the Document +- for public access to a Transparent copy of the Document, and +- likewise the network locations given in the Document for +- previous versions it was based on. These may be placed in +- the "History" section. You may omit a network location for a +- work that was published at least four years before the +- Document itself, or if the original publisher of the version +- it refers to gives permission. +- +- K. For any section Entitled "Acknowledgements" or "Dedications", +- Preserve the Title of the section, and preserve in the +- section all the substance and tone of each of the contributor +- acknowledgements and/or dedications given therein. +- +- L. Preserve all the Invariant Sections of the Document, +- unaltered in their text and in their titles. Section numbers +- or the equivalent are not considered part of the section +- titles. +- +- M. Delete any section Entitled "Endorsements". Such a section +- may not be included in the Modified Version. +- +- N. Do not retitle any existing section to be Entitled +- "Endorsements" or to conflict in title with any Invariant +- Section. +- +- O. Preserve any Warranty Disclaimers. +- +- If the Modified Version includes new front-matter sections or +- appendices that qualify as Secondary Sections and contain no +- material copied from the Document, you may at your option +- designate some or all of these sections as invariant. To do this, +- add their titles to the list of Invariant Sections in the Modified +- Version's license notice. These titles must be distinct from any +- other section titles. +- +- You may add a section Entitled "Endorsements", provided it contains +- nothing but endorsements of your Modified Version by various +- parties--for example, statements of peer review or that the text +- has been approved by an organization as the authoritative +- definition of a standard. +- +- You may add a passage of up to five words as a Front-Cover Text, +- and a passage of up to 25 words as a Back-Cover Text, to the end +- of the list of Cover Texts in the Modified Version. Only one +- passage of Front-Cover Text and one of Back-Cover Text may be +- added by (or through arrangements made by) any one entity. If the +- Document already includes a cover text for the same cover, +- previously added by you or by arrangement made by the same entity +- you are acting on behalf of, you may not add another; but you may +- replace the old one, on explicit permission from the previous +- publisher that added the old one. +- +- The author(s) and publisher(s) of the Document do not by this +- License give permission to use their names for publicity for or to +- assert or imply endorsement of any Modified Version. +- +- 5. COMBINING DOCUMENTS +- +- You may combine the Document with other documents released under +- this License, under the terms defined in section 4 above for +- modified versions, provided that you include in the combination +- all of the Invariant Sections of all of the original documents, +- unmodified, and list them all as Invariant Sections of your +- combined work in its license notice, and that you preserve all +- their Warranty Disclaimers. +- +- The combined work need only contain one copy of this License, and +- multiple identical Invariant Sections may be replaced with a single +- copy. If there are multiple Invariant Sections with the same name +- but different contents, make the title of each such section unique +- by adding at the end of it, in parentheses, the name of the +- original author or publisher of that section if known, or else a +- unique number. Make the same adjustment to the section titles in +- the list of Invariant Sections in the license notice of the +- combined work. +- +- In the combination, you must combine any sections Entitled +- "History" in the various original documents, forming one section +- Entitled "History"; likewise combine any sections Entitled +- "Acknowledgements", and any sections Entitled "Dedications". You +- must delete all sections Entitled "Endorsements." +- +- 6. COLLECTIONS OF DOCUMENTS +- +- You may make a collection consisting of the Document and other +- documents released under this License, and replace the individual +- copies of this License in the various documents with a single copy +- that is included in the collection, provided that you follow the +- rules of this License for verbatim copying of each of the +- documents in all other respects. +- +- You may extract a single document from such a collection, and +- distribute it individually under this License, provided you insert +- a copy of this License into the extracted document, and follow +- this License in all other respects regarding verbatim copying of +- that document. +- +- 7. AGGREGATION WITH INDEPENDENT WORKS +- +- A compilation of the Document or its derivatives with other +- separate and independent documents or works, in or on a volume of +- a storage or distribution medium, is called an "aggregate" if the +- copyright resulting from the compilation is not used to limit the +- legal rights of the compilation's users beyond what the individual +- works permit. When the Document is included in an aggregate, this +- License does not apply to the other works in the aggregate which +- are not themselves derivative works of the Document. +- +- If the Cover Text requirement of section 3 is applicable to these +- copies of the Document, then if the Document is less than one half +- of the entire aggregate, the Document's Cover Texts may be placed +- on covers that bracket the Document within the aggregate, or the +- electronic equivalent of covers if the Document is in electronic +- form. Otherwise they must appear on printed covers that bracket +- the whole aggregate. +- +- 8. TRANSLATION +- +- Translation is considered a kind of modification, so you may +- distribute translations of the Document under the terms of section +- 4. Replacing Invariant Sections with translations requires special +- permission from their copyright holders, but you may include +- translations of some or all Invariant Sections in addition to the +- original versions of these Invariant Sections. You may include a +- translation of this License, and all the license notices in the +- Document, and any Warranty Disclaimers, provided that you also +- include the original English version of this License and the +- original versions of those notices and disclaimers. In case of a +- disagreement between the translation and the original version of +- this License or a notice or disclaimer, the original version will +- prevail. +- +- If a section in the Document is Entitled "Acknowledgements", +- "Dedications", or "History", the requirement (section 4) to +- Preserve its Title (section 1) will typically require changing the +- actual title. +- +- 9. TERMINATION +- +- You may not copy, modify, sublicense, or distribute the Document +- except as expressly provided under this License. Any attempt +- otherwise to copy, modify, sublicense, or distribute it is void, +- and will automatically terminate your rights under this License. +- +- However, if you cease all violation of this License, then your +- license from a particular copyright holder is reinstated (a) +- provisionally, unless and until the copyright holder explicitly +- and finally terminates your license, and (b) permanently, if the +- copyright holder fails to notify you of the violation by some +- reasonable means prior to 60 days after the cessation. +- +- Moreover, your license from a particular copyright holder is +- reinstated permanently if the copyright holder notifies you of the +- violation by some reasonable means, this is the first time you have +- received notice of violation of this License (for any work) from +- that copyright holder, and you cure the violation prior to 30 days +- after your receipt of the notice. +- +- Termination of your rights under this section does not terminate +- the licenses of parties who have received copies or rights from +- you under this License. If your rights have been terminated and +- not permanently reinstated, receipt of a copy of some or all of +- the same material does not give you any rights to use it. +- +- 10. FUTURE REVISIONS OF THIS LICENSE +- +- The Free Software Foundation may publish new, revised versions of +- the GNU Free Documentation License from time to time. Such new +- versions will be similar in spirit to the present version, but may +- differ in detail to address new problems or concerns. See +- `http://www.gnu.org/copyleft/'. +- +- Each version of the License is given a distinguishing version +- number. If the Document specifies that a particular numbered +- version of this License "or any later version" applies to it, you +- have the option of following the terms and conditions either of +- that specified version or of any later version that has been +- published (not as a draft) by the Free Software Foundation. If +- the Document does not specify a version number of this License, +- you may choose any version ever published (not as a draft) by the +- Free Software Foundation. If the Document specifies that a proxy +- can decide which future versions of this License can be used, that +- proxy's public statement of acceptance of a version permanently +- authorizes you to choose that version for the Document. +- +- 11. RELICENSING +- +- "Massive Multiauthor Collaboration Site" (or "MMC Site") means any +- World Wide Web server that publishes copyrightable works and also +- provides prominent facilities for anybody to edit those works. A +- public wiki that anybody can edit is an example of such a server. +- A "Massive Multiauthor Collaboration" (or "MMC") contained in the +- site means any set of copyrightable works thus published on the MMC +- site. +- +- "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +- license published by Creative Commons Corporation, a not-for-profit +- corporation with a principal place of business in San Francisco, +- California, as well as future copyleft versions of that license +- published by that same organization. +- +- "Incorporate" means to publish or republish a Document, in whole or +- in part, as part of another Document. +- +- An MMC is "eligible for relicensing" if it is licensed under this +- License, and if all works that were first published under this +- License somewhere other than this MMC, and subsequently +- incorporated in whole or in part into the MMC, (1) had no cover +- texts or invariant sections, and (2) were thus incorporated prior +- to November 1, 2008. +- +- The operator of an MMC Site may republish an MMC contained in the +- site under CC-BY-SA on the same site at any time before August 1, +- 2009, provided the MMC is eligible for relicensing. +- +- +-ADDENDUM: How to use this License for your documents +-==================================================== +- +-To use this License in a document you have written, include a copy of +-the License in the document and put the following copyright and license +-notices just after the title page: +- +- Copyright (C) YEAR YOUR NAME. +- Permission is granted to copy, distribute and/or modify this document +- under the terms of the GNU Free Documentation License, Version 1.3 +- or any later version published by the Free Software Foundation; +- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover +- Texts. A copy of the license is included in the section entitled ``GNU +- Free Documentation License''. +- +- If you have Invariant Sections, Front-Cover Texts and Back-Cover +-Texts, replace the "with...Texts." line with this: +- +- with the Invariant Sections being LIST THEIR TITLES, with +- the Front-Cover Texts being LIST, and with the Back-Cover Texts +- being LIST. +- +- If you have Invariant Sections without Cover Texts, or some other +-combination of the three, merge those two alternatives to suit the +-situation. +- +- If your document contains nontrivial examples of program code, we +-recommend releasing these examples in parallel under your choice of +-free software license, such as the GNU General Public License, to +-permit their use in free software. +- +- +-File: binutils.info, Node: Binutils Index, Prev: GNU Free Documentation License, Up: Top +- +-Binutils Index +-************** +- +-[index] +-* Menu: +- +-* --enable-deterministic-archives <1>: objcopy. (line 302) +-* --enable-deterministic-archives <2>: ranlib. (line 44) +-* --enable-deterministic-archives <3>: ar cmdline. (line 151) +-* --enable-deterministic-archives <4>: strip. (line 115) +-* --enable-deterministic-archives <5>: ar cmdline. (line 224) +-* --enable-deterministic-archives: objcopy. (line 292) +-* .stab: objdump. (line 413) +-* Add prefix to absolute paths: objdump. (line 356) +-* addr2line: addr2line. (line 6) +-* address to file name and line number: addr2line. (line 6) +-* all header information, object file: objdump. (line 531) +-* ar: ar. (line 6) +-* ar compatibility: ar. (line 60) +-* architecture: objdump. (line 197) +-* architectures available: objdump. (line 182) +-* archive contents: ranlib. (line 6) +-* Archive file symbol index information: readelf. (line 155) +-* archive headers: objdump. (line 67) +-* archives: ar. (line 6) +-* base files: dlltool. (line 124) +-* bug criteria: Bug Criteria. (line 6) +-* bug reports: Bug Reporting. (line 6) +-* bugs: Reporting Bugs. (line 6) +-* bugs, reporting: Bug Reporting. (line 6) +-* c++filt: c++filt. (line 6) +-* changing object addresses: objcopy. (line 337) +-* changing section address: objcopy. (line 347) +-* changing section LMA: objcopy. (line 356) +-* changing section VMA: objcopy. (line 369) +-* changing start address: objcopy. (line 332) +-* collections of files: ar. (line 6) +-* compatibility, ar: ar. (line 60) +-* contents of archive: ar cmdline. (line 97) +-* crash: Bug Criteria. (line 9) +-* creating archives: ar cmdline. (line 145) +-* creating thin archive: ar cmdline. (line 210) +-* cxxfilt: c++filt. (line 14) +-* dates in archive: ar cmdline. (line 184) +-* debug symbols: objdump. (line 413) +-* debugging symbols: nm. (line 147) +-* deleting from archive: ar cmdline. (line 26) +-* demangling C++ symbols: c++filt. (line 6) +-* demangling in nm: nm. (line 155) +-* demangling in objdump <1>: objdump. (line 95) +-* demangling in objdump: addr2line. (line 78) +-* deterministic archives <1>: ranlib. (line 32) +-* deterministic archives <2>: objcopy. (line 292) +-* deterministic archives <3>: ar cmdline. (line 224) +-* deterministic archives <4>: strip. (line 105) +-* deterministic archives <5>: ar cmdline. (line 151) +-* deterministic archives <6>: ranlib. (line 44) +-* deterministic archives: objcopy. (line 302) +-* disassembling object code: objdump. (line 117) +-* disassembly architecture: objdump. (line 197) +-* disassembly endianness: objdump. (line 137) +-* disassembly, with source: objdump. (line 352) +-* discarding symbols: strip. (line 6) +-* DLL: dlltool. (line 6) +-* dlltool: dlltool. (line 6) +-* DWARF: objdump. (line 378) +-* dynamic relocation entries, in object file: objdump. (line 340) +-* dynamic symbol table entries, printing: objdump. (line 515) +-* dynamic symbols: nm. (line 167) +-* ELF dynamic section information: readelf. (line 113) +-* ELF dynamic symbol table information: readelf. (line 88) +-* ELF file header information: readelf. (line 57) +-* ELF file information: readelf. (line 6) +-* ELF notes: readelf. (line 97) +-* ELF object file format: objdump. (line 413) +-* ELF program header information: readelf. (line 63) +-* ELF reloc information: readelf. (line 101) +-* ELF section group information: readelf. (line 74) +-* ELF section information: readelf. (line 79) +-* ELF segment information: readelf. (line 63) +-* ELF symbol table information: readelf. (line 84) +-* ELF version sections information: readelf. (line 117) +-* elfedit: elfedit. (line 6) +-* endianness: objdump. (line 137) +-* error on valid input: Bug Criteria. (line 12) +-* external symbols: nm. (line 179) +-* extract from archive: ar cmdline. (line 112) +-* fatal signal: Bug Criteria. (line 9) +-* file name: nm. (line 141) +-* header information, all: objdump. (line 531) +-* input .def file: dlltool. (line 120) +-* input file name: nm. (line 141) +-* Instruction width: objdump. (line 373) +-* libraries: ar. (line 25) +-* listings strings: strings. (line 6) +-* load plugin: nm. (line 252) +-* machine instructions: objdump. (line 117) +-* moving in archive: ar cmdline. (line 34) +-* MRI compatibility, ar: ar scripts. (line 8) +-* name duplication in archive: ar cmdline. (line 106) +-* name length: ar. (line 18) +-* nm: nm. (line 6) +-* nm compatibility: nm. (line 173) +-* nm format: nm. (line 173) +-* not writing archive index: ar cmdline. (line 203) +-* objdump: objdump. (line 6) +-* object code format <1>: strings. (line 67) +-* object code format <2>: nm. (line 278) +-* object code format <3>: addr2line. (line 73) +-* object code format <4>: objdump. (line 81) +-* object code format: size. (line 84) +-* object file header: objdump. (line 143) +-* object file information: objdump. (line 6) +-* object file offsets: objdump. (line 148) +-* object file sections: objdump. (line 347) +-* object formats available: objdump. (line 182) +-* operations on archive: ar cmdline. (line 22) +-* printing from archive: ar cmdline. (line 46) +-* printing strings: strings. (line 6) +-* quick append to archive: ar cmdline. (line 54) +-* radix for section sizes: size. (line 66) +-* ranlib <1>: ranlib. (line 6) +-* ranlib: ar cmdline. (line 91) +-* readelf: readelf. (line 6) +-* relative placement in archive: ar cmdline. (line 133) +-* relocation entries, in object file: objdump. (line 334) +-* removing symbols: strip. (line 6) +-* repeated names in archive: ar cmdline. (line 106) +-* replacement in archive: ar cmdline. (line 73) +-* reporting bugs: Reporting Bugs. (line 6) +-* scripts, ar: ar scripts. (line 8) +-* section addresses in objdump: objdump. (line 73) +-* section headers: objdump. (line 164) +-* section information: objdump. (line 187) +-* section sizes: size. (line 6) +-* sections, full contents: objdump. (line 347) +-* size: size. (line 6) +-* size display format: size. (line 27) +-* size number format: size. (line 66) +-* sorting symbols: nm. (line 202) +-* source code context: objdump. (line 157) +-* source disassembly: objdump. (line 352) +-* source file name: nm. (line 141) +-* source filenames for object files: objdump. (line 191) +-* stab: objdump. (line 413) +-* start-address: objdump. (line 422) +-* stop-address: objdump. (line 426) +-* strings: strings. (line 6) +-* strings, printing: strings. (line 6) +-* strip: strip. (line 6) +-* Strip absolute paths: objdump. (line 359) +-* symbol index <1>: ar. (line 28) +-* symbol index: ranlib. (line 6) +-* symbol index, listing: nm. (line 224) +-* symbol line numbers: nm. (line 187) +-* symbol table entries, printing: objdump. (line 431) +-* symbols: nm. (line 6) +-* symbols, discarding: strip. (line 6) +-* thin archives: ar. (line 40) +-* undefined symbols: nm. (line 235) +-* Unix compatibility, ar: ar cmdline. (line 8) +-* unwind information: readelf. (line 106) +-* Update ELF header: elfedit. (line 6) +-* updating an archive: ar cmdline. (line 215) +-* version: Top. (line 6) +-* VMA in objdump: objdump. (line 73) +-* wide output, printing: objdump. (line 537) +-* writing archive index: ar cmdline. (line 197) +- +- +- +-Tag Table: +-Node: Top1896 +-Node: ar3609 +-Node: ar cmdline6747 +-Node: ar scripts17089 +-Node: nm22777 +-Node: objcopy32671 +-Node: objdump64440 +-Node: ranlib86571 +-Node: size88176 +-Node: strings91180 +-Node: strip93638 +-Node: c++filt100870 +-Ref: c++filt-Footnote-1105711 +-Node: addr2line105817 +-Node: nlmconv110154 +-Node: windmc112759 +-Node: windres116408 +-Node: dlltool122769 +-Node: def file format135649 +-Node: readelf138188 +-Node: elfedit145743 +-Node: Common Options147997 +-Node: Selecting the Target System149037 +-Node: Target Selection149969 +-Node: Architecture Selection151951 +-Node: Reporting Bugs152779 +-Node: Bug Criteria153558 +-Node: Bug Reporting154111 +-Node: GNU Free Documentation License160981 +-Node: Binutils Index186160 +- +-End Tag Table +diff -Nur binutils-2.24.orig/binutils/doc/cxxfilt.man binutils-2.24/binutils/doc/cxxfilt.man +--- binutils-2.24.orig/binutils/doc/cxxfilt.man 2013-11-18 09:49:32.000000000 +0100 ++++ binutils-2.24/binutils/doc/cxxfilt.man 1970-01-01 01:00:00.000000000 +0100 +@@ -1,336 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "C++FILT 1" +-.TH C++FILT 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-cxxfilt \- Demangle C++ and Java symbols. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-c++filt [\fB\-_\fR|\fB\-\-strip\-underscore\fR] +- [\fB\-n\fR|\fB\-\-no\-strip\-underscore\fR] +- [\fB\-p\fR|\fB\-\-no\-params\fR] +- [\fB\-t\fR|\fB\-\-types\fR] +- [\fB\-i\fR|\fB\-\-no\-verbose\fR] +- [\fB\-s\fR \fIformat\fR|\fB\-\-format=\fR\fIformat\fR] +- [\fB\-\-help\fR] [\fB\-\-version\fR] [\fIsymbol\fR...] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-The \*(C+ and Java languages provide function overloading, which means +-that you can write many functions with the same name, providing that +-each function takes parameters of different types. In order to be +-able to distinguish these similarly named functions \*(C+ and Java +-encode them into a low-level assembler name which uniquely identifies +-each different version. This process is known as \fImangling\fR. The +-\&\fBc++filt\fR +-[1] +-program does the inverse mapping: it decodes (\fIdemangles\fR) low-level +-names into user-level names so that they can be read. +-.PP +-Every alphanumeric word (consisting of letters, digits, underscores, +-dollars, or periods) seen in the input is a potential mangled name. +-If the name decodes into a \*(C+ name, the \*(C+ name replaces the +-low-level name in the output, otherwise the original word is output. +-In this way you can pass an entire assembler source file, containing +-mangled names, through \fBc++filt\fR and see the same source file +-containing demangled names. +-.PP +-You can also use \fBc++filt\fR to decipher individual symbols by +-passing them on the command line: +-.PP +-.Vb 1 +-\& c++filt +-.Ve +-.PP +-If no \fIsymbol\fR arguments are given, \fBc++filt\fR reads symbol +-names from the standard input instead. All the results are printed on +-the standard output. The difference between reading names from the +-command line versus reading names from the standard input is that +-command line arguments are expected to be just mangled names and no +-checking is performed to separate them from surrounding text. Thus +-for example: +-.PP +-.Vb 1 +-\& c++filt \-n _Z1fv +-.Ve +-.PP +-will work and demangle the name to \*(L"f()\*(R" whereas: +-.PP +-.Vb 1 +-\& c++filt \-n _Z1fv, +-.Ve +-.PP +-will not work. (Note the extra comma at the end of the mangled +-name which makes it invalid). This command however will work: +-.PP +-.Vb 1 +-\& echo _Z1fv, | c++filt \-n +-.Ve +-.PP +-and will display \*(L"f(),\*(R", i.e., the demangled name followed by a +-trailing comma. This behaviour is because when the names are read +-from the standard input it is expected that they might be part of an +-assembler source file where there might be extra, extraneous +-characters trailing after a mangled name. For example: +-.PP +-.Vb 1 +-\& .type _Z1fv, @function +-.Ve +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-_\fR" 4 +-.IX Item "-_" +-.PD 0 +-.IP "\fB\-\-strip\-underscore\fR" 4 +-.IX Item "--strip-underscore" +-.PD +-On some systems, both the C and \*(C+ compilers put an underscore in front +-of every name. For example, the C name \f(CW\*(C`foo\*(C'\fR gets the low-level +-name \f(CW\*(C`_foo\*(C'\fR. This option removes the initial underscore. Whether +-\&\fBc++filt\fR removes the underscore by default is target dependent. +-.IP "\fB\-n\fR" 4 +-.IX Item "-n" +-.PD 0 +-.IP "\fB\-\-no\-strip\-underscore\fR" 4 +-.IX Item "--no-strip-underscore" +-.PD +-Do not remove the initial underscore. +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-no\-params\fR" 4 +-.IX Item "--no-params" +-.PD +-When demangling the name of a function, do not display the types of +-the function's parameters. +-.IP "\fB\-t\fR" 4 +-.IX Item "-t" +-.PD 0 +-.IP "\fB\-\-types\fR" 4 +-.IX Item "--types" +-.PD +-Attempt to demangle types as well as function names. This is disabled +-by default since mangled types are normally only used internally in +-the compiler, and they can be confused with non-mangled names. For example, +-a function called \*(L"a\*(R" treated as a mangled type name would be +-demangled to \*(L"signed char\*(R". +-.IP "\fB\-i\fR" 4 +-.IX Item "-i" +-.PD 0 +-.IP "\fB\-\-no\-verbose\fR" 4 +-.IX Item "--no-verbose" +-.PD +-Do not include implementation details (if any) in the demangled +-output. +-.IP "\fB\-s\fR \fIformat\fR" 4 +-.IX Item "-s format" +-.PD 0 +-.IP "\fB\-\-format=\fR\fIformat\fR" 4 +-.IX Item "--format=format" +-.PD +-\&\fBc++filt\fR can decode various methods of mangling, used by +-different compilers. The argument to this option selects which +-method it uses: +-.RS 4 +-.ie n .IP """auto""" 4 +-.el .IP "\f(CWauto\fR" 4 +-.IX Item "auto" +-Automatic selection based on executable (the default method) +-.ie n .IP """gnu""" 4 +-.el .IP "\f(CWgnu\fR" 4 +-.IX Item "gnu" +-the one used by the \s-1GNU\s0 \*(C+ compiler (g++) +-.ie n .IP """lucid""" 4 +-.el .IP "\f(CWlucid\fR" 4 +-.IX Item "lucid" +-the one used by the Lucid compiler (lcc) +-.ie n .IP """arm""" 4 +-.el .IP "\f(CWarm\fR" 4 +-.IX Item "arm" +-the one specified by the \*(C+ Annotated Reference Manual +-.ie n .IP """hp""" 4 +-.el .IP "\f(CWhp\fR" 4 +-.IX Item "hp" +-the one used by the \s-1HP\s0 compiler (aCC) +-.ie n .IP """edg""" 4 +-.el .IP "\f(CWedg\fR" 4 +-.IX Item "edg" +-the one used by the \s-1EDG\s0 compiler +-.ie n .IP """gnu\-v3""" 4 +-.el .IP "\f(CWgnu\-v3\fR" 4 +-.IX Item "gnu-v3" +-the one used by the \s-1GNU\s0 \*(C+ compiler (g++) with the V3 \s-1ABI\s0. +-.ie n .IP """java""" 4 +-.el .IP "\f(CWjava\fR" 4 +-.IX Item "java" +-the one used by the \s-1GNU\s0 Java compiler (gcj) +-.ie n .IP """gnat""" 4 +-.el .IP "\f(CWgnat\fR" 4 +-.IX Item "gnat" +-the one used by the \s-1GNU\s0 Ada compiler (\s-1GNAT\s0). +-.RE +-.RS 4 +-.RE +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-Print a summary of the options to \fBc++filt\fR and exit. +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-Print the version number of \fBc++filt\fR and exit. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "FOOTNOTES" +-.IX Header "FOOTNOTES" +-.IP "1." 4 +-MS-DOS does not allow \f(CW\*(C`+\*(C'\fR characters in file names, so on +-MS-DOS this program is named \fB\s-1CXXFILT\s0\fR. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/dlltool.1 binutils-2.24/binutils/doc/dlltool.1 +--- binutils-2.24.orig/binutils/doc/dlltool.1 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/doc/dlltool.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,529 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "DLLTOOL 1" +-.TH DLLTOOL 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-dlltool \- Create files needed to build and use DLLs. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-dlltool [\fB\-d\fR|\fB\-\-input\-def\fR \fIdef-file-name\fR] +- [\fB\-b\fR|\fB\-\-base\-file\fR \fIbase-file-name\fR] +- [\fB\-e\fR|\fB\-\-output\-exp\fR \fIexports-file-name\fR] +- [\fB\-z\fR|\fB\-\-output\-def\fR \fIdef-file-name\fR] +- [\fB\-l\fR|\fB\-\-output\-lib\fR \fIlibrary-file-name\fR] +- [\fB\-y\fR|\fB\-\-output\-delaylib\fR \fIlibrary-file-name\fR] +- [\fB\-\-export\-all\-symbols\fR] [\fB\-\-no\-export\-all\-symbols\fR] +- [\fB\-\-exclude\-symbols\fR \fIlist\fR] +- [\fB\-\-no\-default\-excludes\fR] +- [\fB\-S\fR|\fB\-\-as\fR \fIpath-to-assembler\fR] [\fB\-f\fR|\fB\-\-as\-flags\fR \fIoptions\fR] +- [\fB\-D\fR|\fB\-\-dllname\fR \fIname\fR] [\fB\-m\fR|\fB\-\-machine\fR \fImachine\fR] +- [\fB\-a\fR|\fB\-\-add\-indirect\fR] +- [\fB\-U\fR|\fB\-\-add\-underscore\fR] [\fB\-\-add\-stdcall\-underscore\fR] +- [\fB\-k\fR|\fB\-\-kill\-at\fR] [\fB\-A\fR|\fB\-\-add\-stdcall\-alias\fR] +- [\fB\-p\fR|\fB\-\-ext\-prefix\-alias\fR \fIprefix\fR] +- [\fB\-x\fR|\fB\-\-no\-idata4\fR] [\fB\-c\fR|\fB\-\-no\-idata5\fR] +- [\fB\-\-use\-nul\-prefixed\-import\-tables\fR] +- [\fB\-I\fR|\fB\-\-identify\fR \fIlibrary-file-name\fR] [\fB\-\-identify\-strict\fR] +- [\fB\-i\fR|\fB\-\-interwork\fR] +- [\fB\-n\fR|\fB\-\-nodelete\fR] [\fB\-t\fR|\fB\-\-temp\-prefix\fR \fIprefix\fR] +- [\fB\-v\fR|\fB\-\-verbose\fR] +- [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] +- [\fB\-\-no\-leading\-underscore\fR] [\fB\-\-leading\-underscore\fR] +- [object\-file ...] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBdlltool\fR reads its inputs, which can come from the \fB\-d\fR and +-\&\fB\-b\fR options as well as object files specified on the command +-line. It then processes these inputs and if the \fB\-e\fR option has +-been specified it creates a exports file. If the \fB\-l\fR option +-has been specified it creates a library file and if the \fB\-z\fR option +-has been specified it creates a def file. Any or all of the \fB\-e\fR, +-\&\fB\-l\fR and \fB\-z\fR options can be present in one invocation of +-dlltool. +-.PP +-When creating a \s-1DLL\s0, along with the source for the \s-1DLL\s0, it is necessary +-to have three other files. \fBdlltool\fR can help with the creation of +-these files. +-.PP +-The first file is a \fI.def\fR file which specifies which functions are +-exported from the \s-1DLL\s0, which functions the \s-1DLL\s0 imports, and so on. This +-is a text file and can be created by hand, or \fBdlltool\fR can be used +-to create it using the \fB\-z\fR option. In this case \fBdlltool\fR +-will scan the object files specified on its command line looking for +-those functions which have been specially marked as being exported and +-put entries for them in the \fI.def\fR file it creates. +-.PP +-In order to mark a function as being exported from a \s-1DLL\s0, it needs to +-have an \fB\-export:\fR entry in the \fB.drectve\fR +-section of the object file. This can be done in C by using the +-\&\fIasm()\fR operator: +-.PP +-.Vb 2 +-\& asm (".section .drectve"); +-\& asm (".ascii \e"\-export:my_func\e""); +-\& +-\& int my_func (void) { ... } +-.Ve +-.PP +-The second file needed for \s-1DLL\s0 creation is an exports file. This file +-is linked with the object files that make up the body of the \s-1DLL\s0 and it +-handles the interface between the \s-1DLL\s0 and the outside world. This is a +-binary file and it can be created by giving the \fB\-e\fR option to +-\&\fBdlltool\fR when it is creating or reading in a \fI.def\fR file. +-.PP +-The third file needed for \s-1DLL\s0 creation is the library file that programs +-will link with in order to access the functions in the \s-1DLL\s0 (an `import +-library'). This file can be created by giving the \fB\-l\fR option to +-dlltool when it is creating or reading in a \fI.def\fR file. +-.PP +-If the \fB\-y\fR option is specified, dlltool generates a delay-import +-library that can be used instead of the normal import library to allow +-a program to link to the dll only as soon as an imported function is +-called for the first time. The resulting executable will need to be +-linked to the static delayimp library containing _\|\fI_delayLoadHelper2()\fR, +-which in turn will import LoadLibraryA and GetProcAddress from kernel32. +-.PP +-\&\fBdlltool\fR builds the library file by hand, but it builds the +-exports file by creating temporary files containing assembler statements +-and then assembling these. The \fB\-S\fR command line option can be +-used to specify the path to the assembler that dlltool will use, +-and the \fB\-f\fR option can be used to pass specific flags to that +-assembler. The \fB\-n\fR can be used to prevent dlltool from deleting +-these temporary assembler files when it is done, and if \fB\-n\fR is +-specified twice then this will prevent dlltool from deleting the +-temporary object files it used to build the library. +-.PP +-Here is an example of creating a \s-1DLL\s0 from a source file \fBdll.c\fR and +-also creating a program (from an object file called \fBprogram.o\fR) +-that uses that \s-1DLL:\s0 +-.PP +-.Vb 4 +-\& gcc \-c dll.c +-\& dlltool \-e exports.o \-l dll.lib dll.o +-\& gcc dll.o exports.o \-o dll.dll +-\& gcc program.o dll.lib \-o program +-.Ve +-.PP +-\&\fBdlltool\fR may also be used to query an existing import library +-to determine the name of the \s-1DLL\s0 to which it is associated. See the +-description of the \fB\-I\fR or \fB\-\-identify\fR option. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The command line options have the following meanings: +-.IP "\fB\-d\fR \fIfilename\fR" 4 +-.IX Item "-d filename" +-.PD 0 +-.IP "\fB\-\-input\-def\fR \fIfilename\fR" 4 +-.IX Item "--input-def filename" +-.PD +-Specifies the name of a \fI.def\fR file to be read in and processed. +-.IP "\fB\-b\fR \fIfilename\fR" 4 +-.IX Item "-b filename" +-.PD 0 +-.IP "\fB\-\-base\-file\fR \fIfilename\fR" 4 +-.IX Item "--base-file filename" +-.PD +-Specifies the name of a base file to be read in and processed. The +-contents of this file will be added to the relocation section in the +-exports file generated by dlltool. +-.IP "\fB\-e\fR \fIfilename\fR" 4 +-.IX Item "-e filename" +-.PD 0 +-.IP "\fB\-\-output\-exp\fR \fIfilename\fR" 4 +-.IX Item "--output-exp filename" +-.PD +-Specifies the name of the export file to be created by dlltool. +-.IP "\fB\-z\fR \fIfilename\fR" 4 +-.IX Item "-z filename" +-.PD 0 +-.IP "\fB\-\-output\-def\fR \fIfilename\fR" 4 +-.IX Item "--output-def filename" +-.PD +-Specifies the name of the \fI.def\fR file to be created by dlltool. +-.IP "\fB\-l\fR \fIfilename\fR" 4 +-.IX Item "-l filename" +-.PD 0 +-.IP "\fB\-\-output\-lib\fR \fIfilename\fR" 4 +-.IX Item "--output-lib filename" +-.PD +-Specifies the name of the library file to be created by dlltool. +-.IP "\fB\-y\fR \fIfilename\fR" 4 +-.IX Item "-y filename" +-.PD 0 +-.IP "\fB\-\-output\-delaylib\fR \fIfilename\fR" 4 +-.IX Item "--output-delaylib filename" +-.PD +-Specifies the name of the delay-import library file to be created by dlltool. +-.IP "\fB\-\-export\-all\-symbols\fR" 4 +-.IX Item "--export-all-symbols" +-Treat all global and weak defined symbols found in the input object +-files as symbols to be exported. There is a small list of symbols which +-are not exported by default; see the \fB\-\-no\-default\-excludes\fR +-option. You may add to the list of symbols to not export by using the +-\&\fB\-\-exclude\-symbols\fR option. +-.IP "\fB\-\-no\-export\-all\-symbols\fR" 4 +-.IX Item "--no-export-all-symbols" +-Only export symbols explicitly listed in an input \fI.def\fR file or in +-\&\fB.drectve\fR sections in the input object files. This is the default +-behaviour. The \fB.drectve\fR sections are created by \fBdllexport\fR +-attributes in the source code. +-.IP "\fB\-\-exclude\-symbols\fR \fIlist\fR" 4 +-.IX Item "--exclude-symbols list" +-Do not export the symbols in \fIlist\fR. This is a list of symbol names +-separated by comma or colon characters. The symbol names should not +-contain a leading underscore. This is only meaningful when +-\&\fB\-\-export\-all\-symbols\fR is used. +-.IP "\fB\-\-no\-default\-excludes\fR" 4 +-.IX Item "--no-default-excludes" +-When \fB\-\-export\-all\-symbols\fR is used, it will by default avoid +-exporting certain special symbols. The current list of symbols to avoid +-exporting is \fBDllMain@12\fR, \fBDllEntryPoint@0\fR, +-\&\fBimpure_ptr\fR. You may use the \fB\-\-no\-default\-excludes\fR option +-to go ahead and export these special symbols. This is only meaningful +-when \fB\-\-export\-all\-symbols\fR is used. +-.IP "\fB\-S\fR \fIpath\fR" 4 +-.IX Item "-S path" +-.PD 0 +-.IP "\fB\-\-as\fR \fIpath\fR" 4 +-.IX Item "--as path" +-.PD +-Specifies the path, including the filename, of the assembler to be used +-to create the exports file. +-.IP "\fB\-f\fR \fIoptions\fR" 4 +-.IX Item "-f options" +-.PD 0 +-.IP "\fB\-\-as\-flags\fR \fIoptions\fR" 4 +-.IX Item "--as-flags options" +-.PD +-Specifies any specific command line options to be passed to the +-assembler when building the exports file. This option will work even if +-the \fB\-S\fR option is not used. This option only takes one argument, +-and if it occurs more than once on the command line, then later +-occurrences will override earlier occurrences. So if it is necessary to +-pass multiple options to the assembler they should be enclosed in +-double quotes. +-.IP "\fB\-D\fR \fIname\fR" 4 +-.IX Item "-D name" +-.PD 0 +-.IP "\fB\-\-dll\-name\fR \fIname\fR" 4 +-.IX Item "--dll-name name" +-.PD +-Specifies the name to be stored in the \fI.def\fR file as the name of +-the \s-1DLL\s0 when the \fB\-e\fR option is used. If this option is not +-present, then the filename given to the \fB\-e\fR option will be +-used as the name of the \s-1DLL\s0. +-.IP "\fB\-m\fR \fImachine\fR" 4 +-.IX Item "-m machine" +-.PD 0 +-.IP "\fB\-machine\fR \fImachine\fR" 4 +-.IX Item "-machine machine" +-.PD +-Specifies the type of machine for which the library file should be +-built. \fBdlltool\fR has a built in default type, depending upon how +-it was created, but this option can be used to override that. This is +-normally only useful when creating DLLs for an \s-1ARM\s0 processor, when the +-contents of the \s-1DLL\s0 are actually encode using Thumb instructions. +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-add\-indirect\fR" 4 +-.IX Item "--add-indirect" +-.PD +-Specifies that when \fBdlltool\fR is creating the exports file it +-should add a section which allows the exported functions to be +-referenced without using the import library. Whatever the hell that +-means! +-.IP "\fB\-U\fR" 4 +-.IX Item "-U" +-.PD 0 +-.IP "\fB\-\-add\-underscore\fR" 4 +-.IX Item "--add-underscore" +-.PD +-Specifies that when \fBdlltool\fR is creating the exports file it +-should prepend an underscore to the names of \fIall\fR exported symbols. +-.IP "\fB\-\-no\-leading\-underscore\fR" 4 +-.IX Item "--no-leading-underscore" +-.PD 0 +-.IP "\fB\-\-leading\-underscore\fR" 4 +-.IX Item "--leading-underscore" +-.PD +-Specifies whether standard symbol should be forced to be prefixed, or +-not. +-.IP "\fB\-\-add\-stdcall\-underscore\fR" 4 +-.IX Item "--add-stdcall-underscore" +-Specifies that when \fBdlltool\fR is creating the exports file it +-should prepend an underscore to the names of exported \fIstdcall\fR +-functions. Variable names and non-stdcall function names are not modified. +-This option is useful when creating GNU-compatible import libs for third +-party DLLs that were built with MS-Windows tools. +-.IP "\fB\-k\fR" 4 +-.IX Item "-k" +-.PD 0 +-.IP "\fB\-\-kill\-at\fR" 4 +-.IX Item "--kill-at" +-.PD +-Specifies that when \fBdlltool\fR is creating the exports file it +-should not append the string \fB@ \fR. These numbers are +-called ordinal numbers and they represent another way of accessing the +-function in a \s-1DLL\s0, other than by name. +-.IP "\fB\-A\fR" 4 +-.IX Item "-A" +-.PD 0 +-.IP "\fB\-\-add\-stdcall\-alias\fR" 4 +-.IX Item "--add-stdcall-alias" +-.PD +-Specifies that when \fBdlltool\fR is creating the exports file it +-should add aliases for stdcall symbols without \fB@ \fR +-in addition to the symbols with \fB@ \fR. +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-ext\-prefix\-alias\fR \fIprefix\fR" 4 +-.IX Item "--ext-prefix-alias prefix" +-.PD +-Causes \fBdlltool\fR to create external aliases for all \s-1DLL\s0 +-imports with the specified prefix. The aliases are created for both +-external and import symbols with no leading underscore. +-.IP "\fB\-x\fR" 4 +-.IX Item "-x" +-.PD 0 +-.IP "\fB\-\-no\-idata4\fR" 4 +-.IX Item "--no-idata4" +-.PD +-Specifies that when \fBdlltool\fR is creating the exports and library +-files it should omit the \f(CW\*(C`.idata4\*(C'\fR section. This is for compatibility +-with certain operating systems. +-.IP "\fB\-\-use\-nul\-prefixed\-import\-tables\fR" 4 +-.IX Item "--use-nul-prefixed-import-tables" +-Specifies that when \fBdlltool\fR is creating the exports and library +-files it should prefix the \f(CW\*(C`.idata4\*(C'\fR and \f(CW\*(C`.idata5\*(C'\fR by zero an +-element. This emulates old gnu import library generation of +-\&\f(CW\*(C`dlltool\*(C'\fR. By default this option is turned off. +-.IP "\fB\-c\fR" 4 +-.IX Item "-c" +-.PD 0 +-.IP "\fB\-\-no\-idata5\fR" 4 +-.IX Item "--no-idata5" +-.PD +-Specifies that when \fBdlltool\fR is creating the exports and library +-files it should omit the \f(CW\*(C`.idata5\*(C'\fR section. This is for compatibility +-with certain operating systems. +-.IP "\fB\-I\fR \fIfilename\fR" 4 +-.IX Item "-I filename" +-.PD 0 +-.IP "\fB\-\-identify\fR \fIfilename\fR" 4 +-.IX Item "--identify filename" +-.PD +-Specifies that \fBdlltool\fR should inspect the import library +-indicated by \fIfilename\fR and report, on \f(CW\*(C`stdout\*(C'\fR, the name(s) +-of the associated \s-1DLL\s0(s). This can be performed in addition to any +-other operations indicated by the other options and arguments. +-\&\fBdlltool\fR fails if the import library does not exist or is not +-actually an import library. See also \fB\-\-identify\-strict\fR. +-.IP "\fB\-\-identify\-strict\fR" 4 +-.IX Item "--identify-strict" +-Modifies the behavior of the \fB\-\-identify\fR option, such +-that an error is reported if \fIfilename\fR is associated with +-more than one \s-1DLL\s0. +-.IP "\fB\-i\fR" 4 +-.IX Item "-i" +-.PD 0 +-.IP "\fB\-\-interwork\fR" 4 +-.IX Item "--interwork" +-.PD +-Specifies that \fBdlltool\fR should mark the objects in the library +-file and exports file that it produces as supporting interworking +-between \s-1ARM\s0 and Thumb code. +-.IP "\fB\-n\fR" 4 +-.IX Item "-n" +-.PD 0 +-.IP "\fB\-\-nodelete\fR" 4 +-.IX Item "--nodelete" +-.PD +-Makes \fBdlltool\fR preserve the temporary assembler files it used to +-create the exports file. If this option is repeated then dlltool will +-also preserve the temporary object files it uses to create the library +-file. +-.IP "\fB\-t\fR \fIprefix\fR" 4 +-.IX Item "-t prefix" +-.PD 0 +-.IP "\fB\-\-temp\-prefix\fR \fIprefix\fR" 4 +-.IX Item "--temp-prefix prefix" +-.PD +-Makes \fBdlltool\fR use \fIprefix\fR when constructing the names of +-temporary assembler and object files. By default, the temp file prefix +-is generated from the pid. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-\-verbose\fR" 4 +-.IX Item "--verbose" +-.PD +-Make dlltool describe what it is doing. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Displays a list of command line options and then exits. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Displays dlltool's version number and then exits. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-The Info pages for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/elfedit.1 binutils-2.24/binutils/doc/elfedit.1 +--- binutils-2.24.orig/binutils/doc/elfedit.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/elfedit.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,233 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "ELFEDIT 1" +-.TH ELFEDIT 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-elfedit \- Update the ELF header of ELF files. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-elfedit [\fB\-\-input\-mach=\fR\fImachine\fR] +- [\fB\-\-input\-type=\fR\fItype\fR] +- [\fB\-\-input\-osabi=\fR\fIosabi\fR] +- \fB\-\-output\-mach=\fR\fImachine\fR +- \fB\-\-output\-type=\fR\fItype\fR +- \fB\-\-output\-osabi=\fR\fIosabi\fR +- [\fB\-v\fR|\fB\-\-version\fR] +- [\fB\-h\fR|\fB\-\-help\fR] +- \fIelffile\fR... +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBelfedit\fR updates the \s-1ELF\s0 header of \s-1ELF\s0 files which have +-the matching \s-1ELF\s0 machine and file types. The options control how and +-which fields in the \s-1ELF\s0 header should be updated. +-.PP +-\&\fIelffile\fR... are the \s-1ELF\s0 files to be updated. 32\-bit and +-64\-bit \s-1ELF\s0 files are supported, as are archives containing \s-1ELF\s0 files. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The long and short forms of options, shown here as alternatives, are +-equivalent. At least one of the \fB\-\-output\-mach\fR, +-\&\fB\-\-output\-type\fR and \fB\-\-output\-osabi\fR options must be given. +-.IP "\fB\-\-input\-mach=\fR\fImachine\fR" 4 +-.IX Item "--input-mach=machine" +-Set the matching input \s-1ELF\s0 machine type to \fImachine\fR. If +-\&\fB\-\-input\-mach\fR isn't specified, it will match any \s-1ELF\s0 +-machine types. +-.Sp +-The supported \s-1ELF\s0 machine types are, \fIL1OM\fR, \fIK1OM\fR and +-\&\fIx86\-64\fR. +-.IP "\fB\-\-output\-mach=\fR\fImachine\fR" 4 +-.IX Item "--output-mach=machine" +-Change the \s-1ELF\s0 machine type in the \s-1ELF\s0 header to \fImachine\fR. The +-supported \s-1ELF\s0 machine types are the same as \fB\-\-input\-mach\fR. +-.IP "\fB\-\-input\-type=\fR\fItype\fR" 4 +-.IX Item "--input-type=type" +-Set the matching input \s-1ELF\s0 file type to \fItype\fR. If +-\&\fB\-\-input\-type\fR isn't specified, it will match any \s-1ELF\s0 file types. +-.Sp +-The supported \s-1ELF\s0 file types are, \fIrel\fR, \fIexec\fR and \fIdyn\fR. +-.IP "\fB\-\-output\-type=\fR\fItype\fR" 4 +-.IX Item "--output-type=type" +-Change the \s-1ELF\s0 file type in the \s-1ELF\s0 header to \fItype\fR. The +-supported \s-1ELF\s0 types are the same as \fB\-\-input\-type\fR. +-.IP "\fB\-\-input\-osabi=\fR\fIosabi\fR" 4 +-.IX Item "--input-osabi=osabi" +-Set the matching input \s-1ELF\s0 file \s-1OSABI\s0 to \fIosabi\fR. If +-\&\fB\-\-input\-osabi\fR isn't specified, it will match any \s-1ELF\s0 OSABIs. +-.Sp +-The supported \s-1ELF\s0 OSABIs are, \fInone\fR, \fI\s-1HPUX\s0\fR, \fINetBSD\fR, +-\&\fI\s-1GNU\s0\fR, \fILinux\fR (alias for \fI\s-1GNU\s0\fR), +-\&\fISolaris\fR, \fI\s-1AIX\s0\fR, \fIIrix\fR, +-\&\fIFreeBSD\fR, \fI\s-1TRU64\s0\fR, \fIModesto\fR, \fIOpenBSD\fR, \fIOpenVMS\fR, +-\&\fI\s-1NSK\s0\fR, \fI\s-1AROS\s0\fR and \fIFenixOS\fR. +-.IP "\fB\-\-output\-osabi=\fR\fIosabi\fR" 4 +-.IX Item "--output-osabi=osabi" +-Change the \s-1ELF\s0 \s-1OSABI\s0 in the \s-1ELF\s0 header to \fIosabi\fR. The +-supported \s-1ELF\s0 \s-1OSABI\s0 are the same as \fB\-\-input\-osabi\fR. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Display the version number of \fBelfedit\fR. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Display the command line options understood by \fBelfedit\fR. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/nlmconv.1 binutils-2.24/binutils/doc/nlmconv.1 +--- binutils-2.24.orig/binutils/doc/nlmconv.1 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/doc/nlmconv.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,242 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "NLMCONV 1" +-.TH NLMCONV 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-nlmconv \- converts object code into an NLM. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-nlmconv [\fB\-I\fR \fIbfdname\fR|\fB\-\-input\-target=\fR\fIbfdname\fR] +- [\fB\-O\fR \fIbfdname\fR|\fB\-\-output\-target=\fR\fIbfdname\fR] +- [\fB\-T\fR \fIheaderfile\fR|\fB\-\-header\-file=\fR\fIheaderfile\fR] +- [\fB\-d\fR|\fB\-\-debug\fR] [\fB\-l\fR \fIlinker\fR|\fB\-\-linker=\fR\fIlinker\fR] +- [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] +- \fIinfile\fR \fIoutfile\fR +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBnlmconv\fR converts the relocatable \fBi386\fR object file +-\&\fIinfile\fR into the NetWare Loadable Module \fIoutfile\fR, optionally +-reading \fIheaderfile\fR for \s-1NLM\s0 header information. For instructions +-on writing the \s-1NLM\s0 command file language used in header files, see the +-\&\fBlinkers\fR section, \fB\s-1NLMLINK\s0\fR in particular, of the \fI\s-1NLM\s0 +-Development and Tools Overview\fR, which is part of the \s-1NLM\s0 Software +-Developer's Kit (\*(L"\s-1NLM\s0 \s-1SDK\s0\*(R"), available from Novell, Inc. +-\&\fBnlmconv\fR uses the \s-1GNU\s0 Binary File Descriptor library to read +-\&\fIinfile\fR; +-.PP +-\&\fBnlmconv\fR can perform a link step. In other words, you can list +-more than one object file for input if you list them in the definitions +-file (rather than simply specifying one input file on the command line). +-In this case, \fBnlmconv\fR calls the linker for you. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-I\fR \fIbfdname\fR" 4 +-.IX Item "-I bfdname" +-.PD 0 +-.IP "\fB\-\-input\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--input-target=bfdname" +-.PD +-Object format of the input file. \fBnlmconv\fR can usually determine +-the format of a given file (so no default is necessary). +-.IP "\fB\-O\fR \fIbfdname\fR" 4 +-.IX Item "-O bfdname" +-.PD 0 +-.IP "\fB\-\-output\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--output-target=bfdname" +-.PD +-Object format of the output file. \fBnlmconv\fR infers the output +-format based on the input format, e.g. for a \fBi386\fR input file the +-output format is \fBnlm32\-i386\fR. +-.IP "\fB\-T\fR \fIheaderfile\fR" 4 +-.IX Item "-T headerfile" +-.PD 0 +-.IP "\fB\-\-header\-file=\fR\fIheaderfile\fR" 4 +-.IX Item "--header-file=headerfile" +-.PD +-Reads \fIheaderfile\fR for \s-1NLM\s0 header information. For instructions on +-writing the \s-1NLM\s0 command file language used in header files, see see the +-\&\fBlinkers\fR section, of the \fI\s-1NLM\s0 Development and Tools +-Overview\fR, which is part of the \s-1NLM\s0 Software Developer's Kit, available +-from Novell, Inc. +-.IP "\fB\-d\fR" 4 +-.IX Item "-d" +-.PD 0 +-.IP "\fB\-\-debug\fR" 4 +-.IX Item "--debug" +-.PD +-Displays (on standard error) the linker command line used by \fBnlmconv\fR. +-.IP "\fB\-l\fR \fIlinker\fR" 4 +-.IX Item "-l linker" +-.PD 0 +-.IP "\fB\-\-linker=\fR\fIlinker\fR" 4 +-.IX Item "--linker=linker" +-.PD +-Use \fIlinker\fR for any linking. \fIlinker\fR can be an absolute or a +-relative pathname. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Prints a usage summary. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Prints the version number for \fBnlmconv\fR. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/nm.1 binutils-2.24/binutils/doc/nm.1 +--- binutils-2.24.orig/binutils/doc/nm.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/nm.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,530 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "NM 1" +-.TH NM 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-nm \- list symbols from object files +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-nm [\fB\-A\fR|\fB\-o\fR|\fB\-\-print\-file\-name\fR] [\fB\-a\fR|\fB\-\-debug\-syms\fR] +- [\fB\-B\fR|\fB\-\-format=bsd\fR] [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR]] +- [\fB\-D\fR|\fB\-\-dynamic\fR] [\fB\-f\fR\fIformat\fR|\fB\-\-format=\fR\fIformat\fR] +- [\fB\-g\fR|\fB\-\-extern\-only\fR] [\fB\-h\fR|\fB\-\-help\fR] +- [\fB\-l\fR|\fB\-\-line\-numbers\fR] [\fB\-n\fR|\fB\-v\fR|\fB\-\-numeric\-sort\fR] +- [\fB\-P\fR|\fB\-\-portability\fR] [\fB\-p\fR|\fB\-\-no\-sort\fR] +- [\fB\-r\fR|\fB\-\-reverse\-sort\fR] [\fB\-S\fR|\fB\-\-print\-size\fR] +- [\fB\-s\fR|\fB\-\-print\-armap\fR] [\fB\-t\fR \fIradix\fR|\fB\-\-radix=\fR\fIradix\fR] +- [\fB\-u\fR|\fB\-\-undefined\-only\fR] [\fB\-V\fR|\fB\-\-version\fR] +- [\fB\-X 32_64\fR] [\fB\-\-defined\-only\fR] [\fB\-\-no\-demangle\fR] +- [\fB\-\-plugin\fR \fIname\fR] [\fB\-\-size\-sort\fR] [\fB\-\-special\-syms\fR] +- [\fB\-\-synthetic\fR] [\fB\-\-target=\fR\fIbfdname\fR] +- [\fIobjfile\fR...] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\s-1GNU\s0 \fBnm\fR lists the symbols from object files \fIobjfile\fR.... +-If no object files are listed as arguments, \fBnm\fR assumes the file +-\&\fIa.out\fR. +-.PP +-For each symbol, \fBnm\fR shows: +-.IP "\(bu" 4 +-The symbol value, in the radix selected by options (see below), or +-hexadecimal by default. +-.IP "\(bu" 4 +-The symbol type. At least the following types are used; others are, as +-well, depending on the object file format. If lowercase, the symbol is +-usually local; if uppercase, the symbol is global (external). There +-are however a few lowercase symbols that are shown for special global +-symbols (\f(CW\*(C`u\*(C'\fR, \f(CW\*(C`v\*(C'\fR and \f(CW\*(C`w\*(C'\fR). +-.RS 4 +-.ie n .IP """A""" 4 +-.el .IP "\f(CWA\fR" 4 +-.IX Item "A" +-The symbol's value is absolute, and will not be changed by further +-linking. +-.ie n .IP """B""" 4 +-.el .IP "\f(CWB\fR" 4 +-.IX Item "B" +-.PD 0 +-.ie n .IP """b""" 4 +-.el .IP "\f(CWb\fR" 4 +-.IX Item "b" +-.PD +-The symbol is in the uninitialized data section (known as \s-1BSS\s0). +-.ie n .IP """C""" 4 +-.el .IP "\f(CWC\fR" 4 +-.IX Item "C" +-The symbol is common. Common symbols are uninitialized data. When +-linking, multiple common symbols may appear with the same name. If the +-symbol is defined anywhere, the common symbols are treated as undefined +-references. +-.ie n .IP """D""" 4 +-.el .IP "\f(CWD\fR" 4 +-.IX Item "D" +-.PD 0 +-.ie n .IP """d""" 4 +-.el .IP "\f(CWd\fR" 4 +-.IX Item "d" +-.PD +-The symbol is in the initialized data section. +-.ie n .IP """G""" 4 +-.el .IP "\f(CWG\fR" 4 +-.IX Item "G" +-.PD 0 +-.ie n .IP """g""" 4 +-.el .IP "\f(CWg\fR" 4 +-.IX Item "g" +-.PD +-The symbol is in an initialized data section for small objects. Some +-object file formats permit more efficient access to small data objects, +-such as a global int variable as opposed to a large global array. +-.ie n .IP """i""" 4 +-.el .IP "\f(CWi\fR" 4 +-.IX Item "i" +-For \s-1PE\s0 format files this indicates that the symbol is in a section +-specific to the implementation of DLLs. For \s-1ELF\s0 format files this +-indicates that the symbol is an indirect function. This is a \s-1GNU\s0 +-extension to the standard set of \s-1ELF\s0 symbol types. It indicates a +-symbol which if referenced by a relocation does not evaluate to its +-address, but instead must be invoked at runtime. The runtime +-execution will then return the value to be used in the relocation. +-.ie n .IP """I""" 4 +-.el .IP "\f(CWI\fR" 4 +-.IX Item "I" +-The symbol is an indirect reference to another symbol. +-.ie n .IP """N""" 4 +-.el .IP "\f(CWN\fR" 4 +-.IX Item "N" +-The symbol is a debugging symbol. +-.ie n .IP """p""" 4 +-.el .IP "\f(CWp\fR" 4 +-.IX Item "p" +-The symbols is in a stack unwind section. +-.ie n .IP """R""" 4 +-.el .IP "\f(CWR\fR" 4 +-.IX Item "R" +-.PD 0 +-.ie n .IP """r""" 4 +-.el .IP "\f(CWr\fR" 4 +-.IX Item "r" +-.PD +-The symbol is in a read only data section. +-.ie n .IP """S""" 4 +-.el .IP "\f(CWS\fR" 4 +-.IX Item "S" +-.PD 0 +-.ie n .IP """s""" 4 +-.el .IP "\f(CWs\fR" 4 +-.IX Item "s" +-.PD +-The symbol is in an uninitialized data section for small objects. +-.ie n .IP """T""" 4 +-.el .IP "\f(CWT\fR" 4 +-.IX Item "T" +-.PD 0 +-.ie n .IP """t""" 4 +-.el .IP "\f(CWt\fR" 4 +-.IX Item "t" +-.PD +-The symbol is in the text (code) section. +-.ie n .IP """U""" 4 +-.el .IP "\f(CWU\fR" 4 +-.IX Item "U" +-The symbol is undefined. +-.ie n .IP """u""" 4 +-.el .IP "\f(CWu\fR" 4 +-.IX Item "u" +-The symbol is a unique global symbol. This is a \s-1GNU\s0 extension to the +-standard set of \s-1ELF\s0 symbol bindings. For such a symbol the dynamic linker +-will make sure that in the entire process there is just one symbol with +-this name and type in use. +-.ie n .IP """V""" 4 +-.el .IP "\f(CWV\fR" 4 +-.IX Item "V" +-.PD 0 +-.ie n .IP """v""" 4 +-.el .IP "\f(CWv\fR" 4 +-.IX Item "v" +-.PD +-The symbol is a weak object. When a weak defined symbol is linked with +-a normal defined symbol, the normal defined symbol is used with no error. +-When a weak undefined symbol is linked and the symbol is not defined, +-the value of the weak symbol becomes zero with no error. On some +-systems, uppercase indicates that a default value has been specified. +-.ie n .IP """W""" 4 +-.el .IP "\f(CWW\fR" 4 +-.IX Item "W" +-.PD 0 +-.ie n .IP """w""" 4 +-.el .IP "\f(CWw\fR" 4 +-.IX Item "w" +-.PD +-The symbol is a weak symbol that has not been specifically tagged as a +-weak object symbol. When a weak defined symbol is linked with a normal +-defined symbol, the normal defined symbol is used with no error. +-When a weak undefined symbol is linked and the symbol is not defined, +-the value of the symbol is determined in a system-specific manner without +-error. On some systems, uppercase indicates that a default value has been +-specified. +-.ie n .IP """\-""" 4 +-.el .IP "\f(CW\-\fR" 4 +-.IX Item "-" +-The symbol is a stabs symbol in an a.out object file. In this case, the +-next values printed are the stabs other field, the stabs desc field, and +-the stab type. Stabs symbols are used to hold debugging information. +-.ie n .IP """?""" 4 +-.el .IP "\f(CW?\fR" 4 +-.IX Item "?" +-The symbol type is unknown, or object file format specific. +-.RE +-.RS 4 +-.RE +-.IP "\(bu" 4 +-The symbol name. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The long and short forms of options, shown here as alternatives, are +-equivalent. +-.IP "\fB\-A\fR" 4 +-.IX Item "-A" +-.PD 0 +-.IP "\fB\-o\fR" 4 +-.IX Item "-o" +-.IP "\fB\-\-print\-file\-name\fR" 4 +-.IX Item "--print-file-name" +-.PD +-Precede each symbol by the name of the input file (or archive member) +-in which it was found, rather than identifying the input file once only, +-before all of its symbols. +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-debug\-syms\fR" 4 +-.IX Item "--debug-syms" +-.PD +-Display all symbols, even debugger-only symbols; normally these are not +-listed. +-.IP "\fB\-B\fR" 4 +-.IX Item "-B" +-The same as \fB\-\-format=bsd\fR (for compatibility with the \s-1MIPS\s0 \fBnm\fR). +-.IP "\fB\-C\fR" 4 +-.IX Item "-C" +-.PD 0 +-.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 +-.IX Item "--demangle[=style]" +-.PD +-Decode (\fIdemangle\fR) low-level symbol names into user-level names. +-Besides removing any initial underscore prepended by the system, this +-makes \*(C+ function names readable. Different compilers have different +-mangling styles. The optional demangling style argument can be used to +-choose an appropriate demangling style for your compiler. +-.IP "\fB\-\-no\-demangle\fR" 4 +-.IX Item "--no-demangle" +-Do not demangle low-level symbol names. This is the default. +-.IP "\fB\-D\fR" 4 +-.IX Item "-D" +-.PD 0 +-.IP "\fB\-\-dynamic\fR" 4 +-.IX Item "--dynamic" +-.PD +-Display the dynamic symbols rather than the normal symbols. This is +-only meaningful for dynamic objects, such as certain types of shared +-libraries. +-.IP "\fB\-f\fR \fIformat\fR" 4 +-.IX Item "-f format" +-.PD 0 +-.IP "\fB\-\-format=\fR\fIformat\fR" 4 +-.IX Item "--format=format" +-.PD +-Use the output format \fIformat\fR, which can be \f(CW\*(C`bsd\*(C'\fR, +-\&\f(CW\*(C`sysv\*(C'\fR, or \f(CW\*(C`posix\*(C'\fR. The default is \f(CW\*(C`bsd\*(C'\fR. +-Only the first character of \fIformat\fR is significant; it can be +-either upper or lower case. +-.IP "\fB\-g\fR" 4 +-.IX Item "-g" +-.PD 0 +-.IP "\fB\-\-extern\-only\fR" 4 +-.IX Item "--extern-only" +-.PD +-Display only external symbols. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Show a summary of the options to \fBnm\fR and exit. +-.IP "\fB\-l\fR" 4 +-.IX Item "-l" +-.PD 0 +-.IP "\fB\-\-line\-numbers\fR" 4 +-.IX Item "--line-numbers" +-.PD +-For each symbol, use debugging information to try to find a filename and +-line number. For a defined symbol, look for the line number of the +-address of the symbol. For an undefined symbol, look for the line +-number of a relocation entry which refers to the symbol. If line number +-information can be found, print it after the other symbol information. +-.IP "\fB\-n\fR" 4 +-.IX Item "-n" +-.PD 0 +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.IP "\fB\-\-numeric\-sort\fR" 4 +-.IX Item "--numeric-sort" +-.PD +-Sort symbols numerically by their addresses, rather than alphabetically +-by their names. +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-no\-sort\fR" 4 +-.IX Item "--no-sort" +-.PD +-Do not bother to sort the symbols in any order; print them in the order +-encountered. +-.IP "\fB\-P\fR" 4 +-.IX Item "-P" +-.PD 0 +-.IP "\fB\-\-portability\fR" 4 +-.IX Item "--portability" +-.PD +-Use the \s-1POSIX\s0.2 standard output format instead of the default format. +-Equivalent to \fB\-f posix\fR. +-.IP "\fB\-r\fR" 4 +-.IX Item "-r" +-.PD 0 +-.IP "\fB\-\-reverse\-sort\fR" 4 +-.IX Item "--reverse-sort" +-.PD +-Reverse the order of the sort (whether numeric or alphabetic); let the +-last come first. +-.IP "\fB\-S\fR" 4 +-.IX Item "-S" +-.PD 0 +-.IP "\fB\-\-print\-size\fR" 4 +-.IX Item "--print-size" +-.PD +-Print both value and size of defined symbols for the \f(CW\*(C`bsd\*(C'\fR output style. +-This option has no effect for object formats that do not record symbol +-sizes, unless \fB\-\-size\-sort\fR is also used in which case a +-calculated size is displayed. +-.IP "\fB\-s\fR" 4 +-.IX Item "-s" +-.PD 0 +-.IP "\fB\-\-print\-armap\fR" 4 +-.IX Item "--print-armap" +-.PD +-When listing symbols from archive members, include the index: a mapping +-(stored in the archive by \fBar\fR or \fBranlib\fR) of which modules +-contain definitions for which names. +-.IP "\fB\-t\fR \fIradix\fR" 4 +-.IX Item "-t radix" +-.PD 0 +-.IP "\fB\-\-radix=\fR\fIradix\fR" 4 +-.IX Item "--radix=radix" +-.PD +-Use \fIradix\fR as the radix for printing the symbol values. It must be +-\&\fBd\fR for decimal, \fBo\fR for octal, or \fBx\fR for hexadecimal. +-.IP "\fB\-u\fR" 4 +-.IX Item "-u" +-.PD 0 +-.IP "\fB\-\-undefined\-only\fR" 4 +-.IX Item "--undefined-only" +-.PD +-Display only undefined symbols (those external to each object file). +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Show the version number of \fBnm\fR and exit. +-.IP "\fB\-X\fR" 4 +-.IX Item "-X" +-This option is ignored for compatibility with the \s-1AIX\s0 version of +-\&\fBnm\fR. It takes one parameter which must be the string +-\&\fB32_64\fR. The default mode of \s-1AIX\s0 \fBnm\fR corresponds +-to \fB\-X 32\fR, which is not supported by \s-1GNU\s0 \fBnm\fR. +-.IP "\fB\-\-defined\-only\fR" 4 +-.IX Item "--defined-only" +-Display only defined symbols for each object file. +-.IP "\fB\-\-plugin\fR \fIname\fR" 4 +-.IX Item "--plugin name" +-Load the plugin called \fIname\fR to add support for extra target +-types. This option is only available if the toolchain has been built +-with plugin support enabled. +-.IP "\fB\-\-size\-sort\fR" 4 +-.IX Item "--size-sort" +-Sort symbols by size. The size is computed as the difference between +-the value of the symbol and the value of the symbol with the next higher +-value. If the \f(CW\*(C`bsd\*(C'\fR output format is used the size of the symbol +-is printed, rather than the value, and \fB\-S\fR must be used in order +-both size and value to be printed. +-.IP "\fB\-\-special\-syms\fR" 4 +-.IX Item "--special-syms" +-Display symbols which have a target-specific special meaning. These +-symbols are usually used by the target for some special processing and +-are not normally helpful when included in the normal symbol lists. +-For example for \s-1ARM\s0 targets this option would skip the mapping symbols +-used to mark transitions between \s-1ARM\s0 code, \s-1THUMB\s0 code and data. +-.IP "\fB\-\-synthetic\fR" 4 +-.IX Item "--synthetic" +-Include synthetic symbols in the output. These are special symbols +-created by the linker for various purposes. They are not shown by +-default since they are not part of the binary's original source code. +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-Specify an object code format other than your system's default format. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIar\fR\|(1), \fIobjdump\fR\|(1), \fIranlib\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/objcopy.1 binutils-2.24/binutils/doc/objcopy.1 +--- binutils-2.24.orig/binutils/doc/objcopy.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/objcopy.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1012 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "OBJCOPY 1" +-.TH OBJCOPY 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-objcopy \- copy and translate object files +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-objcopy [\fB\-F\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] +- [\fB\-I\fR \fIbfdname\fR|\fB\-\-input\-target=\fR\fIbfdname\fR] +- [\fB\-O\fR \fIbfdname\fR|\fB\-\-output\-target=\fR\fIbfdname\fR] +- [\fB\-B\fR \fIbfdarch\fR|\fB\-\-binary\-architecture=\fR\fIbfdarch\fR] +- [\fB\-S\fR|\fB\-\-strip\-all\fR] +- [\fB\-g\fR|\fB\-\-strip\-debug\fR] +- [\fB\-K\fR \fIsymbolname\fR|\fB\-\-keep\-symbol=\fR\fIsymbolname\fR] +- [\fB\-N\fR \fIsymbolname\fR|\fB\-\-strip\-symbol=\fR\fIsymbolname\fR] +- [\fB\-\-strip\-unneeded\-symbol=\fR\fIsymbolname\fR] +- [\fB\-G\fR \fIsymbolname\fR|\fB\-\-keep\-global\-symbol=\fR\fIsymbolname\fR] +- [\fB\-\-localize\-hidden\fR] +- [\fB\-L\fR \fIsymbolname\fR|\fB\-\-localize\-symbol=\fR\fIsymbolname\fR] +- [\fB\-\-globalize\-symbol=\fR\fIsymbolname\fR] +- [\fB\-W\fR \fIsymbolname\fR|\fB\-\-weaken\-symbol=\fR\fIsymbolname\fR] +- [\fB\-w\fR|\fB\-\-wildcard\fR] +- [\fB\-x\fR|\fB\-\-discard\-all\fR] +- [\fB\-X\fR|\fB\-\-discard\-locals\fR] +- [\fB\-b\fR \fIbyte\fR|\fB\-\-byte=\fR\fIbyte\fR] +- [\fB\-i\fR [\fIbreadth\fR]|\fB\-\-interleave\fR[=\fIbreadth\fR]] +- [\fB\-\-interleave\-width=\fR\fIwidth\fR] +- [\fB\-j\fR \fIsectionpattern\fR|\fB\-\-only\-section=\fR\fIsectionpattern\fR] +- [\fB\-R\fR \fIsectionpattern\fR|\fB\-\-remove\-section=\fR\fIsectionpattern\fR] +- [\fB\-p\fR|\fB\-\-preserve\-dates\fR] +- [\fB\-D\fR|\fB\-\-enable\-deterministic\-archives\fR] +- [\fB\-U\fR|\fB\-\-disable\-deterministic\-archives\fR] +- [\fB\-\-debugging\fR] +- [\fB\-\-gap\-fill=\fR\fIval\fR] +- [\fB\-\-pad\-to=\fR\fIaddress\fR] +- [\fB\-\-set\-start=\fR\fIval\fR] +- [\fB\-\-adjust\-start=\fR\fIincr\fR] +- [\fB\-\-change\-addresses=\fR\fIincr\fR] +- [\fB\-\-change\-section\-address\fR \fIsectionpattern\fR{=,+,\-}\fIval\fR] +- [\fB\-\-change\-section\-lma\fR \fIsectionpattern\fR{=,+,\-}\fIval\fR] +- [\fB\-\-change\-section\-vma\fR \fIsectionpattern\fR{=,+,\-}\fIval\fR] +- [\fB\-\-change\-warnings\fR] [\fB\-\-no\-change\-warnings\fR] +- [\fB\-\-set\-section\-flags\fR \fIsectionpattern\fR=\fIflags\fR] +- [\fB\-\-add\-section\fR \fIsectionname\fR=\fIfilename\fR] +- [\fB\-\-rename\-section\fR \fIoldname\fR=\fInewname\fR[,\fIflags\fR]] +- [\fB\-\-long\-section\-names\fR {enable,disable,keep}] +- [\fB\-\-change\-leading\-char\fR] [\fB\-\-remove\-leading\-char\fR] +- [\fB\-\-reverse\-bytes=\fR\fInum\fR] +- [\fB\-\-srec\-len=\fR\fIival\fR] [\fB\-\-srec\-forceS3\fR] +- [\fB\-\-redefine\-sym\fR \fIold\fR=\fInew\fR] +- [\fB\-\-redefine\-syms=\fR\fIfilename\fR] +- [\fB\-\-weaken\fR] +- [\fB\-\-keep\-symbols=\fR\fIfilename\fR] +- [\fB\-\-strip\-symbols=\fR\fIfilename\fR] +- [\fB\-\-strip\-unneeded\-symbols=\fR\fIfilename\fR] +- [\fB\-\-keep\-global\-symbols=\fR\fIfilename\fR] +- [\fB\-\-localize\-symbols=\fR\fIfilename\fR] +- [\fB\-\-globalize\-symbols=\fR\fIfilename\fR] +- [\fB\-\-weaken\-symbols=\fR\fIfilename\fR] +- [\fB\-\-alt\-machine\-code=\fR\fIindex\fR] +- [\fB\-\-prefix\-symbols=\fR\fIstring\fR] +- [\fB\-\-prefix\-sections=\fR\fIstring\fR] +- [\fB\-\-prefix\-alloc\-sections=\fR\fIstring\fR] +- [\fB\-\-add\-gnu\-debuglink=\fR\fIpath-to-file\fR] +- [\fB\-\-keep\-file\-symbols\fR] +- [\fB\-\-only\-keep\-debug\fR] +- [\fB\-\-strip\-dwo\fR] +- [\fB\-\-extract\-dwo\fR] +- [\fB\-\-extract\-symbol\fR] +- [\fB\-\-writable\-text\fR] +- [\fB\-\-readonly\-text\fR] +- [\fB\-\-pure\fR] +- [\fB\-\-impure\fR] +- [\fB\-\-file\-alignment=\fR\fInum\fR] +- [\fB\-\-heap=\fR\fIsize\fR] +- [\fB\-\-image\-base=\fR\fIaddress\fR] +- [\fB\-\-section\-alignment=\fR\fInum\fR] +- [\fB\-\-stack=\fR\fIsize\fR] +- [\fB\-\-subsystem=\fR\fIwhich\fR:\fImajor\fR.\fIminor\fR] +- [\fB\-\-compress\-debug\-sections\fR] +- [\fB\-\-decompress\-debug\-sections\fR] +- [\fB\-\-dwarf\-depth=\fR\fIn\fR] +- [\fB\-\-dwarf\-start=\fR\fIn\fR] +- [\fB\-v\fR|\fB\-\-verbose\fR] +- [\fB\-V\fR|\fB\-\-version\fR] +- [\fB\-\-help\fR] [\fB\-\-info\fR] +- \fIinfile\fR [\fIoutfile\fR] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-The \s-1GNU\s0 \fBobjcopy\fR utility copies the contents of an object +-file to another. \fBobjcopy\fR uses the \s-1GNU\s0 \s-1BFD\s0 Library to +-read and write the object files. It can write the destination object +-file in a format different from that of the source object file. The +-exact behavior of \fBobjcopy\fR is controlled by command-line options. +-Note that \fBobjcopy\fR should be able to copy a fully linked file +-between any two formats. However, copying a relocatable object file +-between any two formats may not work as expected. +-.PP +-\&\fBobjcopy\fR creates temporary files to do its translations and +-deletes them afterward. \fBobjcopy\fR uses \s-1BFD\s0 to do all its +-translation work; it has access to all the formats described in \s-1BFD\s0 +-and thus is able to recognize most formats without being told +-explicitly. +-.PP +-\&\fBobjcopy\fR can be used to generate S\-records by using an output +-target of \fBsrec\fR (e.g., use \fB\-O srec\fR). +-.PP +-\&\fBobjcopy\fR can be used to generate a raw binary file by using an +-output target of \fBbinary\fR (e.g., use \fB\-O binary\fR). When +-\&\fBobjcopy\fR generates a raw binary file, it will essentially produce +-a memory dump of the contents of the input object file. All symbols and +-relocation information will be discarded. The memory dump will start at +-the load address of the lowest section copied into the output file. +-.PP +-When generating an S\-record or a raw binary file, it may be helpful to +-use \fB\-S\fR to remove sections containing debugging information. In +-some cases \fB\-R\fR will be useful to remove sections which contain +-information that is not needed by the binary file. +-.PP +-Note\-\-\-\fBobjcopy\fR is not able to change the endianness of its input +-files. If the input format has an endianness (some formats do not), +-\&\fBobjcopy\fR can only copy the inputs into file formats that have the +-same endianness or which have no endianness (e.g., \fBsrec\fR). +-(However, see the \fB\-\-reverse\-bytes\fR option.) +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fIinfile\fR" 4 +-.IX Item "infile" +-.PD 0 +-.IP "\fIoutfile\fR" 4 +-.IX Item "outfile" +-.PD +-The input and output files, respectively. +-If you do not specify \fIoutfile\fR, \fBobjcopy\fR creates a +-temporary file and destructively renames the result with +-the name of \fIinfile\fR. +-.IP "\fB\-I\fR \fIbfdname\fR" 4 +-.IX Item "-I bfdname" +-.PD 0 +-.IP "\fB\-\-input\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--input-target=bfdname" +-.PD +-Consider the source file's object format to be \fIbfdname\fR, rather than +-attempting to deduce it. +-.IP "\fB\-O\fR \fIbfdname\fR" 4 +-.IX Item "-O bfdname" +-.PD 0 +-.IP "\fB\-\-output\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--output-target=bfdname" +-.PD +-Write the output file using the object format \fIbfdname\fR. +-.IP "\fB\-F\fR \fIbfdname\fR" 4 +-.IX Item "-F bfdname" +-.PD 0 +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-.PD +-Use \fIbfdname\fR as the object format for both the input and the output +-file; i.e., simply transfer data from source to destination with no +-translation. +-.IP "\fB\-B\fR \fIbfdarch\fR" 4 +-.IX Item "-B bfdarch" +-.PD 0 +-.IP "\fB\-\-binary\-architecture=\fR\fIbfdarch\fR" 4 +-.IX Item "--binary-architecture=bfdarch" +-.PD +-Useful when transforming a architecture-less input file into an object file. +-In this case the output architecture can be set to \fIbfdarch\fR. This +-option will be ignored if the input file has a known \fIbfdarch\fR. You +-can access this binary data inside a program by referencing the special +-symbols that are created by the conversion process. These symbols are +-called _binary_\fIobjfile\fR_start, _binary_\fIobjfile\fR_end and +-_binary_\fIobjfile\fR_size. e.g. you can transform a picture file into +-an object file and then access it in your code using these symbols. +-.IP "\fB\-j\fR \fIsectionpattern\fR" 4 +-.IX Item "-j sectionpattern" +-.PD 0 +-.IP "\fB\-\-only\-section=\fR\fIsectionpattern\fR" 4 +-.IX Item "--only-section=sectionpattern" +-.PD +-Copy only the indicated sections from the input file to the output file. +-This option may be given more than once. Note that using this option +-inappropriately may make the output file unusable. Wildcard +-characters are accepted in \fIsectionpattern\fR. +-.IP "\fB\-R\fR \fIsectionpattern\fR" 4 +-.IX Item "-R sectionpattern" +-.PD 0 +-.IP "\fB\-\-remove\-section=\fR\fIsectionpattern\fR" 4 +-.IX Item "--remove-section=sectionpattern" +-.PD +-Remove any section matching \fIsectionpattern\fR from the output file. +-This option may be given more than once. Note that using this option +-inappropriately may make the output file unusable. Wildcard +-characters are accepted in \fIsectionpattern\fR. Using both the +-\&\fB\-j\fR and \fB\-R\fR options together results in undefined +-behaviour. +-.IP "\fB\-S\fR" 4 +-.IX Item "-S" +-.PD 0 +-.IP "\fB\-\-strip\-all\fR" 4 +-.IX Item "--strip-all" +-.PD +-Do not copy relocation and symbol information from the source file. +-.IP "\fB\-g\fR" 4 +-.IX Item "-g" +-.PD 0 +-.IP "\fB\-\-strip\-debug\fR" 4 +-.IX Item "--strip-debug" +-.PD +-Do not copy debugging symbols or sections from the source file. +-.IP "\fB\-\-strip\-unneeded\fR" 4 +-.IX Item "--strip-unneeded" +-Strip all symbols that are not needed for relocation processing. +-.IP "\fB\-K\fR \fIsymbolname\fR" 4 +-.IX Item "-K symbolname" +-.PD 0 +-.IP "\fB\-\-keep\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--keep-symbol=symbolname" +-.PD +-When stripping symbols, keep symbol \fIsymbolname\fR even if it would +-normally be stripped. This option may be given more than once. +-.IP "\fB\-N\fR \fIsymbolname\fR" 4 +-.IX Item "-N symbolname" +-.PD 0 +-.IP "\fB\-\-strip\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--strip-symbol=symbolname" +-.PD +-Do not copy symbol \fIsymbolname\fR from the source file. This option +-may be given more than once. +-.IP "\fB\-\-strip\-unneeded\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--strip-unneeded-symbol=symbolname" +-Do not copy symbol \fIsymbolname\fR from the source file unless it is needed +-by a relocation. This option may be given more than once. +-.IP "\fB\-G\fR \fIsymbolname\fR" 4 +-.IX Item "-G symbolname" +-.PD 0 +-.IP "\fB\-\-keep\-global\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--keep-global-symbol=symbolname" +-.PD +-Keep only symbol \fIsymbolname\fR global. Make all other symbols local +-to the file, so that they are not visible externally. This option may +-be given more than once. +-.IP "\fB\-\-localize\-hidden\fR" 4 +-.IX Item "--localize-hidden" +-In an \s-1ELF\s0 object, mark all symbols that have hidden or internal visibility +-as local. This option applies on top of symbol-specific localization options +-such as \fB\-L\fR. +-.IP "\fB\-L\fR \fIsymbolname\fR" 4 +-.IX Item "-L symbolname" +-.PD 0 +-.IP "\fB\-\-localize\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--localize-symbol=symbolname" +-.PD +-Make symbol \fIsymbolname\fR local to the file, so that it is not +-visible externally. This option may be given more than once. +-.IP "\fB\-W\fR \fIsymbolname\fR" 4 +-.IX Item "-W symbolname" +-.PD 0 +-.IP "\fB\-\-weaken\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--weaken-symbol=symbolname" +-.PD +-Make symbol \fIsymbolname\fR weak. This option may be given more than once. +-.IP "\fB\-\-globalize\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--globalize-symbol=symbolname" +-Give symbol \fIsymbolname\fR global scoping so that it is visible +-outside of the file in which it is defined. This option may be given +-more than once. +-.IP "\fB\-w\fR" 4 +-.IX Item "-w" +-.PD 0 +-.IP "\fB\-\-wildcard\fR" 4 +-.IX Item "--wildcard" +-.PD +-Permit regular expressions in \fIsymbolname\fRs used in other command +-line options. The question mark (?), asterisk (*), backslash (\e) and +-square brackets ([]) operators can be used anywhere in the symbol +-name. If the first character of the symbol name is the exclamation +-point (!) then the sense of the switch is reversed for that symbol. +-For example: +-.Sp +-.Vb 1 +-\& \-w \-W !foo \-W fo* +-.Ve +-.Sp +-would cause objcopy to weaken all symbols that start with \*(L"fo\*(R" +-except for the symbol \*(L"foo\*(R". +-.IP "\fB\-x\fR" 4 +-.IX Item "-x" +-.PD 0 +-.IP "\fB\-\-discard\-all\fR" 4 +-.IX Item "--discard-all" +-.PD +-Do not copy non-global symbols from the source file. +-.IP "\fB\-X\fR" 4 +-.IX Item "-X" +-.PD 0 +-.IP "\fB\-\-discard\-locals\fR" 4 +-.IX Item "--discard-locals" +-.PD +-Do not copy compiler-generated local symbols. +-(These usually start with \fBL\fR or \fB.\fR.) +-.IP "\fB\-b\fR \fIbyte\fR" 4 +-.IX Item "-b byte" +-.PD 0 +-.IP "\fB\-\-byte=\fR\fIbyte\fR" 4 +-.IX Item "--byte=byte" +-.PD +-If interleaving has been enabled via the \fB\-\-interleave\fR option +-then start the range of bytes to keep at the \fIbyte\fRth byte. +-\&\fIbyte\fR can be in the range from 0 to \fIbreadth\fR\-1, where +-\&\fIbreadth\fR is the value given by the \fB\-\-interleave\fR option. +-.IP "\fB\-i [\fR\fIbreadth\fR\fB]\fR" 4 +-.IX Item "-i [breadth]" +-.PD 0 +-.IP "\fB\-\-interleave[=\fR\fIbreadth\fR\fB]\fR" 4 +-.IX Item "--interleave[=breadth]" +-.PD +-Only copy a range out of every \fIbreadth\fR bytes. (Header data is +-not affected). Select which byte in the range begins the copy with +-the \fB\-\-byte\fR option. Select the width of the range with the +-\&\fB\-\-interleave\-width\fR option. +-.Sp +-This option is useful for creating files to program \s-1ROM\s0. It is +-typically used with an \f(CW\*(C`srec\*(C'\fR output target. Note that +-\&\fBobjcopy\fR will complain if you do not specify the +-\&\fB\-\-byte\fR option as well. +-.Sp +-The default interleave breadth is 4, so with \fB\-\-byte\fR set to 0, +-\&\fBobjcopy\fR would copy the first byte out of every four bytes +-from the input to the output. +-.IP "\fB\-\-interleave\-width=\fR\fIwidth\fR" 4 +-.IX Item "--interleave-width=width" +-When used with the \fB\-\-interleave\fR option, copy \fIwidth\fR +-bytes at a time. The start of the range of bytes to be copied is set +-by the \fB\-\-byte\fR option, and the extent of the range is set with +-the \fB\-\-interleave\fR option. +-.Sp +-The default value for this option is 1. The value of \fIwidth\fR plus +-the \fIbyte\fR value set by the \fB\-\-byte\fR option must not exceed +-the interleave breadth set by the \fB\-\-interleave\fR option. +-.Sp +-This option can be used to create images for two 16\-bit flashes interleaved +-in a 32\-bit bus by passing \fB\-b 0 \-i 4 \-\-interleave\-width=2\fR +-and \fB\-b 2 \-i 4 \-\-interleave\-width=2\fR to two \fBobjcopy\fR +-commands. If the input was '12345678' then the outputs would be +-\&'1256' and '3478' respectively. +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-preserve\-dates\fR" 4 +-.IX Item "--preserve-dates" +-.PD +-Set the access and modification dates of the output file to be the same +-as those of the input file. +-.IP "\fB\-D\fR" 4 +-.IX Item "-D" +-.PD 0 +-.IP "\fB\-\-enable\-deterministic\-archives\fR" 4 +-.IX Item "--enable-deterministic-archives" +-.PD +-Operate in \fIdeterministic\fR mode. When copying archive members +-and writing the archive index, use zero for UIDs, GIDs, timestamps, +-and use consistent file modes for all files. +-.Sp +-If \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR, then this mode is on by default. +-It can be disabled with the \fB\-U\fR option, below. +-.IP "\fB\-U\fR" 4 +-.IX Item "-U" +-.PD 0 +-.IP "\fB\-\-disable\-deterministic\-archives\fR" 4 +-.IX Item "--disable-deterministic-archives" +-.PD +-Do \fInot\fR operate in \fIdeterministic\fR mode. This is the +-inverse of the \fB\-D\fR option, above: when copying archive members +-and writing the archive index, use their actual \s-1UID\s0, \s-1GID\s0, timestamp, +-and file mode values. +-.Sp +-This is the default unless \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR. +-.IP "\fB\-\-debugging\fR" 4 +-.IX Item "--debugging" +-Convert debugging information, if possible. This is not the default +-because only certain debugging formats are supported, and the +-conversion process can be time consuming. +-.IP "\fB\-\-gap\-fill\fR \fIval\fR" 4 +-.IX Item "--gap-fill val" +-Fill gaps between sections with \fIval\fR. This operation applies to +-the \fIload address\fR (\s-1LMA\s0) of the sections. It is done by increasing +-the size of the section with the lower address, and filling in the extra +-space created with \fIval\fR. +-.IP "\fB\-\-pad\-to\fR \fIaddress\fR" 4 +-.IX Item "--pad-to address" +-Pad the output file up to the load address \fIaddress\fR. This is +-done by increasing the size of the last section. The extra space is +-filled in with the value specified by \fB\-\-gap\-fill\fR (default zero). +-.IP "\fB\-\-set\-start\fR \fIval\fR" 4 +-.IX Item "--set-start val" +-Set the start address of the new file to \fIval\fR. Not all object file +-formats support setting the start address. +-.IP "\fB\-\-change\-start\fR \fIincr\fR" 4 +-.IX Item "--change-start incr" +-.PD 0 +-.IP "\fB\-\-adjust\-start\fR \fIincr\fR" 4 +-.IX Item "--adjust-start incr" +-.PD +-Change the start address by adding \fIincr\fR. Not all object file +-formats support setting the start address. +-.IP "\fB\-\-change\-addresses\fR \fIincr\fR" 4 +-.IX Item "--change-addresses incr" +-.PD 0 +-.IP "\fB\-\-adjust\-vma\fR \fIincr\fR" 4 +-.IX Item "--adjust-vma incr" +-.PD +-Change the \s-1VMA\s0 and \s-1LMA\s0 addresses of all sections, as well as the start +-address, by adding \fIincr\fR. Some object file formats do not permit +-section addresses to be changed arbitrarily. Note that this does not +-relocate the sections; if the program expects sections to be loaded at a +-certain address, and this option is used to change the sections such +-that they are loaded at a different address, the program may fail. +-.IP "\fB\-\-change\-section\-address\fR \fIsectionpattern\fR\fB{=,+,\-}\fR\fIval\fR" 4 +-.IX Item "--change-section-address sectionpattern{=,+,-}val" +-.PD 0 +-.IP "\fB\-\-adjust\-section\-vma\fR \fIsectionpattern\fR\fB{=,+,\-}\fR\fIval\fR" 4 +-.IX Item "--adjust-section-vma sectionpattern{=,+,-}val" +-.PD +-Set or change both the \s-1VMA\s0 address and the \s-1LMA\s0 address of any section +-matching \fIsectionpattern\fR. If \fB=\fR is used, the section +-address is set to \fIval\fR. Otherwise, \fIval\fR is added to or +-subtracted from the section address. See the comments under +-\&\fB\-\-change\-addresses\fR, above. If \fIsectionpattern\fR does not +-match any sections in the input file, a warning will be issued, unless +-\&\fB\-\-no\-change\-warnings\fR is used. +-.IP "\fB\-\-change\-section\-lma\fR \fIsectionpattern\fR\fB{=,+,\-}\fR\fIval\fR" 4 +-.IX Item "--change-section-lma sectionpattern{=,+,-}val" +-Set or change the \s-1LMA\s0 address of any sections matching +-\&\fIsectionpattern\fR. The \s-1LMA\s0 address is the address where the +-section will be loaded into memory at program load time. Normally +-this is the same as the \s-1VMA\s0 address, which is the address of the +-section at program run time, but on some systems, especially those +-where a program is held in \s-1ROM\s0, the two can be different. If \fB=\fR +-is used, the section address is set to \fIval\fR. Otherwise, +-\&\fIval\fR is added to or subtracted from the section address. See the +-comments under \fB\-\-change\-addresses\fR, above. If +-\&\fIsectionpattern\fR does not match any sections in the input file, a +-warning will be issued, unless \fB\-\-no\-change\-warnings\fR is used. +-.IP "\fB\-\-change\-section\-vma\fR \fIsectionpattern\fR\fB{=,+,\-}\fR\fIval\fR" 4 +-.IX Item "--change-section-vma sectionpattern{=,+,-}val" +-Set or change the \s-1VMA\s0 address of any section matching +-\&\fIsectionpattern\fR. The \s-1VMA\s0 address is the address where the +-section will be located once the program has started executing. +-Normally this is the same as the \s-1LMA\s0 address, which is the address +-where the section will be loaded into memory, but on some systems, +-especially those where a program is held in \s-1ROM\s0, the two can be +-different. If \fB=\fR is used, the section address is set to +-\&\fIval\fR. Otherwise, \fIval\fR is added to or subtracted from the +-section address. See the comments under \fB\-\-change\-addresses\fR, +-above. If \fIsectionpattern\fR does not match any sections in the +-input file, a warning will be issued, unless +-\&\fB\-\-no\-change\-warnings\fR is used. +-.IP "\fB\-\-change\-warnings\fR" 4 +-.IX Item "--change-warnings" +-.PD 0 +-.IP "\fB\-\-adjust\-warnings\fR" 4 +-.IX Item "--adjust-warnings" +-.PD +-If \fB\-\-change\-section\-address\fR or \fB\-\-change\-section\-lma\fR or +-\&\fB\-\-change\-section\-vma\fR is used, and the section pattern does not +-match any sections, issue a warning. This is the default. +-.IP "\fB\-\-no\-change\-warnings\fR" 4 +-.IX Item "--no-change-warnings" +-.PD 0 +-.IP "\fB\-\-no\-adjust\-warnings\fR" 4 +-.IX Item "--no-adjust-warnings" +-.PD +-Do not issue a warning if \fB\-\-change\-section\-address\fR or +-\&\fB\-\-adjust\-section\-lma\fR or \fB\-\-adjust\-section\-vma\fR is used, even +-if the section pattern does not match any sections. +-.IP "\fB\-\-set\-section\-flags\fR \fIsectionpattern\fR\fB=\fR\fIflags\fR" 4 +-.IX Item "--set-section-flags sectionpattern=flags" +-Set the flags for any sections matching \fIsectionpattern\fR. The +-\&\fIflags\fR argument is a comma separated string of flag names. The +-recognized names are \fBalloc\fR, \fBcontents\fR, \fBload\fR, +-\&\fBnoload\fR, \fBreadonly\fR, \fBcode\fR, \fBdata\fR, \fBrom\fR, +-\&\fBshare\fR, and \fBdebug\fR. You can set the \fBcontents\fR flag +-for a section which does not have contents, but it is not meaningful +-to clear the \fBcontents\fR flag of a section which does have +-contents\*(--just remove the section instead. Not all flags are +-meaningful for all object file formats. +-.IP "\fB\-\-add\-section\fR \fIsectionname\fR\fB=\fR\fIfilename\fR" 4 +-.IX Item "--add-section sectionname=filename" +-Add a new section named \fIsectionname\fR while copying the file. The +-contents of the new section are taken from the file \fIfilename\fR. The +-size of the section will be the size of the file. This option only +-works on file formats which can support sections with arbitrary names. +-.IP "\fB\-\-rename\-section\fR \fIoldname\fR\fB=\fR\fInewname\fR\fB[,\fR\fIflags\fR\fB]\fR" 4 +-.IX Item "--rename-section oldname=newname[,flags]" +-Rename a section from \fIoldname\fR to \fInewname\fR, optionally +-changing the section's flags to \fIflags\fR in the process. This has +-the advantage over usng a linker script to perform the rename in that +-the output stays as an object file and does not become a linked +-executable. +-.Sp +-This option is particularly helpful when the input format is binary, +-since this will always create a section called .data. If for example, +-you wanted instead to create a section called .rodata containing binary +-data you could use the following command line to achieve it: +-.Sp +-.Vb 3 +-\& objcopy \-I binary \-O \-B \e +-\& \-\-rename\-section .data=.rodata,alloc,load,readonly,data,contents \e +-\& +-.Ve +-.IP "\fB\-\-long\-section\-names {enable,disable,keep}\fR" 4 +-.IX Item "--long-section-names {enable,disable,keep}" +-Controls the handling of long section names when processing \f(CW\*(C`COFF\*(C'\fR +-and \f(CW\*(C`PE\-COFF\*(C'\fR object formats. The default behaviour, \fBkeep\fR, +-is to preserve long section names if any are present in the input file. +-The \fBenable\fR and \fBdisable\fR options forcibly enable or disable +-the use of long section names in the output object; when \fBdisable\fR +-is in effect, any long section names in the input object will be truncated. +-The \fBenable\fR option will only emit long section names if any are +-present in the inputs; this is mostly the same as \fBkeep\fR, but it +-is left undefined whether the \fBenable\fR option might force the +-creation of an empty string table in the output file. +-.IP "\fB\-\-change\-leading\-char\fR" 4 +-.IX Item "--change-leading-char" +-Some object file formats use special characters at the start of +-symbols. The most common such character is underscore, which compilers +-often add before every symbol. This option tells \fBobjcopy\fR to +-change the leading character of every symbol when it converts between +-object file formats. If the object file formats use the same leading +-character, this option has no effect. Otherwise, it will add a +-character, or remove a character, or change a character, as +-appropriate. +-.IP "\fB\-\-remove\-leading\-char\fR" 4 +-.IX Item "--remove-leading-char" +-If the first character of a global symbol is a special symbol leading +-character used by the object file format, remove the character. The +-most common symbol leading character is underscore. This option will +-remove a leading underscore from all global symbols. This can be useful +-if you want to link together objects of different file formats with +-different conventions for symbol names. This is different from +-\&\fB\-\-change\-leading\-char\fR because it always changes the symbol name +-when appropriate, regardless of the object file format of the output +-file. +-.IP "\fB\-\-reverse\-bytes=\fR\fInum\fR" 4 +-.IX Item "--reverse-bytes=num" +-Reverse the bytes in a section with output contents. A section length must +-be evenly divisible by the value given in order for the swap to be able to +-take place. Reversing takes place before the interleaving is performed. +-.Sp +-This option is used typically in generating \s-1ROM\s0 images for problematic +-target systems. For example, on some target boards, the 32\-bit words +-fetched from 8\-bit ROMs are re-assembled in little-endian byte order +-regardless of the \s-1CPU\s0 byte order. Depending on the programming model, the +-endianness of the \s-1ROM\s0 may need to be modified. +-.Sp +-Consider a simple file with a section containing the following eight +-bytes: \f(CW12345678\fR. +-.Sp +-Using \fB\-\-reverse\-bytes=2\fR for the above example, the bytes in the +-output file would be ordered \f(CW21436587\fR. +-.Sp +-Using \fB\-\-reverse\-bytes=4\fR for the above example, the bytes in the +-output file would be ordered \f(CW43218765\fR. +-.Sp +-By using \fB\-\-reverse\-bytes=2\fR for the above example, followed by +-\&\fB\-\-reverse\-bytes=4\fR on the output file, the bytes in the second +-output file would be ordered \f(CW34127856\fR. +-.IP "\fB\-\-srec\-len=\fR\fIival\fR" 4 +-.IX Item "--srec-len=ival" +-Meaningful only for srec output. Set the maximum length of the Srecords +-being produced to \fIival\fR. This length covers both address, data and +-crc fields. +-.IP "\fB\-\-srec\-forceS3\fR" 4 +-.IX Item "--srec-forceS3" +-Meaningful only for srec output. Avoid generation of S1/S2 records, +-creating S3\-only record format. +-.IP "\fB\-\-redefine\-sym\fR \fIold\fR\fB=\fR\fInew\fR" 4 +-.IX Item "--redefine-sym old=new" +-Change the name of a symbol \fIold\fR, to \fInew\fR. This can be useful +-when one is trying link two things together for which you have no +-source, and there are name collisions. +-.IP "\fB\-\-redefine\-syms=\fR\fIfilename\fR" 4 +-.IX Item "--redefine-syms=filename" +-Apply \fB\-\-redefine\-sym\fR to each symbol pair "\fIold\fR \fInew\fR" +-listed in the file \fIfilename\fR. \fIfilename\fR is simply a flat file, +-with one symbol pair per line. Line comments may be introduced by the hash +-character. This option may be given more than once. +-.IP "\fB\-\-weaken\fR" 4 +-.IX Item "--weaken" +-Change all global symbols in the file to be weak. This can be useful +-when building an object which will be linked against other objects using +-the \fB\-R\fR option to the linker. This option is only effective when +-using an object file format which supports weak symbols. +-.IP "\fB\-\-keep\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--keep-symbols=filename" +-Apply \fB\-\-keep\-symbol\fR option to each symbol listed in the file +-\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol +-name per line. Line comments may be introduced by the hash character. +-This option may be given more than once. +-.IP "\fB\-\-strip\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--strip-symbols=filename" +-Apply \fB\-\-strip\-symbol\fR option to each symbol listed in the file +-\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol +-name per line. Line comments may be introduced by the hash character. +-This option may be given more than once. +-.IP "\fB\-\-strip\-unneeded\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--strip-unneeded-symbols=filename" +-Apply \fB\-\-strip\-unneeded\-symbol\fR option to each symbol listed in +-the file \fIfilename\fR. \fIfilename\fR is simply a flat file, with one +-symbol name per line. Line comments may be introduced by the hash +-character. This option may be given more than once. +-.IP "\fB\-\-keep\-global\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--keep-global-symbols=filename" +-Apply \fB\-\-keep\-global\-symbol\fR option to each symbol listed in the +-file \fIfilename\fR. \fIfilename\fR is simply a flat file, with one +-symbol name per line. Line comments may be introduced by the hash +-character. This option may be given more than once. +-.IP "\fB\-\-localize\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--localize-symbols=filename" +-Apply \fB\-\-localize\-symbol\fR option to each symbol listed in the file +-\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol +-name per line. Line comments may be introduced by the hash character. +-This option may be given more than once. +-.IP "\fB\-\-globalize\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--globalize-symbols=filename" +-Apply \fB\-\-globalize\-symbol\fR option to each symbol listed in the file +-\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol +-name per line. Line comments may be introduced by the hash character. +-This option may be given more than once. +-.IP "\fB\-\-weaken\-symbols=\fR\fIfilename\fR" 4 +-.IX Item "--weaken-symbols=filename" +-Apply \fB\-\-weaken\-symbol\fR option to each symbol listed in the file +-\&\fIfilename\fR. \fIfilename\fR is simply a flat file, with one symbol +-name per line. Line comments may be introduced by the hash character. +-This option may be given more than once. +-.IP "\fB\-\-alt\-machine\-code=\fR\fIindex\fR" 4 +-.IX Item "--alt-machine-code=index" +-If the output architecture has alternate machine codes, use the +-\&\fIindex\fRth code instead of the default one. This is useful in case +-a machine is assigned an official code and the tool-chain adopts the +-new code, but other applications still depend on the original code +-being used. For \s-1ELF\s0 based architectures if the \fIindex\fR +-alternative does not exist then the value is treated as an absolute +-number to be stored in the e_machine field of the \s-1ELF\s0 header. +-.IP "\fB\-\-writable\-text\fR" 4 +-.IX Item "--writable-text" +-Mark the output text as writable. This option isn't meaningful for all +-object file formats. +-.IP "\fB\-\-readonly\-text\fR" 4 +-.IX Item "--readonly-text" +-Make the output text write protected. This option isn't meaningful for all +-object file formats. +-.IP "\fB\-\-pure\fR" 4 +-.IX Item "--pure" +-Mark the output file as demand paged. This option isn't meaningful for all +-object file formats. +-.IP "\fB\-\-impure\fR" 4 +-.IX Item "--impure" +-Mark the output file as impure. This option isn't meaningful for all +-object file formats. +-.IP "\fB\-\-prefix\-symbols=\fR\fIstring\fR" 4 +-.IX Item "--prefix-symbols=string" +-Prefix all symbols in the output file with \fIstring\fR. +-.IP "\fB\-\-prefix\-sections=\fR\fIstring\fR" 4 +-.IX Item "--prefix-sections=string" +-Prefix all section names in the output file with \fIstring\fR. +-.IP "\fB\-\-prefix\-alloc\-sections=\fR\fIstring\fR" 4 +-.IX Item "--prefix-alloc-sections=string" +-Prefix all the names of all allocated sections in the output file with +-\&\fIstring\fR. +-.IP "\fB\-\-add\-gnu\-debuglink=\fR\fIpath-to-file\fR" 4 +-.IX Item "--add-gnu-debuglink=path-to-file" +-Creates a .gnu_debuglink section which contains a reference to \fIpath-to-file\fR +-and adds it to the output file. +-.IP "\fB\-\-keep\-file\-symbols\fR" 4 +-.IX Item "--keep-file-symbols" +-When stripping a file, perhaps with \fB\-\-strip\-debug\fR or +-\&\fB\-\-strip\-unneeded\fR, retain any symbols specifying source file names, +-which would otherwise get stripped. +-.IP "\fB\-\-only\-keep\-debug\fR" 4 +-.IX Item "--only-keep-debug" +-Strip a file, removing contents of any sections that would not be +-stripped by \fB\-\-strip\-debug\fR and leaving the debugging sections +-intact. In \s-1ELF\s0 files, this preserves all note sections in the output. +-.Sp +-The intention is that this option will be used in conjunction with +-\&\fB\-\-add\-gnu\-debuglink\fR to create a two part executable. One a +-stripped binary which will occupy less space in \s-1RAM\s0 and in a +-distribution and the second a debugging information file which is only +-needed if debugging abilities are required. The suggested procedure +-to create these files is as follows: +-.RS 4 +-.IP "1." 4 +-.IX Item "1." +-\&\f(CW\*(C`foo\*(C'\fR then... +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-create a file containing the debugging info. +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-stripped executable. +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-to add a link to the debugging info into the stripped executable. +-.RE +-.RS 4 +-.Sp +-Note\-\-\-the choice of \f(CW\*(C`.dbg\*(C'\fR as an extension for the debug info +-file is arbitrary. Also the \f(CW\*(C`\-\-only\-keep\-debug\*(C'\fR step is +-optional. You could instead do this: +-.IP "1." 4 +-.IX Item "1." +-.PD 0 +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-.RE +-.RS 4 +-.PD +-.Sp +-i.e., the file pointed to by the \fB\-\-add\-gnu\-debuglink\fR can be the +-full executable. It does not have to be a file created by the +-\&\fB\-\-only\-keep\-debug\fR switch. +-.Sp +-Note\-\-\-this switch is only intended for use on fully linked files. It +-does not make sense to use it on object files where the debugging +-information may be incomplete. Besides the gnu_debuglink feature +-currently only supports the presence of one filename containing +-debugging information, not multiple filenames on a one-per-object-file +-basis. +-.RE +-.IP "\fB\-\-strip\-dwo\fR" 4 +-.IX Item "--strip-dwo" +-Remove the contents of all \s-1DWARF\s0 .dwo sections, leaving the +-remaining debugging sections and all symbols intact. +-This option is intended for use by the compiler as part of +-the \fB\-gsplit\-dwarf\fR option, which splits debug information +-between the .o file and a separate .dwo file. The compiler +-generates all debug information in the same file, then uses +-the \fB\-\-extract\-dwo\fR option to copy the .dwo sections to +-the .dwo file, then the \fB\-\-strip\-dwo\fR option to remove +-those sections from the original .o file. +-.IP "\fB\-\-extract\-dwo\fR" 4 +-.IX Item "--extract-dwo" +-Extract the contents of all \s-1DWARF\s0 .dwo sections. See the +-\&\fB\-\-strip\-dwo\fR option for more information. +-.IP "\fB\-\-file\-alignment\fR \fInum\fR" 4 +-.IX Item "--file-alignment num" +-Specify the file alignment. Sections in the file will always begin at +-file offsets which are multiples of this number. This defaults to +-512. +-[This option is specific to \s-1PE\s0 targets.] +-.IP "\fB\-\-heap\fR \fIreserve\fR" 4 +-.IX Item "--heap reserve" +-.PD 0 +-.IP "\fB\-\-heap\fR \fIreserve\fR\fB,\fR\fIcommit\fR" 4 +-.IX Item "--heap reserve,commit" +-.PD +-Specify the number of bytes of memory to reserve (and optionally commit) +-to be used as heap for this program. +-[This option is specific to \s-1PE\s0 targets.] +-.IP "\fB\-\-image\-base\fR \fIvalue\fR" 4 +-.IX Item "--image-base value" +-Use \fIvalue\fR as the base address of your program or dll. This is +-the lowest memory location that will be used when your program or dll +-is loaded. To reduce the need to relocate and improve performance of +-your dlls, each should have a unique base address and not overlap any +-other dlls. The default is 0x400000 for executables, and 0x10000000 +-for dlls. +-[This option is specific to \s-1PE\s0 targets.] +-.IP "\fB\-\-section\-alignment\fR \fInum\fR" 4 +-.IX Item "--section-alignment num" +-Sets the section alignment. Sections in memory will always begin at +-addresses which are a multiple of this number. Defaults to 0x1000. +-[This option is specific to \s-1PE\s0 targets.] +-.IP "\fB\-\-stack\fR \fIreserve\fR" 4 +-.IX Item "--stack reserve" +-.PD 0 +-.IP "\fB\-\-stack\fR \fIreserve\fR\fB,\fR\fIcommit\fR" 4 +-.IX Item "--stack reserve,commit" +-.PD +-Specify the number of bytes of memory to reserve (and optionally commit) +-to be used as stack for this program. +-[This option is specific to \s-1PE\s0 targets.] +-.IP "\fB\-\-subsystem\fR \fIwhich\fR" 4 +-.IX Item "--subsystem which" +-.PD 0 +-.IP "\fB\-\-subsystem\fR \fIwhich\fR\fB:\fR\fImajor\fR" 4 +-.IX Item "--subsystem which:major" +-.IP "\fB\-\-subsystem\fR \fIwhich\fR\fB:\fR\fImajor\fR\fB.\fR\fIminor\fR" 4 +-.IX Item "--subsystem which:major.minor" +-.PD +-Specifies the subsystem under which your program will execute. The +-legal values for \fIwhich\fR are \f(CW\*(C`native\*(C'\fR, \f(CW\*(C`windows\*(C'\fR, +-\&\f(CW\*(C`console\*(C'\fR, \f(CW\*(C`posix\*(C'\fR, \f(CW\*(C`efi\-app\*(C'\fR, \f(CW\*(C`efi\-bsd\*(C'\fR, +-\&\f(CW\*(C`efi\-rtd\*(C'\fR, \f(CW\*(C`sal\-rtd\*(C'\fR, and \f(CW\*(C`xbox\*(C'\fR. You may optionally set +-the subsystem version also. Numeric values are also accepted for +-\&\fIwhich\fR. +-[This option is specific to \s-1PE\s0 targets.] +-.IP "\fB\-\-extract\-symbol\fR" 4 +-.IX Item "--extract-symbol" +-Keep the file's section flags and symbols but remove all section data. +-Specifically, the option: +-.RS 4 +-.IP "*" 4 +-.IX Item "*" +-.PD 0 +-.IP "*" 4 +-.IX Item "*" +-.IP "*" 4 +-.IX Item "*" +-.RE +-.RS 4 +-.PD +-.Sp +-This option is used to build a \fI.sym\fR file for a VxWorks kernel. +-It can also be a useful way of reducing the size of a \fB\-\-just\-symbols\fR +-linker input file. +-.RE +-.IP "\fB\-\-compress\-debug\-sections\fR" 4 +-.IX Item "--compress-debug-sections" +-Compress \s-1DWARF\s0 debug sections using zlib. +-.IP "\fB\-\-decompress\-debug\-sections\fR" 4 +-.IX Item "--decompress-debug-sections" +-Decompress \s-1DWARF\s0 debug sections using zlib. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Show the version number of \fBobjcopy\fR. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-\-verbose\fR" 4 +-.IX Item "--verbose" +-.PD +-Verbose output: list all object files modified. In the case of +-archives, \fBobjcopy \-V\fR lists all members of the archive. +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-Show a summary of the options to \fBobjcopy\fR. +-.IP "\fB\-\-info\fR" 4 +-.IX Item "--info" +-Display a list showing all architectures and object formats available. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIld\fR\|(1), \fIobjdump\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/objdump.1 binutils-2.24/binutils/doc/objdump.1 +--- binutils-2.24.orig/binutils/doc/objdump.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/objdump.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,842 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "OBJDUMP 1" +-.TH OBJDUMP 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-objdump \- display information from object files. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-objdump [\fB\-a\fR|\fB\-\-archive\-headers\fR] +- [\fB\-b\fR \fIbfdname\fR|\fB\-\-target=\fR\fIbfdname\fR] +- [\fB\-C\fR|\fB\-\-demangle\fR[=\fIstyle\fR] ] +- [\fB\-d\fR|\fB\-\-disassemble\fR] +- [\fB\-D\fR|\fB\-\-disassemble\-all\fR] +- [\fB\-z\fR|\fB\-\-disassemble\-zeroes\fR] +- [\fB\-EB\fR|\fB\-EL\fR|\fB\-\-endian=\fR{big | little }] +- [\fB\-f\fR|\fB\-\-file\-headers\fR] +- [\fB\-F\fR|\fB\-\-file\-offsets\fR] +- [\fB\-\-file\-start\-context\fR] +- [\fB\-g\fR|\fB\-\-debugging\fR] +- [\fB\-e\fR|\fB\-\-debugging\-tags\fR] +- [\fB\-h\fR|\fB\-\-section\-headers\fR|\fB\-\-headers\fR] +- [\fB\-i\fR|\fB\-\-info\fR] +- [\fB\-j\fR \fIsection\fR|\fB\-\-section=\fR\fIsection\fR] +- [\fB\-l\fR|\fB\-\-line\-numbers\fR] +- [\fB\-S\fR|\fB\-\-source\fR] +- [\fB\-m\fR \fImachine\fR|\fB\-\-architecture=\fR\fImachine\fR] +- [\fB\-M\fR \fIoptions\fR|\fB\-\-disassembler\-options=\fR\fIoptions\fR] +- [\fB\-p\fR|\fB\-\-private\-headers\fR] +- [\fB\-P\fR \fIoptions\fR|\fB\-\-private=\fR\fIoptions\fR] +- [\fB\-r\fR|\fB\-\-reloc\fR] +- [\fB\-R\fR|\fB\-\-dynamic\-reloc\fR] +- [\fB\-s\fR|\fB\-\-full\-contents\fR] +- [\fB\-W[lLiaprmfFsoRt]\fR| +- \fB\-\-dwarf\fR[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] +- [\fB\-G\fR|\fB\-\-stabs\fR] +- [\fB\-t\fR|\fB\-\-syms\fR] +- [\fB\-T\fR|\fB\-\-dynamic\-syms\fR] +- [\fB\-x\fR|\fB\-\-all\-headers\fR] +- [\fB\-w\fR|\fB\-\-wide\fR] +- [\fB\-\-start\-address=\fR\fIaddress\fR] +- [\fB\-\-stop\-address=\fR\fIaddress\fR] +- [\fB\-\-prefix\-addresses\fR] +- [\fB\-\-[no\-]show\-raw\-insn\fR] +- [\fB\-\-adjust\-vma=\fR\fIoffset\fR] +- [\fB\-\-special\-syms\fR] +- [\fB\-\-prefix=\fR\fIprefix\fR] +- [\fB\-\-prefix\-strip=\fR\fIlevel\fR] +- [\fB\-\-insn\-width=\fR\fIwidth\fR] +- [\fB\-V\fR|\fB\-\-version\fR] +- [\fB\-H\fR|\fB\-\-help\fR] +- \fIobjfile\fR... +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBobjdump\fR displays information about one or more object files. +-The options control what particular information to display. This +-information is mostly useful to programmers who are working on the +-compilation tools, as opposed to programmers who just want their +-program to compile and work. +-.PP +-\&\fIobjfile\fR... are the object files to be examined. When you +-specify archives, \fBobjdump\fR shows information on each of the member +-object files. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The long and short forms of options, shown here as alternatives, are +-equivalent. At least one option from the list +-\&\fB\-a,\-d,\-D,\-e,\-f,\-g,\-G,\-h,\-H,\-p,\-P,\-r,\-R,\-s,\-S,\-t,\-T,\-V,\-x\fR must be given. +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-archive\-header\fR" 4 +-.IX Item "--archive-header" +-.PD +-If any of the \fIobjfile\fR files are archives, display the archive +-header information (in a format similar to \fBls \-l\fR). Besides the +-information you could list with \fBar tv\fR, \fBobjdump \-a\fR shows +-the object file format of each archive member. +-.IP "\fB\-\-adjust\-vma=\fR\fIoffset\fR" 4 +-.IX Item "--adjust-vma=offset" +-When dumping information, first add \fIoffset\fR to all the section +-addresses. This is useful if the section addresses do not correspond to +-the symbol table, which can happen when putting sections at particular +-addresses when using a format which can not represent section addresses, +-such as a.out. +-.IP "\fB\-b\fR \fIbfdname\fR" 4 +-.IX Item "-b bfdname" +-.PD 0 +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-.PD +-Specify that the object-code format for the object files is +-\&\fIbfdname\fR. This option may not be necessary; \fIobjdump\fR can +-automatically recognize many formats. +-.Sp +-For example, +-.Sp +-.Vb 1 +-\& objdump \-b oasys \-m vax \-h fu.o +-.Ve +-.Sp +-displays summary information from the section headers (\fB\-h\fR) of +-\&\fIfu.o\fR, which is explicitly identified (\fB\-m\fR) as a \s-1VAX\s0 object +-file in the format produced by Oasys compilers. You can list the +-formats available with the \fB\-i\fR option. +-.IP "\fB\-C\fR" 4 +-.IX Item "-C" +-.PD 0 +-.IP "\fB\-\-demangle[=\fR\fIstyle\fR\fB]\fR" 4 +-.IX Item "--demangle[=style]" +-.PD +-Decode (\fIdemangle\fR) low-level symbol names into user-level names. +-Besides removing any initial underscore prepended by the system, this +-makes \*(C+ function names readable. Different compilers have different +-mangling styles. The optional demangling style argument can be used to +-choose an appropriate demangling style for your compiler. +-.IP "\fB\-g\fR" 4 +-.IX Item "-g" +-.PD 0 +-.IP "\fB\-\-debugging\fR" 4 +-.IX Item "--debugging" +-.PD +-Display debugging information. This attempts to parse \s-1STABS\s0 and \s-1IEEE\s0 +-debugging format information stored in the file and print it out using +-a C like syntax. If neither of these formats are found this option +-falls back on the \fB\-W\fR option to print any \s-1DWARF\s0 information in +-the file. +-.IP "\fB\-e\fR" 4 +-.IX Item "-e" +-.PD 0 +-.IP "\fB\-\-debugging\-tags\fR" 4 +-.IX Item "--debugging-tags" +-.PD +-Like \fB\-g\fR, but the information is generated in a format compatible +-with ctags tool. +-.IP "\fB\-d\fR" 4 +-.IX Item "-d" +-.PD 0 +-.IP "\fB\-\-disassemble\fR" 4 +-.IX Item "--disassemble" +-.PD +-Display the assembler mnemonics for the machine instructions from +-\&\fIobjfile\fR. This option only disassembles those sections which are +-expected to contain instructions. +-.IP "\fB\-D\fR" 4 +-.IX Item "-D" +-.PD 0 +-.IP "\fB\-\-disassemble\-all\fR" 4 +-.IX Item "--disassemble-all" +-.PD +-Like \fB\-d\fR, but disassemble the contents of all sections, not just +-those expected to contain instructions. +-.Sp +-If the target is an \s-1ARM\s0 architecture this switch also has the effect +-of forcing the disassembler to decode pieces of data found in code +-sections as if they were instructions. +-.IP "\fB\-\-prefix\-addresses\fR" 4 +-.IX Item "--prefix-addresses" +-When disassembling, print the complete address on each line. This is +-the older disassembly format. +-.IP "\fB\-EB\fR" 4 +-.IX Item "-EB" +-.PD 0 +-.IP "\fB\-EL\fR" 4 +-.IX Item "-EL" +-.IP "\fB\-\-endian={big|little}\fR" 4 +-.IX Item "--endian={big|little}" +-.PD +-Specify the endianness of the object files. This only affects +-disassembly. This can be useful when disassembling a file format which +-does not describe endianness information, such as S\-records. +-.IP "\fB\-f\fR" 4 +-.IX Item "-f" +-.PD 0 +-.IP "\fB\-\-file\-headers\fR" 4 +-.IX Item "--file-headers" +-.PD +-Display summary information from the overall header of +-each of the \fIobjfile\fR files. +-.IP "\fB\-F\fR" 4 +-.IX Item "-F" +-.PD 0 +-.IP "\fB\-\-file\-offsets\fR" 4 +-.IX Item "--file-offsets" +-.PD +-When disassembling sections, whenever a symbol is displayed, also +-display the file offset of the region of data that is about to be +-dumped. If zeroes are being skipped, then when disassembly resumes, +-tell the user how many zeroes were skipped and the file offset of the +-location from where the disassembly resumes. When dumping sections, +-display the file offset of the location from where the dump starts. +-.IP "\fB\-\-file\-start\-context\fR" 4 +-.IX Item "--file-start-context" +-Specify that when displaying interlisted source code/disassembly +-(assumes \fB\-S\fR) from a file that has not yet been displayed, extend the +-context to the start of the file. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-section\-headers\fR" 4 +-.IX Item "--section-headers" +-.IP "\fB\-\-headers\fR" 4 +-.IX Item "--headers" +-.PD +-Display summary information from the section headers of the +-object file. +-.Sp +-File segments may be relocated to nonstandard addresses, for example by +-using the \fB\-Ttext\fR, \fB\-Tdata\fR, or \fB\-Tbss\fR options to +-\&\fBld\fR. However, some object file formats, such as a.out, do not +-store the starting address of the file segments. In those situations, +-although \fBld\fR relocates the sections correctly, using \fBobjdump +-\&\-h\fR to list the file section headers cannot show the correct addresses. +-Instead, it shows the usual addresses, which are implicit for the +-target. +-.IP "\fB\-H\fR" 4 +-.IX Item "-H" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Print a summary of the options to \fBobjdump\fR and exit. +-.IP "\fB\-i\fR" 4 +-.IX Item "-i" +-.PD 0 +-.IP "\fB\-\-info\fR" 4 +-.IX Item "--info" +-.PD +-Display a list showing all architectures and object formats available +-for specification with \fB\-b\fR or \fB\-m\fR. +-.IP "\fB\-j\fR \fIname\fR" 4 +-.IX Item "-j name" +-.PD 0 +-.IP "\fB\-\-section=\fR\fIname\fR" 4 +-.IX Item "--section=name" +-.PD +-Display information only for section \fIname\fR. +-.IP "\fB\-l\fR" 4 +-.IX Item "-l" +-.PD 0 +-.IP "\fB\-\-line\-numbers\fR" 4 +-.IX Item "--line-numbers" +-.PD +-Label the display (using debugging information) with the filename and +-source line numbers corresponding to the object code or relocs shown. +-Only useful with \fB\-d\fR, \fB\-D\fR, or \fB\-r\fR. +-.IP "\fB\-m\fR \fImachine\fR" 4 +-.IX Item "-m machine" +-.PD 0 +-.IP "\fB\-\-architecture=\fR\fImachine\fR" 4 +-.IX Item "--architecture=machine" +-.PD +-Specify the architecture to use when disassembling object files. This +-can be useful when disassembling object files which do not describe +-architecture information, such as S\-records. You can list the available +-architectures with the \fB\-i\fR option. +-.Sp +-If the target is an \s-1ARM\s0 architecture then this switch has an +-additional effect. It restricts the disassembly to only those +-instructions supported by the architecture specified by \fImachine\fR. +-If it is necessary to use this switch because the input file does not +-contain any architecture information, but it is also desired to +-disassemble all the instructions use \fB\-marm\fR. +-.IP "\fB\-M\fR \fIoptions\fR" 4 +-.IX Item "-M options" +-.PD 0 +-.IP "\fB\-\-disassembler\-options=\fR\fIoptions\fR" 4 +-.IX Item "--disassembler-options=options" +-.PD +-Pass target specific information to the disassembler. Only supported on +-some targets. If it is necessary to specify more than one +-disassembler option then multiple \fB\-M\fR options can be used or +-can be placed together into a comma separated list. +-.Sp +-If the target is an \s-1ARM\s0 architecture then this switch can be used to +-select which register name set is used during disassembler. Specifying +-\&\fB\-M reg-names-std\fR (the default) will select the register names as +-used in \s-1ARM\s0's instruction set documentation, but with register 13 called +-\&'sp', register 14 called 'lr' and register 15 called 'pc'. Specifying +-\&\fB\-M reg-names-apcs\fR will select the name set used by the \s-1ARM\s0 +-Procedure Call Standard, whilst specifying \fB\-M reg-names-raw\fR will +-just use \fBr\fR followed by the register number. +-.Sp +-There are also two variants on the \s-1APCS\s0 register naming scheme enabled +-by \fB\-M reg-names-atpcs\fR and \fB\-M reg-names-special-atpcs\fR which +-use the ARM/Thumb Procedure Call Standard naming conventions. (Either +-with the normal register names or the special register names). +-.Sp +-This option can also be used for \s-1ARM\s0 architectures to force the +-disassembler to interpret all instructions as Thumb instructions by +-using the switch \fB\-\-disassembler\-options=force\-thumb\fR. This can be +-useful when attempting to disassemble thumb code produced by other +-compilers. +-.Sp +-For the x86, some of the options duplicate functions of the \fB\-m\fR +-switch, but allow finer grained control. Multiple selections from the +-following may be specified as a comma separated string. +-\&\fBx86\-64\fR, \fBi386\fR and \fBi8086\fR select disassembly for +-the given architecture. \fBintel\fR and \fBatt\fR select between +-intel syntax mode and \s-1AT&T\s0 syntax mode. +-\&\fBintel-mnemonic\fR and \fBatt-mnemonic\fR select between +-intel mnemonic mode and \s-1AT&T\s0 mnemonic mode. \fBintel-mnemonic\fR +-implies \fBintel\fR and \fBatt-mnemonic\fR implies \fBatt\fR. +-\&\fBaddr64\fR, \fBaddr32\fR, +-\&\fBaddr16\fR, \fBdata32\fR and \fBdata16\fR specify the default +-address size and operand size. These four options will be overridden if +-\&\fBx86\-64\fR, \fBi386\fR or \fBi8086\fR appear later in the +-option string. Lastly, \fBsuffix\fR, when in \s-1AT&T\s0 mode, +-instructs the disassembler to print a mnemonic suffix even when the +-suffix could be inferred by the operands. +-.Sp +-For PowerPC, \fBbooke\fR controls the disassembly of BookE +-instructions. \fB32\fR and \fB64\fR select PowerPC and +-PowerPC64 disassembly, respectively. \fBe300\fR selects +-disassembly for the e300 family. \fB440\fR selects disassembly for +-the PowerPC 440. \fBppcps\fR selects disassembly for the paired +-single instructions of the \s-1PPC750CL\s0. +-.Sp +-For \s-1MIPS\s0, this option controls the printing of instruction mnemonic +-names and register names in disassembled instructions. Multiple +-selections from the following may be specified as a comma separated +-string, and invalid options are ignored: +-.RS 4 +-.ie n .IP """no\-aliases""" 4 +-.el .IP "\f(CWno\-aliases\fR" 4 +-.IX Item "no-aliases" +-Print the 'raw' instruction mnemonic instead of some pseudo +-instruction mnemonic. I.e., print 'daddu' or 'or' instead of 'move', +-\&'sll' instead of 'nop', etc. +-.ie n .IP """virt""" 4 +-.el .IP "\f(CWvirt\fR" 4 +-.IX Item "virt" +-Disassemble the virtualization \s-1ASE\s0 instructions. +-.ie n .IP """gpr\-names=\f(CIABI\f(CW""" 4 +-.el .IP "\f(CWgpr\-names=\f(CIABI\f(CW\fR" 4 +-.IX Item "gpr-names=ABI" +-Print \s-1GPR\s0 (general-purpose register) names as appropriate +-for the specified \s-1ABI\s0. By default, \s-1GPR\s0 names are selected according to +-the \s-1ABI\s0 of the binary being disassembled. +-.ie n .IP """fpr\-names=\f(CIABI\f(CW""" 4 +-.el .IP "\f(CWfpr\-names=\f(CIABI\f(CW\fR" 4 +-.IX Item "fpr-names=ABI" +-Print \s-1FPR\s0 (floating-point register) names as +-appropriate for the specified \s-1ABI\s0. By default, \s-1FPR\s0 numbers are printed +-rather than names. +-.ie n .IP """cp0\-names=\f(CIARCH\f(CW""" 4 +-.el .IP "\f(CWcp0\-names=\f(CIARCH\f(CW\fR" 4 +-.IX Item "cp0-names=ARCH" +-Print \s-1CP0\s0 (system control coprocessor; coprocessor 0) register names +-as appropriate for the \s-1CPU\s0 or architecture specified by +-\&\fI\s-1ARCH\s0\fR. By default, \s-1CP0\s0 register names are selected according to +-the architecture and \s-1CPU\s0 of the binary being disassembled. +-.ie n .IP """hwr\-names=\f(CIARCH\f(CW""" 4 +-.el .IP "\f(CWhwr\-names=\f(CIARCH\f(CW\fR" 4 +-.IX Item "hwr-names=ARCH" +-Print \s-1HWR\s0 (hardware register, used by the \f(CW\*(C`rdhwr\*(C'\fR instruction) names +-as appropriate for the \s-1CPU\s0 or architecture specified by +-\&\fI\s-1ARCH\s0\fR. By default, \s-1HWR\s0 names are selected according to +-the architecture and \s-1CPU\s0 of the binary being disassembled. +-.ie n .IP """reg\-names=\f(CIABI\f(CW""" 4 +-.el .IP "\f(CWreg\-names=\f(CIABI\f(CW\fR" 4 +-.IX Item "reg-names=ABI" +-Print \s-1GPR\s0 and \s-1FPR\s0 names as appropriate for the selected \s-1ABI\s0. +-.ie n .IP """reg\-names=\f(CIARCH\f(CW""" 4 +-.el .IP "\f(CWreg\-names=\f(CIARCH\f(CW\fR" 4 +-.IX Item "reg-names=ARCH" +-Print CPU-specific register names (\s-1CP0\s0 register and \s-1HWR\s0 names) +-as appropriate for the selected \s-1CPU\s0 or architecture. +-.RE +-.RS 4 +-.Sp +-For any of the options listed above, \fI\s-1ABI\s0\fR or +-\&\fI\s-1ARCH\s0\fR may be specified as \fBnumeric\fR to have numbers printed +-rather than names, for the selected types of registers. +-You can list the available values of \fI\s-1ABI\s0\fR and \fI\s-1ARCH\s0\fR using +-the \fB\-\-help\fR option. +-.Sp +-For \s-1VAX\s0, you can specify function entry addresses with \fB\-M +-entry:0xf00ba\fR. You can use this multiple times to properly +-disassemble \s-1VAX\s0 binary files that don't contain symbol tables (like +-\&\s-1ROM\s0 dumps). In these cases, the function entry mask would otherwise +-be decoded as \s-1VAX\s0 instructions, which would probably lead the rest +-of the function being wrongly disassembled. +-.RE +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-private\-headers\fR" 4 +-.IX Item "--private-headers" +-.PD +-Print information that is specific to the object file format. The exact +-information printed depends upon the object file format. For some +-object file formats, no additional information is printed. +-.IP "\fB\-P\fR \fIoptions\fR" 4 +-.IX Item "-P options" +-.PD 0 +-.IP "\fB\-\-private=\fR\fIoptions\fR" 4 +-.IX Item "--private=options" +-.PD +-Print information that is specific to the object file format. The +-argument \fIoptions\fR is a comma separated list that depends on the +-format (the lists of options is displayed with the help). +-.Sp +-For \s-1XCOFF\s0, the available options are: \fBheader\fR, \fBaout\fR, +-\&\fBsections\fR, \fBsyms\fR, \fBrelocs\fR, \fBlineno\fR, +-\&\fBloader\fR, \fBexcept\fR, \fBtypchk\fR, \fBtraceback\fR, +-\&\fBtoc\fR and \fBldinfo\fR. +-.IP "\fB\-r\fR" 4 +-.IX Item "-r" +-.PD 0 +-.IP "\fB\-\-reloc\fR" 4 +-.IX Item "--reloc" +-.PD +-Print the relocation entries of the file. If used with \fB\-d\fR or +-\&\fB\-D\fR, the relocations are printed interspersed with the +-disassembly. +-.IP "\fB\-R\fR" 4 +-.IX Item "-R" +-.PD 0 +-.IP "\fB\-\-dynamic\-reloc\fR" 4 +-.IX Item "--dynamic-reloc" +-.PD +-Print the dynamic relocation entries of the file. This is only +-meaningful for dynamic objects, such as certain types of shared +-libraries. As for \fB\-r\fR, if used with \fB\-d\fR or +-\&\fB\-D\fR, the relocations are printed interspersed with the +-disassembly. +-.IP "\fB\-s\fR" 4 +-.IX Item "-s" +-.PD 0 +-.IP "\fB\-\-full\-contents\fR" 4 +-.IX Item "--full-contents" +-.PD +-Display the full contents of any sections requested. By default all +-non-empty sections are displayed. +-.IP "\fB\-S\fR" 4 +-.IX Item "-S" +-.PD 0 +-.IP "\fB\-\-source\fR" 4 +-.IX Item "--source" +-.PD +-Display source code intermixed with disassembly, if possible. Implies +-\&\fB\-d\fR. +-.IP "\fB\-\-prefix=\fR\fIprefix\fR" 4 +-.IX Item "--prefix=prefix" +-Specify \fIprefix\fR to add to the absolute paths when used with +-\&\fB\-S\fR. +-.IP "\fB\-\-prefix\-strip=\fR\fIlevel\fR" 4 +-.IX Item "--prefix-strip=level" +-Indicate how many initial directory names to strip off the hardwired +-absolute paths. It has no effect without \fB\-\-prefix=\fR\fIprefix\fR. +-.IP "\fB\-\-show\-raw\-insn\fR" 4 +-.IX Item "--show-raw-insn" +-When disassembling instructions, print the instruction in hex as well as +-in symbolic form. This is the default except when +-\&\fB\-\-prefix\-addresses\fR is used. +-.IP "\fB\-\-no\-show\-raw\-insn\fR" 4 +-.IX Item "--no-show-raw-insn" +-When disassembling instructions, do not print the instruction bytes. +-This is the default when \fB\-\-prefix\-addresses\fR is used. +-.IP "\fB\-\-insn\-width=\fR\fIwidth\fR" 4 +-.IX Item "--insn-width=width" +-Display \fIwidth\fR bytes on a single line when disassembling +-instructions. +-.IP "\fB\-W[lLiaprmfFsoRt]\fR" 4 +-.IX Item "-W[lLiaprmfFsoRt]" +-.PD 0 +-.IP "\fB\-\-dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]\fR" 4 +-.IX Item "--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]" +-.PD +-Displays the contents of the debug sections in the file, if any are +-present. If one of the optional letters or words follows the switch +-then only data found in those specific sections will be dumped. +-.Sp +-Note that there is no single letter option to display the content of +-trace sections or .gdb_index. +-.Sp +-Note: the output from the \fB=info\fR option can also be affected +-by the options \fB\-\-dwarf\-depth\fR, the \fB\-\-dwarf\-start\fR and +-the \fB\-\-dwarf\-check\fR. +-.IP "\fB\-\-dwarf\-depth=\fR\fIn\fR" 4 +-.IX Item "--dwarf-depth=n" +-Limit the dump of the \f(CW\*(C`.debug_info\*(C'\fR section to \fIn\fR children. +-This is only useful with \fB\-\-dwarf=info\fR. The default is +-to print all DIEs; the special value 0 for \fIn\fR will also have this +-effect. +-.Sp +-With a non-zero value for \fIn\fR, DIEs at or deeper than \fIn\fR +-levels will not be printed. The range for \fIn\fR is zero-based. +-.IP "\fB\-\-dwarf\-start=\fR\fIn\fR" 4 +-.IX Item "--dwarf-start=n" +-Print only DIEs beginning with the \s-1DIE\s0 numbered \fIn\fR. This is only +-useful with \fB\-\-dwarf=info\fR. +-.Sp +-If specified, this option will suppress printing of any header +-information and all DIEs before the \s-1DIE\s0 numbered \fIn\fR. Only +-siblings and children of the specified \s-1DIE\s0 will be printed. +-.Sp +-This can be used in conjunction with \fB\-\-dwarf\-depth\fR. +-.IP "\fB\-\-dwarf\-check\fR" 4 +-.IX Item "--dwarf-check" +-Enable additional checks for consistency of Dwarf information. +-.IP "\fB\-G\fR" 4 +-.IX Item "-G" +-.PD 0 +-.IP "\fB\-\-stabs\fR" 4 +-.IX Item "--stabs" +-.PD +-Display the full contents of any sections requested. Display the +-contents of the .stab and .stab.index and .stab.excl sections from an +-\&\s-1ELF\s0 file. This is only useful on systems (such as Solaris 2.0) in which +-\&\f(CW\*(C`.stab\*(C'\fR debugging symbol-table entries are carried in an \s-1ELF\s0 +-section. In most other file formats, debugging symbol-table entries are +-interleaved with linkage symbols, and are visible in the \fB\-\-syms\fR +-output. +-.IP "\fB\-\-start\-address=\fR\fIaddress\fR" 4 +-.IX Item "--start-address=address" +-Start displaying data at the specified address. This affects the output +-of the \fB\-d\fR, \fB\-r\fR and \fB\-s\fR options. +-.IP "\fB\-\-stop\-address=\fR\fIaddress\fR" 4 +-.IX Item "--stop-address=address" +-Stop displaying data at the specified address. This affects the output +-of the \fB\-d\fR, \fB\-r\fR and \fB\-s\fR options. +-.IP "\fB\-t\fR" 4 +-.IX Item "-t" +-.PD 0 +-.IP "\fB\-\-syms\fR" 4 +-.IX Item "--syms" +-.PD +-Print the symbol table entries of the file. +-This is similar to the information provided by the \fBnm\fR program, +-although the display format is different. The format of the output +-depends upon the format of the file being dumped, but there are two main +-types. One looks like this: +-.Sp +-.Vb 2 +-\& [ 4](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss +-\& [ 6](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 fred +-.Ve +-.Sp +-where the number inside the square brackets is the number of the entry +-in the symbol table, the \fIsec\fR number is the section number, the +-\&\fIfl\fR value are the symbol's flag bits, the \fIty\fR number is the +-symbol's type, the \fIscl\fR number is the symbol's storage class and +-the \fInx\fR value is the number of auxilary entries associated with +-the symbol. The last two fields are the symbol's value and its name. +-.Sp +-The other common output format, usually seen with \s-1ELF\s0 based files, +-looks like this: +-.Sp +-.Vb 2 +-\& 00000000 l d .bss 00000000 .bss +-\& 00000000 g .text 00000000 fred +-.Ve +-.Sp +-Here the first number is the symbol's value (sometimes refered to as +-its address). The next field is actually a set of characters and +-spaces indicating the flag bits that are set on the symbol. These +-characters are described below. Next is the section with which the +-symbol is associated or \fI*ABS*\fR if the section is absolute (ie +-not connected with any section), or \fI*UND*\fR if the section is +-referenced in the file being dumped, but not defined there. +-.Sp +-After the section name comes another field, a number, which for common +-symbols is the alignment and for other symbol is the size. Finally +-the symbol's name is displayed. +-.Sp +-The flag characters are divided into 7 groups as follows: +-.RS 4 +-.ie n .IP """l""" 4 +-.el .IP "\f(CWl\fR" 4 +-.IX Item "l" +-.PD 0 +-.ie n .IP """g""" 4 +-.el .IP "\f(CWg\fR" 4 +-.IX Item "g" +-.ie n .IP """u""" 4 +-.el .IP "\f(CWu\fR" 4 +-.IX Item "u" +-.ie n .IP """!""" 4 +-.el .IP "\f(CW!\fR" 4 +-.IX Item "!" +-.PD +-The symbol is a local (l), global (g), unique global (u), neither +-global nor local (a space) or both global and local (!). A +-symbol can be neither local or global for a variety of reasons, e.g., +-because it is used for debugging, but it is probably an indication of +-a bug if it is ever both local and global. Unique global symbols are +-a \s-1GNU\s0 extension to the standard set of \s-1ELF\s0 symbol bindings. For such +-a symbol the dynamic linker will make sure that in the entire process +-there is just one symbol with this name and type in use. +-.ie n .IP """w""" 4 +-.el .IP "\f(CWw\fR" 4 +-.IX Item "w" +-The symbol is weak (w) or strong (a space). +-.ie n .IP """C""" 4 +-.el .IP "\f(CWC\fR" 4 +-.IX Item "C" +-The symbol denotes a constructor (C) or an ordinary symbol (a space). +-.ie n .IP """W""" 4 +-.el .IP "\f(CWW\fR" 4 +-.IX Item "W" +-The symbol is a warning (W) or a normal symbol (a space). A warning +-symbol's name is a message to be displayed if the symbol following the +-warning symbol is ever referenced. +-.ie n .IP """I""" 4 +-.el .IP "\f(CWI\fR" 4 +-.IX Item "I" +-.PD 0 +-.ie n .IP """i""" 4 +-.el .IP "\f(CWi\fR" 4 +-.IX Item "i" +-.PD +-The symbol is an indirect reference to another symbol (I), a function +-to be evaluated during reloc processing (i) or a normal symbol (a +-space). +-.ie n .IP """d""" 4 +-.el .IP "\f(CWd\fR" 4 +-.IX Item "d" +-.PD 0 +-.ie n .IP """D""" 4 +-.el .IP "\f(CWD\fR" 4 +-.IX Item "D" +-.PD +-The symbol is a debugging symbol (d) or a dynamic symbol (D) or a +-normal symbol (a space). +-.ie n .IP """F""" 4 +-.el .IP "\f(CWF\fR" 4 +-.IX Item "F" +-.PD 0 +-.ie n .IP """f""" 4 +-.el .IP "\f(CWf\fR" 4 +-.IX Item "f" +-.ie n .IP """O""" 4 +-.el .IP "\f(CWO\fR" 4 +-.IX Item "O" +-.PD +-The symbol is the name of a function (F) or a file (f) or an object +-(O) or just a normal symbol (a space). +-.RE +-.RS 4 +-.RE +-.IP "\fB\-T\fR" 4 +-.IX Item "-T" +-.PD 0 +-.IP "\fB\-\-dynamic\-syms\fR" 4 +-.IX Item "--dynamic-syms" +-.PD +-Print the dynamic symbol table entries of the file. This is only +-meaningful for dynamic objects, such as certain types of shared +-libraries. This is similar to the information provided by the \fBnm\fR +-program when given the \fB\-D\fR (\fB\-\-dynamic\fR) option. +-.IP "\fB\-\-special\-syms\fR" 4 +-.IX Item "--special-syms" +-When displaying symbols include those which the target considers to be +-special in some way and which would not normally be of interest to the +-user. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Print the version number of \fBobjdump\fR and exit. +-.IP "\fB\-x\fR" 4 +-.IX Item "-x" +-.PD 0 +-.IP "\fB\-\-all\-headers\fR" 4 +-.IX Item "--all-headers" +-.PD +-Display all available header information, including the symbol table and +-relocation entries. Using \fB\-x\fR is equivalent to specifying all of +-\&\fB\-a \-f \-h \-p \-r \-t\fR. +-.IP "\fB\-w\fR" 4 +-.IX Item "-w" +-.PD 0 +-.IP "\fB\-\-wide\fR" 4 +-.IX Item "--wide" +-.PD +-Format some lines for output devices that have more than 80 columns. +-Also do not truncate symbol names when they are displayed. +-.IP "\fB\-z\fR" 4 +-.IX Item "-z" +-.PD 0 +-.IP "\fB\-\-disassemble\-zeroes\fR" 4 +-.IX Item "--disassemble-zeroes" +-.PD +-Normally the disassembly output will skip blocks of zeroes. This +-option directs the disassembler to disassemble those blocks, just like +-any other data. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fInm\fR\|(1), \fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/ranlib.1 binutils-2.24/binutils/doc/ranlib.1 +--- binutils-2.24.orig/binutils/doc/ranlib.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/ranlib.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,218 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "RANLIB 1" +-.TH RANLIB 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-ranlib \- generate index to archive. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-ranlib [\fB\-\-plugin\fR \fIname\fR] [\fB\-DhHvVt\fR] \fIarchive\fR +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBranlib\fR generates an index to the contents of an archive and +-stores it in the archive. The index lists each symbol defined by a +-member of an archive that is a relocatable object file. +-.PP +-You may use \fBnm \-s\fR or \fBnm \-\-print\-armap\fR to list this index. +-.PP +-An archive with such an index speeds up linking to the library and +-allows routines in the library to call each other without regard to +-their placement in the archive. +-.PP +-The \s-1GNU\s0 \fBranlib\fR program is another form of \s-1GNU\s0 \fBar\fR; running +-\&\fBranlib\fR is completely equivalent to executing \fBar \-s\fR. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-H\fR" 4 +-.IX Item "-H" +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Show usage information for \fBranlib\fR. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Show the version number of \fBranlib\fR. +-.IP "\fB\-D\fR" 4 +-.IX Item "-D" +-Operate in \fIdeterministic\fR mode. The symbol map archive member's +-header will show zero for the \s-1UID\s0, \s-1GID\s0, and timestamp. When this +-option is used, multiple runs will produce identical output files. +-.Sp +-If \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR, then this mode is on by +-default. It can be disabled with the \fB\-U\fR option, described +-below. +-.IP "\fB\-t\fR" 4 +-.IX Item "-t" +-Update the timestamp of the symbol map of an archive. +-.IP "\fB\-U\fR" 4 +-.IX Item "-U" +-Do \fInot\fR operate in \fIdeterministic\fR mode. This is the +-inverse of the \fB\-D\fR option, above: the archive index will get +-actual \s-1UID\s0, \s-1GID\s0, timestamp, and file mode values. +-.Sp +-If \fIbinutils\fR was configured \fIwithout\fR +-\&\fB\-\-enable\-deterministic\-archives\fR, then this mode is on by +-default. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIar\fR\|(1), \fInm\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/readelf.1 binutils-2.24/binutils/doc/readelf.1 +--- binutils-2.24.orig/binutils/doc/readelf.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/readelf.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,448 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "READELF 1" +-.TH READELF 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-readelf \- Displays information about ELF files. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-readelf [\fB\-a\fR|\fB\-\-all\fR] +- [\fB\-h\fR|\fB\-\-file\-header\fR] +- [\fB\-l\fR|\fB\-\-program\-headers\fR|\fB\-\-segments\fR] +- [\fB\-S\fR|\fB\-\-section\-headers\fR|\fB\-\-sections\fR] +- [\fB\-g\fR|\fB\-\-section\-groups\fR] +- [\fB\-t\fR|\fB\-\-section\-details\fR] +- [\fB\-e\fR|\fB\-\-headers\fR] +- [\fB\-s\fR|\fB\-\-syms\fR|\fB\-\-symbols\fR] +- [\fB\-\-dyn\-syms\fR] +- [\fB\-n\fR|\fB\-\-notes\fR] +- [\fB\-r\fR|\fB\-\-relocs\fR] +- [\fB\-u\fR|\fB\-\-unwind\fR] +- [\fB\-d\fR|\fB\-\-dynamic\fR] +- [\fB\-V\fR|\fB\-\-version\-info\fR] +- [\fB\-A\fR|\fB\-\-arch\-specific\fR] +- [\fB\-D\fR|\fB\-\-use\-dynamic\fR] +- [\fB\-x\fR |\fB\-\-hex\-dump=\fR] +- [\fB\-p\fR |\fB\-\-string\-dump=\fR] +- [\fB\-R\fR |\fB\-\-relocated\-dump=\fR] +- [\fB\-c\fR|\fB\-\-archive\-index\fR] +- [\fB\-w[lLiaprmfFsoRt]\fR| +- \fB\-\-debug\-dump\fR[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]] +- [\fB\-\-dwarf\-depth=\fR\fIn\fR] +- [\fB\-\-dwarf\-start=\fR\fIn\fR] +- [\fB\-I\fR|\fB\-\-histogram\fR] +- [\fB\-v\fR|\fB\-\-version\fR] +- [\fB\-W\fR|\fB\-\-wide\fR] +- [\fB\-H\fR|\fB\-\-help\fR] +- \fIelffile\fR... +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBreadelf\fR displays information about one or more \s-1ELF\s0 format object +-files. The options control what particular information to display. +-.PP +-\&\fIelffile\fR... are the object files to be examined. 32\-bit and +-64\-bit \s-1ELF\s0 files are supported, as are archives containing \s-1ELF\s0 files. +-.PP +-This program performs a similar function to \fBobjdump\fR but it +-goes into more detail and it exists independently of the \s-1BFD\s0 +-library, so if there is a bug in \s-1BFD\s0 then readelf will not be +-affected. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The long and short forms of options, shown here as alternatives, are +-equivalent. At least one option besides \fB\-v\fR or \fB\-H\fR must be +-given. +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-all\fR" 4 +-.IX Item "--all" +-.PD +-Equivalent to specifying \fB\-\-file\-header\fR, +-\&\fB\-\-program\-headers\fR, \fB\-\-sections\fR, \fB\-\-symbols\fR, +-\&\fB\-\-relocs\fR, \fB\-\-dynamic\fR, \fB\-\-notes\fR and +-\&\fB\-\-version\-info\fR. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-file\-header\fR" 4 +-.IX Item "--file-header" +-.PD +-Displays the information contained in the \s-1ELF\s0 header at the start of the +-file. +-.IP "\fB\-l\fR" 4 +-.IX Item "-l" +-.PD 0 +-.IP "\fB\-\-program\-headers\fR" 4 +-.IX Item "--program-headers" +-.IP "\fB\-\-segments\fR" 4 +-.IX Item "--segments" +-.PD +-Displays the information contained in the file's segment headers, if it +-has any. +-.IP "\fB\-S\fR" 4 +-.IX Item "-S" +-.PD 0 +-.IP "\fB\-\-sections\fR" 4 +-.IX Item "--sections" +-.IP "\fB\-\-section\-headers\fR" 4 +-.IX Item "--section-headers" +-.PD +-Displays the information contained in the file's section headers, if it +-has any. +-.IP "\fB\-g\fR" 4 +-.IX Item "-g" +-.PD 0 +-.IP "\fB\-\-section\-groups\fR" 4 +-.IX Item "--section-groups" +-.PD +-Displays the information contained in the file's section groups, if it +-has any. +-.IP "\fB\-t\fR" 4 +-.IX Item "-t" +-.PD 0 +-.IP "\fB\-\-section\-details\fR" 4 +-.IX Item "--section-details" +-.PD +-Displays the detailed section information. Implies \fB\-S\fR. +-.IP "\fB\-s\fR" 4 +-.IX Item "-s" +-.PD 0 +-.IP "\fB\-\-symbols\fR" 4 +-.IX Item "--symbols" +-.IP "\fB\-\-syms\fR" 4 +-.IX Item "--syms" +-.PD +-Displays the entries in symbol table section of the file, if it has one. +-.IP "\fB\-\-dyn\-syms\fR" 4 +-.IX Item "--dyn-syms" +-Displays the entries in dynamic symbol table section of the file, if it +-has one. +-.IP "\fB\-e\fR" 4 +-.IX Item "-e" +-.PD 0 +-.IP "\fB\-\-headers\fR" 4 +-.IX Item "--headers" +-.PD +-Display all the headers in the file. Equivalent to \fB\-h \-l \-S\fR. +-.IP "\fB\-n\fR" 4 +-.IX Item "-n" +-.PD 0 +-.IP "\fB\-\-notes\fR" 4 +-.IX Item "--notes" +-.PD +-Displays the contents of the \s-1NOTE\s0 segments and/or sections, if any. +-.IP "\fB\-r\fR" 4 +-.IX Item "-r" +-.PD 0 +-.IP "\fB\-\-relocs\fR" 4 +-.IX Item "--relocs" +-.PD +-Displays the contents of the file's relocation section, if it has one. +-.IP "\fB\-u\fR" 4 +-.IX Item "-u" +-.PD 0 +-.IP "\fB\-\-unwind\fR" 4 +-.IX Item "--unwind" +-.PD +-Displays the contents of the file's unwind section, if it has one. Only +-the unwind sections for \s-1IA64\s0 \s-1ELF\s0 files, as well as \s-1ARM\s0 unwind tables +-(\f(CW\*(C`.ARM.exidx\*(C'\fR / \f(CW\*(C`.ARM.extab\*(C'\fR) are currently supported. +-.IP "\fB\-d\fR" 4 +-.IX Item "-d" +-.PD 0 +-.IP "\fB\-\-dynamic\fR" 4 +-.IX Item "--dynamic" +-.PD +-Displays the contents of the file's dynamic section, if it has one. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\-info\fR" 4 +-.IX Item "--version-info" +-.PD +-Displays the contents of the version sections in the file, it they +-exist. +-.IP "\fB\-A\fR" 4 +-.IX Item "-A" +-.PD 0 +-.IP "\fB\-\-arch\-specific\fR" 4 +-.IX Item "--arch-specific" +-.PD +-Displays architecture-specific information in the file, if there +-is any. +-.IP "\fB\-D\fR" 4 +-.IX Item "-D" +-.PD 0 +-.IP "\fB\-\-use\-dynamic\fR" 4 +-.IX Item "--use-dynamic" +-.PD +-When displaying symbols, this option makes \fBreadelf\fR use the +-symbol hash tables in the file's dynamic section, rather than the +-symbol table sections. +-.IP "\fB\-x \fR" 4 +-.IX Item "-x " +-.PD 0 +-.IP "\fB\-\-hex\-dump=\fR" 4 +-.IX Item "--hex-dump=" +-.PD +-Displays the contents of the indicated section as a hexadecimal bytes. +-A number identifies a particular section by index in the section table; +-any other string identifies all sections with that name in the object file. +-.IP "\fB\-R \fR" 4 +-.IX Item "-R " +-.PD 0 +-.IP "\fB\-\-relocated\-dump=\fR" 4 +-.IX Item "--relocated-dump=" +-.PD +-Displays the contents of the indicated section as a hexadecimal +-bytes. A number identifies a particular section by index in the +-section table; any other string identifies all sections with that name +-in the object file. The contents of the section will be relocated +-before they are displayed. +-.IP "\fB\-p \fR" 4 +-.IX Item "-p " +-.PD 0 +-.IP "\fB\-\-string\-dump=\fR" 4 +-.IX Item "--string-dump=" +-.PD +-Displays the contents of the indicated section as printable strings. +-A number identifies a particular section by index in the section table; +-any other string identifies all sections with that name in the object file. +-.IP "\fB\-c\fR" 4 +-.IX Item "-c" +-.PD 0 +-.IP "\fB\-\-archive\-index\fR" 4 +-.IX Item "--archive-index" +-.PD +-Displays the file symbol index information contained in the header part +-of binary archives. Performs the same function as the \fBt\fR +-command to \fBar\fR, but without using the \s-1BFD\s0 library. +-.IP "\fB\-w[lLiaprmfFsoRt]\fR" 4 +-.IX Item "-w[lLiaprmfFsoRt]" +-.PD 0 +-.IP "\fB\-\-debug\-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames\-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]\fR" 4 +-.IX Item "--debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index]" +-.PD +-Displays the contents of the debug sections in the file, if any are +-present. If one of the optional letters or words follows the switch +-then only data found in those specific sections will be dumped. +-.Sp +-Note that there is no single letter option to display the content of +-trace sections or .gdb_index. +-.Sp +-Note: the \fB=decodedline\fR option will display the interpreted +-contents of a .debug_line section whereas the \fB=rawline\fR option +-dumps the contents in a raw format. +-.Sp +-Note: the \fB=frames\-interp\fR option will display the interpreted +-contents of a .debug_frame section whereas the \fB=frames\fR option +-dumps the contents in a raw format. +-.Sp +-Note: the output from the \fB=info\fR option can also be affected +-by the options \fB\-\-dwarf\-depth\fR and \fB\-\-dwarf\-start\fR. +-.IP "\fB\-\-dwarf\-depth=\fR\fIn\fR" 4 +-.IX Item "--dwarf-depth=n" +-Limit the dump of the \f(CW\*(C`.debug_info\*(C'\fR section to \fIn\fR children. +-This is only useful with \fB\-\-debug\-dump=info\fR. The default is +-to print all DIEs; the special value 0 for \fIn\fR will also have this +-effect. +-.Sp +-With a non-zero value for \fIn\fR, DIEs at or deeper than \fIn\fR +-levels will not be printed. The range for \fIn\fR is zero-based. +-.IP "\fB\-\-dwarf\-start=\fR\fIn\fR" 4 +-.IX Item "--dwarf-start=n" +-Print only DIEs beginning with the \s-1DIE\s0 numbered \fIn\fR. This is only +-useful with \fB\-\-debug\-dump=info\fR. +-.Sp +-If specified, this option will suppress printing of any header +-information and all DIEs before the \s-1DIE\s0 numbered \fIn\fR. Only +-siblings and children of the specified \s-1DIE\s0 will be printed. +-.Sp +-This can be used in conjunction with \fB\-\-dwarf\-depth\fR. +-.IP "\fB\-I\fR" 4 +-.IX Item "-I" +-.PD 0 +-.IP "\fB\-\-histogram\fR" 4 +-.IX Item "--histogram" +-.PD +-Display a histogram of bucket list lengths when displaying the contents +-of the symbol tables. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Display the version number of readelf. +-.IP "\fB\-W\fR" 4 +-.IX Item "-W" +-.PD 0 +-.IP "\fB\-\-wide\fR" 4 +-.IX Item "--wide" +-.PD +-Don't break output lines to fit into 80 columns. By default +-\&\fBreadelf\fR breaks section header and segment listing lines for +-64\-bit \s-1ELF\s0 files, so that they fit into 80 columns. This option causes +-\&\fBreadelf\fR to print each section header resp. each segment one a +-single line, which is far more readable on terminals wider than 80 columns. +-.IP "\fB\-H\fR" 4 +-.IX Item "-H" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Display the command line options understood by \fBreadelf\fR. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIobjdump\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/size.1 binutils-2.24/binutils/doc/size.1 +--- binutils-2.24.orig/binutils/doc/size.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/size.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,266 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "SIZE 1" +-.TH SIZE 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-size \- list section sizes and total size. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-size [\fB\-A\fR|\fB\-B\fR|\fB\-\-format=\fR\fIcompatibility\fR] +- [\fB\-\-help\fR] +- [\fB\-d\fR|\fB\-o\fR|\fB\-x\fR|\fB\-\-radix=\fR\fInumber\fR] +- [\fB\-\-common\fR] +- [\fB\-t\fR|\fB\-\-totals\fR] +- [\fB\-\-target=\fR\fIbfdname\fR] [\fB\-V\fR|\fB\-\-version\fR] +- [\fIobjfile\fR...] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-The \s-1GNU\s0 \fBsize\fR utility lists the section sizes\-\-\-and the total +-size\-\-\-for each of the object or archive files \fIobjfile\fR in its +-argument list. By default, one line of output is generated for each +-object file or each module in an archive. +-.PP +-\&\fIobjfile\fR... are the object files to be examined. +-If none are specified, the file \f(CW\*(C`a.out\*(C'\fR will be used. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-The command line options have the following meanings: +-.IP "\fB\-A\fR" 4 +-.IX Item "-A" +-.PD 0 +-.IP "\fB\-B\fR" 4 +-.IX Item "-B" +-.IP "\fB\-\-format=\fR\fIcompatibility\fR" 4 +-.IX Item "--format=compatibility" +-.PD +-Using one of these options, you can choose whether the output from \s-1GNU\s0 +-\&\fBsize\fR resembles output from System V \fBsize\fR (using \fB\-A\fR, +-or \fB\-\-format=sysv\fR), or Berkeley \fBsize\fR (using \fB\-B\fR, or +-\&\fB\-\-format=berkeley\fR). The default is the one-line format similar to +-Berkeley's. +-.Sp +-Here is an example of the Berkeley (default) format of output from +-\&\fBsize\fR: +-.Sp +-.Vb 4 +-\& $ size \-\-format=Berkeley ranlib size +-\& text data bss dec hex filename +-\& 294880 81920 11592 388392 5ed28 ranlib +-\& 294880 81920 11888 388688 5ee50 size +-.Ve +-.Sp +-This is the same data, but displayed closer to System V conventions: +-.Sp +-.Vb 7 +-\& $ size \-\-format=SysV ranlib size +-\& ranlib : +-\& section size addr +-\& .text 294880 8192 +-\& .data 81920 303104 +-\& .bss 11592 385024 +-\& Total 388392 +-\& +-\& +-\& size : +-\& section size addr +-\& .text 294880 8192 +-\& .data 81920 303104 +-\& .bss 11888 385024 +-\& Total 388688 +-.Ve +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-Show a summary of acceptable arguments and options. +-.IP "\fB\-d\fR" 4 +-.IX Item "-d" +-.PD 0 +-.IP "\fB\-o\fR" 4 +-.IX Item "-o" +-.IP "\fB\-x\fR" 4 +-.IX Item "-x" +-.IP "\fB\-\-radix=\fR\fInumber\fR" 4 +-.IX Item "--radix=number" +-.PD +-Using one of these options, you can control whether the size of each +-section is given in decimal (\fB\-d\fR, or \fB\-\-radix=10\fR); octal +-(\fB\-o\fR, or \fB\-\-radix=8\fR); or hexadecimal (\fB\-x\fR, or +-\&\fB\-\-radix=16\fR). In \fB\-\-radix=\fR\fInumber\fR, only the three +-values (8, 10, 16) are supported. The total size is always given in two +-radices; decimal and hexadecimal for \fB\-d\fR or \fB\-x\fR output, or +-octal and hexadecimal if you're using \fB\-o\fR. +-.IP "\fB\-\-common\fR" 4 +-.IX Item "--common" +-Print total size of common symbols in each file. When using Berkeley +-format these are included in the bss size. +-.IP "\fB\-t\fR" 4 +-.IX Item "-t" +-.PD 0 +-.IP "\fB\-\-totals\fR" 4 +-.IX Item "--totals" +-.PD +-Show totals of all objects listed (Berkeley format listing mode only). +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-Specify that the object-code format for \fIobjfile\fR is +-\&\fIbfdname\fR. This option may not be necessary; \fBsize\fR can +-automatically recognize many formats. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Display the version number of \fBsize\fR. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIar\fR\|(1), \fIobjdump\fR\|(1), \fIreadelf\fR\|(1), and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/strings.1 binutils-2.24/binutils/doc/strings.1 +--- binutils-2.24.orig/binutils/doc/strings.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/strings.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,255 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "STRINGS 1" +-.TH STRINGS 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-strings \- print the strings of printable characters in files. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-strings [\fB\-afovV\fR] [\fB\-\fR\fImin-len\fR] +- [\fB\-n\fR \fImin-len\fR] [\fB\-\-bytes=\fR\fImin-len\fR] +- [\fB\-t\fR \fIradix\fR] [\fB\-\-radix=\fR\fIradix\fR] +- [\fB\-e\fR \fIencoding\fR] [\fB\-\-encoding=\fR\fIencoding\fR] +- [\fB\-\fR] [\fB\-\-all\fR] [\fB\-\-print\-file\-name\fR] +- [\fB\-T\fR \fIbfdname\fR] [\fB\-\-target=\fR\fIbfdname\fR] +- [\fB\-\-help\fR] [\fB\-\-version\fR] \fIfile\fR... +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-For each \fIfile\fR given, \s-1GNU\s0 \fBstrings\fR prints the printable +-character sequences that are at least 4 characters long (or the number +-given with the options below) and are followed by an unprintable +-character. By default, it only prints the strings from the initialized +-and loaded sections of object files; for other types of files, it prints +-the strings from the whole file. +-.PP +-\&\fBstrings\fR is mainly useful for determining the contents of non-text +-files. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-all\fR" 4 +-.IX Item "--all" +-.IP "\fB\-\fR" 4 +-.IX Item "-" +-.PD +-Do not scan only the initialized and loaded sections of object files; +-scan the whole files. +-.IP "\fB\-f\fR" 4 +-.IX Item "-f" +-.PD 0 +-.IP "\fB\-\-print\-file\-name\fR" 4 +-.IX Item "--print-file-name" +-.PD +-Print the name of the file before each string. +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-Print a summary of the program usage on the standard output and exit. +-.IP "\fB\-\fR\fImin-len\fR" 4 +-.IX Item "-min-len" +-.PD 0 +-.IP "\fB\-n\fR \fImin-len\fR" 4 +-.IX Item "-n min-len" +-.IP "\fB\-\-bytes=\fR\fImin-len\fR" 4 +-.IX Item "--bytes=min-len" +-.PD +-Print sequences of characters that are at least \fImin-len\fR characters +-long, instead of the default 4. +-.IP "\fB\-o\fR" 4 +-.IX Item "-o" +-Like \fB\-t o\fR. Some other versions of \fBstrings\fR have \fB\-o\fR +-act like \fB\-t d\fR instead. Since we can not be compatible with both +-ways, we simply chose one. +-.IP "\fB\-t\fR \fIradix\fR" 4 +-.IX Item "-t radix" +-.PD 0 +-.IP "\fB\-\-radix=\fR\fIradix\fR" 4 +-.IX Item "--radix=radix" +-.PD +-Print the offset within the file before each string. The single +-character argument specifies the radix of the offset\-\-\-\fBo\fR for +-octal, \fBx\fR for hexadecimal, or \fBd\fR for decimal. +-.IP "\fB\-e\fR \fIencoding\fR" 4 +-.IX Item "-e encoding" +-.PD 0 +-.IP "\fB\-\-encoding=\fR\fIencoding\fR" 4 +-.IX Item "--encoding=encoding" +-.PD +-Select the character encoding of the strings that are to be found. +-Possible values for \fIencoding\fR are: \fBs\fR = single\-7\-bit\-byte +-characters (\s-1ASCII\s0, \s-1ISO\s0 8859, etc., default), \fBS\fR = +-single\-8\-bit\-byte characters, \fBb\fR = 16\-bit bigendian, \fBl\fR = +-16\-bit littleendian, \fBB\fR = 32\-bit bigendian, \fBL\fR = 32\-bit +-littleendian. Useful for finding wide character strings. (\fBl\fR +-and \fBb\fR apply to, for example, Unicode \s-1UTF\-16/UCS\-2\s0 encodings). +-.IP "\fB\-T\fR \fIbfdname\fR" 4 +-.IX Item "-T bfdname" +-.PD 0 +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-.PD +-Specify an object code format other than your system's default format. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Print the program version number on the standard output and exit. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-\&\fIar\fR\|(1), \fInm\fR\|(1), \fIobjdump\fR\|(1), \fIranlib\fR\|(1), \fIreadelf\fR\|(1) +-and the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/strip.1 binutils-2.24/binutils/doc/strip.1 +--- binutils-2.24.orig/binutils/doc/strip.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/strip.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,427 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "STRIP 1" +-.TH STRIP 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-strip \- Discard symbols from object files. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-strip [\fB\-F\fR \fIbfdname\fR |\fB\-\-target=\fR\fIbfdname\fR] +- [\fB\-I\fR \fIbfdname\fR |\fB\-\-input\-target=\fR\fIbfdname\fR] +- [\fB\-O\fR \fIbfdname\fR |\fB\-\-output\-target=\fR\fIbfdname\fR] +- [\fB\-s\fR|\fB\-\-strip\-all\fR] +- [\fB\-S\fR|\fB\-g\fR|\fB\-d\fR|\fB\-\-strip\-debug\fR] +- [\fB\-\-strip\-dwo\fR] +- [\fB\-K\fR \fIsymbolname\fR |\fB\-\-keep\-symbol=\fR\fIsymbolname\fR] +- [\fB\-N\fR \fIsymbolname\fR |\fB\-\-strip\-symbol=\fR\fIsymbolname\fR] +- [\fB\-w\fR|\fB\-\-wildcard\fR] +- [\fB\-x\fR|\fB\-\-discard\-all\fR] [\fB\-X\fR |\fB\-\-discard\-locals\fR] +- [\fB\-R\fR \fIsectionname\fR |\fB\-\-remove\-section=\fR\fIsectionname\fR] +- [\fB\-o\fR \fIfile\fR] [\fB\-p\fR|\fB\-\-preserve\-dates\fR] +- [\fB\-D\fR|\fB\-\-enable\-deterministic\-archives\fR] +- [\fB\-U\fR|\fB\-\-disable\-deterministic\-archives\fR] +- [\fB\-\-keep\-file\-symbols\fR] +- [\fB\-\-only\-keep\-debug\fR] +- [\fB\-v\fR |\fB\-\-verbose\fR] [\fB\-V\fR|\fB\-\-version\fR] +- [\fB\-\-help\fR] [\fB\-\-info\fR] +- \fIobjfile\fR... +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\s-1GNU\s0 \fBstrip\fR discards all symbols from object files +-\&\fIobjfile\fR. The list of object files may include archives. +-At least one object file must be given. +-.PP +-\&\fBstrip\fR modifies the files named in its argument, +-rather than writing modified copies under different names. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-F\fR \fIbfdname\fR" 4 +-.IX Item "-F bfdname" +-.PD 0 +-.IP "\fB\-\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--target=bfdname" +-.PD +-Treat the original \fIobjfile\fR as a file with the object +-code format \fIbfdname\fR, and rewrite it in the same format. +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-Show a summary of the options to \fBstrip\fR and exit. +-.IP "\fB\-\-info\fR" 4 +-.IX Item "--info" +-Display a list showing all architectures and object formats available. +-.IP "\fB\-I\fR \fIbfdname\fR" 4 +-.IX Item "-I bfdname" +-.PD 0 +-.IP "\fB\-\-input\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--input-target=bfdname" +-.PD +-Treat the original \fIobjfile\fR as a file with the object +-code format \fIbfdname\fR. +-.IP "\fB\-O\fR \fIbfdname\fR" 4 +-.IX Item "-O bfdname" +-.PD 0 +-.IP "\fB\-\-output\-target=\fR\fIbfdname\fR" 4 +-.IX Item "--output-target=bfdname" +-.PD +-Replace \fIobjfile\fR with a file in the output format \fIbfdname\fR. +-.IP "\fB\-R\fR \fIsectionname\fR" 4 +-.IX Item "-R sectionname" +-.PD 0 +-.IP "\fB\-\-remove\-section=\fR\fIsectionname\fR" 4 +-.IX Item "--remove-section=sectionname" +-.PD +-Remove any section named \fIsectionname\fR from the output file. This +-option may be given more than once. Note that using this option +-inappropriately may make the output file unusable. The wildcard +-character \fB*\fR may be given at the end of \fIsectionname\fR. If +-so, then any section starting with \fIsectionname\fR will be removed. +-.IP "\fB\-s\fR" 4 +-.IX Item "-s" +-.PD 0 +-.IP "\fB\-\-strip\-all\fR" 4 +-.IX Item "--strip-all" +-.PD +-Remove all symbols. +-.IP "\fB\-g\fR" 4 +-.IX Item "-g" +-.PD 0 +-.IP "\fB\-S\fR" 4 +-.IX Item "-S" +-.IP "\fB\-d\fR" 4 +-.IX Item "-d" +-.IP "\fB\-\-strip\-debug\fR" 4 +-.IX Item "--strip-debug" +-.PD +-Remove debugging symbols only. +-.IP "\fB\-\-strip\-dwo\fR" 4 +-.IX Item "--strip-dwo" +-Remove the contents of all \s-1DWARF\s0 .dwo sections, leaving the +-remaining debugging sections and all symbols intact. +-See the description of this option in the \fBobjcopy\fR section +-for more information. +-.IP "\fB\-\-strip\-unneeded\fR" 4 +-.IX Item "--strip-unneeded" +-Remove all symbols that are not needed for relocation processing. +-.IP "\fB\-K\fR \fIsymbolname\fR" 4 +-.IX Item "-K symbolname" +-.PD 0 +-.IP "\fB\-\-keep\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--keep-symbol=symbolname" +-.PD +-When stripping symbols, keep symbol \fIsymbolname\fR even if it would +-normally be stripped. This option may be given more than once. +-.IP "\fB\-N\fR \fIsymbolname\fR" 4 +-.IX Item "-N symbolname" +-.PD 0 +-.IP "\fB\-\-strip\-symbol=\fR\fIsymbolname\fR" 4 +-.IX Item "--strip-symbol=symbolname" +-.PD +-Remove symbol \fIsymbolname\fR from the source file. This option may be +-given more than once, and may be combined with strip options other than +-\&\fB\-K\fR. +-.IP "\fB\-o\fR \fIfile\fR" 4 +-.IX Item "-o file" +-Put the stripped output in \fIfile\fR, rather than replacing the +-existing file. When this argument is used, only one \fIobjfile\fR +-argument may be specified. +-.IP "\fB\-p\fR" 4 +-.IX Item "-p" +-.PD 0 +-.IP "\fB\-\-preserve\-dates\fR" 4 +-.IX Item "--preserve-dates" +-.PD +-Preserve the access and modification dates of the file. +-.IP "\fB\-D\fR" 4 +-.IX Item "-D" +-.PD 0 +-.IP "\fB\-\-enable\-deterministic\-archives\fR" 4 +-.IX Item "--enable-deterministic-archives" +-.PD +-Operate in \fIdeterministic\fR mode. When copying archive members +-and writing the archive index, use zero for UIDs, GIDs, timestamps, +-and use consistent file modes for all files. +-.Sp +-If \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR, then this mode is on by default. +-It can be disabled with the \fB\-U\fR option, below. +-.IP "\fB\-U\fR" 4 +-.IX Item "-U" +-.PD 0 +-.IP "\fB\-\-disable\-deterministic\-archives\fR" 4 +-.IX Item "--disable-deterministic-archives" +-.PD +-Do \fInot\fR operate in \fIdeterministic\fR mode. This is the +-inverse of the \fB\-D\fR option, above: when copying archive members +-and writing the archive index, use their actual \s-1UID\s0, \s-1GID\s0, timestamp, +-and file mode values. +-.Sp +-This is the default unless \fIbinutils\fR was configured with +-\&\fB\-\-enable\-deterministic\-archives\fR. +-.IP "\fB\-w\fR" 4 +-.IX Item "-w" +-.PD 0 +-.IP "\fB\-\-wildcard\fR" 4 +-.IX Item "--wildcard" +-.PD +-Permit regular expressions in \fIsymbolname\fRs used in other command +-line options. The question mark (?), asterisk (*), backslash (\e) and +-square brackets ([]) operators can be used anywhere in the symbol +-name. If the first character of the symbol name is the exclamation +-point (!) then the sense of the switch is reversed for that symbol. +-For example: +-.Sp +-.Vb 1 +-\& \-w \-K !foo \-K fo* +-.Ve +-.Sp +-would cause strip to only keep symbols that start with the letters +-\&\*(L"fo\*(R", but to discard the symbol \*(L"foo\*(R". +-.IP "\fB\-x\fR" 4 +-.IX Item "-x" +-.PD 0 +-.IP "\fB\-\-discard\-all\fR" 4 +-.IX Item "--discard-all" +-.PD +-Remove non-global symbols. +-.IP "\fB\-X\fR" 4 +-.IX Item "-X" +-.PD 0 +-.IP "\fB\-\-discard\-locals\fR" 4 +-.IX Item "--discard-locals" +-.PD +-Remove compiler-generated local symbols. +-(These usually start with \fBL\fR or \fB.\fR.) +-.IP "\fB\-\-keep\-file\-symbols\fR" 4 +-.IX Item "--keep-file-symbols" +-When stripping a file, perhaps with \fB\-\-strip\-debug\fR or +-\&\fB\-\-strip\-unneeded\fR, retain any symbols specifying source file names, +-which would otherwise get stripped. +-.IP "\fB\-\-only\-keep\-debug\fR" 4 +-.IX Item "--only-keep-debug" +-Strip a file, removing contents of any sections that would not be +-stripped by \fB\-\-strip\-debug\fR and leaving the debugging sections +-intact. In \s-1ELF\s0 files, this preserves all note sections in the output. +-.Sp +-The intention is that this option will be used in conjunction with +-\&\fB\-\-add\-gnu\-debuglink\fR to create a two part executable. One a +-stripped binary which will occupy less space in \s-1RAM\s0 and in a +-distribution and the second a debugging information file which is only +-needed if debugging abilities are required. The suggested procedure +-to create these files is as follows: +-.RS 4 +-.IP "1." 4 +-.IX Item "1." +-\&\f(CW\*(C`foo\*(C'\fR then... +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-create a file containing the debugging info. +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-stripped executable. +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-to add a link to the debugging info into the stripped executable. +-.RE +-.RS 4 +-.Sp +-Note\-\-\-the choice of \f(CW\*(C`.dbg\*(C'\fR as an extension for the debug info +-file is arbitrary. Also the \f(CW\*(C`\-\-only\-keep\-debug\*(C'\fR step is +-optional. You could instead do this: +-.IP "1." 4 +-.IX Item "1." +-.PD 0 +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-.ie n .IP "1." 4 +-.el .IP "1." 4 +-.IX Item "1." +-.RE +-.RS 4 +-.PD +-.Sp +-i.e., the file pointed to by the \fB\-\-add\-gnu\-debuglink\fR can be the +-full executable. It does not have to be a file created by the +-\&\fB\-\-only\-keep\-debug\fR switch. +-.Sp +-Note\-\-\-this switch is only intended for use on fully linked files. It +-does not make sense to use it on object files where the debugging +-information may be incomplete. Besides the gnu_debuglink feature +-currently only supports the presence of one filename containing +-debugging information, not multiple filenames on a one-per-object-file +-basis. +-.RE +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Show the version number for \fBstrip\fR. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-\-verbose\fR" 4 +-.IX Item "--verbose" +-.PD +-Verbose output: list all object files modified. In the case of +-archives, \fBstrip \-v\fR lists all members of the archive. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/windmc.1 binutils-2.24/binutils/doc/windmc.1 +--- binutils-2.24.orig/binutils/doc/windmc.1 2013-11-18 09:49:32.000000000 +0100 ++++ binutils-2.24/binutils/doc/windmc.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,351 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "WINDMC 1" +-.TH WINDMC 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-windmc \- generates Windows message resources. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-windmc [options] input-file +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBwindmc\fR reads message definitions from an input file (.mc) and +-translate them into a set of output files. The output files may be of +-four kinds: +-.ie n .IP """h""" 4 +-.el .IP "\f(CWh\fR" 4 +-.IX Item "h" +-A C header file containing the message definitions. +-.ie n .IP """rc""" 4 +-.el .IP "\f(CWrc\fR" 4 +-.IX Item "rc" +-A resource file compilable by the \fBwindres\fR tool. +-.ie n .IP """bin""" 4 +-.el .IP "\f(CWbin\fR" 4 +-.IX Item "bin" +-One or more binary files containing the resource data for a specific +-message language. +-.ie n .IP """dbg""" 4 +-.el .IP "\f(CWdbg\fR" 4 +-.IX Item "dbg" +-A C include file that maps message id's to their symbolic name. +-.PP +-The exact description of these different formats is available in +-documentation from Microsoft. +-.PP +-When \fBwindmc\fR converts from the \f(CW\*(C`mc\*(C'\fR format to the \f(CW\*(C`bin\*(C'\fR +-format, \f(CW\*(C`rc\*(C'\fR, \f(CW\*(C`h\*(C'\fR, and optional \f(CW\*(C`dbg\*(C'\fR it is acting like the +-Windows Message Compiler. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-a\fR" 4 +-.IX Item "-a" +-.PD 0 +-.IP "\fB\-\-ascii_in\fR" 4 +-.IX Item "--ascii_in" +-.PD +-Specifies that the input file specified is \s-1ASCII\s0. This is the default +-behaviour. +-.IP "\fB\-A\fR" 4 +-.IX Item "-A" +-.PD 0 +-.IP "\fB\-\-ascii_out\fR" 4 +-.IX Item "--ascii_out" +-.PD +-Specifies that messages in the output \f(CW\*(C`bin\*(C'\fR files should be in \s-1ASCII\s0 +-format. +-.IP "\fB\-b\fR" 4 +-.IX Item "-b" +-.PD 0 +-.IP "\fB\-\-binprefix\fR" 4 +-.IX Item "--binprefix" +-.PD +-Specifies that \f(CW\*(C`bin\*(C'\fR filenames should have to be prefixed by the +-basename of the source file. +-.IP "\fB\-c\fR" 4 +-.IX Item "-c" +-.PD 0 +-.IP "\fB\-\-customflag\fR" 4 +-.IX Item "--customflag" +-.PD +-Sets the customer bit in all message id's. +-.IP "\fB\-C\fR \fIcodepage\fR" 4 +-.IX Item "-C codepage" +-.PD 0 +-.IP "\fB\-\-codepage_in\fR \fIcodepage\fR" 4 +-.IX Item "--codepage_in codepage" +-.PD +-Sets the default codepage to be used to convert input file to \s-1UTF16\s0. The +-default is ocdepage 1252. +-.IP "\fB\-d\fR" 4 +-.IX Item "-d" +-.PD 0 +-.IP "\fB\-\-decimal_values\fR" 4 +-.IX Item "--decimal_values" +-.PD +-Outputs the constants in the header file in decimal. Default is using +-hexadecimal output. +-.IP "\fB\-e\fR \fIext\fR" 4 +-.IX Item "-e ext" +-.PD 0 +-.IP "\fB\-\-extension\fR \fIext\fR" 4 +-.IX Item "--extension ext" +-.PD +-The extension for the header file. The default is .h extension. +-.IP "\fB\-F\fR \fItarget\fR" 4 +-.IX Item "-F target" +-.PD 0 +-.IP "\fB\-\-target\fR \fItarget\fR" 4 +-.IX Item "--target target" +-.PD +-Specify the \s-1BFD\s0 format to use for a bin file as output. This +-is a \s-1BFD\s0 target name; you can use the \fB\-\-help\fR option to see a list +-of supported targets. Normally \fBwindmc\fR will use the default +-format, which is the first one listed by the \fB\-\-help\fR option. +-.IP "\fB\-h\fR \fIpath\fR" 4 +-.IX Item "-h path" +-.PD 0 +-.IP "\fB\-\-headerdir\fR \fIpath\fR" 4 +-.IX Item "--headerdir path" +-.PD +-The target directory of the generated header file. The default is the +-current directory. +-.IP "\fB\-H\fR" 4 +-.IX Item "-H" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Displays a list of command line options and then exits. +-.IP "\fB\-m\fR \fIcharacters\fR" 4 +-.IX Item "-m characters" +-.PD 0 +-.IP "\fB\-\-maxlength\fR \fIcharacters\fR" 4 +-.IX Item "--maxlength characters" +-.PD +-Instructs \fBwindmc\fR to generate a warning if the length +-of any message exceeds the number specified. +-.IP "\fB\-n\fR" 4 +-.IX Item "-n" +-.PD 0 +-.IP "\fB\-\-nullterminate\fR" 4 +-.IX Item "--nullterminate" +-.PD +-Terminate message text in \f(CW\*(C`bin\*(C'\fR files by zero. By default they are +-terminated by \s-1CR/LF\s0. +-.IP "\fB\-o\fR" 4 +-.IX Item "-o" +-.PD 0 +-.IP "\fB\-\-hresult_use\fR" 4 +-.IX Item "--hresult_use" +-.PD +-Not yet implemented. Instructs \f(CW\*(C`windmc\*(C'\fR to generate an \s-1OLE2\s0 header +-file, using \s-1HRESULT\s0 definitions. Status codes are used if the flag is not +-specified. +-.IP "\fB\-O\fR \fIcodepage\fR" 4 +-.IX Item "-O codepage" +-.PD 0 +-.IP "\fB\-\-codepage_out\fR \fIcodepage\fR" 4 +-.IX Item "--codepage_out codepage" +-.PD +-Sets the default codepage to be used to output text files. The default +-is ocdepage 1252. +-.IP "\fB\-r\fR \fIpath\fR" 4 +-.IX Item "-r path" +-.PD 0 +-.IP "\fB\-\-rcdir\fR \fIpath\fR" 4 +-.IX Item "--rcdir path" +-.PD +-The target directory for the generated \f(CW\*(C`rc\*(C'\fR script and the generated +-\&\f(CW\*(C`bin\*(C'\fR files that the resource compiler script includes. The default +-is the current directory. +-.IP "\fB\-u\fR" 4 +-.IX Item "-u" +-.PD 0 +-.IP "\fB\-\-unicode_in\fR" 4 +-.IX Item "--unicode_in" +-.PD +-Specifies that the input file is \s-1UTF16\s0. +-.IP "\fB\-U\fR" 4 +-.IX Item "-U" +-.PD 0 +-.IP "\fB\-\-unicode_out\fR" 4 +-.IX Item "--unicode_out" +-.PD +-Specifies that messages in the output \f(CW\*(C`bin\*(C'\fR file should be in \s-1UTF16\s0 +-format. This is the default behaviour. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-.PD 0 +-.IP "\fB\-\-verbose\fR" 4 +-.IX Item "--verbose" +-.PD +-Enable verbose mode. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Prints the version number for \fBwindmc\fR. +-.IP "\fB\-x\fR \fIpath\fR" 4 +-.IX Item "-x path" +-.PD 0 +-.IP "\fB\-\-xdgb\fR \fIpath\fR" 4 +-.IX Item "--xdgb path" +-.PD +-The path of the \f(CW\*(C`dbg\*(C'\fR C include file that maps message id's to the +-symbolic name. No such file is generated without specifying the switch. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/doc/windres.1 binutils-2.24/binutils/doc/windres.1 +--- binutils-2.24.orig/binutils/doc/windres.1 2013-11-18 09:49:31.000000000 +0100 ++++ binutils-2.24/binutils/doc/windres.1 1970-01-01 01:00:00.000000000 +0100 +@@ -1,359 +0,0 @@ +-.\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14) +-.\" +-.\" Standard preamble: +-.\" ======================================================================== +-.de Sp \" Vertical space (when we can't use .PP) +-.if t .sp .5v +-.if n .sp +-.. +-.de Vb \" Begin verbatim text +-.ft CW +-.nf +-.ne \\$1 +-.. +-.de Ve \" End verbatim text +-.ft R +-.fi +-.. +-.\" Set up some character translations and predefined strings. \*(-- will +-.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +-.\" double quote, and \*(R" will give a right double quote. \*(C+ will +-.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +-.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +-.\" nothing in troff, for use with C<>. +-.tr \(*W- +-.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +-.ie n \{\ +-. ds -- \(*W- +-. ds PI pi +-. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +-. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +-. ds L" "" +-. ds R" "" +-. ds C` "" +-. ds C' "" +-'br\} +-.el\{\ +-. ds -- \|\(em\| +-. ds PI \(*p +-. ds L" `` +-. ds R" '' +-'br\} +-.\" +-.\" Escape single quotes in literal strings from groff's Unicode transform. +-.ie \n(.g .ds Aq \(aq +-.el .ds Aq ' +-.\" +-.\" If the F register is turned on, we'll generate index entries on stderr for +-.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index +-.\" entries marked with X<> in POD. Of course, you'll have to process the +-.\" output yourself in some meaningful fashion. +-.ie \nF \{\ +-. de IX +-. tm Index:\\$1\t\\n%\t"\\$2" +-.. +-. nr % 0 +-. rr F +-.\} +-.el \{\ +-. de IX +-.. +-.\} +-.\" +-.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +-.\" Fear. Run. Save yourself. No user-serviceable parts. +-. \" fudge factors for nroff and troff +-.if n \{\ +-. ds #H 0 +-. ds #V .8m +-. ds #F .3m +-. ds #[ \f1 +-. ds #] \fP +-.\} +-.if t \{\ +-. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +-. ds #V .6m +-. ds #F 0 +-. ds #[ \& +-. ds #] \& +-.\} +-. \" simple accents for nroff and troff +-.if n \{\ +-. ds ' \& +-. ds ` \& +-. ds ^ \& +-. ds , \& +-. ds ~ ~ +-. ds / +-.\} +-.if t \{\ +-. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +-. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +-. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +-. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +-. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +-. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +-.\} +-. \" troff and (daisy-wheel) nroff accents +-.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +-.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +-.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +-.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +-.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +-.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +-.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +-.ds ae a\h'-(\w'a'u*4/10)'e +-.ds Ae A\h'-(\w'A'u*4/10)'E +-. \" corrections for vroff +-.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +-.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +-. \" for low resolution devices (crt and lpr) +-.if \n(.H>23 .if \n(.V>19 \ +-\{\ +-. ds : e +-. ds 8 ss +-. ds o a +-. ds d- d\h'-1'\(ga +-. ds D- D\h'-1'\(hy +-. ds th \o'bp' +-. ds Th \o'LP' +-. ds ae ae +-. ds Ae AE +-.\} +-.rm #[ #] #H #V #F C +-.\" ======================================================================== +-.\" +-.IX Title "WINDRES 1" +-.TH WINDRES 1 "2013-11-18" "binutils-2.23.91" "GNU Development Tools" +-.\" For nroff, turn off justification. Always turn off hyphenation; it makes +-.\" way too many mistakes in technical documents. +-.if n .ad l +-.nh +-.SH "NAME" +-windres \- manipulate Windows resources. +-.SH "SYNOPSIS" +-.IX Header "SYNOPSIS" +-windres [options] [input\-file] [output\-file] +-.SH "DESCRIPTION" +-.IX Header "DESCRIPTION" +-\&\fBwindres\fR reads resources from an input file and copies them into +-an output file. Either file may be in one of three formats: +-.ie n .IP """rc""" 4 +-.el .IP "\f(CWrc\fR" 4 +-.IX Item "rc" +-A text format read by the Resource Compiler. +-.ie n .IP """res""" 4 +-.el .IP "\f(CWres\fR" 4 +-.IX Item "res" +-A binary format generated by the Resource Compiler. +-.ie n .IP """coff""" 4 +-.el .IP "\f(CWcoff\fR" 4 +-.IX Item "coff" +-A \s-1COFF\s0 object or executable. +-.PP +-The exact description of these different formats is available in +-documentation from Microsoft. +-.PP +-When \fBwindres\fR converts from the \f(CW\*(C`rc\*(C'\fR format to the \f(CW\*(C`res\*(C'\fR +-format, it is acting like the Windows Resource Compiler. When +-\&\fBwindres\fR converts from the \f(CW\*(C`res\*(C'\fR format to the \f(CW\*(C`coff\*(C'\fR +-format, it is acting like the Windows \f(CW\*(C`CVTRES\*(C'\fR program. +-.PP +-When \fBwindres\fR generates an \f(CW\*(C`rc\*(C'\fR file, the output is similar +-but not identical to the format expected for the input. When an input +-\&\f(CW\*(C`rc\*(C'\fR file refers to an external filename, an output \f(CW\*(C`rc\*(C'\fR file +-will instead include the file contents. +-.PP +-If the input or output format is not specified, \fBwindres\fR will +-guess based on the file name, or, for the input file, the file contents. +-A file with an extension of \fI.rc\fR will be treated as an \f(CW\*(C`rc\*(C'\fR +-file, a file with an extension of \fI.res\fR will be treated as a +-\&\f(CW\*(C`res\*(C'\fR file, and a file with an extension of \fI.o\fR or +-\&\fI.exe\fR will be treated as a \f(CW\*(C`coff\*(C'\fR file. +-.PP +-If no output file is specified, \fBwindres\fR will print the resources +-in \f(CW\*(C`rc\*(C'\fR format to standard output. +-.PP +-The normal use is for you to write an \f(CW\*(C`rc\*(C'\fR file, use \fBwindres\fR +-to convert it to a \s-1COFF\s0 object file, and then link the \s-1COFF\s0 file into +-your application. This will make the resources described in the +-\&\f(CW\*(C`rc\*(C'\fR file available to Windows. +-.SH "OPTIONS" +-.IX Header "OPTIONS" +-.IP "\fB\-i\fR \fIfilename\fR" 4 +-.IX Item "-i filename" +-.PD 0 +-.IP "\fB\-\-input\fR \fIfilename\fR" 4 +-.IX Item "--input filename" +-.PD +-The name of the input file. If this option is not used, then +-\&\fBwindres\fR will use the first non-option argument as the input file +-name. If there are no non-option arguments, then \fBwindres\fR will +-read from standard input. \fBwindres\fR can not read a \s-1COFF\s0 file from +-standard input. +-.IP "\fB\-o\fR \fIfilename\fR" 4 +-.IX Item "-o filename" +-.PD 0 +-.IP "\fB\-\-output\fR \fIfilename\fR" 4 +-.IX Item "--output filename" +-.PD +-The name of the output file. If this option is not used, then +-\&\fBwindres\fR will use the first non-option argument, after any used +-for the input file name, as the output file name. If there is no +-non-option argument, then \fBwindres\fR will write to standard output. +-\&\fBwindres\fR can not write a \s-1COFF\s0 file to standard output. Note, +-for compatibility with \fBrc\fR the option \fB\-fo\fR is also +-accepted, but its use is not recommended. +-.IP "\fB\-J\fR \fIformat\fR" 4 +-.IX Item "-J format" +-.PD 0 +-.IP "\fB\-\-input\-format\fR \fIformat\fR" 4 +-.IX Item "--input-format format" +-.PD +-The input format to read. \fIformat\fR may be \fBres\fR, \fBrc\fR, or +-\&\fBcoff\fR. If no input format is specified, \fBwindres\fR will +-guess, as described above. +-.IP "\fB\-O\fR \fIformat\fR" 4 +-.IX Item "-O format" +-.PD 0 +-.IP "\fB\-\-output\-format\fR \fIformat\fR" 4 +-.IX Item "--output-format format" +-.PD +-The output format to generate. \fIformat\fR may be \fBres\fR, +-\&\fBrc\fR, or \fBcoff\fR. If no output format is specified, +-\&\fBwindres\fR will guess, as described above. +-.IP "\fB\-F\fR \fItarget\fR" 4 +-.IX Item "-F target" +-.PD 0 +-.IP "\fB\-\-target\fR \fItarget\fR" 4 +-.IX Item "--target target" +-.PD +-Specify the \s-1BFD\s0 format to use for a \s-1COFF\s0 file as input or output. This +-is a \s-1BFD\s0 target name; you can use the \fB\-\-help\fR option to see a list +-of supported targets. Normally \fBwindres\fR will use the default +-format, which is the first one listed by the \fB\-\-help\fR option. +-.IP "\fB\-\-preprocessor\fR \fIprogram\fR" 4 +-.IX Item "--preprocessor program" +-When \fBwindres\fR reads an \f(CW\*(C`rc\*(C'\fR file, it runs it through the C +-preprocessor first. This option may be used to specify the preprocessor +-to use, including any leading arguments. The default preprocessor +-argument is \f(CW\*(C`gcc \-E \-xc\-header \-DRC_INVOKED\*(C'\fR. +-.IP "\fB\-\-preprocessor\-arg\fR \fIoption\fR" 4 +-.IX Item "--preprocessor-arg option" +-When \fBwindres\fR reads an \f(CW\*(C`rc\*(C'\fR file, it runs it through +-the C preprocessor first. This option may be used to specify additional +-text to be passed to preprocessor on its command line. +-This option can be used multiple times to add multiple options to the +-preprocessor command line. +-.IP "\fB\-I\fR \fIdirectory\fR" 4 +-.IX Item "-I directory" +-.PD 0 +-.IP "\fB\-\-include\-dir\fR \fIdirectory\fR" 4 +-.IX Item "--include-dir directory" +-.PD +-Specify an include directory to use when reading an \f(CW\*(C`rc\*(C'\fR file. +-\&\fBwindres\fR will pass this to the preprocessor as an \fB\-I\fR +-option. \fBwindres\fR will also search this directory when looking for +-files named in the \f(CW\*(C`rc\*(C'\fR file. If the argument passed to this command +-matches any of the supported \fIformats\fR (as described in the \fB\-J\fR +-option), it will issue a deprecation warning, and behave just like the +-\&\fB\-J\fR option. New programs should not use this behaviour. If a +-directory happens to match a \fIformat\fR, simple prefix it with \fB./\fR +-to disable the backward compatibility. +-.IP "\fB\-D\fR \fItarget\fR" 4 +-.IX Item "-D target" +-.PD 0 +-.IP "\fB\-\-define\fR \fIsym\fR\fB[=\fR\fIval\fR\fB]\fR" 4 +-.IX Item "--define sym[=val]" +-.PD +-Specify a \fB\-D\fR option to pass to the preprocessor when reading an +-\&\f(CW\*(C`rc\*(C'\fR file. +-.IP "\fB\-U\fR \fItarget\fR" 4 +-.IX Item "-U target" +-.PD 0 +-.IP "\fB\-\-undefine\fR \fIsym\fR" 4 +-.IX Item "--undefine sym" +-.PD +-Specify a \fB\-U\fR option to pass to the preprocessor when reading an +-\&\f(CW\*(C`rc\*(C'\fR file. +-.IP "\fB\-r\fR" 4 +-.IX Item "-r" +-Ignored for compatibility with rc. +-.IP "\fB\-v\fR" 4 +-.IX Item "-v" +-Enable verbose mode. This tells you what the preprocessor is if you +-didn't specify one. +-.IP "\fB\-c\fR \fIval\fR" 4 +-.IX Item "-c val" +-.PD 0 +-.IP "\fB\-\-codepage\fR \fIval\fR" 4 +-.IX Item "--codepage val" +-.PD +-Specify the default codepage to use when reading an \f(CW\*(C`rc\*(C'\fR file. +-\&\fIval\fR should be a hexadecimal prefixed by \fB0x\fR or decimal +-codepage code. The valid range is from zero up to 0xffff, but the +-validity of the codepage is host and configuration dependent. +-.IP "\fB\-l\fR \fIval\fR" 4 +-.IX Item "-l val" +-.PD 0 +-.IP "\fB\-\-language\fR \fIval\fR" 4 +-.IX Item "--language val" +-.PD +-Specify the default language to use when reading an \f(CW\*(C`rc\*(C'\fR file. +-\&\fIval\fR should be a hexadecimal language code. The low eight bits are +-the language, and the high eight bits are the sublanguage. +-.IP "\fB\-\-use\-temp\-file\fR" 4 +-.IX Item "--use-temp-file" +-Use a temporary file to instead of using popen to read the output of +-the preprocessor. Use this option if the popen implementation is buggy +-on the host (eg., certain non-English language versions of Windows 95 and +-Windows 98 are known to have buggy popen where the output will instead +-go the console). +-.IP "\fB\-\-no\-use\-temp\-file\fR" 4 +-.IX Item "--no-use-temp-file" +-Use popen, not a temporary file, to read the output of the preprocessor. +-This is the default behaviour. +-.IP "\fB\-h\fR" 4 +-.IX Item "-h" +-.PD 0 +-.IP "\fB\-\-help\fR" 4 +-.IX Item "--help" +-.PD +-Prints a usage summary. +-.IP "\fB\-V\fR" 4 +-.IX Item "-V" +-.PD 0 +-.IP "\fB\-\-version\fR" 4 +-.IX Item "--version" +-.PD +-Prints the version number for \fBwindres\fR. +-.IP "\fB\-\-yydebug\fR" 4 +-.IX Item "--yydebug" +-If \fBwindres\fR is compiled with \f(CW\*(C`YYDEBUG\*(C'\fR defined as \f(CW1\fR, +-this will turn on parser debugging. +-.IP "\fB@\fR\fIfile\fR" 4 +-.IX Item "@file" +-Read command-line options from \fIfile\fR. The options read are +-inserted in place of the original @\fIfile\fR option. If \fIfile\fR +-does not exist, or cannot be read, then the option will be treated +-literally, and not removed. +-.Sp +-Options in \fIfile\fR are separated by whitespace. A whitespace +-character may be included in an option by surrounding the entire +-option in either single or double quotes. Any character (including a +-backslash) may be included by prefixing the character to be included +-with a backslash. The \fIfile\fR may itself contain additional +-@\fIfile\fR options; any such options will be processed recursively. +-.SH "SEE ALSO" +-.IX Header "SEE ALSO" +-the Info entries for \fIbinutils\fR. +-.SH "COPYRIGHT" +-.IX Header "COPYRIGHT" +-Copyright (c) 1991\-2013 Free Software Foundation, Inc. +-.PP +-Permission is granted to copy, distribute and/or modify this document +-under the terms of the \s-1GNU\s0 Free Documentation License, Version 1.3 +-or any later version published by the Free Software Foundation; +-with no Invariant Sections, with no Front-Cover Texts, and with no +-Back-Cover Texts. A copy of the license is included in the +-section entitled \*(L"\s-1GNU\s0 Free Documentation License\*(R". +diff -Nur binutils-2.24.orig/binutils/dwarf.c binutils-2.24/binutils/dwarf.c +--- binutils-2.24.orig/binutils/dwarf.c 2013-11-08 11:13:48.000000000 +0100 ++++ binutils-2.24/binutils/dwarf.c 2016-04-10 20:30:46.000000000 +0200 +@@ -263,7 +263,7 @@ + *length_return = num_read; + + if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) +- result |= -1L << shift; ++ result |= (dwarf_vma) -1 << shift; + + return result; + } +@@ -2663,14 +2663,10 @@ + linfo->li_max_ops_per_insn = 1; + + SAFE_BYTE_GET_AND_INC (linfo->li_default_is_stmt, hdrptr, 1, end); +- SAFE_BYTE_GET_AND_INC (linfo->li_line_base, hdrptr, 1, end); ++ SAFE_SIGNED_BYTE_GET_AND_INC (linfo->li_line_base, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_line_range, hdrptr, 1, end); + SAFE_BYTE_GET_AND_INC (linfo->li_opcode_base, hdrptr, 1, end); + +- /* Sign extend the line base field. */ +- linfo->li_line_base <<= 24; +- linfo->li_line_base >>= 24; +- + * end_of_sequence = data + linfo->li_length + initial_length_size; + return hdrptr; + } +diff -Nur binutils-2.24.orig/binutils/mcparse.c binutils-2.24/binutils/mcparse.c +--- binutils-2.24.orig/binutils/mcparse.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/mcparse.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2156 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton implementation for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "2.3" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Using locations. */ +-#define YYLSP_NEEDED 0 +- +- +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- NL = 258, +- MCIDENT = 259, +- MCFILENAME = 260, +- MCLINE = 261, +- MCCOMMENT = 262, +- MCTOKEN = 263, +- MCENDLINE = 264, +- MCLANGUAGENAMES = 265, +- MCFACILITYNAMES = 266, +- MCSEVERITYNAMES = 267, +- MCOUTPUTBASE = 268, +- MCMESSAGEIDTYPEDEF = 269, +- MCLANGUAGE = 270, +- MCMESSAGEID = 271, +- MCSEVERITY = 272, +- MCFACILITY = 273, +- MCSYMBOLICNAME = 274, +- MCNUMBER = 275 +- }; +-#endif +-/* Tokens. */ +-#define NL 258 +-#define MCIDENT 259 +-#define MCFILENAME 260 +-#define MCLINE 261 +-#define MCCOMMENT 262 +-#define MCTOKEN 263 +-#define MCENDLINE 264 +-#define MCLANGUAGENAMES 265 +-#define MCFACILITYNAMES 266 +-#define MCSEVERITYNAMES 267 +-#define MCOUTPUTBASE 268 +-#define MCMESSAGEIDTYPEDEF 269 +-#define MCLANGUAGE 270 +-#define MCMESSAGEID 271 +-#define MCSEVERITY 272 +-#define MCFACILITY 273 +-#define MCSYMBOLICNAME 274 +-#define MCNUMBER 275 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 1 "mcparse.y" +- /* mcparse.y -- parser for Windows mc files +- Copyright 2007 +- Free Software Foundation, Inc. +- +- Parser for Windows mc files +- Written by Kai Tietz, Onevision. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +-/* This is a parser for Windows rc files. It is based on the parser +- by Gunther Ebert . */ +- +-#include "sysdep.h" +-#include "bfd.h" +-#include "bucomm.h" +-#include "libiberty.h" +-#include "windmc.h" +-#include "safe-ctype.h" +- +-static rc_uint_type mc_last_id = 0; +-static rc_uint_type mc_sefa_val = 0; +-static unichar *mc_last_symbol = NULL; +-static const mc_keyword *mc_cur_severity = NULL; +-static const mc_keyword *mc_cur_facility = NULL; +-static mc_node *cur_node = NULL; +- +- +- +-/* Enabling traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* Enabling the token table. */ +-#ifndef YYTOKEN_TABLE +-# define YYTOKEN_TABLE 0 +-#endif +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 45 "mcparse.y" +-{ +- rc_uint_type ival; +- unichar *ustr; +- const mc_keyword *tok; +- mc_node *nod; +-} +-/* Line 193 of yacc.c. */ +-#line 186 "mcparse.c" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +- +- +-/* Copy the second part of user declarations. */ +- +- +-/* Line 216 of yacc.c. */ +-#line 199 "mcparse.c" +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; +-#else +-typedef short int yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(msgid) dgettext ("bison-runtime", msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(msgid) msgid +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(e) ((void) (e)) +-#else +-# define YYUSE(e) /* empty */ +-#endif +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(n) (n) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int i) +-#else +-static int +-YYID (i) +- int i; +-#endif +-{ +- return i; +-} +-#endif +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined _STDLIB_H \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss; +- YYSTYPE yyvs; +- }; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-/* Copy COUNT objects from FROM to TO. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(To, From, Count) \ +- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +-# else +-# define YYCOPY(To, From, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (To)[yyi] = (From)[yyi]; \ +- } \ +- while (YYID (0)) +-# endif +-# endif +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack, Stack, yysize); \ +- Stack = &yyptr->Stack; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) +- +-#endif +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 3 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 114 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 26 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 29 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 82 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 125 +- +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 275 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 22, 23, 2, 25, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 24, 2, +- 2, 21, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20 +-}; +- +-#if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint16 yyprhs[] = +-{ +- 0, 0, 3, 5, 6, 9, 11, 13, 15, 17, +- 23, 29, 33, 36, 42, 48, 52, 55, 61, 67, +- 71, 74, 78, 82, 86, 89, 91, 94, 96, 101, +- 105, 108, 110, 113, 115, 120, 124, 127, 129, 132, +- 134, 141, 148, 153, 157, 160, 161, 164, 167, 168, +- 173, 177, 181, 184, 185, 187, 190, 193, 194, 197, +- 200, 203, 207, 211, 215, 217, 220, 225, 227, 230, +- 232, 235, 237, 240, 246, 252, 258, 263, 266, 268, +- 270, 271, 272 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int8 yyrhs[] = +-{ +- 27, 0, -1, 28, -1, -1, 28, 29, -1, 30, +- -1, 38, -1, 49, -1, 1, -1, 12, 21, 22, +- 31, 23, -1, 12, 21, 22, 31, 1, -1, 12, +- 21, 1, -1, 12, 1, -1, 10, 21, 22, 35, +- 23, -1, 10, 21, 22, 35, 1, -1, 10, 21, +- 1, -1, 10, 1, -1, 11, 21, 22, 33, 23, +- -1, 11, 21, 22, 33, 1, -1, 11, 21, 1, +- -1, 11, 1, -1, 13, 21, 20, -1, 14, 21, +- 4, -1, 14, 21, 1, -1, 14, 1, -1, 32, +- -1, 31, 32, -1, 1, -1, 51, 21, 20, 37, +- -1, 51, 21, 1, -1, 51, 1, -1, 34, -1, +- 33, 34, -1, 1, -1, 51, 21, 20, 37, -1, +- 51, 21, 1, -1, 51, 1, -1, 36, -1, 35, +- 36, -1, 1, -1, 51, 21, 20, 54, 24, 5, +- -1, 51, 21, 20, 54, 24, 1, -1, 51, 21, +- 20, 1, -1, 51, 21, 1, -1, 51, 1, -1, +- -1, 24, 4, -1, 24, 1, -1, -1, 40, 42, +- 39, 46, -1, 16, 21, 41, -1, 16, 21, 1, +- -1, 16, 1, -1, -1, 20, -1, 25, 20, -1, +- 25, 1, -1, -1, 42, 43, -1, 42, 44, -1, +- 42, 45, -1, 17, 21, 8, -1, 18, 21, 8, +- -1, 19, 21, 4, -1, 47, -1, 46, 47, -1, +- 50, 53, 48, 9, -1, 6, -1, 48, 6, -1, +- 1, -1, 48, 1, -1, 7, -1, 49, 7, -1, +- 15, 52, 21, 8, 3, -1, 15, 52, 21, 4, +- 3, -1, 15, 52, 21, 51, 1, -1, 15, 52, +- 21, 1, -1, 15, 1, -1, 4, -1, 8, -1, +- -1, -1, -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 67, 67, 70, 72, 74, 75, 76, 81, 85, +- 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, +- 96, 97, 103, 107, 111, 118, 119, 120, 124, 128, +- 129, 133, 134, 135, 139, 143, 144, 148, 149, 150, +- 154, 158, 159, 160, 161, 166, 169, 173, 178, 177, +- 190, 191, 192, 196, 199, 203, 207, 212, 219, 225, +- 231, 239, 247, 255, 262, 263, 267, 277, 281, 293, +- 294, 297, 298, 312, 316, 321, 326, 331, 338, 339, +- 343, 347, 351 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "NL", "MCIDENT", "MCFILENAME", "MCLINE", +- "MCCOMMENT", "MCTOKEN", "MCENDLINE", "MCLANGUAGENAMES", +- "MCFACILITYNAMES", "MCSEVERITYNAMES", "MCOUTPUTBASE", +- "MCMESSAGEIDTYPEDEF", "MCLANGUAGE", "MCMESSAGEID", "MCSEVERITY", +- "MCFACILITY", "MCSYMBOLICNAME", "MCNUMBER", "'='", "'('", "')'", "':'", +- "'+'", "$accept", "input", "entities", "entity", "global_section", +- "severitymaps", "severitymap", "facilitymaps", "facilitymap", "langmaps", +- "langmap", "alias_name", "message", "@1", "id", "vid", "sefasy_def", +- "severity", "facility", "symbol", "lang_entities", "lang_entity", +- "lines", "comments", "lang", "token", "lex_want_nl", "lex_want_line", +- "lex_want_filename", 0 +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 61, 40, 41, 58, 43 +-}; +-# endif +- +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 26, 27, 28, 28, 29, 29, 29, 29, 30, +- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +- 30, 30, 30, 30, 30, 31, 31, 31, 32, 32, +- 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, +- 36, 36, 36, 36, 36, 37, 37, 37, 39, 38, +- 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, +- 42, 43, 44, 45, 46, 46, 47, 48, 48, 48, +- 48, 49, 49, 50, 50, 50, 50, 50, 51, 51, +- 52, 53, 54 +-}; +- +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 1, 0, 2, 1, 1, 1, 1, 5, +- 5, 3, 2, 5, 5, 3, 2, 5, 5, 3, +- 2, 3, 3, 3, 2, 1, 2, 1, 4, 3, +- 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, +- 6, 6, 4, 3, 2, 0, 2, 2, 0, 4, +- 3, 3, 2, 0, 1, 2, 2, 0, 2, 2, +- 2, 3, 3, 3, 1, 2, 4, 1, 2, 1, +- 2, 1, 2, 5, 5, 5, 4, 2, 1, 1, +- 0, 0, 0 +-}; +- +-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state +- STATE-NUM when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 3, 0, 0, 1, 8, 71, 0, 0, 0, 0, +- 0, 0, 4, 5, 6, 57, 7, 16, 0, 20, +- 0, 12, 0, 0, 24, 0, 52, 0, 48, 72, +- 15, 0, 19, 0, 11, 0, 21, 23, 22, 51, +- 54, 0, 50, 0, 0, 0, 0, 58, 59, 60, +- 39, 78, 79, 0, 37, 0, 33, 0, 31, 0, +- 27, 0, 25, 0, 56, 55, 0, 0, 0, 0, +- 49, 64, 81, 14, 13, 38, 44, 0, 18, 17, +- 32, 36, 0, 10, 9, 26, 30, 0, 61, 62, +- 63, 77, 0, 65, 0, 43, 0, 35, 45, 29, +- 45, 0, 69, 67, 0, 42, 0, 0, 34, 28, +- 76, 78, 79, 0, 70, 68, 66, 0, 47, 46, +- 74, 73, 75, 41, 40 +-}; +- +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int8 yydefgoto[] = +-{ +- -1, 1, 2, 12, 13, 61, 62, 57, 58, 53, +- 54, 108, 14, 46, 15, 42, 28, 47, 48, 49, +- 70, 71, 104, 16, 72, 55, 92, 94, 106 +-}; +- +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -34 +-static const yytype_int8 yypact[] = +-{ +- -34, 62, 70, -34, -34, -34, 15, 22, 30, -15, +- 34, 37, -34, -34, -34, -34, 56, -34, 10, -34, +- 12, -34, 20, 25, -34, 52, -34, 0, 80, -34, +- -34, 71, -34, 84, -34, 86, -34, -34, -34, -34, +- -34, 45, -34, 1, 68, 74, 76, -34, -34, -34, +- -34, -34, -34, 4, -34, 38, -34, 6, -34, 39, +- -34, 29, -34, 40, -34, -34, 93, 94, 99, 43, +- 76, -34, -34, -34, -34, -34, -34, 46, -34, -34, +- -34, -34, 47, -34, -34, -34, -34, 49, -34, -34, +- -34, -34, 83, -34, 3, -34, 2, -34, 81, -34, +- 81, 92, -34, -34, 48, -34, 82, 72, -34, -34, +- -34, 104, 105, 108, -34, -34, -34, 73, -34, -34, +- -34, -34, -34, -34, -34 +-}; +- +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = +-{ +- -34, -34, -34, -34, -34, -34, 50, -34, 53, -34, +- 59, 13, -34, -34, -34, -34, -34, -34, -34, -34, +- -34, 44, -34, -34, -34, -33, -34, -34, -34 +-}; +- +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If zero, do what YYDEFACT says. +- If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -83 +-static const yytype_int8 yytable[] = +-{ +- 59, 39, 63, 105, 102, 73, 23, 78, 51, 103, +- 51, 30, 52, 32, 52, -53, 17, -53, -53, -53, +- 40, 34, 66, 19, 59, 41, -82, 74, 63, 79, +- 83, 21, 31, 51, 33, 24, 18, 52, 26, 76, +- 81, 86, 35, 20, 91, 36, 64, 95, 97, 114, +- 99, 22, 84, 37, 115, 25, 38, 116, 27, 77, +- 82, 87, 3, 29, -80, 65, 96, 98, 113, 100, +- -2, 4, 50, 118, 123, 51, 119, 5, 124, 52, +- 6, 7, 8, 9, 10, 56, 11, 60, 51, 67, +- 51, 69, 52, 110, 52, 68, 111, 43, 44, 45, +- 112, 88, 89, 90, 101, 107, 117, 120, 121, 122, +- 80, 85, 75, 109, 93 +-}; +- +-static const yytype_uint8 yycheck[] = +-{ +- 33, 1, 35, 1, 1, 1, 21, 1, 4, 6, +- 4, 1, 8, 1, 8, 15, 1, 17, 18, 19, +- 20, 1, 21, 1, 57, 25, 24, 23, 61, 23, +- 1, 1, 22, 4, 22, 1, 21, 8, 1, 1, +- 1, 1, 22, 21, 1, 20, 1, 1, 1, 1, +- 1, 21, 23, 1, 6, 21, 4, 9, 21, 21, +- 21, 21, 0, 7, 21, 20, 20, 20, 101, 20, +- 0, 1, 1, 1, 1, 4, 4, 7, 5, 8, +- 10, 11, 12, 13, 14, 1, 16, 1, 4, 21, +- 4, 15, 8, 1, 8, 21, 4, 17, 18, 19, +- 8, 8, 8, 4, 21, 24, 24, 3, 3, 1, +- 57, 61, 53, 100, 70 +-}; +- +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 27, 28, 0, 1, 7, 10, 11, 12, 13, +- 14, 16, 29, 30, 38, 40, 49, 1, 21, 1, +- 21, 1, 21, 21, 1, 21, 1, 21, 42, 7, +- 1, 22, 1, 22, 1, 22, 20, 1, 4, 1, +- 20, 25, 41, 17, 18, 19, 39, 43, 44, 45, +- 1, 4, 8, 35, 36, 51, 1, 33, 34, 51, +- 1, 31, 32, 51, 1, 20, 21, 21, 21, 15, +- 46, 47, 50, 1, 23, 36, 1, 21, 1, 23, +- 34, 1, 21, 1, 23, 32, 1, 21, 8, 8, +- 4, 1, 52, 47, 53, 1, 20, 1, 20, 1, +- 20, 21, 1, 6, 48, 1, 54, 24, 37, 37, +- 1, 4, 8, 51, 1, 6, 9, 24, 1, 4, +- 3, 3, 1, 1, 5 +-}; +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. */ +- +-#define YYFAIL goto yyerrlab +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY && yylen == 1) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK (1); \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) +- +- +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +- If N is 0, then set CURRENT to the empty location which ends +- the previous symbol: RHS[0] (always defined). */ +- +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +-#ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (YYID (N)) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (YYID (0)) +-#endif +- +- +-/* YY_LOCATION_PRINT -- Print the location on the stream. +- This macro was not mandated originally: define only if we know +- we won't break user code: when these are the locations we know. */ +- +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +-# define YY_LOCATION_PRINT(File, Loc) \ +- fprintf (File, "%d.%d-%d.%d", \ +- (Loc).first_line, (Loc).first_column, \ +- (Loc).last_line, (Loc).last_column) +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif +- +- +-/* YYLEX -- calling `yylex' with the right arguments. */ +- +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); +-# endif +- switch (yytype) +- { +- default: +- break; +- } +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +-#else +-static void +-yy_stack_print (bottom, top) +- yytype_int16 *bottom; +- yytype_int16 *top; +-#endif +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; bottom <= top; ++bottom) +- YYFPRINTF (stderr, " %d", *bottom); +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif +-{ +- int yynrhs = yyr2[yyrule]; +- int yyi; +- unsigned long int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- fprintf (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- fprintf (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static YYSIZE_T +-yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into YYRESULT an error message about the unexpected token +- YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not +- copy anything; just return the number of bytes that would be +- copied. As a special case, return 0 if an ordinary "syntax error" +- message will do. Return YYSIZE_MAXIMUM if overflow occurs during +- size calculation. */ +-static YYSIZE_T +-yysyntax_error (char *yyresult, int yystate, int yychar) +-{ +- int yyn = yypact[yystate]; +- +- if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) +- return 0; +- else +- { +- int yytype = YYTRANSLATE (yychar); +- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); +- YYSIZE_T yysize = yysize0; +- YYSIZE_T yysize1; +- int yysize_overflow = 0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- int yyx; +- +-# if 0 +- /* This is so xgettext sees the translatable formats that are +- constructed on the fly. */ +- YY_("syntax error, unexpected %s"); +- YY_("syntax error, unexpected %s, expecting %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +-# endif +- char *yyfmt; +- char const *yyf; +- static char const yyunexpected[] = "syntax error, unexpected %s"; +- static char const yyexpecting[] = ", expecting %s"; +- static char const yyor[] = " or %s"; +- char yyformat[sizeof yyunexpected +- + sizeof yyexpecting - 1 +- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) +- * (sizeof yyor - 1))]; +- char const *yyprefix = yyexpecting; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 1; +- +- yyarg[0] = yytname[yytype]; +- yyfmt = yystpcpy (yyformat, yyunexpected); +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- yyformat[sizeof yyunexpected - 1] = '\0'; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- yysize1 = yysize + yytnamerr (0, yytname[yyx]); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- yyfmt = yystpcpy (yyfmt, yyprefix); +- yyprefix = yyor; +- } +- +- yyf = YY_(yyformat); +- yysize1 = yysize + yystrlen (yyf); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- +- if (yysize_overflow) +- return YYSIZE_MAXIMUM; +- +- if (yyresult) +- { +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- char *yyp = yyresult; +- int yyi = 0; +- while ((*yyp = *yyf) != '\0') +- { +- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyf += 2; +- } +- else +- { +- yyp++; +- yyf++; +- } +- } +- } +- return yysize; +- } +-} +-#endif /* YYERROR_VERBOSE */ +- +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif +-{ +- YYUSE (yyvaluep); +- +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- switch (yytype) +- { +- +- default: +- break; +- } +-} +- +- +-/* Prevent warnings from -Wmissing-prototypes. */ +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ +- +- +- +-/* The look-ahead symbol. */ +-int yychar; +- +-/* The semantic value of the look-ahead symbol. */ +-YYSTYPE yylval; +- +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif +-{ +- +- int yystate; +- int yyn; +- int yyresult; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- /* Look-ahead token as an internal (translated) token number. */ +- int yytoken = 0; +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +- /* Three stacks and their tools: +- `yyss': related to states, +- `yyvs': related to semantic values, +- `yyls': related to locations. +- +- Refer to the stacks thru separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss = yyssa; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs = yyvsa; +- YYSTYPE *yyvsp; +- +- +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- YYSIZE_T yystacksize = YYINITDEPTH; +- +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- +- /* Initialize stack pointers. +- Waste one element of value and location stack +- so that they stay on the same level as the state stack. +- The wasted elements are never initialized. */ +- +- yyssp = yyss; +- yyvsp = yyvs; +- +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss); +- YYSTACK_RELOCATE (yyvs); +- +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- look-ahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to look-ahead token. */ +- yyn = yypact[yystate]; +- if (yyn == YYPACT_NINF) +- goto yydefault; +- +- /* Not known => get a look-ahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yyn == 0 || yyn == YYTABLE_NINF) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the look-ahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- yystate = yyn; +- *++yyvsp = yylval; +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 7: +-#line 77 "mcparse.y" +- { +- cur_node = mc_add_node (); +- cur_node->user_text = (yyvsp[(1) - (1)].ustr); +- } +- break; +- +- case 8: +-#line 81 "mcparse.y" +- { mc_fatal ("syntax error"); } +- break; +- +- case 10: +-#line 86 "mcparse.y" +- { mc_fatal ("missing ')' in SeverityNames"); } +- break; +- +- case 11: +-#line 87 "mcparse.y" +- { mc_fatal ("missing '(' in SeverityNames"); } +- break; +- +- case 12: +-#line 88 "mcparse.y" +- { mc_fatal ("missing '=' for SeverityNames"); } +- break; +- +- case 14: +-#line 90 "mcparse.y" +- { mc_fatal ("missing ')' in LanguageNames"); } +- break; +- +- case 15: +-#line 91 "mcparse.y" +- { mc_fatal ("missing '(' in LanguageNames"); } +- break; +- +- case 16: +-#line 92 "mcparse.y" +- { mc_fatal ("missing '=' for LanguageNames"); } +- break; +- +- case 18: +-#line 94 "mcparse.y" +- { mc_fatal ("missing ')' in FacilityNames"); } +- break; +- +- case 19: +-#line 95 "mcparse.y" +- { mc_fatal ("missing '(' in FacilityNames"); } +- break; +- +- case 20: +-#line 96 "mcparse.y" +- { mc_fatal ("missing '=' for FacilityNames"); } +- break; +- +- case 21: +-#line 98 "mcparse.y" +- { +- if ((yyvsp[(3) - (3)].ival) != 10 && (yyvsp[(3) - (3)].ival) != 16) +- mc_fatal ("OutputBase allows 10 or 16 as value"); +- mcset_out_values_are_decimal = ((yyvsp[(3) - (3)].ival) == 10 ? 1 : 0); +- } +- break; +- +- case 22: +-#line 104 "mcparse.y" +- { +- mcset_msg_id_typedef = (yyvsp[(3) - (3)].ustr); +- } +- break; +- +- case 23: +-#line 108 "mcparse.y" +- { +- mc_fatal ("MessageIdTypedef expects an identifier"); +- } +- break; +- +- case 24: +-#line 112 "mcparse.y" +- { +- mc_fatal ("missing '=' for MessageIdTypedef"); +- } +- break; +- +- case 27: +-#line 120 "mcparse.y" +- { mc_fatal ("severity ident missing"); } +- break; +- +- case 28: +-#line 125 "mcparse.y" +- { +- mc_add_keyword ((yyvsp[(1) - (4)].ustr), MCTOKEN, "severity", (yyvsp[(3) - (4)].ival), (yyvsp[(4) - (4)].ustr)); +- } +- break; +- +- case 29: +-#line 128 "mcparse.y" +- { mc_fatal ("severity number missing"); } +- break; +- +- case 30: +-#line 129 "mcparse.y" +- { mc_fatal ("severity missing '='"); } +- break; +- +- case 33: +-#line 135 "mcparse.y" +- { mc_fatal ("missing ident in FacilityNames"); } +- break; +- +- case 34: +-#line 140 "mcparse.y" +- { +- mc_add_keyword ((yyvsp[(1) - (4)].ustr), MCTOKEN, "facility", (yyvsp[(3) - (4)].ival), (yyvsp[(4) - (4)].ustr)); +- } +- break; +- +- case 35: +-#line 143 "mcparse.y" +- { mc_fatal ("facility number missing"); } +- break; +- +- case 36: +-#line 144 "mcparse.y" +- { mc_fatal ("facility missing '='"); } +- break; +- +- case 39: +-#line 150 "mcparse.y" +- { mc_fatal ("missing ident in LanguageNames"); } +- break; +- +- case 40: +-#line 155 "mcparse.y" +- { +- mc_add_keyword ((yyvsp[(1) - (6)].ustr), MCTOKEN, "language", (yyvsp[(3) - (6)].ival), (yyvsp[(6) - (6)].ustr)); +- } +- break; +- +- case 41: +-#line 158 "mcparse.y" +- { mc_fatal ("missing filename in LanguageNames"); } +- break; +- +- case 42: +-#line 159 "mcparse.y" +- { mc_fatal ("missing ':' in LanguageNames"); } +- break; +- +- case 43: +-#line 160 "mcparse.y" +- { mc_fatal ("missing language code in LanguageNames"); } +- break; +- +- case 44: +-#line 161 "mcparse.y" +- { mc_fatal ("missing '=' for LanguageNames"); } +- break; +- +- case 45: +-#line 166 "mcparse.y" +- { +- (yyval.ustr) = NULL; +- } +- break; +- +- case 46: +-#line 170 "mcparse.y" +- { +- (yyval.ustr) = (yyvsp[(2) - (2)].ustr); +- } +- break; +- +- case 47: +-#line 173 "mcparse.y" +- { mc_fatal ("illegal token in identifier"); (yyval.ustr) = NULL; } +- break; +- +- case 48: +-#line 178 "mcparse.y" +- { +- cur_node = mc_add_node (); +- cur_node->symbol = mc_last_symbol; +- cur_node->facility = mc_cur_facility; +- cur_node->severity = mc_cur_severity; +- cur_node->id = ((yyvsp[(1) - (2)].ival) & 0xffffUL); +- cur_node->vid = ((yyvsp[(1) - (2)].ival) & 0xffffUL) | mc_sefa_val; +- mc_last_id = (yyvsp[(1) - (2)].ival); +- } +- break; +- +- case 50: +-#line 190 "mcparse.y" +- { (yyval.ival) = (yyvsp[(3) - (3)].ival); } +- break; +- +- case 51: +-#line 191 "mcparse.y" +- { mc_fatal ("missing number in MessageId"); (yyval.ival) = 0; } +- break; +- +- case 52: +-#line 192 "mcparse.y" +- { mc_fatal ("missing '=' for MessageId"); (yyval.ival) = 0; } +- break; +- +- case 53: +-#line 196 "mcparse.y" +- { +- (yyval.ival) = ++mc_last_id; +- } +- break; +- +- case 54: +-#line 200 "mcparse.y" +- { +- (yyval.ival) = (yyvsp[(1) - (1)].ival); +- } +- break; +- +- case 55: +-#line 204 "mcparse.y" +- { +- (yyval.ival) = mc_last_id + (yyvsp[(2) - (2)].ival); +- } +- break; +- +- case 56: +-#line 207 "mcparse.y" +- { mc_fatal ("missing number after MessageId '+'"); } +- break; +- +- case 57: +-#line 212 "mcparse.y" +- { +- (yyval.ival) = 0; +- mc_sefa_val = (mcset_custom_bit ? 1 : 0) << 29; +- mc_last_symbol = NULL; +- mc_cur_severity = NULL; +- mc_cur_facility = NULL; +- } +- break; +- +- case 58: +-#line 220 "mcparse.y" +- { +- if ((yyvsp[(1) - (2)].ival) & 1) +- mc_warn (_("duplicate definition of Severity")); +- (yyval.ival) = (yyvsp[(1) - (2)].ival) | 1; +- } +- break; +- +- case 59: +-#line 226 "mcparse.y" +- { +- if ((yyvsp[(1) - (2)].ival) & 2) +- mc_warn (_("duplicate definition of Facility")); +- (yyval.ival) = (yyvsp[(1) - (2)].ival) | 2; +- } +- break; +- +- case 60: +-#line 232 "mcparse.y" +- { +- if ((yyvsp[(1) - (2)].ival) & 4) +- mc_warn (_("duplicate definition of SymbolicName")); +- (yyval.ival) = (yyvsp[(1) - (2)].ival) | 4; +- } +- break; +- +- case 61: +-#line 240 "mcparse.y" +- { +- mc_sefa_val &= ~ (0x3UL << 30); +- mc_sefa_val |= (((yyvsp[(3) - (3)].tok)->nval & 0x3UL) << 30); +- mc_cur_severity = (yyvsp[(3) - (3)].tok); +- } +- break; +- +- case 62: +-#line 248 "mcparse.y" +- { +- mc_sefa_val &= ~ (0xfffUL << 16); +- mc_sefa_val |= (((yyvsp[(3) - (3)].tok)->nval & 0xfffUL) << 16); +- mc_cur_facility = (yyvsp[(3) - (3)].tok); +- } +- break; +- +- case 63: +-#line 256 "mcparse.y" +- { +- mc_last_symbol = (yyvsp[(3) - (3)].ustr); +- } +- break; +- +- case 66: +-#line 268 "mcparse.y" +- { +- mc_node_lang *h; +- h = mc_add_node_lang (cur_node, (yyvsp[(1) - (4)].tok), cur_node->vid); +- h->message = (yyvsp[(3) - (4)].ustr); +- if (mcset_max_message_length != 0 && unichar_len (h->message) > mcset_max_message_length) +- mc_warn ("message length to long"); +- } +- break; +- +- case 67: +-#line 278 "mcparse.y" +- { +- (yyval.ustr) = (yyvsp[(1) - (1)].ustr); +- } +- break; +- +- case 68: +-#line 282 "mcparse.y" +- { +- unichar *h; +- rc_uint_type l1,l2; +- l1 = unichar_len ((yyvsp[(1) - (2)].ustr)); +- l2 = unichar_len ((yyvsp[(2) - (2)].ustr)); +- h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); +- if (l1) memcpy (h, (yyvsp[(1) - (2)].ustr), l1 * sizeof (unichar)); +- if (l2) memcpy (&h[l1], (yyvsp[(2) - (2)].ustr), l2 * sizeof (unichar)); +- h[l1 + l2] = 0; +- (yyval.ustr) = h; +- } +- break; +- +- case 69: +-#line 293 "mcparse.y" +- { mc_fatal ("missing end of message text"); (yyval.ustr) = NULL; } +- break; +- +- case 70: +-#line 294 "mcparse.y" +- { mc_fatal ("missing end of message text"); (yyval.ustr) = (yyvsp[(1) - (2)].ustr); } +- break; +- +- case 71: +-#line 297 "mcparse.y" +- { (yyval.ustr) = (yyvsp[(1) - (1)].ustr); } +- break; +- +- case 72: +-#line 299 "mcparse.y" +- { +- unichar *h; +- rc_uint_type l1,l2; +- l1 = unichar_len ((yyvsp[(1) - (2)].ustr)); +- l2 = unichar_len ((yyvsp[(2) - (2)].ustr)); +- h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); +- if (l1) memcpy (h, (yyvsp[(1) - (2)].ustr), l1 * sizeof (unichar)); +- if (l2) memcpy (&h[l1], (yyvsp[(2) - (2)].ustr), l2 * sizeof (unichar)); +- h[l1 + l2] = 0; +- (yyval.ustr) = h; +- } +- break; +- +- case 73: +-#line 313 "mcparse.y" +- { +- (yyval.tok) = (yyvsp[(4) - (5)].tok); +- } +- break; +- +- case 74: +-#line 317 "mcparse.y" +- { +- (yyval.tok) = NULL; +- mc_fatal (_("undeclared language identifier")); +- } +- break; +- +- case 75: +-#line 322 "mcparse.y" +- { +- (yyval.tok) = NULL; +- mc_fatal ("missing newline after Language"); +- } +- break; +- +- case 76: +-#line 327 "mcparse.y" +- { +- (yyval.tok) = NULL; +- mc_fatal ("missing ident for Language"); +- } +- break; +- +- case 77: +-#line 332 "mcparse.y" +- { +- (yyval.tok) = NULL; +- mc_fatal ("missing '=' for Language"); +- } +- break; +- +- case 78: +-#line 338 "mcparse.y" +- { (yyval.ustr) = (yyvsp[(1) - (1)].ustr); } +- break; +- +- case 79: +-#line 339 "mcparse.y" +- { (yyval.ustr) = (yyvsp[(1) - (1)].tok)->usz; } +- break; +- +- case 80: +-#line 343 "mcparse.y" +- { mclex_want_nl = 1; } +- break; +- +- case 81: +-#line 347 "mcparse.y" +- { mclex_want_line = 1; } +- break; +- +- case 82: +-#line 351 "mcparse.y" +- { mclex_want_filename = 1; } +- break; +- +- +-/* Line 1267 of yacc.c. */ +-#line 1939 "mcparse.c" +- default: break; +- } +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- +- /* Now `shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ +-yyerrlab: +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +- { +- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); +- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) +- { +- YYSIZE_T yyalloc = 2 * yysize; +- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) +- yyalloc = YYSTACK_ALLOC_MAXIMUM; +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yyalloc); +- if (yymsg) +- yymsg_alloc = yyalloc; +- else +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- } +- } +- +- if (0 < yysize && yysize <= yymsg_alloc) +- { +- (void) yysyntax_error (yymsg, yystate, yychar); +- yyerror (yymsg); +- } +- else +- { +- yyerror (YY_("syntax error")); +- if (yysize != 0) +- goto yyexhaustedlab; +- } +- } +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse look-ahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse look-ahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule which action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (yyn != YYPACT_NINF) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- *++yyvsp = yylval; +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#ifndef yyoverflow +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEOF && yychar != YYEMPTY) +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- /* Do not reclaim the symbols of the rule which action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); +-} +- +- +-#line 354 "mcparse.y" +- +- +-/* Something else. */ +- +diff -Nur binutils-2.24.orig/binutils/mcparse.h binutils-2.24/binutils/mcparse.h +--- binutils-2.24.orig/binutils/mcparse.h 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/mcparse.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,103 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton interface for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- NL = 258, +- MCIDENT = 259, +- MCFILENAME = 260, +- MCLINE = 261, +- MCCOMMENT = 262, +- MCTOKEN = 263, +- MCENDLINE = 264, +- MCLANGUAGENAMES = 265, +- MCFACILITYNAMES = 266, +- MCSEVERITYNAMES = 267, +- MCOUTPUTBASE = 268, +- MCMESSAGEIDTYPEDEF = 269, +- MCLANGUAGE = 270, +- MCMESSAGEID = 271, +- MCSEVERITY = 272, +- MCFACILITY = 273, +- MCSYMBOLICNAME = 274, +- MCNUMBER = 275 +- }; +-#endif +-/* Tokens. */ +-#define NL 258 +-#define MCIDENT 259 +-#define MCFILENAME 260 +-#define MCLINE 261 +-#define MCCOMMENT 262 +-#define MCTOKEN 263 +-#define MCENDLINE 264 +-#define MCLANGUAGENAMES 265 +-#define MCFACILITYNAMES 266 +-#define MCSEVERITYNAMES 267 +-#define MCOUTPUTBASE 268 +-#define MCMESSAGEIDTYPEDEF 269 +-#define MCLANGUAGE 270 +-#define MCMESSAGEID 271 +-#define MCSEVERITY 272 +-#define MCFACILITY 273 +-#define MCSYMBOLICNAME 274 +-#define MCNUMBER 275 +- +- +- +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 45 "mcparse.y" +-{ +- rc_uint_type ival; +- unichar *ustr; +- const mc_keyword *tok; +- mc_node *nod; +-} +-/* Line 1529 of yacc.c. */ +-#line 96 "mcparse.h" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +-extern YYSTYPE yylval; +- +diff -Nur binutils-2.24.orig/binutils/nlmheader.c binutils-2.24/binutils/nlmheader.c +--- binutils-2.24.orig/binutils/nlmheader.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/nlmheader.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,2698 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton implementation for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "2.3" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Using locations. */ +-#define YYLSP_NEEDED 0 +- +- +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- CHECK = 258, +- CODESTART = 259, +- COPYRIGHT = 260, +- CUSTOM = 261, +- DATE = 262, +- DEBUG_K = 263, +- DESCRIPTION = 264, +- EXIT = 265, +- EXPORT = 266, +- FLAG_ON = 267, +- FLAG_OFF = 268, +- FULLMAP = 269, +- HELP = 270, +- IMPORT = 271, +- INPUT = 272, +- MAP = 273, +- MESSAGES = 274, +- MODULE = 275, +- MULTIPLE = 276, +- OS_DOMAIN = 277, +- OUTPUT = 278, +- PSEUDOPREEMPTION = 279, +- REENTRANT = 280, +- SCREENNAME = 281, +- SHARELIB = 282, +- STACK = 283, +- START = 284, +- SYNCHRONIZE = 285, +- THREADNAME = 286, +- TYPE = 287, +- VERBOSE = 288, +- VERSIONK = 289, +- XDCDATA = 290, +- STRING = 291, +- QUOTED_STRING = 292 +- }; +-#endif +-/* Tokens. */ +-#define CHECK 258 +-#define CODESTART 259 +-#define COPYRIGHT 260 +-#define CUSTOM 261 +-#define DATE 262 +-#define DEBUG_K 263 +-#define DESCRIPTION 264 +-#define EXIT 265 +-#define EXPORT 266 +-#define FLAG_ON 267 +-#define FLAG_OFF 268 +-#define FULLMAP 269 +-#define HELP 270 +-#define IMPORT 271 +-#define INPUT 272 +-#define MAP 273 +-#define MESSAGES 274 +-#define MODULE 275 +-#define MULTIPLE 276 +-#define OS_DOMAIN 277 +-#define OUTPUT 278 +-#define PSEUDOPREEMPTION 279 +-#define REENTRANT 280 +-#define SCREENNAME 281 +-#define SHARELIB 282 +-#define STACK 283 +-#define START 284 +-#define SYNCHRONIZE 285 +-#define THREADNAME 286 +-#define TYPE 287 +-#define VERBOSE 288 +-#define VERSIONK 289 +-#define XDCDATA 290 +-#define STRING 291 +-#define QUOTED_STRING 292 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 1 "nlmheader.y" +-/* nlmheader.y - parse NLM header specification keywords. +- Copyright 1993, 1994, 1995, 1997, 1998, 2001, 2002, 2003, 2005, 2007, +- 2010 Free Software Foundation, Inc. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +-/* Written by Ian Lance Taylor . +- +- This bison file parses the commands recognized by the NetWare NLM +- linker, except for lists of object files. It stores the +- information in global variables. +- +- This implementation is based on the description in the NetWare Tool +- Maker Specification manual, edition 1.0. */ +- +-#include "sysdep.h" +-#include "safe-ctype.h" +-#include "bfd.h" +-#include "nlm/common.h" +-#include "nlm/internal.h" +-#include "bucomm.h" +-#include "nlmconv.h" +- +-/* Information is stored in the structures pointed to by these +- variables. */ +- +-Nlm_Internal_Fixed_Header *fixed_hdr; +-Nlm_Internal_Variable_Header *var_hdr; +-Nlm_Internal_Version_Header *version_hdr; +-Nlm_Internal_Copyright_Header *copyright_hdr; +-Nlm_Internal_Extended_Header *extended_hdr; +- +-/* Procedure named by CHECK. */ +-char *check_procedure; +-/* File named by CUSTOM. */ +-char *custom_file; +-/* Whether to generate debugging information (DEBUG). */ +-bfd_boolean debug_info; +-/* Procedure named by EXIT. */ +-char *exit_procedure; +-/* Exported symbols (EXPORT). */ +-struct string_list *export_symbols; +-/* List of files from INPUT. */ +-struct string_list *input_files; +-/* Map file name (MAP, FULLMAP). */ +-char *map_file; +-/* Whether a full map has been requested (FULLMAP). */ +-bfd_boolean full_map; +-/* File named by HELP. */ +-char *help_file; +-/* Imported symbols (IMPORT). */ +-struct string_list *import_symbols; +-/* File named by MESSAGES. */ +-char *message_file; +-/* Autoload module list (MODULE). */ +-struct string_list *modules; +-/* File named by OUTPUT. */ +-char *output_file; +-/* File named by SHARELIB. */ +-char *sharelib_file; +-/* Start procedure name (START). */ +-char *start_procedure; +-/* VERBOSE. */ +-bfd_boolean verbose; +-/* RPC description file (XDCDATA). */ +-char *rpc_file; +- +-/* The number of serious errors that have occurred. */ +-int parse_errors; +- +-/* The current symbol prefix when reading a list of import or export +- symbols. */ +-static char *symbol_prefix; +- +-/* Parser error message handler. */ +-#define yyerror(msg) nlmheader_error (msg); +- +-/* Local functions. */ +-static int yylex (void); +-static void nlmlex_file_push (const char *); +-static bfd_boolean nlmlex_file_open (const char *); +-static int nlmlex_buf_init (void); +-static char nlmlex_buf_add (int); +-static long nlmlex_get_number (const char *); +-static void nlmheader_identify (void); +-static void nlmheader_warn (const char *, int); +-static void nlmheader_error (const char *); +-static struct string_list * string_list_cons (char *, struct string_list *); +-static struct string_list * string_list_append (struct string_list *, +- struct string_list *); +-static struct string_list * string_list_append1 (struct string_list *, +- char *); +-static char *xstrdup (const char *); +- +- +- +-/* Enabling traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* Enabling the token table. */ +-#ifndef YYTOKEN_TABLE +-# define YYTOKEN_TABLE 0 +-#endif +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 113 "nlmheader.y" +-{ +- char *string; +- struct string_list *list; +-} +-/* Line 193 of yacc.c. */ +-#line 286 "nlmheader.c" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +- +- +-/* Copy the second part of user declarations. */ +- +- +-/* Line 216 of yacc.c. */ +-#line 299 "nlmheader.c" +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; +-#else +-typedef short int yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(msgid) dgettext ("bison-runtime", msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(msgid) msgid +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(e) ((void) (e)) +-#else +-# define YYUSE(e) /* empty */ +-#endif +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(n) (n) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int i) +-#else +-static int +-YYID (i) +- int i; +-#endif +-{ +- return i; +-} +-#endif +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined _STDLIB_H \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss; +- YYSTYPE yyvs; +- }; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-/* Copy COUNT objects from FROM to TO. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(To, From, Count) \ +- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +-# else +-# define YYCOPY(To, From, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (To)[yyi] = (From)[yyi]; \ +- } \ +- while (YYID (0)) +-# endif +-# endif +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack, Stack, yysize); \ +- Stack = &yyptr->Stack; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) +- +-#endif +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 64 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 73 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 40 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 11 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 52 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 82 +- +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 292 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 38, 39, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +- 35, 36, 37 +-}; +- +-#if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint8 yyprhs[] = +-{ +- 0, 0, 3, 5, 6, 9, 12, 15, 18, 21, +- 26, 28, 31, 34, 35, 39, 42, 45, 47, 50, +- 53, 54, 58, 61, 63, 66, 69, 72, 74, 76, +- 79, 81, 83, 86, 89, 92, 95, 97, 100, 103, +- 105, 110, 114, 117, 118, 120, 122, 124, 127, 130, +- 134, 136, 137 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int8 yyrhs[] = +-{ +- 41, 0, -1, 42, -1, -1, 43, 42, -1, 3, +- 36, -1, 4, 36, -1, 5, 37, -1, 6, 36, +- -1, 7, 36, 36, 36, -1, 8, -1, 9, 37, +- -1, 10, 36, -1, -1, 11, 44, 46, -1, 12, +- 36, -1, 13, 36, -1, 14, -1, 14, 36, -1, +- 15, 36, -1, -1, 16, 45, 46, -1, 17, 50, +- -1, 18, -1, 18, 36, -1, 19, 36, -1, 20, +- 50, -1, 21, -1, 22, -1, 23, 36, -1, 24, +- -1, 25, -1, 26, 37, -1, 27, 36, -1, 28, +- 36, -1, 29, 36, -1, 30, -1, 31, 37, -1, +- 32, 36, -1, 33, -1, 34, 36, 36, 36, -1, +- 34, 36, 36, -1, 35, 36, -1, -1, 47, -1, +- 49, -1, 48, -1, 47, 49, -1, 47, 48, -1, +- 38, 36, 39, -1, 36, -1, -1, 36, 50, -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 144, 144, 149, 151, 157, 161, 166, 183, 187, +- 205, 209, 225, 230, 229, 237, 242, 247, 252, 257, +- 262, 261, 269, 273, 277, 281, 285, 289, 293, 297, +- 304, 308, 312, 328, 332, 337, 341, 345, 361, 366, +- 370, 394, 410, 420, 423, 434, 438, 442, 446, 455, +- 466, 483, 486 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "CHECK", "CODESTART", "COPYRIGHT", +- "CUSTOM", "DATE", "DEBUG_K", "DESCRIPTION", "EXIT", "EXPORT", "FLAG_ON", +- "FLAG_OFF", "FULLMAP", "HELP", "IMPORT", "INPUT", "MAP", "MESSAGES", +- "MODULE", "MULTIPLE", "OS_DOMAIN", "OUTPUT", "PSEUDOPREEMPTION", +- "REENTRANT", "SCREENNAME", "SHARELIB", "STACK", "START", "SYNCHRONIZE", +- "THREADNAME", "TYPE", "VERBOSE", "VERSIONK", "XDCDATA", "STRING", +- "QUOTED_STRING", "'('", "')'", "$accept", "file", "commands", "command", +- "@1", "@2", "symbol_list_opt", "symbol_list", "symbol_prefix", "symbol", +- "string_list", 0 +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, +- 285, 286, 287, 288, 289, 290, 291, 292, 40, 41 +-}; +-# endif +- +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 40, 41, 42, 42, 43, 43, 43, 43, 43, +- 43, 43, 43, 44, 43, 43, 43, 43, 43, 43, +- 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, +- 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, +- 43, 43, 43, 46, 46, 47, 47, 47, 47, 48, +- 49, 50, 50 +-}; +- +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 1, 0, 2, 2, 2, 2, 2, 4, +- 1, 2, 2, 0, 3, 2, 2, 1, 2, 2, +- 0, 3, 2, 1, 2, 2, 2, 1, 1, 2, +- 1, 1, 2, 2, 2, 2, 1, 2, 2, 1, +- 4, 3, 2, 0, 1, 1, 1, 2, 2, 3, +- 1, 0, 2 +-}; +- +-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state +- STATE-NUM when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 3, 0, 0, 0, 0, 0, 10, 0, 0, 13, +- 0, 0, 17, 0, 20, 51, 23, 0, 51, 27, +- 28, 0, 30, 31, 0, 0, 0, 0, 36, 0, +- 0, 39, 0, 0, 0, 2, 3, 5, 6, 7, +- 8, 0, 11, 12, 43, 15, 16, 18, 19, 43, +- 51, 22, 24, 25, 26, 29, 32, 33, 34, 35, +- 37, 38, 0, 42, 1, 4, 0, 50, 0, 14, +- 44, 46, 45, 21, 52, 41, 9, 0, 48, 47, +- 40, 49 +-}; +- +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int8 yydefgoto[] = +-{ +- -1, 34, 35, 36, 44, 49, 69, 70, 71, 72, +- 51 +-}; +- +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -20 +-static const yytype_int8 yypact[] = +-{ +- -3, -1, 1, 2, 4, 5, -20, 6, 8, -20, +- 9, 10, 11, 12, -20, 13, 14, 16, 13, -20, +- -20, 17, -20, -20, 18, 20, 21, 22, -20, 23, +- 25, -20, 26, 27, 38, -20, -3, -20, -20, -20, +- -20, 28, -20, -20, -2, -20, -20, -20, -20, -2, +- 13, -20, -20, -20, -20, -20, -20, -20, -20, -20, +- -20, -20, 30, -20, -20, -20, 31, -20, 32, -20, +- -2, -20, -20, -20, -20, 33, -20, 3, -20, -20, +- -20, -20 +-}; +- +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = +-{ +- -20, -20, 34, -20, -20, -20, 24, -20, -19, -16, +- 15 +-}; +- +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If zero, do what YYDEFACT says. +- If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -1 +-static const yytype_uint8 yytable[] = +-{ +- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, +- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, +- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, +- 31, 32, 33, 54, 67, 37, 68, 38, 64, 39, +- 40, 41, 81, 42, 43, 45, 46, 47, 48, 50, +- 52, 78, 53, 55, 79, 56, 57, 58, 59, 0, +- 60, 61, 62, 63, 66, 74, 75, 76, 77, 80, +- 65, 0, 0, 73 +-}; +- +-static const yytype_int8 yycheck[] = +-{ +- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, +- 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, +- 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, +- 33, 34, 35, 18, 36, 36, 38, 36, 0, 37, +- 36, 36, 39, 37, 36, 36, 36, 36, 36, 36, +- 36, 70, 36, 36, 70, 37, 36, 36, 36, -1, +- 37, 36, 36, 36, 36, 50, 36, 36, 36, 36, +- 36, -1, -1, 49 +-}; +- +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, +- 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, +- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, +- 32, 33, 34, 35, 41, 42, 43, 36, 36, 37, +- 36, 36, 37, 36, 44, 36, 36, 36, 36, 45, +- 36, 50, 36, 36, 50, 36, 37, 36, 36, 36, +- 37, 36, 36, 36, 0, 42, 36, 36, 38, 46, +- 47, 48, 49, 46, 50, 36, 36, 36, 48, 49, +- 36, 39 +-}; +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. */ +- +-#define YYFAIL goto yyerrlab +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY && yylen == 1) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK (1); \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) +- +- +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +- If N is 0, then set CURRENT to the empty location which ends +- the previous symbol: RHS[0] (always defined). */ +- +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +-#ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (YYID (N)) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (YYID (0)) +-#endif +- +- +-/* YY_LOCATION_PRINT -- Print the location on the stream. +- This macro was not mandated originally: define only if we know +- we won't break user code: when these are the locations we know. */ +- +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +-# define YY_LOCATION_PRINT(File, Loc) \ +- fprintf (File, "%d.%d-%d.%d", \ +- (Loc).first_line, (Loc).first_column, \ +- (Loc).last_line, (Loc).last_column) +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif +- +- +-/* YYLEX -- calling `yylex' with the right arguments. */ +- +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); +-# endif +- switch (yytype) +- { +- default: +- break; +- } +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +-#else +-static void +-yy_stack_print (bottom, top) +- yytype_int16 *bottom; +- yytype_int16 *top; +-#endif +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; bottom <= top; ++bottom) +- YYFPRINTF (stderr, " %d", *bottom); +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif +-{ +- int yynrhs = yyr2[yyrule]; +- int yyi; +- unsigned long int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- fprintf (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- fprintf (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static YYSIZE_T +-yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into YYRESULT an error message about the unexpected token +- YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not +- copy anything; just return the number of bytes that would be +- copied. As a special case, return 0 if an ordinary "syntax error" +- message will do. Return YYSIZE_MAXIMUM if overflow occurs during +- size calculation. */ +-static YYSIZE_T +-yysyntax_error (char *yyresult, int yystate, int yychar) +-{ +- int yyn = yypact[yystate]; +- +- if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) +- return 0; +- else +- { +- int yytype = YYTRANSLATE (yychar); +- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); +- YYSIZE_T yysize = yysize0; +- YYSIZE_T yysize1; +- int yysize_overflow = 0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- int yyx; +- +-# if 0 +- /* This is so xgettext sees the translatable formats that are +- constructed on the fly. */ +- YY_("syntax error, unexpected %s"); +- YY_("syntax error, unexpected %s, expecting %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +-# endif +- char *yyfmt; +- char const *yyf; +- static char const yyunexpected[] = "syntax error, unexpected %s"; +- static char const yyexpecting[] = ", expecting %s"; +- static char const yyor[] = " or %s"; +- char yyformat[sizeof yyunexpected +- + sizeof yyexpecting - 1 +- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) +- * (sizeof yyor - 1))]; +- char const *yyprefix = yyexpecting; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 1; +- +- yyarg[0] = yytname[yytype]; +- yyfmt = yystpcpy (yyformat, yyunexpected); +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- yyformat[sizeof yyunexpected - 1] = '\0'; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- yysize1 = yysize + yytnamerr (0, yytname[yyx]); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- yyfmt = yystpcpy (yyfmt, yyprefix); +- yyprefix = yyor; +- } +- +- yyf = YY_(yyformat); +- yysize1 = yysize + yystrlen (yyf); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- +- if (yysize_overflow) +- return YYSIZE_MAXIMUM; +- +- if (yyresult) +- { +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- char *yyp = yyresult; +- int yyi = 0; +- while ((*yyp = *yyf) != '\0') +- { +- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyf += 2; +- } +- else +- { +- yyp++; +- yyf++; +- } +- } +- } +- return yysize; +- } +-} +-#endif /* YYERROR_VERBOSE */ +- +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif +-{ +- YYUSE (yyvaluep); +- +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- switch (yytype) +- { +- +- default: +- break; +- } +-} +- +- +-/* Prevent warnings from -Wmissing-prototypes. */ +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ +- +- +- +-/* The look-ahead symbol. */ +-int yychar; +- +-/* The semantic value of the look-ahead symbol. */ +-YYSTYPE yylval; +- +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif +-{ +- +- int yystate; +- int yyn; +- int yyresult; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- /* Look-ahead token as an internal (translated) token number. */ +- int yytoken = 0; +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +- /* Three stacks and their tools: +- `yyss': related to states, +- `yyvs': related to semantic values, +- `yyls': related to locations. +- +- Refer to the stacks thru separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss = yyssa; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs = yyvsa; +- YYSTYPE *yyvsp; +- +- +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- YYSIZE_T yystacksize = YYINITDEPTH; +- +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- +- /* Initialize stack pointers. +- Waste one element of value and location stack +- so that they stay on the same level as the state stack. +- The wasted elements are never initialized. */ +- +- yyssp = yyss; +- yyvsp = yyvs; +- +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss); +- YYSTACK_RELOCATE (yyvs); +- +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- look-ahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to look-ahead token. */ +- yyn = yypact[yystate]; +- if (yyn == YYPACT_NINF) +- goto yydefault; +- +- /* Not known => get a look-ahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yyn == 0 || yyn == YYTABLE_NINF) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the look-ahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- yystate = yyn; +- *++yyvsp = yylval; +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 5: +-#line 158 "nlmheader.y" +- { +- check_procedure = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 6: +-#line 162 "nlmheader.y" +- { +- nlmheader_warn (_("CODESTART is not implemented; sorry"), -1); +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 7: +-#line 167 "nlmheader.y" +- { +- int len; +- +- strncpy (copyright_hdr->stamp, "CoPyRiGhT=", 10); +- len = strlen ((yyvsp[(2) - (2)].string)); +- if (len >= NLM_MAX_COPYRIGHT_MESSAGE_LENGTH) +- { +- nlmheader_warn (_("copyright string is too long"), +- NLM_MAX_COPYRIGHT_MESSAGE_LENGTH - 1); +- len = NLM_MAX_COPYRIGHT_MESSAGE_LENGTH - 1; +- } +- copyright_hdr->copyrightMessageLength = len; +- strncpy (copyright_hdr->copyrightMessage, (yyvsp[(2) - (2)].string), len); +- copyright_hdr->copyrightMessage[len] = '\0'; +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 8: +-#line 184 "nlmheader.y" +- { +- custom_file = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 9: +-#line 188 "nlmheader.y" +- { +- /* We don't set the version stamp here, because we use the +- version stamp to detect whether the required VERSION +- keyword was given. */ +- version_hdr->month = nlmlex_get_number ((yyvsp[(2) - (4)].string)); +- version_hdr->day = nlmlex_get_number ((yyvsp[(3) - (4)].string)); +- version_hdr->year = nlmlex_get_number ((yyvsp[(4) - (4)].string)); +- free ((yyvsp[(2) - (4)].string)); +- free ((yyvsp[(3) - (4)].string)); +- free ((yyvsp[(4) - (4)].string)); +- if (version_hdr->month < 1 || version_hdr->month > 12) +- nlmheader_warn (_("illegal month"), -1); +- if (version_hdr->day < 1 || version_hdr->day > 31) +- nlmheader_warn (_("illegal day"), -1); +- if (version_hdr->year < 1900 || version_hdr->year > 3000) +- nlmheader_warn (_("illegal year"), -1); +- } +- break; +- +- case 10: +-#line 206 "nlmheader.y" +- { +- debug_info = TRUE; +- } +- break; +- +- case 11: +-#line 210 "nlmheader.y" +- { +- int len; +- +- len = strlen ((yyvsp[(2) - (2)].string)); +- if (len > NLM_MAX_DESCRIPTION_LENGTH) +- { +- nlmheader_warn (_("description string is too long"), +- NLM_MAX_DESCRIPTION_LENGTH); +- len = NLM_MAX_DESCRIPTION_LENGTH; +- } +- var_hdr->descriptionLength = len; +- strncpy (var_hdr->descriptionText, (yyvsp[(2) - (2)].string), len); +- var_hdr->descriptionText[len] = '\0'; +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 12: +-#line 226 "nlmheader.y" +- { +- exit_procedure = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 13: +-#line 230 "nlmheader.y" +- { +- symbol_prefix = NULL; +- } +- break; +- +- case 14: +-#line 234 "nlmheader.y" +- { +- export_symbols = string_list_append (export_symbols, (yyvsp[(3) - (3)].list)); +- } +- break; +- +- case 15: +-#line 238 "nlmheader.y" +- { +- fixed_hdr->flags |= nlmlex_get_number ((yyvsp[(2) - (2)].string)); +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 16: +-#line 243 "nlmheader.y" +- { +- fixed_hdr->flags &=~ nlmlex_get_number ((yyvsp[(2) - (2)].string)); +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 17: +-#line 248 "nlmheader.y" +- { +- map_file = ""; +- full_map = TRUE; +- } +- break; +- +- case 18: +-#line 253 "nlmheader.y" +- { +- map_file = (yyvsp[(2) - (2)].string); +- full_map = TRUE; +- } +- break; +- +- case 19: +-#line 258 "nlmheader.y" +- { +- help_file = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 20: +-#line 262 "nlmheader.y" +- { +- symbol_prefix = NULL; +- } +- break; +- +- case 21: +-#line 266 "nlmheader.y" +- { +- import_symbols = string_list_append (import_symbols, (yyvsp[(3) - (3)].list)); +- } +- break; +- +- case 22: +-#line 270 "nlmheader.y" +- { +- input_files = string_list_append (input_files, (yyvsp[(2) - (2)].list)); +- } +- break; +- +- case 23: +-#line 274 "nlmheader.y" +- { +- map_file = ""; +- } +- break; +- +- case 24: +-#line 278 "nlmheader.y" +- { +- map_file = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 25: +-#line 282 "nlmheader.y" +- { +- message_file = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 26: +-#line 286 "nlmheader.y" +- { +- modules = string_list_append (modules, (yyvsp[(2) - (2)].list)); +- } +- break; +- +- case 27: +-#line 290 "nlmheader.y" +- { +- fixed_hdr->flags |= 0x2; +- } +- break; +- +- case 28: +-#line 294 "nlmheader.y" +- { +- fixed_hdr->flags |= 0x10; +- } +- break; +- +- case 29: +-#line 298 "nlmheader.y" +- { +- if (output_file == NULL) +- output_file = (yyvsp[(2) - (2)].string); +- else +- nlmheader_warn (_("ignoring duplicate OUTPUT statement"), -1); +- } +- break; +- +- case 30: +-#line 305 "nlmheader.y" +- { +- fixed_hdr->flags |= 0x8; +- } +- break; +- +- case 31: +-#line 309 "nlmheader.y" +- { +- fixed_hdr->flags |= 0x1; +- } +- break; +- +- case 32: +-#line 313 "nlmheader.y" +- { +- int len; +- +- len = strlen ((yyvsp[(2) - (2)].string)); +- if (len >= NLM_MAX_SCREEN_NAME_LENGTH) +- { +- nlmheader_warn (_("screen name is too long"), +- NLM_MAX_SCREEN_NAME_LENGTH); +- len = NLM_MAX_SCREEN_NAME_LENGTH; +- } +- var_hdr->screenNameLength = len; +- strncpy (var_hdr->screenName, (yyvsp[(2) - (2)].string), len); +- var_hdr->screenName[NLM_MAX_SCREEN_NAME_LENGTH] = '\0'; +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 33: +-#line 329 "nlmheader.y" +- { +- sharelib_file = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 34: +-#line 333 "nlmheader.y" +- { +- var_hdr->stackSize = nlmlex_get_number ((yyvsp[(2) - (2)].string)); +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 35: +-#line 338 "nlmheader.y" +- { +- start_procedure = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 36: +-#line 342 "nlmheader.y" +- { +- fixed_hdr->flags |= 0x4; +- } +- break; +- +- case 37: +-#line 346 "nlmheader.y" +- { +- int len; +- +- len = strlen ((yyvsp[(2) - (2)].string)); +- if (len >= NLM_MAX_THREAD_NAME_LENGTH) +- { +- nlmheader_warn (_("thread name is too long"), +- NLM_MAX_THREAD_NAME_LENGTH); +- len = NLM_MAX_THREAD_NAME_LENGTH; +- } +- var_hdr->threadNameLength = len; +- strncpy (var_hdr->threadName, (yyvsp[(2) - (2)].string), len); +- var_hdr->threadName[len] = '\0'; +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 38: +-#line 362 "nlmheader.y" +- { +- fixed_hdr->moduleType = nlmlex_get_number ((yyvsp[(2) - (2)].string)); +- free ((yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 39: +-#line 367 "nlmheader.y" +- { +- verbose = TRUE; +- } +- break; +- +- case 40: +-#line 371 "nlmheader.y" +- { +- long val; +- +- strncpy (version_hdr->stamp, "VeRsIoN#", 8); +- version_hdr->majorVersion = nlmlex_get_number ((yyvsp[(2) - (4)].string)); +- val = nlmlex_get_number ((yyvsp[(3) - (4)].string)); +- if (val < 0 || val > 99) +- nlmheader_warn (_("illegal minor version number (must be between 0 and 99)"), +- -1); +- else +- version_hdr->minorVersion = val; +- val = nlmlex_get_number ((yyvsp[(4) - (4)].string)); +- if (val < 0) +- nlmheader_warn (_("illegal revision number (must be between 0 and 26)"), +- -1); +- else if (val > 26) +- version_hdr->revision = 0; +- else +- version_hdr->revision = val; +- free ((yyvsp[(2) - (4)].string)); +- free ((yyvsp[(3) - (4)].string)); +- free ((yyvsp[(4) - (4)].string)); +- } +- break; +- +- case 41: +-#line 395 "nlmheader.y" +- { +- long val; +- +- strncpy (version_hdr->stamp, "VeRsIoN#", 8); +- version_hdr->majorVersion = nlmlex_get_number ((yyvsp[(2) - (3)].string)); +- val = nlmlex_get_number ((yyvsp[(3) - (3)].string)); +- if (val < 0 || val > 99) +- nlmheader_warn (_("illegal minor version number (must be between 0 and 99)"), +- -1); +- else +- version_hdr->minorVersion = val; +- version_hdr->revision = 0; +- free ((yyvsp[(2) - (3)].string)); +- free ((yyvsp[(3) - (3)].string)); +- } +- break; +- +- case 42: +-#line 411 "nlmheader.y" +- { +- rpc_file = (yyvsp[(2) - (2)].string); +- } +- break; +- +- case 43: +-#line 420 "nlmheader.y" +- { +- (yyval.list) = NULL; +- } +- break; +- +- case 44: +-#line 424 "nlmheader.y" +- { +- (yyval.list) = (yyvsp[(1) - (1)].list); +- } +- break; +- +- case 45: +-#line 435 "nlmheader.y" +- { +- (yyval.list) = string_list_cons ((yyvsp[(1) - (1)].string), NULL); +- } +- break; +- +- case 46: +-#line 439 "nlmheader.y" +- { +- (yyval.list) = NULL; +- } +- break; +- +- case 47: +-#line 443 "nlmheader.y" +- { +- (yyval.list) = string_list_append1 ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].string)); +- } +- break; +- +- case 48: +-#line 447 "nlmheader.y" +- { +- (yyval.list) = (yyvsp[(1) - (2)].list); +- } +- break; +- +- case 49: +-#line 456 "nlmheader.y" +- { +- if (symbol_prefix != NULL) +- free (symbol_prefix); +- symbol_prefix = (yyvsp[(2) - (3)].string); +- } +- break; +- +- case 50: +-#line 467 "nlmheader.y" +- { +- if (symbol_prefix == NULL) +- (yyval.string) = (yyvsp[(1) - (1)].string); +- else +- { +- (yyval.string) = xmalloc (strlen (symbol_prefix) + strlen ((yyvsp[(1) - (1)].string)) + 2); +- sprintf ((yyval.string), "%s@%s", symbol_prefix, (yyvsp[(1) - (1)].string)); +- free ((yyvsp[(1) - (1)].string)); +- } +- } +- break; +- +- case 51: +-#line 483 "nlmheader.y" +- { +- (yyval.list) = NULL; +- } +- break; +- +- case 52: +-#line 487 "nlmheader.y" +- { +- (yyval.list) = string_list_cons ((yyvsp[(1) - (2)].string), (yyvsp[(2) - (2)].list)); +- } +- break; +- +- +-/* Line 1267 of yacc.c. */ +-#line 2015 "nlmheader.c" +- default: break; +- } +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- +- /* Now `shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ +-yyerrlab: +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +- { +- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); +- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) +- { +- YYSIZE_T yyalloc = 2 * yysize; +- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) +- yyalloc = YYSTACK_ALLOC_MAXIMUM; +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yyalloc); +- if (yymsg) +- yymsg_alloc = yyalloc; +- else +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- } +- } +- +- if (0 < yysize && yysize <= yymsg_alloc) +- { +- (void) yysyntax_error (yymsg, yystate, yychar); +- yyerror (yymsg); +- } +- else +- { +- yyerror (YY_("syntax error")); +- if (yysize != 0) +- goto yyexhaustedlab; +- } +- } +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse look-ahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse look-ahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule which action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (yyn != YYPACT_NINF) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- *++yyvsp = yylval; +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#ifndef yyoverflow +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEOF && yychar != YYEMPTY) +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- /* Do not reclaim the symbols of the rule which action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); +-} +- +- +-#line 492 "nlmheader.y" +- +- +-/* If strerror is just a macro, we want to use the one from libiberty +- since it will handle undefined values. */ +-#undef strerror +-extern char *strerror PARAMS ((int)); +- +-/* The lexer is simple, too simple for flex. Keywords are only +- recognized at the start of lines. Everything else must be an +- argument. A comma is treated as whitespace. */ +- +-/* The states the lexer can be in. */ +- +-enum lex_state +-{ +- /* At the beginning of a line. */ +- BEGINNING_OF_LINE, +- /* In the middle of a line. */ +- IN_LINE +-}; +- +-/* We need to keep a stack of files to handle file inclusion. */ +- +-struct input +-{ +- /* The file to read from. */ +- FILE *file; +- /* The name of the file. */ +- char *name; +- /* The current line number. */ +- int lineno; +- /* The current state. */ +- enum lex_state state; +- /* The next file on the stack. */ +- struct input *next; +-}; +- +-/* The current input file. */ +- +-static struct input current; +- +-/* The character which introduces comments. */ +-#define COMMENT_CHAR '#' +- +-/* Start the lexer going on the main input file. */ +- +-bfd_boolean +-nlmlex_file (const char *name) +-{ +- current.next = NULL; +- return nlmlex_file_open (name); +-} +- +-/* Start the lexer going on a subsidiary input file. */ +- +-static void +-nlmlex_file_push (const char *name) +-{ +- struct input *push; +- +- push = (struct input *) xmalloc (sizeof (struct input)); +- *push = current; +- if (nlmlex_file_open (name)) +- current.next = push; +- else +- { +- current = *push; +- free (push); +- } +-} +- +-/* Start lexing from a file. */ +- +-static bfd_boolean +-nlmlex_file_open (const char *name) +-{ +- current.file = fopen (name, "r"); +- if (current.file == NULL) +- { +- fprintf (stderr, "%s:%s: %s\n", program_name, name, strerror (errno)); +- ++parse_errors; +- return FALSE; +- } +- current.name = xstrdup (name); +- current.lineno = 1; +- current.state = BEGINNING_OF_LINE; +- return TRUE; +-} +- +-/* Table used to turn keywords into tokens. */ +- +-struct keyword_tokens_struct +-{ +- const char *keyword; +- int token; +-}; +- +-static struct keyword_tokens_struct keyword_tokens[] = +-{ +- { "CHECK", CHECK }, +- { "CODESTART", CODESTART }, +- { "COPYRIGHT", COPYRIGHT }, +- { "CUSTOM", CUSTOM }, +- { "DATE", DATE }, +- { "DEBUG", DEBUG_K }, +- { "DESCRIPTION", DESCRIPTION }, +- { "EXIT", EXIT }, +- { "EXPORT", EXPORT }, +- { "FLAG_ON", FLAG_ON }, +- { "FLAG_OFF", FLAG_OFF }, +- { "FULLMAP", FULLMAP }, +- { "HELP", HELP }, +- { "IMPORT", IMPORT }, +- { "INPUT", INPUT }, +- { "MAP", MAP }, +- { "MESSAGES", MESSAGES }, +- { "MODULE", MODULE }, +- { "MULTIPLE", MULTIPLE }, +- { "OS_DOMAIN", OS_DOMAIN }, +- { "OUTPUT", OUTPUT }, +- { "PSEUDOPREEMPTION", PSEUDOPREEMPTION }, +- { "REENTRANT", REENTRANT }, +- { "SCREENNAME", SCREENNAME }, +- { "SHARELIB", SHARELIB }, +- { "STACK", STACK }, +- { "STACKSIZE", STACK }, +- { "START", START }, +- { "SYNCHRONIZE", SYNCHRONIZE }, +- { "THREADNAME", THREADNAME }, +- { "TYPE", TYPE }, +- { "VERBOSE", VERBOSE }, +- { "VERSION", VERSIONK }, +- { "XDCDATA", XDCDATA } +-}; +- +-#define KEYWORD_COUNT (sizeof (keyword_tokens) / sizeof (keyword_tokens[0])) +- +-/* The lexer accumulates strings in these variables. */ +-static char *lex_buf; +-static int lex_size; +-static int lex_pos; +- +-/* Start accumulating strings into the buffer. */ +-#define BUF_INIT() \ +- ((void) (lex_buf != NULL ? lex_pos = 0 : nlmlex_buf_init ())) +- +-static int +-nlmlex_buf_init (void) +-{ +- lex_size = 10; +- lex_buf = xmalloc (lex_size + 1); +- lex_pos = 0; +- return 0; +-} +- +-/* Finish a string in the buffer. */ +-#define BUF_FINISH() ((void) (lex_buf[lex_pos] = '\0')) +- +-/* Accumulate a character into the buffer. */ +-#define BUF_ADD(c) \ +- ((void) (lex_pos < lex_size \ +- ? lex_buf[lex_pos++] = (c) \ +- : nlmlex_buf_add (c))) +- +-static char +-nlmlex_buf_add (int c) +-{ +- if (lex_pos >= lex_size) +- { +- lex_size *= 2; +- lex_buf = xrealloc (lex_buf, lex_size + 1); +- } +- +- return lex_buf[lex_pos++] = c; +-} +- +-/* The lexer proper. This is called by the bison generated parsing +- code. */ +- +-static int +-yylex (void) +-{ +- int c; +- +-tail_recurse: +- +- c = getc (current.file); +- +- /* Commas are treated as whitespace characters. */ +- while (ISSPACE (c) || c == ',') +- { +- current.state = IN_LINE; +- if (c == '\n') +- { +- ++current.lineno; +- current.state = BEGINNING_OF_LINE; +- } +- c = getc (current.file); +- } +- +- /* At the end of the file we either pop to the previous file or +- finish up. */ +- if (c == EOF) +- { +- fclose (current.file); +- free (current.name); +- if (current.next == NULL) +- return 0; +- else +- { +- struct input *next; +- +- next = current.next; +- current = *next; +- free (next); +- goto tail_recurse; +- } +- } +- +- /* A comment character always means to drop everything until the +- next newline. */ +- if (c == COMMENT_CHAR) +- { +- do +- { +- c = getc (current.file); +- } +- while (c != '\n'); +- ++current.lineno; +- current.state = BEGINNING_OF_LINE; +- goto tail_recurse; +- } +- +- /* An '@' introduces an include file. */ +- if (c == '@') +- { +- do +- { +- c = getc (current.file); +- if (c == '\n') +- ++current.lineno; +- } +- while (ISSPACE (c)); +- BUF_INIT (); +- while (! ISSPACE (c) && c != EOF) +- { +- BUF_ADD (c); +- c = getc (current.file); +- } +- BUF_FINISH (); +- +- ungetc (c, current.file); +- +- nlmlex_file_push (lex_buf); +- goto tail_recurse; +- } +- +- /* A non-space character at the start of a line must be the start of +- a keyword. */ +- if (current.state == BEGINNING_OF_LINE) +- { +- BUF_INIT (); +- while (ISALNUM (c) || c == '_') +- { +- BUF_ADD (TOUPPER (c)); +- c = getc (current.file); +- } +- BUF_FINISH (); +- +- if (c != EOF && ! ISSPACE (c) && c != ',') +- { +- nlmheader_identify (); +- fprintf (stderr, _("%s:%d: illegal character in keyword: %c\n"), +- current.name, current.lineno, c); +- } +- else +- { +- unsigned int i; +- +- for (i = 0; i < KEYWORD_COUNT; i++) +- { +- if (lex_buf[0] == keyword_tokens[i].keyword[0] +- && strcmp (lex_buf, keyword_tokens[i].keyword) == 0) +- { +- /* Pushing back the final whitespace avoids worrying +- about \n here. */ +- ungetc (c, current.file); +- current.state = IN_LINE; +- return keyword_tokens[i].token; +- } +- } +- +- nlmheader_identify (); +- fprintf (stderr, _("%s:%d: unrecognized keyword: %s\n"), +- current.name, current.lineno, lex_buf); +- } +- +- ++parse_errors; +- /* Treat the rest of this line as a comment. */ +- ungetc (COMMENT_CHAR, current.file); +- goto tail_recurse; +- } +- +- /* Parentheses just represent themselves. */ +- if (c == '(' || c == ')') +- return c; +- +- /* Handle quoted strings. */ +- if (c == '"' || c == '\'') +- { +- int quote; +- int start_lineno; +- +- quote = c; +- start_lineno = current.lineno; +- +- c = getc (current.file); +- BUF_INIT (); +- while (c != quote && c != EOF) +- { +- BUF_ADD (c); +- if (c == '\n') +- ++current.lineno; +- c = getc (current.file); +- } +- BUF_FINISH (); +- +- if (c == EOF) +- { +- nlmheader_identify (); +- fprintf (stderr, _("%s:%d: end of file in quoted string\n"), +- current.name, start_lineno); +- ++parse_errors; +- } +- +- /* FIXME: Possible memory leak. */ +- yylval.string = xstrdup (lex_buf); +- return QUOTED_STRING; +- } +- +- /* Gather a generic argument. */ +- BUF_INIT (); +- while (! ISSPACE (c) +- && c != ',' +- && c != COMMENT_CHAR +- && c != '(' +- && c != ')') +- { +- BUF_ADD (c); +- c = getc (current.file); +- } +- BUF_FINISH (); +- +- ungetc (c, current.file); +- +- /* FIXME: Possible memory leak. */ +- yylval.string = xstrdup (lex_buf); +- return STRING; +-} +- +-/* Get a number from a string. */ +- +-static long +-nlmlex_get_number (const char *s) +-{ +- long ret; +- char *send; +- +- ret = strtol (s, &send, 10); +- if (*send != '\0') +- nlmheader_warn (_("bad number"), -1); +- return ret; +-} +- +-/* Prefix the nlmconv warnings with a note as to where they come from. +- We don't use program_name on every warning, because then some +- versions of the emacs next-error function can't recognize the line +- number. */ +- +-static void +-nlmheader_identify (void) +-{ +- static int done; +- +- if (! done) +- { +- fprintf (stderr, _("%s: problems in NLM command language input:\n"), +- program_name); +- done = 1; +- } +-} +- +-/* Issue a warning. */ +- +-static void +-nlmheader_warn (const char *s, int imax) +-{ +- nlmheader_identify (); +- fprintf (stderr, "%s:%d: %s", current.name, current.lineno, s); +- if (imax != -1) +- fprintf (stderr, " (max %d)", imax); +- fprintf (stderr, "\n"); +-} +- +-/* Report an error. */ +- +-static void +-nlmheader_error (const char *s) +-{ +- nlmheader_warn (s, -1); +- ++parse_errors; +-} +- +-/* Add a string to a string list. */ +- +-static struct string_list * +-string_list_cons (char *s, struct string_list *l) +-{ +- struct string_list *ret; +- +- ret = (struct string_list *) xmalloc (sizeof (struct string_list)); +- ret->next = l; +- ret->string = s; +- return ret; +-} +- +-/* Append a string list to another string list. */ +- +-static struct string_list * +-string_list_append (struct string_list *l1, struct string_list *l2) +-{ +- register struct string_list **pp; +- +- for (pp = &l1; *pp != NULL; pp = &(*pp)->next) +- ; +- *pp = l2; +- return l1; +-} +- +-/* Append a string to a string list. */ +- +-static struct string_list * +-string_list_append1 (struct string_list *l, char *s) +-{ +- struct string_list *n; +- register struct string_list **pp; +- +- n = (struct string_list *) xmalloc (sizeof (struct string_list)); +- n->next = NULL; +- n->string = s; +- for (pp = &l; *pp != NULL; pp = &(*pp)->next) +- ; +- *pp = n; +- return l; +-} +- +-/* Duplicate a string in memory. */ +- +-static char * +-xstrdup (const char *s) +-{ +- unsigned long len; +- char *ret; +- +- len = strlen (s); +- ret = xmalloc (len + 1); +- strcpy (ret, s); +- return ret; +-} +- +diff -Nur binutils-2.24.orig/binutils/nlmheader.h binutils-2.24/binutils/nlmheader.h +--- binutils-2.24.orig/binutils/nlmheader.h 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/nlmheader.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,135 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton interface for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- CHECK = 258, +- CODESTART = 259, +- COPYRIGHT = 260, +- CUSTOM = 261, +- DATE = 262, +- DEBUG_K = 263, +- DESCRIPTION = 264, +- EXIT = 265, +- EXPORT = 266, +- FLAG_ON = 267, +- FLAG_OFF = 268, +- FULLMAP = 269, +- HELP = 270, +- IMPORT = 271, +- INPUT = 272, +- MAP = 273, +- MESSAGES = 274, +- MODULE = 275, +- MULTIPLE = 276, +- OS_DOMAIN = 277, +- OUTPUT = 278, +- PSEUDOPREEMPTION = 279, +- REENTRANT = 280, +- SCREENNAME = 281, +- SHARELIB = 282, +- STACK = 283, +- START = 284, +- SYNCHRONIZE = 285, +- THREADNAME = 286, +- TYPE = 287, +- VERBOSE = 288, +- VERSIONK = 289, +- XDCDATA = 290, +- STRING = 291, +- QUOTED_STRING = 292 +- }; +-#endif +-/* Tokens. */ +-#define CHECK 258 +-#define CODESTART 259 +-#define COPYRIGHT 260 +-#define CUSTOM 261 +-#define DATE 262 +-#define DEBUG_K 263 +-#define DESCRIPTION 264 +-#define EXIT 265 +-#define EXPORT 266 +-#define FLAG_ON 267 +-#define FLAG_OFF 268 +-#define FULLMAP 269 +-#define HELP 270 +-#define IMPORT 271 +-#define INPUT 272 +-#define MAP 273 +-#define MESSAGES 274 +-#define MODULE 275 +-#define MULTIPLE 276 +-#define OS_DOMAIN 277 +-#define OUTPUT 278 +-#define PSEUDOPREEMPTION 279 +-#define REENTRANT 280 +-#define SCREENNAME 281 +-#define SHARELIB 282 +-#define STACK 283 +-#define START 284 +-#define SYNCHRONIZE 285 +-#define THREADNAME 286 +-#define TYPE 287 +-#define VERBOSE 288 +-#define VERSIONK 289 +-#define XDCDATA 290 +-#define STRING 291 +-#define QUOTED_STRING 292 +- +- +- +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 113 "nlmheader.y" +-{ +- char *string; +- struct string_list *list; +-} +-/* Line 1529 of yacc.c. */ +-#line 128 "nlmheader.h" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +-extern YYSTYPE yylval; +- +diff -Nur binutils-2.24.orig/binutils/po/.cvsignore binutils-2.24/binutils/po/.cvsignore +--- binutils-2.24.orig/binutils/po/.cvsignore 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/binutils/po/.cvsignore 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1 @@ ++*.gmo +diff -Nur binutils-2.24.orig/binutils/rcparse.c binutils-2.24/binutils/rcparse.c +--- binutils-2.24.orig/binutils/rcparse.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/rcparse.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,4663 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton implementation for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "2.3" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Using locations. */ +-#define YYLSP_NEEDED 0 +- +- +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- BEG = 258, +- END = 259, +- ACCELERATORS = 260, +- VIRTKEY = 261, +- ASCII = 262, +- NOINVERT = 263, +- SHIFT = 264, +- CONTROL = 265, +- ALT = 266, +- BITMAP = 267, +- CURSOR = 268, +- DIALOG = 269, +- DIALOGEX = 270, +- EXSTYLE = 271, +- CAPTION = 272, +- CLASS = 273, +- STYLE = 274, +- AUTO3STATE = 275, +- AUTOCHECKBOX = 276, +- AUTORADIOBUTTON = 277, +- CHECKBOX = 278, +- COMBOBOX = 279, +- CTEXT = 280, +- DEFPUSHBUTTON = 281, +- EDITTEXT = 282, +- GROUPBOX = 283, +- LISTBOX = 284, +- LTEXT = 285, +- PUSHBOX = 286, +- PUSHBUTTON = 287, +- RADIOBUTTON = 288, +- RTEXT = 289, +- SCROLLBAR = 290, +- STATE3 = 291, +- USERBUTTON = 292, +- BEDIT = 293, +- HEDIT = 294, +- IEDIT = 295, +- FONT = 296, +- ICON = 297, +- ANICURSOR = 298, +- ANIICON = 299, +- DLGINCLUDE = 300, +- DLGINIT = 301, +- FONTDIR = 302, +- HTML = 303, +- MANIFEST = 304, +- PLUGPLAY = 305, +- VXD = 306, +- TOOLBAR = 307, +- BUTTON = 308, +- LANGUAGE = 309, +- CHARACTERISTICS = 310, +- VERSIONK = 311, +- MENU = 312, +- MENUEX = 313, +- MENUITEM = 314, +- SEPARATOR = 315, +- POPUP = 316, +- CHECKED = 317, +- GRAYED = 318, +- HELP = 319, +- INACTIVE = 320, +- MENUBARBREAK = 321, +- MENUBREAK = 322, +- MESSAGETABLE = 323, +- RCDATA = 324, +- STRINGTABLE = 325, +- VERSIONINFO = 326, +- FILEVERSION = 327, +- PRODUCTVERSION = 328, +- FILEFLAGSMASK = 329, +- FILEFLAGS = 330, +- FILEOS = 331, +- FILETYPE = 332, +- FILESUBTYPE = 333, +- BLOCKSTRINGFILEINFO = 334, +- BLOCKVARFILEINFO = 335, +- VALUE = 336, +- BLOCK = 337, +- MOVEABLE = 338, +- FIXED = 339, +- PURE = 340, +- IMPURE = 341, +- PRELOAD = 342, +- LOADONCALL = 343, +- DISCARDABLE = 344, +- NOT = 345, +- QUOTEDUNISTRING = 346, +- QUOTEDSTRING = 347, +- STRING = 348, +- NUMBER = 349, +- SIZEDUNISTRING = 350, +- SIZEDSTRING = 351, +- IGNORED_TOKEN = 352, +- NEG = 353 +- }; +-#endif +-/* Tokens. */ +-#define BEG 258 +-#define END 259 +-#define ACCELERATORS 260 +-#define VIRTKEY 261 +-#define ASCII 262 +-#define NOINVERT 263 +-#define SHIFT 264 +-#define CONTROL 265 +-#define ALT 266 +-#define BITMAP 267 +-#define CURSOR 268 +-#define DIALOG 269 +-#define DIALOGEX 270 +-#define EXSTYLE 271 +-#define CAPTION 272 +-#define CLASS 273 +-#define STYLE 274 +-#define AUTO3STATE 275 +-#define AUTOCHECKBOX 276 +-#define AUTORADIOBUTTON 277 +-#define CHECKBOX 278 +-#define COMBOBOX 279 +-#define CTEXT 280 +-#define DEFPUSHBUTTON 281 +-#define EDITTEXT 282 +-#define GROUPBOX 283 +-#define LISTBOX 284 +-#define LTEXT 285 +-#define PUSHBOX 286 +-#define PUSHBUTTON 287 +-#define RADIOBUTTON 288 +-#define RTEXT 289 +-#define SCROLLBAR 290 +-#define STATE3 291 +-#define USERBUTTON 292 +-#define BEDIT 293 +-#define HEDIT 294 +-#define IEDIT 295 +-#define FONT 296 +-#define ICON 297 +-#define ANICURSOR 298 +-#define ANIICON 299 +-#define DLGINCLUDE 300 +-#define DLGINIT 301 +-#define FONTDIR 302 +-#define HTML 303 +-#define MANIFEST 304 +-#define PLUGPLAY 305 +-#define VXD 306 +-#define TOOLBAR 307 +-#define BUTTON 308 +-#define LANGUAGE 309 +-#define CHARACTERISTICS 310 +-#define VERSIONK 311 +-#define MENU 312 +-#define MENUEX 313 +-#define MENUITEM 314 +-#define SEPARATOR 315 +-#define POPUP 316 +-#define CHECKED 317 +-#define GRAYED 318 +-#define HELP 319 +-#define INACTIVE 320 +-#define MENUBARBREAK 321 +-#define MENUBREAK 322 +-#define MESSAGETABLE 323 +-#define RCDATA 324 +-#define STRINGTABLE 325 +-#define VERSIONINFO 326 +-#define FILEVERSION 327 +-#define PRODUCTVERSION 328 +-#define FILEFLAGSMASK 329 +-#define FILEFLAGS 330 +-#define FILEOS 331 +-#define FILETYPE 332 +-#define FILESUBTYPE 333 +-#define BLOCKSTRINGFILEINFO 334 +-#define BLOCKVARFILEINFO 335 +-#define VALUE 336 +-#define BLOCK 337 +-#define MOVEABLE 338 +-#define FIXED 339 +-#define PURE 340 +-#define IMPURE 341 +-#define PRELOAD 342 +-#define LOADONCALL 343 +-#define DISCARDABLE 344 +-#define NOT 345 +-#define QUOTEDUNISTRING 346 +-#define QUOTEDSTRING 347 +-#define STRING 348 +-#define NUMBER 349 +-#define SIZEDUNISTRING 350 +-#define SIZEDSTRING 351 +-#define IGNORED_TOKEN 352 +-#define NEG 353 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 1 "rcparse.y" +- /* rcparse.y -- parser for Windows rc files +- Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008, +- 2011 Free Software Foundation, Inc. +- Written by Ian Lance Taylor, Cygnus Support. +- Extended by Kai Tietz, Onevision. +- +- This file is part of GNU Binutils. +- +- 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 3 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. */ +- +- +-/* This is a parser for Windows rc files. It is based on the parser +- by Gunther Ebert . */ +- +-#include "sysdep.h" +-#include "bfd.h" +-#include "bucomm.h" +-#include "libiberty.h" +-#include "windres.h" +-#include "safe-ctype.h" +- +-/* The current language. */ +- +-static unsigned short language; +- +-/* The resource information during a sub statement. */ +- +-static rc_res_res_info sub_res_info; +- +-/* Dialog information. This is built by the nonterminals styles and +- controls. */ +- +-static rc_dialog dialog; +- +-/* This is used when building a style. It is modified by the +- nonterminal styleexpr. */ +- +-static unsigned long style; +- +-/* These are used when building a control. They are set before using +- control_params. */ +- +-static rc_uint_type base_style; +-static rc_uint_type default_style; +-static rc_res_id class; +-static rc_res_id res_text_field; +-static unichar null_unichar; +- +-/* This is used for COMBOBOX, LISTBOX and EDITTEXT which +- do not allow resource 'text' field in control definition. */ +-static const rc_res_id res_null_text = { 1, {{0, &null_unichar}}}; +- +- +- +-/* Enabling traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* Enabling the token table. */ +-#ifndef YYTOKEN_TABLE +-# define YYTOKEN_TABLE 0 +-#endif +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 69 "rcparse.y" +-{ +- rc_accelerator acc; +- rc_accelerator *pacc; +- rc_dialog_control *dialog_control; +- rc_menuitem *menuitem; +- struct +- { +- rc_rcdata_item *first; +- rc_rcdata_item *last; +- } rcdata; +- rc_rcdata_item *rcdata_item; +- rc_fixed_versioninfo *fixver; +- rc_ver_info *verinfo; +- rc_ver_stringtable *verstringtable; +- rc_ver_stringinfo *verstring; +- rc_ver_varinfo *vervar; +- rc_toolbar_item *toobar_item; +- rc_res_id id; +- rc_res_res_info res_info; +- struct +- { +- rc_uint_type on; +- rc_uint_type off; +- } memflags; +- struct +- { +- rc_uint_type val; +- /* Nonzero if this number was explicitly specified as long. */ +- int dword; +- } i; +- rc_uint_type il; +- rc_uint_type is; +- const char *s; +- struct +- { +- rc_uint_type length; +- const char *s; +- } ss; +- unichar *uni; +- struct +- { +- rc_uint_type length; +- const unichar *s; +- } suni; +-} +-/* Line 193 of yacc.c. */ +-#line 405 "rcparse.c" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +- +- +-/* Copy the second part of user declarations. */ +- +- +-/* Line 216 of yacc.c. */ +-#line 418 "rcparse.c" +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; +-#else +-typedef short int yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(msgid) dgettext ("bison-runtime", msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(msgid) msgid +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(e) ((void) (e)) +-#else +-# define YYUSE(e) /* empty */ +-#endif +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(n) (n) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int i) +-#else +-static int +-YYID (i) +- int i; +-#endif +-{ +- return i; +-} +-#endif +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined _STDLIB_H \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss; +- YYSTYPE yyvs; +- }; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-/* Copy COUNT objects from FROM to TO. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(To, From, Count) \ +- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +-# else +-# define YYCOPY(To, From, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (To)[yyi] = (From)[yyi]; \ +- } \ +- while (YYID (0)) +-# endif +-# endif +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack, Stack, yysize); \ +- Stack = &yyptr->Stack; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) +- +-#endif +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 2 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 830 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 112 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 102 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 276 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 520 +- +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 353 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 105, 100, 2, +- 110, 111, 103, 101, 108, 102, 2, 104, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 109, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 99, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 98, 2, 106, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, +- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, +- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, +- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, +- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, +- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, +- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, +- 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, +- 95, 96, 97, 107 +-}; +- +-#if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint16 yyprhs[] = +-{ +- 0, 0, 3, 4, 7, 10, 13, 16, 19, 22, +- 25, 28, 31, 34, 37, 40, 43, 46, 49, 56, +- 57, 60, 63, 68, 70, 72, 74, 78, 81, 83, +- 85, 87, 89, 91, 93, 98, 103, 104, 118, 119, +- 133, 134, 149, 150, 154, 155, 159, 163, 167, 171, +- 175, 181, 188, 196, 205, 209, 213, 218, 222, 223, +- 226, 227, 232, 233, 238, 239, 244, 245, 250, 251, +- 256, 257, 261, 273, 286, 287, 292, 293, 298, 299, +- 303, 304, 309, 310, 315, 322, 331, 342, 354, 355, +- 360, 361, 365, 366, 371, 372, 377, 378, 383, 384, +- 389, 390, 395, 396, 400, 401, 406, 407, 423, 430, +- 439, 449, 452, 453, 456, 458, 460, 461, 465, 466, +- 470, 471, 475, 476, 480, 485, 490, 494, 501, 502, +- 505, 510, 513, 520, 521, 525, 528, 530, 532, 534, +- 536, 538, 540, 547, 548, 551, 554, 558, 564, 567, +- 573, 580, 588, 598, 603, 604, 607, 608, 610, 612, +- 614, 616, 620, 624, 628, 631, 632, 639, 640, 644, +- 649, 652, 654, 656, 658, 660, 662, 664, 666, 668, +- 670, 672, 679, 684, 693, 694, 698, 701, 708, 709, +- 716, 723, 727, 731, 735, 739, 743, 744, 750, 758, +- 759, 765, 766, 772, 773, 777, 779, 781, 783, 785, +- 788, 790, 793, 794, 797, 801, 806, 810, 811, 814, +- 815, 818, 820, 822, 824, 826, 828, 830, 832, 834, +- 836, 838, 841, 843, 845, 847, 849, 851, 854, 856, +- 859, 861, 864, 866, 869, 873, 878, 880, 884, 885, +- 887, 890, 892, 894, 898, 901, 904, 908, 912, 916, +- 920, 924, 928, 932, 936, 939, 941, 943, 947, 950, +- 954, 958, 962, 966, 970, 974, 978 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int16 yyrhs[] = +-{ +- 113, 0, -1, -1, 113, 114, -1, 113, 120, -1, +- 113, 121, -1, 113, 122, -1, 113, 162, -1, 113, +- 163, -1, 113, 164, -1, 113, 165, -1, 113, 170, +- -1, 113, 173, -1, 113, 178, -1, 113, 183, -1, +- 113, 182, -1, 113, 185, -1, 113, 97, -1, 191, +- 5, 194, 3, 115, 4, -1, -1, 115, 116, -1, +- 117, 211, -1, 117, 211, 108, 118, -1, 92, -1, +- 212, -1, 119, -1, 118, 108, 119, -1, 118, 119, +- -1, 6, -1, 7, -1, 8, -1, 9, -1, 10, +- -1, 11, -1, 191, 12, 196, 198, -1, 191, 13, +- 195, 198, -1, -1, 191, 14, 196, 126, 212, 208, +- 208, 208, 123, 127, 3, 128, 4, -1, -1, 191, +- 15, 196, 126, 212, 208, 208, 208, 124, 127, 3, +- 128, 4, -1, -1, 191, 15, 196, 126, 212, 208, +- 208, 208, 208, 125, 127, 3, 128, 4, -1, -1, +- 16, 109, 209, -1, -1, 127, 17, 199, -1, 127, +- 18, 191, -1, 127, 19, 205, -1, 127, 16, 209, +- -1, 127, 18, 199, -1, 127, 41, 209, 108, 199, +- -1, 127, 41, 209, 108, 199, 208, -1, 127, 41, +- 209, 108, 199, 208, 208, -1, 127, 41, 209, 108, +- 199, 208, 208, 208, -1, 127, 57, 191, -1, 127, +- 55, 209, -1, 127, 54, 209, 208, -1, 127, 56, +- 209, -1, -1, 128, 129, -1, -1, 20, 153, 130, +- 151, -1, -1, 21, 153, 131, 151, -1, -1, 22, +- 153, 132, 151, -1, -1, 38, 153, 133, 151, -1, +- -1, 23, 153, 134, 151, -1, -1, 24, 135, 151, +- -1, 10, 153, 209, 152, 156, 208, 208, 208, 208, +- 207, 155, -1, 10, 153, 209, 152, 156, 208, 208, +- 208, 208, 208, 208, 155, -1, -1, 25, 153, 136, +- 151, -1, -1, 26, 153, 137, 151, -1, -1, 27, +- 138, 151, -1, -1, 28, 153, 139, 151, -1, -1, +- 39, 153, 140, 151, -1, 42, 193, 209, 208, 208, +- 155, -1, 42, 193, 209, 208, 208, 208, 208, 155, +- -1, 42, 193, 209, 208, 208, 208, 208, 158, 207, +- 155, -1, 42, 193, 209, 208, 208, 208, 208, 158, +- 208, 208, 155, -1, -1, 40, 153, 141, 151, -1, +- -1, 29, 142, 151, -1, -1, 30, 153, 143, 151, +- -1, -1, 31, 153, 144, 151, -1, -1, 32, 153, +- 145, 151, -1, -1, 33, 153, 146, 151, -1, -1, +- 34, 153, 147, 151, -1, -1, 35, 148, 151, -1, +- -1, 36, 153, 149, 151, -1, -1, 37, 193, 209, +- 108, 209, 108, 209, 108, 209, 108, 209, 108, 150, +- 205, 207, -1, 209, 208, 208, 208, 208, 155, -1, +- 209, 208, 208, 208, 208, 160, 207, 155, -1, 209, +- 208, 208, 208, 208, 160, 208, 208, 155, -1, 108, +- 154, -1, -1, 154, 108, -1, 212, -1, 199, -1, +- -1, 3, 174, 4, -1, -1, 108, 157, 205, -1, +- -1, 108, 159, 205, -1, -1, 108, 161, 205, -1, +- 191, 41, 195, 198, -1, 191, 42, 195, 198, -1, +- 54, 209, 208, -1, 191, 57, 194, 3, 166, 4, +- -1, -1, 166, 167, -1, 59, 199, 208, 168, -1, +- 59, 60, -1, 61, 199, 168, 3, 166, 4, -1, +- -1, 168, 108, 169, -1, 168, 169, -1, 62, -1, +- 63, -1, 64, -1, 65, -1, 66, -1, 67, -1, +- 191, 58, 194, 3, 171, 4, -1, -1, 171, 172, +- -1, 59, 199, -1, 59, 199, 208, -1, 59, 199, +- 208, 208, 207, -1, 59, 60, -1, 61, 199, 3, +- 171, 4, -1, 61, 199, 208, 3, 171, 4, -1, +- 61, 199, 208, 208, 3, 171, 4, -1, 61, 199, +- 208, 208, 208, 207, 3, 171, 4, -1, 191, 68, +- 196, 198, -1, -1, 175, 176, -1, -1, 177, -1, +- 203, -1, 204, -1, 210, -1, 177, 108, 203, -1, +- 177, 108, 204, -1, 177, 108, 210, -1, 177, 108, +- -1, -1, 70, 194, 3, 179, 180, 4, -1, -1, +- 180, 209, 202, -1, 180, 209, 108, 202, -1, 180, +- 1, -1, 191, -1, 48, -1, 69, -1, 49, -1, +- 50, -1, 51, -1, 45, -1, 46, -1, 43, -1, +- 44, -1, 191, 181, 194, 3, 174, 4, -1, 191, +- 181, 194, 198, -1, 191, 52, 194, 209, 208, 3, +- 184, 4, -1, -1, 184, 53, 191, -1, 184, 60, +- -1, 191, 71, 186, 3, 187, 4, -1, -1, 186, +- 72, 209, 207, 207, 207, -1, 186, 73, 209, 207, +- 207, 207, -1, 186, 74, 209, -1, 186, 75, 209, +- -1, 186, 76, 209, -1, 186, 77, 209, -1, 186, +- 78, 209, -1, -1, 187, 79, 3, 188, 4, -1, +- 187, 80, 3, 81, 199, 190, 4, -1, -1, 188, +- 82, 3, 189, 4, -1, -1, 189, 81, 199, 108, +- 199, -1, -1, 190, 208, 208, -1, 212, -1, 192, +- -1, 200, -1, 93, -1, 212, 108, -1, 192, -1, +- 192, 108, -1, -1, 194, 197, -1, 194, 55, 209, +- -1, 194, 54, 209, 208, -1, 194, 56, 209, -1, +- -1, 195, 197, -1, -1, 196, 197, -1, 83, -1, +- 84, -1, 85, -1, 86, -1, 87, -1, 88, -1, +- 89, -1, 92, -1, 93, -1, 200, -1, 199, 200, +- -1, 91, -1, 92, -1, 204, -1, 203, -1, 201, +- -1, 202, 201, -1, 96, -1, 203, 96, -1, 95, +- -1, 204, 95, -1, 206, -1, 90, 206, -1, 205, +- 98, 206, -1, 205, 98, 90, 206, -1, 94, -1, +- 110, 209, 111, -1, -1, 208, -1, 108, 209, -1, +- 210, -1, 94, -1, 110, 210, 111, -1, 106, 210, +- -1, 102, 210, -1, 210, 103, 210, -1, 210, 104, +- 210, -1, 210, 105, 210, -1, 210, 101, 210, -1, +- 210, 102, 210, -1, 210, 100, 210, -1, 210, 99, +- 210, -1, 210, 98, 210, -1, 108, 212, -1, 213, +- -1, 94, -1, 110, 210, 111, -1, 106, 210, -1, +- 213, 103, 210, -1, 213, 104, 210, -1, 213, 105, +- 210, -1, 213, 101, 210, -1, 213, 102, 210, -1, +- 213, 100, 210, -1, 213, 99, 210, -1, 213, 98, +- 210, -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 179, 179, 181, 182, 183, 184, 185, 186, 187, +- 188, 189, 190, 191, 192, 193, 194, 195, 201, 212, +- 215, 236, 241, 253, 273, 283, 287, 292, 299, 303, +- 308, 312, 316, 320, 329, 341, 355, 353, 380, 378, +- 407, 405, 437, 440, 446, 448, 454, 458, 463, 467, +- 471, 484, 499, 514, 529, 533, 537, 541, 547, 549, +- 561, 560, 573, 572, 585, 584, 597, 596, 612, 611, +- 624, 623, 637, 648, 658, 657, 670, 669, 682, 681, +- 694, 693, 706, 705, 720, 725, 731, 737, 744, 743, +- 759, 758, 771, 770, 783, 782, 794, 793, 806, 805, +- 818, 817, 830, 829, 842, 841, 855, 853, 874, 885, +- 896, 908, 919, 922, 926, 931, 941, 944, 954, 953, +- 960, 959, 966, 965, 973, 985, 998, 1007, 1018, 1021, +- 1038, 1042, 1046, 1054, 1057, 1061, 1068, 1072, 1076, 1080, +- 1084, 1088, 1097, 1108, 1111, 1128, 1132, 1136, 1140, 1144, +- 1148, 1152, 1156, 1166, 1179, 1179, 1191, 1195, 1202, 1210, +- 1218, 1226, 1235, 1244, 1253, 1263, 1262, 1267, 1269, 1274, +- 1279, 1287, 1291, 1296, 1301, 1306, 1311, 1316, 1321, 1326, +- 1331, 1342, 1349, 1359, 1365, 1366, 1385, 1410, 1421, 1426, +- 1433, 1440, 1445, 1450, 1455, 1460, 1475, 1478, 1482, 1490, +- 1493, 1501, 1504, 1512, 1515, 1524, 1529, 1538, 1542, 1552, +- 1557, 1561, 1572, 1578, 1584, 1589, 1594, 1605, 1610, 1622, +- 1627, 1639, 1644, 1649, 1654, 1659, 1664, 1669, 1679, 1683, +- 1691, 1696, 1711, 1715, 1724, 1728, 1740, 1745, 1761, 1765, +- 1777, 1781, 1803, 1807, 1811, 1815, 1822, 1826, 1836, 1839, +- 1848, 1857, 1866, 1870, 1874, 1879, 1884, 1889, 1894, 1899, +- 1904, 1909, 1914, 1919, 1930, 1939, 1950, 1954, 1958, 1963, +- 1968, 1973, 1978, 1983, 1988, 1993, 1998 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "BEG", "END", "ACCELERATORS", "VIRTKEY", +- "ASCII", "NOINVERT", "SHIFT", "CONTROL", "ALT", "BITMAP", "CURSOR", +- "DIALOG", "DIALOGEX", "EXSTYLE", "CAPTION", "CLASS", "STYLE", +- "AUTO3STATE", "AUTOCHECKBOX", "AUTORADIOBUTTON", "CHECKBOX", "COMBOBOX", +- "CTEXT", "DEFPUSHBUTTON", "EDITTEXT", "GROUPBOX", "LISTBOX", "LTEXT", +- "PUSHBOX", "PUSHBUTTON", "RADIOBUTTON", "RTEXT", "SCROLLBAR", "STATE3", +- "USERBUTTON", "BEDIT", "HEDIT", "IEDIT", "FONT", "ICON", "ANICURSOR", +- "ANIICON", "DLGINCLUDE", "DLGINIT", "FONTDIR", "HTML", "MANIFEST", +- "PLUGPLAY", "VXD", "TOOLBAR", "BUTTON", "LANGUAGE", "CHARACTERISTICS", +- "VERSIONK", "MENU", "MENUEX", "MENUITEM", "SEPARATOR", "POPUP", +- "CHECKED", "GRAYED", "HELP", "INACTIVE", "MENUBARBREAK", "MENUBREAK", +- "MESSAGETABLE", "RCDATA", "STRINGTABLE", "VERSIONINFO", "FILEVERSION", +- "PRODUCTVERSION", "FILEFLAGSMASK", "FILEFLAGS", "FILEOS", "FILETYPE", +- "FILESUBTYPE", "BLOCKSTRINGFILEINFO", "BLOCKVARFILEINFO", "VALUE", +- "BLOCK", "MOVEABLE", "FIXED", "PURE", "IMPURE", "PRELOAD", "LOADONCALL", +- "DISCARDABLE", "NOT", "QUOTEDUNISTRING", "QUOTEDSTRING", "STRING", +- "NUMBER", "SIZEDUNISTRING", "SIZEDSTRING", "IGNORED_TOKEN", "'|'", "'^'", +- "'&'", "'+'", "'-'", "'*'", "'/'", "'%'", "'~'", "NEG", "','", "'='", +- "'('", "')'", "$accept", "input", "accelerator", "acc_entries", +- "acc_entry", "acc_event", "acc_options", "acc_option", "bitmap", +- "cursor", "dialog", "@1", "@2", "@3", "exstyle", "styles", "controls", +- "control", "@4", "@5", "@6", "@7", "@8", "@9", "@10", "@11", "@12", +- "@13", "@14", "@15", "@16", "@17", "@18", "@19", "@20", "@21", "@22", +- "@23", "@24", "control_params", "cresid", "optresidc", "resid", +- "opt_control_data", "control_styleexpr", "@25", "icon_styleexpr", "@26", +- "control_params_styleexpr", "@27", "font", "icon", "language", "menu", +- "menuitems", "menuitem", "menuitem_flags", "menuitem_flag", "menuex", +- "menuexitems", "menuexitem", "messagetable", "optrcdata_data", "@28", +- "optrcdata_data_int", "rcdata_data", "stringtable", "@29", "string_data", +- "rcdata_id", "user", "toolbar", "toolbar_data", "versioninfo", +- "fixedverinfo", "verblocks", "verstringtables", "vervals", "vertrans", +- "id", "resname", "resref", "suboptions", "memflags_move_discard", +- "memflags_move", "memflag", "file_name", "res_unicode_string_concat", +- "res_unicode_string", "res_unicode_sizedstring", +- "res_unicode_sizedstring_concat", "sizedstring", "sizedunistring", +- "styleexpr", "parennumber", "optcnumexpr", "cnumexpr", "numexpr", +- "sizednumexpr", "cposnumexpr", "posnumexpr", "sizedposnumexpr", 0 +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, +- 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, +- 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, +- 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, +- 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, +- 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, +- 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, +- 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, +- 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, +- 345, 346, 347, 348, 349, 350, 351, 352, 124, 94, +- 38, 43, 45, 42, 47, 37, 126, 353, 44, 61, +- 40, 41 +-}; +-# endif +- +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 112, 113, 113, 113, 113, 113, 113, 113, 113, +- 113, 113, 113, 113, 113, 113, 113, 113, 114, 115, +- 115, 116, 116, 117, 117, 118, 118, 118, 119, 119, +- 119, 119, 119, 119, 120, 121, 123, 122, 124, 122, +- 125, 122, 126, 126, 127, 127, 127, 127, 127, 127, +- 127, 127, 127, 127, 127, 127, 127, 127, 128, 128, +- 130, 129, 131, 129, 132, 129, 133, 129, 134, 129, +- 135, 129, 129, 129, 136, 129, 137, 129, 138, 129, +- 139, 129, 140, 129, 129, 129, 129, 129, 141, 129, +- 142, 129, 143, 129, 144, 129, 145, 129, 146, 129, +- 147, 129, 148, 129, 149, 129, 150, 129, 151, 151, +- 151, 152, 153, 153, 154, 154, 155, 155, 157, 156, +- 159, 158, 161, 160, 162, 163, 164, 165, 166, 166, +- 167, 167, 167, 168, 168, 168, 169, 169, 169, 169, +- 169, 169, 170, 171, 171, 172, 172, 172, 172, 172, +- 172, 172, 172, 173, 175, 174, 176, 176, 177, 177, +- 177, 177, 177, 177, 177, 179, 178, 180, 180, 180, +- 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, +- 181, 182, 182, 183, 184, 184, 184, 185, 186, 186, +- 186, 186, 186, 186, 186, 186, 187, 187, 187, 188, +- 188, 189, 189, 190, 190, 191, 191, 192, 192, 193, +- 193, 193, 194, 194, 194, 194, 194, 195, 195, 196, +- 196, 197, 197, 197, 197, 197, 197, 197, 198, 198, +- 199, 199, 200, 200, 201, 201, 202, 202, 203, 203, +- 204, 204, 205, 205, 205, 205, 206, 206, 207, 207, +- 208, 209, 210, 210, 210, 210, 210, 210, 210, 210, +- 210, 210, 210, 210, 211, 212, 213, 213, 213, 213, +- 213, 213, 213, 213, 213, 213, 213 +-}; +- +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 6, 0, +- 2, 2, 4, 1, 1, 1, 3, 2, 1, 1, +- 1, 1, 1, 1, 4, 4, 0, 13, 0, 13, +- 0, 14, 0, 3, 0, 3, 3, 3, 3, 3, +- 5, 6, 7, 8, 3, 3, 4, 3, 0, 2, +- 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, +- 0, 3, 11, 12, 0, 4, 0, 4, 0, 3, +- 0, 4, 0, 4, 6, 8, 10, 11, 0, 4, +- 0, 3, 0, 4, 0, 4, 0, 4, 0, 4, +- 0, 4, 0, 3, 0, 4, 0, 15, 6, 8, +- 9, 2, 0, 2, 1, 1, 0, 3, 0, 3, +- 0, 3, 0, 3, 4, 4, 3, 6, 0, 2, +- 4, 2, 6, 0, 3, 2, 1, 1, 1, 1, +- 1, 1, 6, 0, 2, 2, 3, 5, 2, 5, +- 6, 7, 9, 4, 0, 2, 0, 1, 1, 1, +- 1, 3, 3, 3, 2, 0, 6, 0, 3, 4, +- 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 6, 4, 8, 0, 3, 2, 6, 0, 6, +- 6, 3, 3, 3, 3, 3, 0, 5, 7, 0, +- 5, 0, 5, 0, 3, 1, 1, 1, 1, 2, +- 1, 2, 0, 2, 3, 4, 3, 0, 2, 0, +- 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 2, 1, 1, 1, 1, 1, 2, 1, 2, +- 1, 2, 1, 2, 3, 4, 1, 3, 0, 1, +- 2, 1, 1, 3, 2, 2, 3, 3, 3, 3, +- 3, 3, 3, 3, 2, 1, 1, 3, 2, 3, +- 3, 3, 3, 3, 3, 3, 3 +-}; +- +-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state +- STATE-NUM when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint16 yydefact[] = +-{ +- 2, 0, 1, 0, 212, 232, 233, 208, 266, 17, +- 0, 0, 3, 4, 5, 6, 7, 8, 9, 10, +- 11, 12, 13, 15, 14, 16, 0, 206, 207, 205, +- 265, 252, 0, 0, 0, 0, 251, 0, 268, 0, +- 212, 219, 217, 219, 219, 217, 217, 179, 180, 177, +- 178, 172, 174, 175, 176, 212, 212, 212, 219, 173, +- 188, 212, 171, 0, 0, 0, 0, 0, 0, 0, +- 0, 255, 254, 0, 0, 126, 0, 0, 0, 0, +- 0, 0, 0, 0, 165, 0, 0, 0, 221, 222, +- 223, 224, 225, 226, 227, 213, 267, 0, 0, 0, +- 42, 42, 0, 0, 0, 0, 0, 0, 0, 0, +- 276, 275, 274, 272, 273, 269, 270, 271, 253, 250, +- 263, 262, 261, 259, 260, 256, 257, 258, 167, 0, +- 214, 216, 19, 228, 229, 220, 34, 218, 35, 0, +- 0, 0, 124, 125, 0, 128, 143, 153, 196, 0, +- 0, 0, 0, 0, 0, 0, 154, 182, 0, 215, +- 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, +- 191, 192, 193, 194, 195, 0, 156, 170, 166, 0, +- 18, 23, 20, 0, 24, 43, 0, 0, 184, 127, +- 0, 0, 129, 142, 0, 0, 144, 187, 0, 0, +- 248, 249, 248, 181, 240, 238, 155, 157, 158, 159, +- 160, 0, 236, 168, 235, 234, 0, 21, 0, 0, +- 0, 131, 0, 230, 133, 148, 145, 0, 199, 0, +- 248, 248, 164, 239, 241, 169, 237, 264, 0, 36, +- 38, 183, 0, 186, 231, 133, 0, 146, 143, 0, +- 0, 0, 189, 190, 161, 162, 163, 28, 29, 30, +- 31, 32, 33, 22, 25, 44, 44, 40, 185, 130, +- 128, 136, 137, 138, 139, 140, 141, 0, 135, 248, +- 0, 143, 0, 197, 0, 203, 0, 27, 0, 0, +- 44, 0, 134, 147, 149, 0, 143, 248, 201, 0, +- 26, 58, 0, 0, 0, 0, 0, 0, 0, 0, +- 0, 58, 0, 132, 150, 0, 0, 0, 198, 0, +- 0, 48, 45, 46, 49, 207, 0, 246, 0, 47, +- 242, 0, 0, 55, 57, 54, 0, 58, 151, 143, +- 200, 0, 204, 37, 112, 112, 112, 112, 112, 70, +- 112, 112, 78, 112, 90, 112, 112, 112, 112, 112, +- 102, 112, 0, 112, 112, 112, 0, 59, 243, 0, +- 0, 0, 56, 39, 0, 0, 0, 0, 0, 115, +- 114, 60, 62, 64, 68, 0, 74, 76, 0, 80, +- 0, 92, 94, 96, 98, 100, 0, 104, 210, 0, +- 0, 66, 82, 88, 0, 247, 0, 244, 50, 41, +- 152, 0, 0, 113, 0, 0, 0, 0, 71, 0, +- 0, 0, 79, 0, 91, 0, 0, 0, 0, 0, +- 103, 0, 211, 0, 209, 0, 0, 0, 0, 245, +- 51, 202, 0, 0, 61, 63, 65, 69, 0, 75, +- 77, 81, 93, 95, 97, 99, 101, 105, 0, 67, +- 83, 89, 0, 52, 111, 118, 0, 0, 0, 116, +- 53, 0, 0, 0, 0, 154, 84, 0, 119, 0, +- 116, 0, 0, 116, 0, 122, 108, 248, 0, 117, +- 120, 85, 248, 248, 0, 116, 249, 0, 0, 116, +- 249, 116, 249, 123, 109, 116, 0, 121, 86, 116, +- 72, 116, 110, 0, 87, 73, 106, 0, 248, 107 +-}; +- +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int16 yydefgoto[] = +-{ +- -1, 1, 12, 160, 182, 183, 263, 264, 13, 14, +- 15, 265, 266, 290, 140, 288, 320, 367, 414, 415, +- 416, 435, 417, 385, 420, 421, 388, 423, 436, 437, +- 390, 425, 426, 427, 428, 429, 396, 431, 517, 418, +- 443, 377, 378, 476, 466, 471, 492, 498, 487, 494, +- 16, 17, 18, 19, 165, 192, 246, 278, 20, 166, +- 196, 21, 175, 176, 206, 207, 22, 128, 158, 61, +- 23, 24, 220, 25, 108, 167, 250, 317, 299, 26, +- 27, 399, 37, 99, 98, 95, 136, 379, 223, 212, +- 213, 214, 215, 329, 330, 200, 201, 419, 36, 217, +- 380, 30 +-}; +- +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -446 +-static const yytype_int16 yypact[] = +-{ +- -446, 75, -446, 317, -446, -446, -446, -446, -446, -446, +- 317, 317, -446, -446, -446, -446, -446, -446, -446, -446, +- -446, -446, -446, -446, -446, -446, 463, -446, -446, -446, +- 589, -446, 317, 317, 317, -93, 626, 209, -446, 437, +- -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, +- -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, +- -446, -446, -446, 317, 317, 317, 317, 317, 317, 317, +- 317, -446, -446, 526, 317, -446, 317, 317, 317, 317, +- 317, 317, 317, 317, -446, 317, 317, 317, -446, -446, +- -446, -446, -446, -446, -446, -446, -446, 267, 675, 675, +- 275, 275, 675, 675, 491, 404, 441, 675, 168, 256, +- 719, 379, 397, 213, 213, -446, -446, -446, -446, -446, +- 719, 379, 397, 213, 213, -446, -446, -446, -446, -93, +- -446, -446, -446, -446, -446, -446, -446, -446, -446, -65, +- 144, 144, -446, -446, -93, -446, -446, -446, -446, 317, +- 317, 317, 317, 317, 317, 317, -446, -446, 18, -446, +- 21, 317, -93, -93, 31, 140, 155, 126, -93, -93, +- -446, -446, -446, -446, -446, 47, 177, -446, -446, 212, +- -446, -446, -446, -34, -446, -446, -93, -93, -446, -446, +- -36, -5, -446, -446, -25, -5, -446, -446, 119, 131, +- -93, -446, -93, -446, -446, -446, -446, 54, 68, 84, +- 626, 2, -446, 2, 68, 84, 144, 87, -93, -93, +- 25, -446, 95, -446, -5, -446, 95, 62, -446, 102, +- -93, -93, 177, -446, -446, 2, -446, -446, 552, -446, +- -93, -446, 306, -446, -446, -446, 76, -93, -446, 8, +- 6, -5, -446, -446, 68, 84, 626, -446, -446, -446, +- -446, -446, -446, 167, -446, -446, -446, -446, -446, 271, +- -446, -446, -446, -446, -446, -446, -446, 763, -446, -93, +- 161, -446, 11, -446, 197, -5, 552, -446, 374, 548, +- -446, 178, -446, -446, -446, 190, -446, -93, -446, 3, +- -446, -446, 317, -5, 306, -47, 317, 317, 317, 317, +- 306, -446, 565, -446, -446, 194, 201, -1, -446, -93, +- 639, -446, -5, -446, -5, 143, -33, -446, 317, 110, +- -446, 105, -93, -446, -446, -446, 676, -446, -446, -446, +- -446, -5, -446, -446, 311, 311, 311, 311, 311, -446, +- 311, 311, -446, 311, -446, 311, 311, 311, 311, 311, +- -446, 311, 306, 311, 311, 311, 306, -446, -446, 104, +- -42, -5, -446, -446, 713, 207, 99, 317, 113, -5, +- -446, -446, -446, -446, -446, 317, -446, -446, 317, -446, +- 317, -446, -446, -446, -446, -446, 317, -446, 115, 317, +- 120, -446, -446, -446, 317, -446, -33, -446, 95, -446, +- -446, -5, 152, -446, 317, 317, 317, 317, -446, -93, +- 317, 317, -446, 317, -446, 317, 317, 317, 317, 317, +- -446, 317, -446, 153, -446, 317, 317, 317, -93, -446, +- -93, -5, 311, 159, -446, -446, -446, -446, -93, -446, +- -446, -446, -446, -446, -446, -446, -446, -446, 317, -446, +- -446, -446, -93, -93, -446, -446, -93, -93, 173, 15, +- -446, -47, -93, -93, 317, -446, -446, -93, 110, -93, +- 27, 180, 244, 29, -93, -446, -446, -93, 317, -446, +- -446, -446, -93, -93, -47, 273, -93, 192, -47, 273, +- -93, 273, -93, 110, -446, 273, 317, 110, -446, 273, +- -446, 273, -446, 193, -446, -446, -446, -47, -75, -446 +-}; +- +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int16 yypgoto[] = +-{ +- -446, -446, -446, -446, -446, -446, -446, -236, -446, -446, +- -446, -446, -446, -446, 184, -262, -273, -446, -446, -446, +- -446, -446, -446, -446, -446, -446, -446, -446, -446, -446, +- -446, -446, -446, -446, -446, -446, -446, -446, -446, 219, +- -446, 442, -123, 274, -446, -446, -446, -446, -446, -446, +- -446, -446, -446, -446, 77, -446, 101, 88, -446, -239, +- -446, -446, -109, -446, -446, -446, -446, -446, -446, -446, +- -446, -446, -446, -446, -446, -446, -446, -446, -446, -24, +- -245, 4, 169, 211, 270, 710, 175, -178, 5, -173, +- 157, -156, -122, -445, -325, -161, -30, -3, 26, -446, +- 20, -446 +-}; +- +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If zero, do what YYDEFACT says. +- If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -231 +-static const yytype_int16 yytable[] = +-{ +- 35, 368, 62, 340, 289, 75, 28, 318, 202, 280, +- 283, 281, 222, 224, 296, 74, 226, 227, 475, 177, +- 208, 29, 178, 370, 221, 180, 478, 287, 312, 241, +- 475, 28, 475, 74, 188, 225, 38, 39, 336, 230, +- 236, 231, 295, 326, 161, 407, 29, 327, 406, 503, +- 300, 203, 327, 507, 209, 5, 6, 315, 71, 72, +- 73, 327, 236, 328, 374, 248, 5, 6, 328, 252, +- 253, 119, 518, 285, 216, 2, 254, 328, 242, 270, +- 341, 439, 129, 130, 131, 243, 5, 6, 284, 110, +- 111, 112, 113, 114, 115, 116, 117, 204, 205, 159, +- 375, 144, 120, 121, 122, 123, 124, 125, 126, 127, +- 255, 74, 31, 181, 164, 8, 74, 398, 293, 74, +- 32, 398, 228, 74, 33, 322, 324, 10, 34, 3, +- 197, 11, 186, 187, 229, 485, 316, 490, 271, 272, +- 273, 274, 275, 276, 189, 4, 168, 169, 170, 171, +- 172, 173, 174, 5, 6, 179, 218, 219, 185, 193, +- 162, 163, 232, 376, 233, 294, 5, 6, 7, 8, +- 74, 148, 9, 257, 258, 259, 260, 261, 262, 234, +- 184, 10, 313, 251, 277, 11, 5, 6, 239, 240, +- 5, 6, 245, 408, 314, 238, 247, 249, 338, 190, +- 298, 191, 210, 74, 339, 198, 199, 411, 370, 97, +- 267, 410, 84, 371, 194, 405, 195, 279, 268, 282, +- 194, 413, 195, 432, 104, 105, 106, 244, 434, 244, +- 109, 244, 244, 441, -230, -230, 237, 190, 8, 191, +- 149, 150, 151, 152, 153, 154, 155, 28, 489, 194, +- 10, 195, 297, 194, 11, 195, 102, 103, 256, 156, +- 442, 458, 29, 85, 86, 87, 194, 465, 195, 319, +- 132, 31, 204, 205, 138, 286, 475, 142, 143, 32, +- 323, 474, 147, 33, 157, 141, 335, 34, 488, 342, +- 244, 139, 88, 89, 90, 91, 92, 93, 94, 321, +- 506, 516, 372, 331, 332, 333, 334, 204, 205, 325, +- 85, 86, 87, 100, 101, 28, 81, 82, 83, 464, +- 211, 85, 86, 87, 29, 369, 495, 244, 107, 244, +- 29, 499, 501, 271, 272, 273, 274, 275, 276, 88, +- 89, 90, 91, 92, 93, 94, 269, 291, 133, 134, +- 88, 89, 90, 91, 92, 93, 94, 519, 88, 89, +- 90, 91, 92, 93, 94, 292, 482, 28, 235, 0, +- 404, 28, 0, 0, 412, 0, 0, 301, 440, 277, +- 0, 244, 400, 0, 244, 0, 400, 0, 0, 448, +- 302, 303, 304, 305, 0, 0, 433, 5, 6, 7, +- 8, 438, 5, 6, 0, 8, 0, 145, 462, 0, +- 463, 31, 10, 244, 0, 306, 11, 10, 467, 32, +- 0, 11, 0, 33, 0, 0, 0, 34, 307, 308, +- 309, 310, 469, 470, 0, 0, 472, 473, 0, 477, +- 0, 0, 479, 480, 146, 0, 244, 483, 0, 484, +- 0, 0, 0, 0, 493, 468, 0, 496, 85, 86, +- 87, 0, 500, 502, 0, 0, 505, 0, 40, 0, +- 509, 481, 511, 0, 0, 41, 42, 43, 44, 78, +- 79, 80, 81, 82, 83, 497, 0, 88, 89, 90, +- 91, 92, 93, 94, 0, 85, 86, 87, 79, 80, +- 81, 82, 83, 513, 45, 46, 47, 48, 49, 50, +- 0, 51, 52, 53, 54, 55, 0, 0, 0, 0, +- 56, 57, 0, 0, 88, 89, 90, 91, 92, 93, +- 94, 58, 59, 0, 60, 76, 77, 78, 79, 80, +- 81, 82, 83, 0, 0, 85, 86, 87, 96, 0, +- 0, 311, 0, 0, 5, 6, 7, 8, 257, 258, +- 259, 260, 261, 262, 302, 303, 304, 305, 337, 10, +- 0, 0, 0, 11, 88, 89, 90, 91, 92, 93, +- 94, 302, 303, 304, 305, 31, 0, 0, 0, 306, +- 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, +- 0, 34, 307, 308, 309, 310, 306, 422, 0, 424, +- 0, 0, 0, 0, 0, 430, 0, 0, 0, 307, +- 308, 309, 310, 0, 76, 77, 78, 79, 80, 81, +- 82, 83, 0, 444, 445, 446, 447, 118, 0, 449, +- 450, 0, 451, 343, 452, 453, 454, 455, 456, 344, +- 457, 0, 0, 0, 459, 460, 461, 0, 0, 345, +- 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, +- 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, +- 373, 366, 0, 0, 0, 0, 344, 63, 64, 65, +- 66, 67, 68, 69, 70, 0, 345, 346, 347, 348, +- 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, +- 359, 360, 361, 362, 363, 364, 365, 409, 366, 0, +- 0, 0, 0, 344, 76, 77, 78, 79, 80, 81, +- 82, 83, 0, 345, 346, 347, 348, 349, 350, 351, +- 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, +- 362, 363, 364, 365, 486, 366, 0, 491, 88, 89, +- 90, 91, 92, 93, 94, 0, 0, 133, 134, 504, +- 0, 0, 0, 508, 0, 510, 0, 0, 0, 512, +- 0, 0, 0, 514, 0, 515, 0, 381, 382, 383, +- 384, 0, 386, 387, 0, 389, 0, 391, 392, 393, +- 394, 395, 0, 397, 0, 401, 402, 403, 135, 137, +- 135, 135, 137, 137, 0, 0, 0, 135, 77, 78, +- 79, 80, 81, 82, 83, 271, 272, 273, 274, 275, +- 276 +-}; +- +-static const yytype_int16 yycheck[] = +-{ +- 3, 326, 26, 4, 266, 35, 1, 4, 169, 248, +- 4, 3, 190, 191, 3, 108, 194, 195, 3, 1, +- 176, 1, 4, 98, 60, 4, 471, 263, 290, 4, +- 3, 26, 3, 108, 3, 60, 10, 11, 311, 200, +- 213, 202, 281, 90, 109, 370, 26, 94, 90, 494, +- 286, 4, 94, 498, 176, 91, 92, 296, 32, 33, +- 34, 94, 235, 110, 337, 3, 91, 92, 110, 230, +- 231, 74, 517, 251, 108, 0, 232, 110, 53, 3, +- 81, 406, 85, 86, 87, 60, 91, 92, 82, 63, +- 64, 65, 66, 67, 68, 69, 70, 95, 96, 129, +- 339, 104, 76, 77, 78, 79, 80, 81, 82, 83, +- 232, 108, 94, 92, 144, 94, 108, 362, 279, 108, +- 102, 366, 3, 108, 106, 303, 304, 106, 110, 54, +- 4, 110, 162, 163, 3, 108, 297, 108, 62, 63, +- 64, 65, 66, 67, 4, 70, 149, 150, 151, 152, +- 153, 154, 155, 91, 92, 158, 186, 187, 161, 4, +- 140, 141, 108, 341, 96, 4, 91, 92, 93, 94, +- 108, 3, 97, 6, 7, 8, 9, 10, 11, 95, +- 160, 106, 4, 81, 108, 110, 91, 92, 218, 219, +- 91, 92, 222, 371, 4, 108, 226, 227, 4, 59, +- 3, 61, 176, 108, 3, 79, 80, 108, 98, 40, +- 240, 4, 3, 108, 59, 111, 61, 247, 242, 249, +- 59, 108, 61, 108, 55, 56, 57, 222, 108, 224, +- 61, 226, 227, 411, 91, 92, 216, 59, 94, 61, +- 72, 73, 74, 75, 76, 77, 78, 242, 4, 59, +- 106, 61, 282, 59, 110, 61, 45, 46, 232, 3, +- 108, 108, 242, 54, 55, 56, 59, 108, 61, 299, +- 3, 94, 95, 96, 99, 108, 3, 102, 103, 102, +- 304, 108, 107, 106, 109, 101, 310, 110, 108, 319, +- 285, 16, 83, 84, 85, 86, 87, 88, 89, 302, +- 108, 108, 332, 306, 307, 308, 309, 95, 96, 304, +- 54, 55, 56, 43, 44, 310, 103, 104, 105, 442, +- 108, 54, 55, 56, 304, 328, 487, 322, 58, 324, +- 310, 492, 493, 62, 63, 64, 65, 66, 67, 83, +- 84, 85, 86, 87, 88, 89, 245, 270, 92, 93, +- 83, 84, 85, 86, 87, 88, 89, 518, 83, 84, +- 85, 86, 87, 88, 89, 277, 475, 362, 211, -1, +- 366, 366, -1, -1, 377, -1, -1, 3, 408, 108, +- -1, 376, 362, -1, 379, -1, 366, -1, -1, 419, +- 16, 17, 18, 19, -1, -1, 399, 91, 92, 93, +- 94, 404, 91, 92, -1, 94, -1, 3, 438, -1, +- 440, 94, 106, 408, -1, 41, 110, 106, 448, 102, +- -1, 110, -1, 106, -1, -1, -1, 110, 54, 55, +- 56, 57, 462, 463, -1, -1, 466, 467, -1, 469, +- -1, -1, 472, 473, 3, -1, 441, 477, -1, 479, +- -1, -1, -1, -1, 484, 458, -1, 487, 54, 55, +- 56, -1, 492, 493, -1, -1, 496, -1, 5, -1, +- 500, 474, 502, -1, -1, 12, 13, 14, 15, 100, +- 101, 102, 103, 104, 105, 488, -1, 83, 84, 85, +- 86, 87, 88, 89, -1, 54, 55, 56, 101, 102, +- 103, 104, 105, 506, 41, 42, 43, 44, 45, 46, +- -1, 48, 49, 50, 51, 52, -1, -1, -1, -1, +- 57, 58, -1, -1, 83, 84, 85, 86, 87, 88, +- 89, 68, 69, -1, 71, 98, 99, 100, 101, 102, +- 103, 104, 105, -1, -1, 54, 55, 56, 111, -1, +- -1, 3, -1, -1, 91, 92, 93, 94, 6, 7, +- 8, 9, 10, 11, 16, 17, 18, 19, 3, 106, +- -1, -1, -1, 110, 83, 84, 85, 86, 87, 88, +- 89, 16, 17, 18, 19, 94, -1, -1, -1, 41, +- -1, -1, -1, 102, -1, -1, -1, 106, -1, -1, +- -1, 110, 54, 55, 56, 57, 41, 388, -1, 390, +- -1, -1, -1, -1, -1, 396, -1, -1, -1, 54, +- 55, 56, 57, -1, 98, 99, 100, 101, 102, 103, +- 104, 105, -1, 414, 415, 416, 417, 111, -1, 420, +- 421, -1, 423, 4, 425, 426, 427, 428, 429, 10, +- 431, -1, -1, -1, 435, 436, 437, -1, -1, 20, +- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, +- 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, +- 4, 42, -1, -1, -1, -1, 10, 98, 99, 100, +- 101, 102, 103, 104, 105, -1, 20, 21, 22, 23, +- 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, +- 34, 35, 36, 37, 38, 39, 40, 4, 42, -1, +- -1, -1, -1, 10, 98, 99, 100, 101, 102, 103, +- 104, 105, -1, 20, 21, 22, 23, 24, 25, 26, +- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, +- 37, 38, 39, 40, 480, 42, -1, 483, 83, 84, +- 85, 86, 87, 88, 89, -1, -1, 92, 93, 495, +- -1, -1, -1, 499, -1, 501, -1, -1, -1, 505, +- -1, -1, -1, 509, -1, 511, -1, 345, 346, 347, +- 348, -1, 350, 351, -1, 353, -1, 355, 356, 357, +- 358, 359, -1, 361, -1, 363, 364, 365, 98, 99, +- 100, 101, 102, 103, -1, -1, -1, 107, 99, 100, +- 101, 102, 103, 104, 105, 62, 63, 64, 65, 66, +- 67 +-}; +- +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 113, 0, 54, 70, 91, 92, 93, 94, 97, +- 106, 110, 114, 120, 121, 122, 162, 163, 164, 165, +- 170, 173, 178, 182, 183, 185, 191, 192, 200, 212, +- 213, 94, 102, 106, 110, 209, 210, 194, 210, 210, +- 5, 12, 13, 14, 15, 41, 42, 43, 44, 45, +- 46, 48, 49, 50, 51, 52, 57, 58, 68, 69, +- 71, 181, 191, 98, 99, 100, 101, 102, 103, 104, +- 105, 210, 210, 210, 108, 208, 98, 99, 100, 101, +- 102, 103, 104, 105, 3, 54, 55, 56, 83, 84, +- 85, 86, 87, 88, 89, 197, 111, 194, 196, 195, +- 196, 196, 195, 195, 194, 194, 194, 196, 186, 194, +- 210, 210, 210, 210, 210, 210, 210, 210, 111, 209, +- 210, 210, 210, 210, 210, 210, 210, 210, 179, 209, +- 209, 209, 3, 92, 93, 197, 198, 197, 198, 16, +- 126, 126, 198, 198, 209, 3, 3, 198, 3, 72, +- 73, 74, 75, 76, 77, 78, 3, 198, 180, 208, +- 115, 109, 212, 212, 208, 166, 171, 187, 209, 209, +- 209, 209, 209, 209, 209, 174, 175, 1, 4, 209, +- 4, 92, 116, 117, 212, 209, 208, 208, 3, 4, +- 59, 61, 167, 4, 59, 61, 172, 4, 79, 80, +- 207, 208, 207, 4, 95, 96, 176, 177, 203, 204, +- 210, 108, 201, 202, 203, 204, 108, 211, 208, 208, +- 184, 60, 199, 200, 199, 60, 199, 199, 3, 3, +- 207, 207, 108, 96, 95, 202, 201, 212, 108, 208, +- 208, 4, 53, 60, 200, 208, 168, 208, 3, 208, +- 188, 81, 207, 207, 203, 204, 210, 6, 7, 8, +- 9, 10, 11, 118, 119, 123, 124, 208, 191, 168, +- 3, 62, 63, 64, 65, 66, 67, 108, 169, 208, +- 171, 3, 208, 4, 82, 199, 108, 119, 127, 127, +- 125, 166, 169, 207, 4, 171, 3, 208, 3, 190, +- 119, 3, 16, 17, 18, 19, 41, 54, 55, 56, +- 57, 3, 127, 4, 4, 171, 207, 189, 4, 208, +- 128, 209, 199, 191, 199, 200, 90, 94, 110, 205, +- 206, 209, 209, 209, 209, 191, 128, 3, 4, 3, +- 4, 81, 208, 4, 10, 20, 21, 22, 23, 24, +- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, +- 35, 36, 37, 38, 39, 40, 42, 129, 206, 209, +- 98, 108, 208, 4, 128, 171, 199, 153, 154, 199, +- 212, 153, 153, 153, 153, 135, 153, 153, 138, 153, +- 142, 153, 153, 153, 153, 153, 148, 153, 192, 193, +- 212, 153, 153, 153, 193, 111, 90, 206, 199, 4, +- 4, 108, 209, 108, 130, 131, 132, 134, 151, 209, +- 136, 137, 151, 139, 151, 143, 144, 145, 146, 147, +- 151, 149, 108, 209, 108, 133, 140, 141, 209, 206, +- 208, 199, 108, 152, 151, 151, 151, 151, 208, 151, +- 151, 151, 151, 151, 151, 151, 151, 151, 108, 151, +- 151, 151, 208, 208, 154, 108, 156, 208, 209, 208, +- 208, 157, 208, 208, 108, 3, 155, 208, 205, 208, +- 208, 209, 174, 208, 208, 108, 155, 160, 108, 4, +- 108, 155, 158, 208, 161, 207, 208, 209, 159, 207, +- 208, 207, 208, 205, 155, 208, 108, 205, 155, 208, +- 155, 208, 155, 209, 155, 155, 108, 150, 205, 207 +-}; +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. */ +- +-#define YYFAIL goto yyerrlab +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY && yylen == 1) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK (1); \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) +- +- +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +- If N is 0, then set CURRENT to the empty location which ends +- the previous symbol: RHS[0] (always defined). */ +- +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +-#ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (YYID (N)) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (YYID (0)) +-#endif +- +- +-/* YY_LOCATION_PRINT -- Print the location on the stream. +- This macro was not mandated originally: define only if we know +- we won't break user code: when these are the locations we know. */ +- +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +-# define YY_LOCATION_PRINT(File, Loc) \ +- fprintf (File, "%d.%d-%d.%d", \ +- (Loc).first_line, (Loc).first_column, \ +- (Loc).last_line, (Loc).last_column) +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif +- +- +-/* YYLEX -- calling `yylex' with the right arguments. */ +- +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); +-# endif +- switch (yytype) +- { +- default: +- break; +- } +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +-#else +-static void +-yy_stack_print (bottom, top) +- yytype_int16 *bottom; +- yytype_int16 *top; +-#endif +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; bottom <= top; ++bottom) +- YYFPRINTF (stderr, " %d", *bottom); +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif +-{ +- int yynrhs = yyr2[yyrule]; +- int yyi; +- unsigned long int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- fprintf (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- fprintf (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static YYSIZE_T +-yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into YYRESULT an error message about the unexpected token +- YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not +- copy anything; just return the number of bytes that would be +- copied. As a special case, return 0 if an ordinary "syntax error" +- message will do. Return YYSIZE_MAXIMUM if overflow occurs during +- size calculation. */ +-static YYSIZE_T +-yysyntax_error (char *yyresult, int yystate, int yychar) +-{ +- int yyn = yypact[yystate]; +- +- if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) +- return 0; +- else +- { +- int yytype = YYTRANSLATE (yychar); +- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); +- YYSIZE_T yysize = yysize0; +- YYSIZE_T yysize1; +- int yysize_overflow = 0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- int yyx; +- +-# if 0 +- /* This is so xgettext sees the translatable formats that are +- constructed on the fly. */ +- YY_("syntax error, unexpected %s"); +- YY_("syntax error, unexpected %s, expecting %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +-# endif +- char *yyfmt; +- char const *yyf; +- static char const yyunexpected[] = "syntax error, unexpected %s"; +- static char const yyexpecting[] = ", expecting %s"; +- static char const yyor[] = " or %s"; +- char yyformat[sizeof yyunexpected +- + sizeof yyexpecting - 1 +- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) +- * (sizeof yyor - 1))]; +- char const *yyprefix = yyexpecting; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 1; +- +- yyarg[0] = yytname[yytype]; +- yyfmt = yystpcpy (yyformat, yyunexpected); +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- yyformat[sizeof yyunexpected - 1] = '\0'; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- yysize1 = yysize + yytnamerr (0, yytname[yyx]); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- yyfmt = yystpcpy (yyfmt, yyprefix); +- yyprefix = yyor; +- } +- +- yyf = YY_(yyformat); +- yysize1 = yysize + yystrlen (yyf); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- +- if (yysize_overflow) +- return YYSIZE_MAXIMUM; +- +- if (yyresult) +- { +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- char *yyp = yyresult; +- int yyi = 0; +- while ((*yyp = *yyf) != '\0') +- { +- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyf += 2; +- } +- else +- { +- yyp++; +- yyf++; +- } +- } +- } +- return yysize; +- } +-} +-#endif /* YYERROR_VERBOSE */ +- +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif +-{ +- YYUSE (yyvaluep); +- +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- switch (yytype) +- { +- +- default: +- break; +- } +-} +- +- +-/* Prevent warnings from -Wmissing-prototypes. */ +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ +- +- +- +-/* The look-ahead symbol. */ +-int yychar; +- +-/* The semantic value of the look-ahead symbol. */ +-YYSTYPE yylval; +- +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif +-{ +- +- int yystate; +- int yyn; +- int yyresult; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- /* Look-ahead token as an internal (translated) token number. */ +- int yytoken = 0; +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +- /* Three stacks and their tools: +- `yyss': related to states, +- `yyvs': related to semantic values, +- `yyls': related to locations. +- +- Refer to the stacks thru separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss = yyssa; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs = yyvsa; +- YYSTYPE *yyvsp; +- +- +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- YYSIZE_T yystacksize = YYINITDEPTH; +- +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- +- /* Initialize stack pointers. +- Waste one element of value and location stack +- so that they stay on the same level as the state stack. +- The wasted elements are never initialized. */ +- +- yyssp = yyss; +- yyvsp = yyvs; +- +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss); +- YYSTACK_RELOCATE (yyvs); +- +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- look-ahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to look-ahead token. */ +- yyn = yypact[yystate]; +- if (yyn == YYPACT_NINF) +- goto yydefault; +- +- /* Not known => get a look-ahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yyn == 0 || yyn == YYTABLE_NINF) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the look-ahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- yystate = yyn; +- *++yyvsp = yylval; +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 18: +-#line 202 "rcparse.y" +- { +- define_accelerator ((yyvsp[(1) - (6)].id), &(yyvsp[(3) - (6)].res_info), (yyvsp[(5) - (6)].pacc)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 19: +-#line 212 "rcparse.y" +- { +- (yyval.pacc) = NULL; +- } +- break; +- +- case 20: +-#line 216 "rcparse.y" +- { +- rc_accelerator *a; +- +- a = (rc_accelerator *) res_alloc (sizeof *a); +- *a = (yyvsp[(2) - (2)].acc); +- if ((yyvsp[(1) - (2)].pacc) == NULL) +- (yyval.pacc) = a; +- else +- { +- rc_accelerator **pp; +- +- for (pp = &(yyvsp[(1) - (2)].pacc)->next; *pp != NULL; pp = &(*pp)->next) +- ; +- *pp = a; +- (yyval.pacc) = (yyvsp[(1) - (2)].pacc); +- } +- } +- break; +- +- case 21: +-#line 237 "rcparse.y" +- { +- (yyval.acc) = (yyvsp[(1) - (2)].acc); +- (yyval.acc).id = (yyvsp[(2) - (2)].il); +- } +- break; +- +- case 22: +-#line 242 "rcparse.y" +- { +- (yyval.acc) = (yyvsp[(1) - (4)].acc); +- (yyval.acc).id = (yyvsp[(2) - (4)].il); +- (yyval.acc).flags |= (yyvsp[(4) - (4)].is); +- if (((yyval.acc).flags & ACC_VIRTKEY) == 0 +- && ((yyval.acc).flags & (ACC_SHIFT | ACC_CONTROL)) != 0) +- rcparse_warning (_("inappropriate modifiers for non-VIRTKEY")); +- } +- break; +- +- case 23: +-#line 254 "rcparse.y" +- { +- const char *s = (yyvsp[(1) - (1)].s); +- char ch; +- +- (yyval.acc).next = NULL; +- (yyval.acc).id = 0; +- ch = *s; +- if (ch != '^') +- (yyval.acc).flags = 0; +- else +- { +- (yyval.acc).flags = ACC_CONTROL | ACC_VIRTKEY; +- ++s; +- ch = TOUPPER (s[0]); +- } +- (yyval.acc).key = ch; +- if (s[1] != '\0') +- rcparse_warning (_("accelerator should only be one character")); +- } +- break; +- +- case 24: +-#line 274 "rcparse.y" +- { +- (yyval.acc).next = NULL; +- (yyval.acc).flags = 0; +- (yyval.acc).id = 0; +- (yyval.acc).key = (yyvsp[(1) - (1)].il); +- } +- break; +- +- case 25: +-#line 284 "rcparse.y" +- { +- (yyval.is) = (yyvsp[(1) - (1)].is); +- } +- break; +- +- case 26: +-#line 288 "rcparse.y" +- { +- (yyval.is) = (yyvsp[(1) - (3)].is) | (yyvsp[(3) - (3)].is); +- } +- break; +- +- case 27: +-#line 293 "rcparse.y" +- { +- (yyval.is) = (yyvsp[(1) - (2)].is) | (yyvsp[(2) - (2)].is); +- } +- break; +- +- case 28: +-#line 300 "rcparse.y" +- { +- (yyval.is) = ACC_VIRTKEY; +- } +- break; +- +- case 29: +-#line 304 "rcparse.y" +- { +- /* This is just the absence of VIRTKEY. */ +- (yyval.is) = 0; +- } +- break; +- +- case 30: +-#line 309 "rcparse.y" +- { +- (yyval.is) = ACC_NOINVERT; +- } +- break; +- +- case 31: +-#line 313 "rcparse.y" +- { +- (yyval.is) = ACC_SHIFT; +- } +- break; +- +- case 32: +-#line 317 "rcparse.y" +- { +- (yyval.is) = ACC_CONTROL; +- } +- break; +- +- case 33: +-#line 321 "rcparse.y" +- { +- (yyval.is) = ACC_ALT; +- } +- break; +- +- case 34: +-#line 330 "rcparse.y" +- { +- define_bitmap ((yyvsp[(1) - (4)].id), &(yyvsp[(3) - (4)].res_info), (yyvsp[(4) - (4)].s)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 35: +-#line 342 "rcparse.y" +- { +- define_cursor ((yyvsp[(1) - (4)].id), &(yyvsp[(3) - (4)].res_info), (yyvsp[(4) - (4)].s)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 36: +-#line 355 "rcparse.y" +- { +- memset (&dialog, 0, sizeof dialog); +- dialog.x = (yyvsp[(5) - (8)].il); +- dialog.y = (yyvsp[(6) - (8)].il); +- dialog.width = (yyvsp[(7) - (8)].il); +- dialog.height = (yyvsp[(8) - (8)].il); +- dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; +- dialog.exstyle = (yyvsp[(4) - (8)].il); +- dialog.menu.named = 1; +- dialog.class.named = 1; +- dialog.font = NULL; +- dialog.ex = NULL; +- dialog.controls = NULL; +- sub_res_info = (yyvsp[(3) - (8)].res_info); +- style = 0; +- } +- break; +- +- case 37: +-#line 372 "rcparse.y" +- { +- define_dialog ((yyvsp[(1) - (13)].id), &sub_res_info, &dialog); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 38: +-#line 380 "rcparse.y" +- { +- memset (&dialog, 0, sizeof dialog); +- dialog.x = (yyvsp[(5) - (8)].il); +- dialog.y = (yyvsp[(6) - (8)].il); +- dialog.width = (yyvsp[(7) - (8)].il); +- dialog.height = (yyvsp[(8) - (8)].il); +- dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; +- dialog.exstyle = (yyvsp[(4) - (8)].il); +- dialog.menu.named = 1; +- dialog.class.named = 1; +- dialog.font = NULL; +- dialog.ex = ((rc_dialog_ex *) +- res_alloc (sizeof (rc_dialog_ex))); +- memset (dialog.ex, 0, sizeof (rc_dialog_ex)); +- dialog.controls = NULL; +- sub_res_info = (yyvsp[(3) - (8)].res_info); +- style = 0; +- } +- break; +- +- case 39: +-#line 399 "rcparse.y" +- { +- define_dialog ((yyvsp[(1) - (13)].id), &sub_res_info, &dialog); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 40: +-#line 407 "rcparse.y" +- { +- memset (&dialog, 0, sizeof dialog); +- dialog.x = (yyvsp[(5) - (9)].il); +- dialog.y = (yyvsp[(6) - (9)].il); +- dialog.width = (yyvsp[(7) - (9)].il); +- dialog.height = (yyvsp[(8) - (9)].il); +- dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; +- dialog.exstyle = (yyvsp[(4) - (9)].il); +- dialog.menu.named = 1; +- dialog.class.named = 1; +- dialog.font = NULL; +- dialog.ex = ((rc_dialog_ex *) +- res_alloc (sizeof (rc_dialog_ex))); +- memset (dialog.ex, 0, sizeof (rc_dialog_ex)); +- dialog.ex->help = (yyvsp[(9) - (9)].il); +- dialog.controls = NULL; +- sub_res_info = (yyvsp[(3) - (9)].res_info); +- style = 0; +- } +- break; +- +- case 41: +-#line 427 "rcparse.y" +- { +- define_dialog ((yyvsp[(1) - (14)].id), &sub_res_info, &dialog); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 42: +-#line 437 "rcparse.y" +- { +- (yyval.il) = 0; +- } +- break; +- +- case 43: +-#line 441 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 45: +-#line 449 "rcparse.y" +- { +- dialog.style |= WS_CAPTION; +- style |= WS_CAPTION; +- dialog.caption = (yyvsp[(3) - (3)].uni); +- } +- break; +- +- case 46: +-#line 455 "rcparse.y" +- { +- dialog.class = (yyvsp[(3) - (3)].id); +- } +- break; +- +- case 47: +-#line 460 "rcparse.y" +- { +- dialog.style = style; +- } +- break; +- +- case 48: +-#line 464 "rcparse.y" +- { +- dialog.exstyle = (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 49: +-#line 468 "rcparse.y" +- { +- res_unistring_to_id (& dialog.class, (yyvsp[(3) - (3)].uni)); +- } +- break; +- +- case 50: +-#line 472 "rcparse.y" +- { +- dialog.style |= DS_SETFONT; +- style |= DS_SETFONT; +- dialog.pointsize = (yyvsp[(3) - (5)].il); +- dialog.font = (yyvsp[(5) - (5)].uni); +- if (dialog.ex != NULL) +- { +- dialog.ex->weight = 0; +- dialog.ex->italic = 0; +- dialog.ex->charset = 1; +- } +- } +- break; +- +- case 51: +-#line 485 "rcparse.y" +- { +- dialog.style |= DS_SETFONT; +- style |= DS_SETFONT; +- dialog.pointsize = (yyvsp[(3) - (6)].il); +- dialog.font = (yyvsp[(5) - (6)].uni); +- if (dialog.ex == NULL) +- rcparse_warning (_("extended FONT requires DIALOGEX")); +- else +- { +- dialog.ex->weight = (yyvsp[(6) - (6)].il); +- dialog.ex->italic = 0; +- dialog.ex->charset = 1; +- } +- } +- break; +- +- case 52: +-#line 500 "rcparse.y" +- { +- dialog.style |= DS_SETFONT; +- style |= DS_SETFONT; +- dialog.pointsize = (yyvsp[(3) - (7)].il); +- dialog.font = (yyvsp[(5) - (7)].uni); +- if (dialog.ex == NULL) +- rcparse_warning (_("extended FONT requires DIALOGEX")); +- else +- { +- dialog.ex->weight = (yyvsp[(6) - (7)].il); +- dialog.ex->italic = (yyvsp[(7) - (7)].il); +- dialog.ex->charset = 1; +- } +- } +- break; +- +- case 53: +-#line 515 "rcparse.y" +- { +- dialog.style |= DS_SETFONT; +- style |= DS_SETFONT; +- dialog.pointsize = (yyvsp[(3) - (8)].il); +- dialog.font = (yyvsp[(5) - (8)].uni); +- if (dialog.ex == NULL) +- rcparse_warning (_("extended FONT requires DIALOGEX")); +- else +- { +- dialog.ex->weight = (yyvsp[(6) - (8)].il); +- dialog.ex->italic = (yyvsp[(7) - (8)].il); +- dialog.ex->charset = (yyvsp[(8) - (8)].il); +- } +- } +- break; +- +- case 54: +-#line 530 "rcparse.y" +- { +- dialog.menu = (yyvsp[(3) - (3)].id); +- } +- break; +- +- case 55: +-#line 534 "rcparse.y" +- { +- sub_res_info.characteristics = (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 56: +-#line 538 "rcparse.y" +- { +- sub_res_info.language = (yyvsp[(3) - (4)].il) | ((yyvsp[(4) - (4)].il) << SUBLANG_SHIFT); +- } +- break; +- +- case 57: +-#line 542 "rcparse.y" +- { +- sub_res_info.version = (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 59: +-#line 550 "rcparse.y" +- { +- rc_dialog_control **pp; +- +- for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next) +- ; +- *pp = (yyvsp[(2) - (2)].dialog_control); +- } +- break; +- +- case 60: +-#line 561 "rcparse.y" +- { +- default_style = BS_AUTO3STATE | WS_TABSTOP; +- base_style = BS_AUTO3STATE; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 61: +-#line 569 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 62: +-#line 573 "rcparse.y" +- { +- default_style = BS_AUTOCHECKBOX | WS_TABSTOP; +- base_style = BS_AUTOCHECKBOX; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 63: +-#line 581 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 64: +-#line 585 "rcparse.y" +- { +- default_style = BS_AUTORADIOBUTTON | WS_TABSTOP; +- base_style = BS_AUTORADIOBUTTON; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 65: +-#line 593 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 66: +-#line 597 "rcparse.y" +- { +- default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_EDIT; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 67: +-#line 605 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- if (dialog.ex == NULL) +- rcparse_warning (_("BEDIT requires DIALOGEX")); +- res_string_to_id (&(yyval.dialog_control)->class, "BEDIT"); +- } +- break; +- +- case 68: +-#line 612 "rcparse.y" +- { +- default_style = BS_CHECKBOX | WS_TABSTOP; +- base_style = BS_CHECKBOX | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 69: +-#line 620 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 70: +-#line 624 "rcparse.y" +- { +- /* This is as per MSDN documentation. With some (???) +- versions of MS rc.exe their is no default style. */ +- default_style = CBS_SIMPLE | WS_TABSTOP; +- base_style = 0; +- class.named = 0; +- class.u.id = CTL_COMBOBOX; +- res_text_field = res_null_text; +- } +- break; +- +- case 71: +-#line 634 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(3) - (3)].dialog_control); +- } +- break; +- +- case 72: +-#line 639 "rcparse.y" +- { +- (yyval.dialog_control) = define_control ((yyvsp[(2) - (11)].id), (yyvsp[(3) - (11)].il), (yyvsp[(6) - (11)].il), (yyvsp[(7) - (11)].il), (yyvsp[(8) - (11)].il), (yyvsp[(9) - (11)].il), (yyvsp[(4) - (11)].id), style, (yyvsp[(10) - (11)].il)); +- if ((yyvsp[(11) - (11)].rcdata_item) != NULL) +- { +- if (dialog.ex == NULL) +- rcparse_warning (_("control data requires DIALOGEX")); +- (yyval.dialog_control)->data = (yyvsp[(11) - (11)].rcdata_item); +- } +- } +- break; +- +- case 73: +-#line 650 "rcparse.y" +- { +- (yyval.dialog_control) = define_control ((yyvsp[(2) - (12)].id), (yyvsp[(3) - (12)].il), (yyvsp[(6) - (12)].il), (yyvsp[(7) - (12)].il), (yyvsp[(8) - (12)].il), (yyvsp[(9) - (12)].il), (yyvsp[(4) - (12)].id), style, (yyvsp[(10) - (12)].il)); +- if (dialog.ex == NULL) +- rcparse_warning (_("help ID requires DIALOGEX")); +- (yyval.dialog_control)->help = (yyvsp[(11) - (12)].il); +- (yyval.dialog_control)->data = (yyvsp[(12) - (12)].rcdata_item); +- } +- break; +- +- case 74: +-#line 658 "rcparse.y" +- { +- default_style = SS_CENTER | WS_GROUP; +- base_style = SS_CENTER; +- class.named = 0; +- class.u.id = CTL_STATIC; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 75: +-#line 666 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 76: +-#line 670 "rcparse.y" +- { +- default_style = BS_DEFPUSHBUTTON | WS_TABSTOP; +- base_style = BS_DEFPUSHBUTTON | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 77: +-#line 678 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 78: +-#line 682 "rcparse.y" +- { +- default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_EDIT; +- res_text_field = res_null_text; +- } +- break; +- +- case 79: +-#line 690 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(3) - (3)].dialog_control); +- } +- break; +- +- case 80: +-#line 694 "rcparse.y" +- { +- default_style = BS_GROUPBOX; +- base_style = BS_GROUPBOX; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 81: +-#line 702 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 82: +-#line 706 "rcparse.y" +- { +- default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_EDIT; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 83: +-#line 714 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- if (dialog.ex == NULL) +- rcparse_warning (_("IEDIT requires DIALOGEX")); +- res_string_to_id (&(yyval.dialog_control)->class, "HEDIT"); +- } +- break; +- +- case 84: +-#line 721 "rcparse.y" +- { +- (yyval.dialog_control) = define_icon_control ((yyvsp[(2) - (6)].id), (yyvsp[(3) - (6)].il), (yyvsp[(4) - (6)].il), (yyvsp[(5) - (6)].il), 0, 0, 0, (yyvsp[(6) - (6)].rcdata_item), +- dialog.ex); +- } +- break; +- +- case 85: +-#line 727 "rcparse.y" +- { +- (yyval.dialog_control) = define_icon_control ((yyvsp[(2) - (8)].id), (yyvsp[(3) - (8)].il), (yyvsp[(4) - (8)].il), (yyvsp[(5) - (8)].il), 0, 0, 0, (yyvsp[(8) - (8)].rcdata_item), +- dialog.ex); +- } +- break; +- +- case 86: +-#line 733 "rcparse.y" +- { +- (yyval.dialog_control) = define_icon_control ((yyvsp[(2) - (10)].id), (yyvsp[(3) - (10)].il), (yyvsp[(4) - (10)].il), (yyvsp[(5) - (10)].il), style, (yyvsp[(9) - (10)].il), 0, (yyvsp[(10) - (10)].rcdata_item), +- dialog.ex); +- } +- break; +- +- case 87: +-#line 739 "rcparse.y" +- { +- (yyval.dialog_control) = define_icon_control ((yyvsp[(2) - (11)].id), (yyvsp[(3) - (11)].il), (yyvsp[(4) - (11)].il), (yyvsp[(5) - (11)].il), style, (yyvsp[(9) - (11)].il), (yyvsp[(10) - (11)].il), (yyvsp[(11) - (11)].rcdata_item), +- dialog.ex); +- } +- break; +- +- case 88: +-#line 744 "rcparse.y" +- { +- default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_EDIT; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 89: +-#line 752 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- if (dialog.ex == NULL) +- rcparse_warning (_("IEDIT requires DIALOGEX")); +- res_string_to_id (&(yyval.dialog_control)->class, "IEDIT"); +- } +- break; +- +- case 90: +-#line 759 "rcparse.y" +- { +- default_style = LBS_NOTIFY | WS_BORDER; +- base_style = LBS_NOTIFY | WS_BORDER; +- class.named = 0; +- class.u.id = CTL_LISTBOX; +- res_text_field = res_null_text; +- } +- break; +- +- case 91: +-#line 767 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(3) - (3)].dialog_control); +- } +- break; +- +- case 92: +-#line 771 "rcparse.y" +- { +- default_style = SS_LEFT | WS_GROUP; +- base_style = SS_LEFT; +- class.named = 0; +- class.u.id = CTL_STATIC; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 93: +-#line 779 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 94: +-#line 783 "rcparse.y" +- { +- default_style = BS_PUSHBOX | WS_TABSTOP; +- base_style = BS_PUSHBOX; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- } +- break; +- +- case 95: +-#line 790 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 96: +-#line 794 "rcparse.y" +- { +- default_style = BS_PUSHBUTTON | WS_TABSTOP; +- base_style = BS_PUSHBUTTON | WS_TABSTOP; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 97: +-#line 802 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 98: +-#line 806 "rcparse.y" +- { +- default_style = BS_RADIOBUTTON | WS_TABSTOP; +- base_style = BS_RADIOBUTTON; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 99: +-#line 814 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 100: +-#line 818 "rcparse.y" +- { +- default_style = SS_RIGHT | WS_GROUP; +- base_style = SS_RIGHT; +- class.named = 0; +- class.u.id = CTL_STATIC; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 101: +-#line 826 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 102: +-#line 830 "rcparse.y" +- { +- default_style = SBS_HORZ; +- base_style = 0; +- class.named = 0; +- class.u.id = CTL_SCROLLBAR; +- res_text_field = res_null_text; +- } +- break; +- +- case 103: +-#line 838 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(3) - (3)].dialog_control); +- } +- break; +- +- case 104: +-#line 842 "rcparse.y" +- { +- default_style = BS_3STATE | WS_TABSTOP; +- base_style = BS_3STATE; +- class.named = 0; +- class.u.id = CTL_BUTTON; +- res_text_field = (yyvsp[(2) - (2)].id); +- } +- break; +- +- case 105: +-#line 850 "rcparse.y" +- { +- (yyval.dialog_control) = (yyvsp[(4) - (4)].dialog_control); +- } +- break; +- +- case 106: +-#line 855 "rcparse.y" +- { style = WS_CHILD | WS_VISIBLE; } +- break; +- +- case 107: +-#line 857 "rcparse.y" +- { +- rc_res_id cid; +- cid.named = 0; +- cid.u.id = CTL_BUTTON; +- (yyval.dialog_control) = define_control ((yyvsp[(2) - (15)].id), (yyvsp[(3) - (15)].il), (yyvsp[(5) - (15)].il), (yyvsp[(7) - (15)].il), (yyvsp[(9) - (15)].il), (yyvsp[(11) - (15)].il), cid, +- style, (yyvsp[(15) - (15)].il)); +- } +- break; +- +- case 108: +-#line 875 "rcparse.y" +- { +- (yyval.dialog_control) = define_control (res_text_field, (yyvsp[(1) - (6)].il), (yyvsp[(2) - (6)].il), (yyvsp[(3) - (6)].il), (yyvsp[(4) - (6)].il), (yyvsp[(5) - (6)].il), class, +- default_style | WS_CHILD | WS_VISIBLE, 0); +- if ((yyvsp[(6) - (6)].rcdata_item) != NULL) +- { +- if (dialog.ex == NULL) +- rcparse_warning (_("control data requires DIALOGEX")); +- (yyval.dialog_control)->data = (yyvsp[(6) - (6)].rcdata_item); +- } +- } +- break; +- +- case 109: +-#line 887 "rcparse.y" +- { +- (yyval.dialog_control) = define_control (res_text_field, (yyvsp[(1) - (8)].il), (yyvsp[(2) - (8)].il), (yyvsp[(3) - (8)].il), (yyvsp[(4) - (8)].il), (yyvsp[(5) - (8)].il), class, style, (yyvsp[(7) - (8)].il)); +- if ((yyvsp[(8) - (8)].rcdata_item) != NULL) +- { +- if (dialog.ex == NULL) +- rcparse_warning (_("control data requires DIALOGEX")); +- (yyval.dialog_control)->data = (yyvsp[(8) - (8)].rcdata_item); +- } +- } +- break; +- +- case 110: +-#line 898 "rcparse.y" +- { +- (yyval.dialog_control) = define_control (res_text_field, (yyvsp[(1) - (9)].il), (yyvsp[(2) - (9)].il), (yyvsp[(3) - (9)].il), (yyvsp[(4) - (9)].il), (yyvsp[(5) - (9)].il), class, style, (yyvsp[(7) - (9)].il)); +- if (dialog.ex == NULL) +- rcparse_warning (_("help ID requires DIALOGEX")); +- (yyval.dialog_control)->help = (yyvsp[(8) - (9)].il); +- (yyval.dialog_control)->data = (yyvsp[(9) - (9)].rcdata_item); +- } +- break; +- +- case 111: +-#line 909 "rcparse.y" +- { +- if ((yyvsp[(2) - (2)].id).named) +- res_unistring_to_id (&(yyval.id), (yyvsp[(2) - (2)].id).u.n.name); +- else +- (yyval.id)=(yyvsp[(2) - (2)].id); +- } +- break; +- +- case 112: +-#line 919 "rcparse.y" +- { +- res_string_to_id (&(yyval.id), ""); +- } +- break; +- +- case 113: +-#line 922 "rcparse.y" +- { (yyval.id)=(yyvsp[(1) - (2)].id); } +- break; +- +- case 114: +-#line 927 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = (yyvsp[(1) - (1)].il); +- } +- break; +- +- case 115: +-#line 932 "rcparse.y" +- { +- (yyval.id).named = 1; +- (yyval.id).u.n.name = (yyvsp[(1) - (1)].uni); +- (yyval.id).u.n.length = unichar_len ((yyvsp[(1) - (1)].uni)); +- } +- break; +- +- case 116: +-#line 941 "rcparse.y" +- { +- (yyval.rcdata_item) = NULL; +- } +- break; +- +- case 117: +-#line 945 "rcparse.y" +- { +- (yyval.rcdata_item) = (yyvsp[(2) - (3)].rcdata).first; +- } +- break; +- +- case 118: +-#line 954 "rcparse.y" +- { style = WS_CHILD | WS_VISIBLE; } +- break; +- +- case 120: +-#line 960 "rcparse.y" +- { style = SS_ICON | WS_CHILD | WS_VISIBLE; } +- break; +- +- case 122: +-#line 966 "rcparse.y" +- { style = base_style | WS_CHILD | WS_VISIBLE; } +- break; +- +- case 124: +-#line 974 "rcparse.y" +- { +- define_font ((yyvsp[(1) - (4)].id), &(yyvsp[(3) - (4)].res_info), (yyvsp[(4) - (4)].s)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 125: +-#line 986 "rcparse.y" +- { +- define_icon ((yyvsp[(1) - (4)].id), &(yyvsp[(3) - (4)].res_info), (yyvsp[(4) - (4)].s)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 126: +-#line 999 "rcparse.y" +- { +- language = (yyvsp[(2) - (3)].il) | ((yyvsp[(3) - (3)].il) << SUBLANG_SHIFT); +- } +- break; +- +- case 127: +-#line 1008 "rcparse.y" +- { +- define_menu ((yyvsp[(1) - (6)].id), &(yyvsp[(3) - (6)].res_info), (yyvsp[(5) - (6)].menuitem)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 128: +-#line 1018 "rcparse.y" +- { +- (yyval.menuitem) = NULL; +- } +- break; +- +- case 129: +-#line 1022 "rcparse.y" +- { +- if ((yyvsp[(1) - (2)].menuitem) == NULL) +- (yyval.menuitem) = (yyvsp[(2) - (2)].menuitem); +- else +- { +- rc_menuitem **pp; +- +- for (pp = &(yyvsp[(1) - (2)].menuitem)->next; *pp != NULL; pp = &(*pp)->next) +- ; +- *pp = (yyvsp[(2) - (2)].menuitem); +- (yyval.menuitem) = (yyvsp[(1) - (2)].menuitem); +- } +- } +- break; +- +- case 130: +-#line 1039 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (4)].uni), (yyvsp[(3) - (4)].il), (yyvsp[(4) - (4)].is), 0, 0, NULL); +- } +- break; +- +- case 131: +-#line 1043 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem (NULL, 0, 0, 0, 0, NULL); +- } +- break; +- +- case 132: +-#line 1047 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (6)].uni), 0, (yyvsp[(3) - (6)].is), 0, 0, (yyvsp[(5) - (6)].menuitem)); +- } +- break; +- +- case 133: +-#line 1054 "rcparse.y" +- { +- (yyval.is) = 0; +- } +- break; +- +- case 134: +-#line 1058 "rcparse.y" +- { +- (yyval.is) = (yyvsp[(1) - (3)].is) | (yyvsp[(3) - (3)].is); +- } +- break; +- +- case 135: +-#line 1062 "rcparse.y" +- { +- (yyval.is) = (yyvsp[(1) - (2)].is) | (yyvsp[(2) - (2)].is); +- } +- break; +- +- case 136: +-#line 1069 "rcparse.y" +- { +- (yyval.is) = MENUITEM_CHECKED; +- } +- break; +- +- case 137: +-#line 1073 "rcparse.y" +- { +- (yyval.is) = MENUITEM_GRAYED; +- } +- break; +- +- case 138: +-#line 1077 "rcparse.y" +- { +- (yyval.is) = MENUITEM_HELP; +- } +- break; +- +- case 139: +-#line 1081 "rcparse.y" +- { +- (yyval.is) = MENUITEM_INACTIVE; +- } +- break; +- +- case 140: +-#line 1085 "rcparse.y" +- { +- (yyval.is) = MENUITEM_MENUBARBREAK; +- } +- break; +- +- case 141: +-#line 1089 "rcparse.y" +- { +- (yyval.is) = MENUITEM_MENUBREAK; +- } +- break; +- +- case 142: +-#line 1098 "rcparse.y" +- { +- define_menu ((yyvsp[(1) - (6)].id), &(yyvsp[(3) - (6)].res_info), (yyvsp[(5) - (6)].menuitem)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 143: +-#line 1108 "rcparse.y" +- { +- (yyval.menuitem) = NULL; +- } +- break; +- +- case 144: +-#line 1112 "rcparse.y" +- { +- if ((yyvsp[(1) - (2)].menuitem) == NULL) +- (yyval.menuitem) = (yyvsp[(2) - (2)].menuitem); +- else +- { +- rc_menuitem **pp; +- +- for (pp = &(yyvsp[(1) - (2)].menuitem)->next; *pp != NULL; pp = &(*pp)->next) +- ; +- *pp = (yyvsp[(2) - (2)].menuitem); +- (yyval.menuitem) = (yyvsp[(1) - (2)].menuitem); +- } +- } +- break; +- +- case 145: +-#line 1129 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (2)].uni), 0, 0, 0, 0, NULL); +- } +- break; +- +- case 146: +-#line 1133 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (3)].uni), (yyvsp[(3) - (3)].il), 0, 0, 0, NULL); +- } +- break; +- +- case 147: +-#line 1137 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (5)].uni), (yyvsp[(3) - (5)].il), (yyvsp[(4) - (5)].il), (yyvsp[(5) - (5)].il), 0, NULL); +- } +- break; +- +- case 148: +-#line 1141 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem (NULL, 0, 0, 0, 0, NULL); +- } +- break; +- +- case 149: +-#line 1145 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (5)].uni), 0, 0, 0, 0, (yyvsp[(4) - (5)].menuitem)); +- } +- break; +- +- case 150: +-#line 1149 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (6)].uni), (yyvsp[(3) - (6)].il), 0, 0, 0, (yyvsp[(5) - (6)].menuitem)); +- } +- break; +- +- case 151: +-#line 1153 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (7)].uni), (yyvsp[(3) - (7)].il), (yyvsp[(4) - (7)].il), 0, 0, (yyvsp[(6) - (7)].menuitem)); +- } +- break; +- +- case 152: +-#line 1158 "rcparse.y" +- { +- (yyval.menuitem) = define_menuitem ((yyvsp[(2) - (9)].uni), (yyvsp[(3) - (9)].il), (yyvsp[(4) - (9)].il), (yyvsp[(5) - (9)].il), (yyvsp[(6) - (9)].il), (yyvsp[(8) - (9)].menuitem)); +- } +- break; +- +- case 153: +-#line 1167 "rcparse.y" +- { +- define_messagetable ((yyvsp[(1) - (4)].id), &(yyvsp[(3) - (4)].res_info), (yyvsp[(4) - (4)].s)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 154: +-#line 1179 "rcparse.y" +- { +- rcparse_rcdata (); +- } +- break; +- +- case 155: +-#line 1183 "rcparse.y" +- { +- rcparse_normal (); +- (yyval.rcdata) = (yyvsp[(2) - (2)].rcdata); +- } +- break; +- +- case 156: +-#line 1191 "rcparse.y" +- { +- (yyval.rcdata).first = NULL; +- (yyval.rcdata).last = NULL; +- } +- break; +- +- case 157: +-#line 1196 "rcparse.y" +- { +- (yyval.rcdata) = (yyvsp[(1) - (1)].rcdata); +- } +- break; +- +- case 158: +-#line 1203 "rcparse.y" +- { +- rc_rcdata_item *ri; +- +- ri = define_rcdata_string ((yyvsp[(1) - (1)].ss).s, (yyvsp[(1) - (1)].ss).length); +- (yyval.rcdata).first = ri; +- (yyval.rcdata).last = ri; +- } +- break; +- +- case 159: +-#line 1211 "rcparse.y" +- { +- rc_rcdata_item *ri; +- +- ri = define_rcdata_unistring ((yyvsp[(1) - (1)].suni).s, (yyvsp[(1) - (1)].suni).length); +- (yyval.rcdata).first = ri; +- (yyval.rcdata).last = ri; +- } +- break; +- +- case 160: +-#line 1219 "rcparse.y" +- { +- rc_rcdata_item *ri; +- +- ri = define_rcdata_number ((yyvsp[(1) - (1)].i).val, (yyvsp[(1) - (1)].i).dword); +- (yyval.rcdata).first = ri; +- (yyval.rcdata).last = ri; +- } +- break; +- +- case 161: +-#line 1227 "rcparse.y" +- { +- rc_rcdata_item *ri; +- +- ri = define_rcdata_string ((yyvsp[(3) - (3)].ss).s, (yyvsp[(3) - (3)].ss).length); +- (yyval.rcdata).first = (yyvsp[(1) - (3)].rcdata).first; +- (yyvsp[(1) - (3)].rcdata).last->next = ri; +- (yyval.rcdata).last = ri; +- } +- break; +- +- case 162: +-#line 1236 "rcparse.y" +- { +- rc_rcdata_item *ri; +- +- ri = define_rcdata_unistring ((yyvsp[(3) - (3)].suni).s, (yyvsp[(3) - (3)].suni).length); +- (yyval.rcdata).first = (yyvsp[(1) - (3)].rcdata).first; +- (yyvsp[(1) - (3)].rcdata).last->next = ri; +- (yyval.rcdata).last = ri; +- } +- break; +- +- case 163: +-#line 1245 "rcparse.y" +- { +- rc_rcdata_item *ri; +- +- ri = define_rcdata_number ((yyvsp[(3) - (3)].i).val, (yyvsp[(3) - (3)].i).dword); +- (yyval.rcdata).first = (yyvsp[(1) - (3)].rcdata).first; +- (yyvsp[(1) - (3)].rcdata).last->next = ri; +- (yyval.rcdata).last = ri; +- } +- break; +- +- case 164: +-#line 1254 "rcparse.y" +- { +- (yyval.rcdata)=(yyvsp[(1) - (2)].rcdata); +- } +- break; +- +- case 165: +-#line 1263 "rcparse.y" +- { sub_res_info = (yyvsp[(2) - (3)].res_info); rcparse_rcdata (); } +- break; +- +- case 166: +-#line 1264 "rcparse.y" +- { rcparse_normal (); } +- break; +- +- case 168: +-#line 1270 "rcparse.y" +- { +- define_stringtable (&sub_res_info, (yyvsp[(2) - (3)].il), (yyvsp[(3) - (3)].suni).s, (yyvsp[(3) - (3)].suni).length); +- rcparse_discard_strings (); +- } +- break; +- +- case 169: +-#line 1275 "rcparse.y" +- { +- define_stringtable (&sub_res_info, (yyvsp[(2) - (4)].il), (yyvsp[(4) - (4)].suni).s, (yyvsp[(4) - (4)].suni).length); +- rcparse_discard_strings (); +- } +- break; +- +- case 170: +-#line 1280 "rcparse.y" +- { +- rcparse_warning (_("invalid stringtable resource.")); +- abort (); +- } +- break; +- +- case 171: +-#line 1288 "rcparse.y" +- { +- (yyval.id)=(yyvsp[(1) - (1)].id); +- } +- break; +- +- case 172: +-#line 1292 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = 23; +- } +- break; +- +- case 173: +-#line 1297 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_RCDATA; +- } +- break; +- +- case 174: +-#line 1302 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_MANIFEST; +- } +- break; +- +- case 175: +-#line 1307 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_PLUGPLAY; +- } +- break; +- +- case 176: +-#line 1312 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_VXD; +- } +- break; +- +- case 177: +-#line 1317 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_DLGINCLUDE; +- } +- break; +- +- case 178: +-#line 1322 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_DLGINIT; +- } +- break; +- +- case 179: +-#line 1327 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_ANICURSOR; +- } +- break; +- +- case 180: +-#line 1332 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = RT_ANIICON; +- } +- break; +- +- case 181: +-#line 1343 "rcparse.y" +- { +- define_user_data ((yyvsp[(1) - (6)].id), (yyvsp[(2) - (6)].id), &(yyvsp[(3) - (6)].res_info), (yyvsp[(5) - (6)].rcdata).first); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 182: +-#line 1350 "rcparse.y" +- { +- define_user_file ((yyvsp[(1) - (4)].id), (yyvsp[(2) - (4)].id), &(yyvsp[(3) - (4)].res_info), (yyvsp[(4) - (4)].s)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 183: +-#line 1360 "rcparse.y" +- { +- define_toolbar ((yyvsp[(1) - (8)].id), &(yyvsp[(3) - (8)].res_info), (yyvsp[(4) - (8)].il), (yyvsp[(5) - (8)].il), (yyvsp[(7) - (8)].toobar_item)); +- } +- break; +- +- case 184: +-#line 1365 "rcparse.y" +- { (yyval.toobar_item)= NULL; } +- break; +- +- case 185: +-#line 1367 "rcparse.y" +- { +- rc_toolbar_item *c,*n; +- c = (yyvsp[(1) - (3)].toobar_item); +- n= (rc_toolbar_item *) +- res_alloc (sizeof (rc_toolbar_item)); +- if (c != NULL) +- while (c->next != NULL) +- c = c->next; +- n->prev = c; +- n->next = NULL; +- if (c != NULL) +- c->next = n; +- n->id = (yyvsp[(3) - (3)].id); +- if ((yyvsp[(1) - (3)].toobar_item) == NULL) +- (yyval.toobar_item) = n; +- else +- (yyval.toobar_item) = (yyvsp[(1) - (3)].toobar_item); +- } +- break; +- +- case 186: +-#line 1386 "rcparse.y" +- { +- rc_toolbar_item *c,*n; +- c = (yyvsp[(1) - (2)].toobar_item); +- n= (rc_toolbar_item *) +- res_alloc (sizeof (rc_toolbar_item)); +- if (c != NULL) +- while (c->next != NULL) +- c = c->next; +- n->prev = c; +- n->next = NULL; +- if (c != NULL) +- c->next = n; +- n->id.named = 0; +- n->id.u.id = 0; +- if ((yyvsp[(1) - (2)].toobar_item) == NULL) +- (yyval.toobar_item) = n; +- else +- (yyval.toobar_item) = (yyvsp[(1) - (2)].toobar_item); +- } +- break; +- +- case 187: +-#line 1411 "rcparse.y" +- { +- define_versioninfo ((yyvsp[(1) - (6)].id), language, (yyvsp[(3) - (6)].fixver), (yyvsp[(5) - (6)].verinfo)); +- if (yychar != YYEMPTY) +- YYERROR; +- rcparse_discard_strings (); +- } +- break; +- +- case 188: +-#line 1421 "rcparse.y" +- { +- (yyval.fixver) = ((rc_fixed_versioninfo *) +- res_alloc (sizeof (rc_fixed_versioninfo))); +- memset ((yyval.fixver), 0, sizeof (rc_fixed_versioninfo)); +- } +- break; +- +- case 189: +-#line 1428 "rcparse.y" +- { +- (yyvsp[(1) - (6)].fixver)->file_version_ms = ((yyvsp[(3) - (6)].il) << 16) | (yyvsp[(4) - (6)].il); +- (yyvsp[(1) - (6)].fixver)->file_version_ls = ((yyvsp[(5) - (6)].il) << 16) | (yyvsp[(6) - (6)].il); +- (yyval.fixver) = (yyvsp[(1) - (6)].fixver); +- } +- break; +- +- case 190: +-#line 1435 "rcparse.y" +- { +- (yyvsp[(1) - (6)].fixver)->product_version_ms = ((yyvsp[(3) - (6)].il) << 16) | (yyvsp[(4) - (6)].il); +- (yyvsp[(1) - (6)].fixver)->product_version_ls = ((yyvsp[(5) - (6)].il) << 16) | (yyvsp[(6) - (6)].il); +- (yyval.fixver) = (yyvsp[(1) - (6)].fixver); +- } +- break; +- +- case 191: +-#line 1441 "rcparse.y" +- { +- (yyvsp[(1) - (3)].fixver)->file_flags_mask = (yyvsp[(3) - (3)].il); +- (yyval.fixver) = (yyvsp[(1) - (3)].fixver); +- } +- break; +- +- case 192: +-#line 1446 "rcparse.y" +- { +- (yyvsp[(1) - (3)].fixver)->file_flags = (yyvsp[(3) - (3)].il); +- (yyval.fixver) = (yyvsp[(1) - (3)].fixver); +- } +- break; +- +- case 193: +-#line 1451 "rcparse.y" +- { +- (yyvsp[(1) - (3)].fixver)->file_os = (yyvsp[(3) - (3)].il); +- (yyval.fixver) = (yyvsp[(1) - (3)].fixver); +- } +- break; +- +- case 194: +-#line 1456 "rcparse.y" +- { +- (yyvsp[(1) - (3)].fixver)->file_type = (yyvsp[(3) - (3)].il); +- (yyval.fixver) = (yyvsp[(1) - (3)].fixver); +- } +- break; +- +- case 195: +-#line 1461 "rcparse.y" +- { +- (yyvsp[(1) - (3)].fixver)->file_subtype = (yyvsp[(3) - (3)].il); +- (yyval.fixver) = (yyvsp[(1) - (3)].fixver); +- } +- break; +- +- case 196: +-#line 1475 "rcparse.y" +- { +- (yyval.verinfo) = NULL; +- } +- break; +- +- case 197: +-#line 1479 "rcparse.y" +- { +- (yyval.verinfo) = append_ver_stringfileinfo ((yyvsp[(1) - (5)].verinfo), (yyvsp[(4) - (5)].verstringtable)); +- } +- break; +- +- case 198: +-#line 1483 "rcparse.y" +- { +- (yyval.verinfo) = append_ver_varfileinfo ((yyvsp[(1) - (7)].verinfo), (yyvsp[(5) - (7)].uni), (yyvsp[(6) - (7)].vervar)); +- } +- break; +- +- case 199: +-#line 1490 "rcparse.y" +- { +- (yyval.verstringtable) = NULL; +- } +- break; +- +- case 200: +-#line 1494 "rcparse.y" +- { +- (yyval.verstringtable) = append_ver_stringtable ((yyvsp[(1) - (5)].verstringtable), (yyvsp[(2) - (5)].s), (yyvsp[(4) - (5)].verstring)); +- } +- break; +- +- case 201: +-#line 1501 "rcparse.y" +- { +- (yyval.verstring) = NULL; +- } +- break; +- +- case 202: +-#line 1505 "rcparse.y" +- { +- (yyval.verstring) = append_verval ((yyvsp[(1) - (5)].verstring), (yyvsp[(3) - (5)].uni), (yyvsp[(5) - (5)].uni)); +- } +- break; +- +- case 203: +-#line 1512 "rcparse.y" +- { +- (yyval.vervar) = NULL; +- } +- break; +- +- case 204: +-#line 1516 "rcparse.y" +- { +- (yyval.vervar) = append_vertrans ((yyvsp[(1) - (3)].vervar), (yyvsp[(2) - (3)].il), (yyvsp[(3) - (3)].il)); +- } +- break; +- +- case 205: +-#line 1525 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = (yyvsp[(1) - (1)].il); +- } +- break; +- +- case 206: +-#line 1530 "rcparse.y" +- { +- res_unistring_to_id (&(yyval.id), (yyvsp[(1) - (1)].uni)); +- } +- break; +- +- case 207: +-#line 1539 "rcparse.y" +- { +- (yyval.uni) = (yyvsp[(1) - (1)].uni); +- } +- break; +- +- case 208: +-#line 1543 "rcparse.y" +- { +- unichar *h = NULL; +- unicode_from_ascii ((rc_uint_type *) NULL, &h, (yyvsp[(1) - (1)].s)); +- (yyval.uni) = h; +- } +- break; +- +- case 209: +-#line 1553 "rcparse.y" +- { +- (yyval.id).named = 0; +- (yyval.id).u.id = (yyvsp[(1) - (2)].il); +- } +- break; +- +- case 210: +-#line 1558 "rcparse.y" +- { +- res_unistring_to_id (&(yyval.id), (yyvsp[(1) - (1)].uni)); +- } +- break; +- +- case 211: +-#line 1562 "rcparse.y" +- { +- res_unistring_to_id (&(yyval.id), (yyvsp[(1) - (2)].uni)); +- } +- break; +- +- case 212: +-#line 1572 "rcparse.y" +- { +- memset (&(yyval.res_info), 0, sizeof (rc_res_res_info)); +- (yyval.res_info).language = language; +- /* FIXME: Is this the right default? */ +- (yyval.res_info).memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; +- } +- break; +- +- case 213: +-#line 1579 "rcparse.y" +- { +- (yyval.res_info) = (yyvsp[(1) - (2)].res_info); +- (yyval.res_info).memflags |= (yyvsp[(2) - (2)].memflags).on; +- (yyval.res_info).memflags &=~ (yyvsp[(2) - (2)].memflags).off; +- } +- break; +- +- case 214: +-#line 1585 "rcparse.y" +- { +- (yyval.res_info) = (yyvsp[(1) - (3)].res_info); +- (yyval.res_info).characteristics = (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 215: +-#line 1590 "rcparse.y" +- { +- (yyval.res_info) = (yyvsp[(1) - (4)].res_info); +- (yyval.res_info).language = (yyvsp[(3) - (4)].il) | ((yyvsp[(4) - (4)].il) << SUBLANG_SHIFT); +- } +- break; +- +- case 216: +-#line 1595 "rcparse.y" +- { +- (yyval.res_info) = (yyvsp[(1) - (3)].res_info); +- (yyval.res_info).version = (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 217: +-#line 1605 "rcparse.y" +- { +- memset (&(yyval.res_info), 0, sizeof (rc_res_res_info)); +- (yyval.res_info).language = language; +- (yyval.res_info).memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE; +- } +- break; +- +- case 218: +-#line 1611 "rcparse.y" +- { +- (yyval.res_info) = (yyvsp[(1) - (2)].res_info); +- (yyval.res_info).memflags |= (yyvsp[(2) - (2)].memflags).on; +- (yyval.res_info).memflags &=~ (yyvsp[(2) - (2)].memflags).off; +- } +- break; +- +- case 219: +-#line 1622 "rcparse.y" +- { +- memset (&(yyval.res_info), 0, sizeof (rc_res_res_info)); +- (yyval.res_info).language = language; +- (yyval.res_info).memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; +- } +- break; +- +- case 220: +-#line 1628 "rcparse.y" +- { +- (yyval.res_info) = (yyvsp[(1) - (2)].res_info); +- (yyval.res_info).memflags |= (yyvsp[(2) - (2)].memflags).on; +- (yyval.res_info).memflags &=~ (yyvsp[(2) - (2)].memflags).off; +- } +- break; +- +- case 221: +-#line 1640 "rcparse.y" +- { +- (yyval.memflags).on = MEMFLAG_MOVEABLE; +- (yyval.memflags).off = 0; +- } +- break; +- +- case 222: +-#line 1645 "rcparse.y" +- { +- (yyval.memflags).on = 0; +- (yyval.memflags).off = MEMFLAG_MOVEABLE; +- } +- break; +- +- case 223: +-#line 1650 "rcparse.y" +- { +- (yyval.memflags).on = MEMFLAG_PURE; +- (yyval.memflags).off = 0; +- } +- break; +- +- case 224: +-#line 1655 "rcparse.y" +- { +- (yyval.memflags).on = 0; +- (yyval.memflags).off = MEMFLAG_PURE; +- } +- break; +- +- case 225: +-#line 1660 "rcparse.y" +- { +- (yyval.memflags).on = MEMFLAG_PRELOAD; +- (yyval.memflags).off = 0; +- } +- break; +- +- case 226: +-#line 1665 "rcparse.y" +- { +- (yyval.memflags).on = 0; +- (yyval.memflags).off = MEMFLAG_PRELOAD; +- } +- break; +- +- case 227: +-#line 1670 "rcparse.y" +- { +- (yyval.memflags).on = MEMFLAG_DISCARDABLE; +- (yyval.memflags).off = 0; +- } +- break; +- +- case 228: +-#line 1680 "rcparse.y" +- { +- (yyval.s) = (yyvsp[(1) - (1)].s); +- } +- break; +- +- case 229: +-#line 1684 "rcparse.y" +- { +- (yyval.s) = (yyvsp[(1) - (1)].s); +- } +- break; +- +- case 230: +-#line 1692 "rcparse.y" +- { +- (yyval.uni) = (yyvsp[(1) - (1)].uni); +- } +- break; +- +- case 231: +-#line 1697 "rcparse.y" +- { +- rc_uint_type l1 = unichar_len ((yyvsp[(1) - (2)].uni)); +- rc_uint_type l2 = unichar_len ((yyvsp[(2) - (2)].uni)); +- unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); +- if (l1 != 0) +- memcpy (h, (yyvsp[(1) - (2)].uni), l1 * sizeof (unichar)); +- if (l2 != 0) +- memcpy (h + l1, (yyvsp[(2) - (2)].uni), l2 * sizeof (unichar)); +- h[l1 + l2] = 0; +- (yyval.uni) = h; +- } +- break; +- +- case 232: +-#line 1712 "rcparse.y" +- { +- (yyval.uni) = unichar_dup ((yyvsp[(1) - (1)].uni)); +- } +- break; +- +- case 233: +-#line 1716 "rcparse.y" +- { +- unichar *h = NULL; +- unicode_from_ascii ((rc_uint_type *) NULL, &h, (yyvsp[(1) - (1)].s)); +- (yyval.uni) = h; +- } +- break; +- +- case 234: +-#line 1725 "rcparse.y" +- { +- (yyval.suni) = (yyvsp[(1) - (1)].suni); +- } +- break; +- +- case 235: +-#line 1729 "rcparse.y" +- { +- unichar *h = NULL; +- rc_uint_type l = 0; +- unicode_from_ascii_len (&l, &h, (yyvsp[(1) - (1)].ss).s, (yyvsp[(1) - (1)].ss).length); +- (yyval.suni).s = h; +- (yyval.suni).length = l; +- } +- break; +- +- case 236: +-#line 1741 "rcparse.y" +- { +- (yyval.suni) = (yyvsp[(1) - (1)].suni); +- } +- break; +- +- case 237: +-#line 1746 "rcparse.y" +- { +- rc_uint_type l1 = (yyvsp[(1) - (2)].suni).length; +- rc_uint_type l2 = (yyvsp[(2) - (2)].suni).length; +- unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar)); +- if (l1 != 0) +- memcpy (h, (yyvsp[(1) - (2)].suni).s, l1 * sizeof (unichar)); +- if (l2 != 0) +- memcpy (h + l1, (yyvsp[(2) - (2)].suni).s, l2 * sizeof (unichar)); +- h[l1 + l2] = 0; +- (yyval.suni).length = l1 + l2; +- (yyval.suni).s = h; +- } +- break; +- +- case 238: +-#line 1762 "rcparse.y" +- { +- (yyval.ss) = (yyvsp[(1) - (1)].ss); +- } +- break; +- +- case 239: +-#line 1766 "rcparse.y" +- { +- rc_uint_type l = (yyvsp[(1) - (2)].ss).length + (yyvsp[(2) - (2)].ss).length; +- char *h = (char *) res_alloc (l); +- memcpy (h, (yyvsp[(1) - (2)].ss).s, (yyvsp[(1) - (2)].ss).length); +- memcpy (h + (yyvsp[(1) - (2)].ss).length, (yyvsp[(2) - (2)].ss).s, (yyvsp[(2) - (2)].ss).length); +- (yyval.ss).s = h; +- (yyval.ss).length = l; +- } +- break; +- +- case 240: +-#line 1778 "rcparse.y" +- { +- (yyval.suni) = (yyvsp[(1) - (1)].suni); +- } +- break; +- +- case 241: +-#line 1782 "rcparse.y" +- { +- rc_uint_type l = (yyvsp[(1) - (2)].suni).length + (yyvsp[(2) - (2)].suni).length; +- unichar *h = (unichar *) res_alloc (l * sizeof (unichar)); +- memcpy (h, (yyvsp[(1) - (2)].suni).s, (yyvsp[(1) - (2)].suni).length * sizeof (unichar)); +- memcpy (h + (yyvsp[(1) - (2)].suni).length, (yyvsp[(2) - (2)].suni).s, (yyvsp[(2) - (2)].suni).length * sizeof (unichar)); +- (yyval.suni).s = h; +- (yyval.suni).length = l; +- } +- break; +- +- case 242: +-#line 1804 "rcparse.y" +- { +- style |= (yyvsp[(1) - (1)].il); +- } +- break; +- +- case 243: +-#line 1808 "rcparse.y" +- { +- style &=~ (yyvsp[(2) - (2)].il); +- } +- break; +- +- case 244: +-#line 1812 "rcparse.y" +- { +- style |= (yyvsp[(3) - (3)].il); +- } +- break; +- +- case 245: +-#line 1816 "rcparse.y" +- { +- style &=~ (yyvsp[(4) - (4)].il); +- } +- break; +- +- case 246: +-#line 1823 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(1) - (1)].i).val; +- } +- break; +- +- case 247: +-#line 1827 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(2) - (3)].il); +- } +- break; +- +- case 248: +-#line 1836 "rcparse.y" +- { +- (yyval.il) = 0; +- } +- break; +- +- case 249: +-#line 1840 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(1) - (1)].il); +- } +- break; +- +- case 250: +-#line 1849 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(2) - (2)].il); +- } +- break; +- +- case 251: +-#line 1858 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(1) - (1)].i).val; +- } +- break; +- +- case 252: +-#line 1867 "rcparse.y" +- { +- (yyval.i) = (yyvsp[(1) - (1)].i); +- } +- break; +- +- case 253: +-#line 1871 "rcparse.y" +- { +- (yyval.i) = (yyvsp[(2) - (3)].i); +- } +- break; +- +- case 254: +-#line 1875 "rcparse.y" +- { +- (yyval.i).val = ~ (yyvsp[(2) - (2)].i).val; +- (yyval.i).dword = (yyvsp[(2) - (2)].i).dword; +- } +- break; +- +- case 255: +-#line 1880 "rcparse.y" +- { +- (yyval.i).val = - (yyvsp[(2) - (2)].i).val; +- (yyval.i).dword = (yyvsp[(2) - (2)].i).dword; +- } +- break; +- +- case 256: +-#line 1885 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val * (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 257: +-#line 1890 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val / (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 258: +-#line 1895 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val % (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 259: +-#line 1900 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val + (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 260: +-#line 1905 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val - (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 261: +-#line 1910 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val & (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 262: +-#line 1915 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val ^ (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 263: +-#line 1920 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val | (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 264: +-#line 1931 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(2) - (2)].il); +- } +- break; +- +- case 265: +-#line 1940 "rcparse.y" +- { +- (yyval.il) = (yyvsp[(1) - (1)].i).val; +- } +- break; +- +- case 266: +-#line 1951 "rcparse.y" +- { +- (yyval.i) = (yyvsp[(1) - (1)].i); +- } +- break; +- +- case 267: +-#line 1955 "rcparse.y" +- { +- (yyval.i) = (yyvsp[(2) - (3)].i); +- } +- break; +- +- case 268: +-#line 1959 "rcparse.y" +- { +- (yyval.i).val = ~ (yyvsp[(2) - (2)].i).val; +- (yyval.i).dword = (yyvsp[(2) - (2)].i).dword; +- } +- break; +- +- case 269: +-#line 1964 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val * (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 270: +-#line 1969 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val / (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 271: +-#line 1974 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val % (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 272: +-#line 1979 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val + (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 273: +-#line 1984 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val - (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 274: +-#line 1989 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val & (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 275: +-#line 1994 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val ^ (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- case 276: +-#line 1999 "rcparse.y" +- { +- (yyval.i).val = (yyvsp[(1) - (3)].i).val | (yyvsp[(3) - (3)].i).val; +- (yyval.i).dword = (yyvsp[(1) - (3)].i).dword || (yyvsp[(3) - (3)].i).dword; +- } +- break; +- +- +-/* Line 1267 of yacc.c. */ +-#line 4440 "rcparse.c" +- default: break; +- } +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- +- /* Now `shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ +-yyerrlab: +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +- { +- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); +- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) +- { +- YYSIZE_T yyalloc = 2 * yysize; +- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) +- yyalloc = YYSTACK_ALLOC_MAXIMUM; +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yyalloc); +- if (yymsg) +- yymsg_alloc = yyalloc; +- else +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- } +- } +- +- if (0 < yysize && yysize <= yymsg_alloc) +- { +- (void) yysyntax_error (yymsg, yystate, yychar); +- yyerror (yymsg); +- } +- else +- { +- yyerror (YY_("syntax error")); +- if (yysize != 0) +- goto yyexhaustedlab; +- } +- } +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse look-ahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse look-ahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule which action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (yyn != YYPACT_NINF) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- *++yyvsp = yylval; +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#ifndef yyoverflow +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEOF && yychar != YYEMPTY) +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- /* Do not reclaim the symbols of the rule which action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); +-} +- +- +-#line 2005 "rcparse.y" +- +- +-/* Set the language from the command line. */ +- +-void +-rcparse_set_language (int lang) +-{ +- language = lang; +-} +- +diff -Nur binutils-2.24.orig/binutils/rcparse.h binutils-2.24/binutils/rcparse.h +--- binutils-2.24.orig/binutils/rcparse.h 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/rcparse.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,298 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton interface for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- BEG = 258, +- END = 259, +- ACCELERATORS = 260, +- VIRTKEY = 261, +- ASCII = 262, +- NOINVERT = 263, +- SHIFT = 264, +- CONTROL = 265, +- ALT = 266, +- BITMAP = 267, +- CURSOR = 268, +- DIALOG = 269, +- DIALOGEX = 270, +- EXSTYLE = 271, +- CAPTION = 272, +- CLASS = 273, +- STYLE = 274, +- AUTO3STATE = 275, +- AUTOCHECKBOX = 276, +- AUTORADIOBUTTON = 277, +- CHECKBOX = 278, +- COMBOBOX = 279, +- CTEXT = 280, +- DEFPUSHBUTTON = 281, +- EDITTEXT = 282, +- GROUPBOX = 283, +- LISTBOX = 284, +- LTEXT = 285, +- PUSHBOX = 286, +- PUSHBUTTON = 287, +- RADIOBUTTON = 288, +- RTEXT = 289, +- SCROLLBAR = 290, +- STATE3 = 291, +- USERBUTTON = 292, +- BEDIT = 293, +- HEDIT = 294, +- IEDIT = 295, +- FONT = 296, +- ICON = 297, +- ANICURSOR = 298, +- ANIICON = 299, +- DLGINCLUDE = 300, +- DLGINIT = 301, +- FONTDIR = 302, +- HTML = 303, +- MANIFEST = 304, +- PLUGPLAY = 305, +- VXD = 306, +- TOOLBAR = 307, +- BUTTON = 308, +- LANGUAGE = 309, +- CHARACTERISTICS = 310, +- VERSIONK = 311, +- MENU = 312, +- MENUEX = 313, +- MENUITEM = 314, +- SEPARATOR = 315, +- POPUP = 316, +- CHECKED = 317, +- GRAYED = 318, +- HELP = 319, +- INACTIVE = 320, +- MENUBARBREAK = 321, +- MENUBREAK = 322, +- MESSAGETABLE = 323, +- RCDATA = 324, +- STRINGTABLE = 325, +- VERSIONINFO = 326, +- FILEVERSION = 327, +- PRODUCTVERSION = 328, +- FILEFLAGSMASK = 329, +- FILEFLAGS = 330, +- FILEOS = 331, +- FILETYPE = 332, +- FILESUBTYPE = 333, +- BLOCKSTRINGFILEINFO = 334, +- BLOCKVARFILEINFO = 335, +- VALUE = 336, +- BLOCK = 337, +- MOVEABLE = 338, +- FIXED = 339, +- PURE = 340, +- IMPURE = 341, +- PRELOAD = 342, +- LOADONCALL = 343, +- DISCARDABLE = 344, +- NOT = 345, +- QUOTEDUNISTRING = 346, +- QUOTEDSTRING = 347, +- STRING = 348, +- NUMBER = 349, +- SIZEDUNISTRING = 350, +- SIZEDSTRING = 351, +- IGNORED_TOKEN = 352, +- NEG = 353 +- }; +-#endif +-/* Tokens. */ +-#define BEG 258 +-#define END 259 +-#define ACCELERATORS 260 +-#define VIRTKEY 261 +-#define ASCII 262 +-#define NOINVERT 263 +-#define SHIFT 264 +-#define CONTROL 265 +-#define ALT 266 +-#define BITMAP 267 +-#define CURSOR 268 +-#define DIALOG 269 +-#define DIALOGEX 270 +-#define EXSTYLE 271 +-#define CAPTION 272 +-#define CLASS 273 +-#define STYLE 274 +-#define AUTO3STATE 275 +-#define AUTOCHECKBOX 276 +-#define AUTORADIOBUTTON 277 +-#define CHECKBOX 278 +-#define COMBOBOX 279 +-#define CTEXT 280 +-#define DEFPUSHBUTTON 281 +-#define EDITTEXT 282 +-#define GROUPBOX 283 +-#define LISTBOX 284 +-#define LTEXT 285 +-#define PUSHBOX 286 +-#define PUSHBUTTON 287 +-#define RADIOBUTTON 288 +-#define RTEXT 289 +-#define SCROLLBAR 290 +-#define STATE3 291 +-#define USERBUTTON 292 +-#define BEDIT 293 +-#define HEDIT 294 +-#define IEDIT 295 +-#define FONT 296 +-#define ICON 297 +-#define ANICURSOR 298 +-#define ANIICON 299 +-#define DLGINCLUDE 300 +-#define DLGINIT 301 +-#define FONTDIR 302 +-#define HTML 303 +-#define MANIFEST 304 +-#define PLUGPLAY 305 +-#define VXD 306 +-#define TOOLBAR 307 +-#define BUTTON 308 +-#define LANGUAGE 309 +-#define CHARACTERISTICS 310 +-#define VERSIONK 311 +-#define MENU 312 +-#define MENUEX 313 +-#define MENUITEM 314 +-#define SEPARATOR 315 +-#define POPUP 316 +-#define CHECKED 317 +-#define GRAYED 318 +-#define HELP 319 +-#define INACTIVE 320 +-#define MENUBARBREAK 321 +-#define MENUBREAK 322 +-#define MESSAGETABLE 323 +-#define RCDATA 324 +-#define STRINGTABLE 325 +-#define VERSIONINFO 326 +-#define FILEVERSION 327 +-#define PRODUCTVERSION 328 +-#define FILEFLAGSMASK 329 +-#define FILEFLAGS 330 +-#define FILEOS 331 +-#define FILETYPE 332 +-#define FILESUBTYPE 333 +-#define BLOCKSTRINGFILEINFO 334 +-#define BLOCKVARFILEINFO 335 +-#define VALUE 336 +-#define BLOCK 337 +-#define MOVEABLE 338 +-#define FIXED 339 +-#define PURE 340 +-#define IMPURE 341 +-#define PRELOAD 342 +-#define LOADONCALL 343 +-#define DISCARDABLE 344 +-#define NOT 345 +-#define QUOTEDUNISTRING 346 +-#define QUOTEDSTRING 347 +-#define STRING 348 +-#define NUMBER 349 +-#define SIZEDUNISTRING 350 +-#define SIZEDSTRING 351 +-#define IGNORED_TOKEN 352 +-#define NEG 353 +- +- +- +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 69 "rcparse.y" +-{ +- rc_accelerator acc; +- rc_accelerator *pacc; +- rc_dialog_control *dialog_control; +- rc_menuitem *menuitem; +- struct +- { +- rc_rcdata_item *first; +- rc_rcdata_item *last; +- } rcdata; +- rc_rcdata_item *rcdata_item; +- rc_fixed_versioninfo *fixver; +- rc_ver_info *verinfo; +- rc_ver_stringtable *verstringtable; +- rc_ver_stringinfo *verstring; +- rc_ver_varinfo *vervar; +- rc_toolbar_item *toobar_item; +- rc_res_id id; +- rc_res_res_info res_info; +- struct +- { +- rc_uint_type on; +- rc_uint_type off; +- } memflags; +- struct +- { +- rc_uint_type val; +- /* Nonzero if this number was explicitly specified as long. */ +- int dword; +- } i; +- rc_uint_type il; +- rc_uint_type is; +- const char *s; +- struct +- { +- rc_uint_type length; +- const char *s; +- } ss; +- unichar *uni; +- struct +- { +- rc_uint_type length; +- const unichar *s; +- } suni; +-} +-/* Line 1529 of yacc.c. */ +-#line 291 "rcparse.h" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +-extern YYSTYPE yylval; +- +diff -Nur binutils-2.24.orig/binutils/readelf.c binutils-2.24/binutils/readelf.c +--- binutils-2.24.orig/binutils/readelf.c 2013-11-18 09:40:15.000000000 +0100 ++++ binutils-2.24/binutils/readelf.c 2016-04-10 20:30:46.000000000 +0200 +@@ -131,6 +131,7 @@ + #include "elf/moxie.h" + #include "elf/mt.h" + #include "elf/msp430.h" ++#include "elf/nds32.h" + #include "elf/nios2.h" + #include "elf/or32.h" + #include "elf/pj.h" +@@ -626,6 +627,7 @@ + case EM_MSP430: + case EM_MSP430_OLD: + case EM_MT: ++ case EM_NDS32: + case EM_NIOS32: + case EM_PPC64: + case EM_PPC: +@@ -1144,6 +1146,10 @@ + rtype = elf_msp430_reloc_type (type); + break; + ++ case EM_NDS32: ++ rtype = elf_nds32_reloc_type (type); ++ break; ++ + case EM_PPC: + rtype = elf_ppc_reloc_type (type); + break; +@@ -2307,6 +2313,215 @@ + strcat (buf,_(", ")); + } + ++static void ++decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size) ++{ ++ unsigned abi; ++ unsigned arch; ++ unsigned config; ++ unsigned version; ++ int has_fpu = 0; ++ int r = 0; ++ ++ static const char *ABI_STRINGS[] = { ++ [E_NDS_ABI_V0 >> EF_NDS_ABI_SHIFT] = "ABI v0", /* use r5 as return register; only used in N1213HC */ ++ [E_NDS_ABI_V1 >> EF_NDS_ABI_SHIFT] = "ABI v1", /* use r0 as return register */ ++ [E_NDS_ABI_V2 >> EF_NDS_ABI_SHIFT] = "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */ ++ [E_NDS_ABI_V2FP >> EF_NDS_ABI_SHIFT] = "ABI v2fp", /* for FPU */ ++ [E_NDS_ABI_AABI >> EF_NDS_ABI_SHIFT] = "AABI", ++ [E_NDS_ABI_V2FP_PLUS >> EF_NDS_ABI_SHIFT] = "ABI2 FP+" ++ }; ++ static const char *VER_STRINGS[] = { ++ [E_NDS32_ELF_VER_1_2 >> EF_NDS32_ELF_VERSION_SHIFT] = "Andes ELF V1.3 or older", ++ [E_NDS32_ELF_VER_1_3 >> EF_NDS32_ELF_VERSION_SHIFT] = "Andes ELF V1.3.1", ++ [E_NDS32_ELF_VER_1_4 >> EF_NDS32_ELF_VERSION_SHIFT] = "Andes ELF V1.4", ++ }; ++ static const char *ARCH_STRINGS[] = { ++ [E_NDS_ARCH_STAR_V1_0 >> EF_NDS_ARCH_SHIFT] = "Andes Star v1.0", ++ [E_NDS_ARCH_STAR_V2_0 >> EF_NDS_ARCH_SHIFT] = "Andes Star v2.0", ++ [E_NDS_ARCH_STAR_V3_0 >> EF_NDS_ARCH_SHIFT] = "Andes Star v3.0", ++ [E_NDS_ARCH_STAR_V3_M >> EF_NDS_ARCH_SHIFT] = "Andes Star v3.0m" ++ }; ++ ++ abi = EF_NDS_ABI & e_flags; ++ arch = EF_NDS_ARCH & e_flags; ++ config = EF_NDS_INST & e_flags; ++ version = EF_NDS32_ELF_VERSION & e_flags; ++ ++ memset (buf, 0, size); ++ ++ switch (abi) ++ { ++ case E_NDS_ABI_V0: ++ case E_NDS_ABI_V1: ++ case E_NDS_ABI_V2: ++ case E_NDS_ABI_V2FP: ++ case E_NDS_ABI_AABI: ++ case E_NDS_ABI_V2FP_PLUS: ++ /* In case there are holes in the array. */ ++ r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]); ++ break; ++ ++ default: ++ r += snprintf (buf + r, size - r, ", "); ++ break; ++ } ++ ++ switch (version) ++ { ++ case E_NDS32_ELF_VER_1_2: ++ case E_NDS32_ELF_VER_1_3: ++ case E_NDS32_ELF_VER_1_4: ++ r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]); ++ break; ++ ++ default: ++ r += snprintf (buf + r, size - r, ", "); ++ break; ++ } ++ ++ if (E_NDS_ABI_V0 == abi) ++ { ++ /* OLD ABI; only used in N1213HC, has performance extension 1 */ ++ r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1"); ++ if (arch == E_NDS_ARCH_STAR_V1_0) ++ r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */ ++ return; ++ } ++ ++ switch (arch) ++ { ++ case E_NDS_ARCH_STAR_V1_0: ++ case E_NDS_ARCH_STAR_V2_0: ++ case E_NDS_ARCH_STAR_V3_0: ++ case E_NDS_ARCH_STAR_V3_M: ++ r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]); ++ break; ++ ++ default: ++ r += snprintf (buf + r, size - r, ", "); ++ /* ARCH version determines how the e_flags are interpreted. ++ If it is unknown, we cannot proceed. */ ++ return; ++ } ++ ++ /* newer ABI; Now handle architecture specific flags. */ ++ if (arch == E_NDS_ARCH_STAR_V1_0) ++ { ++ if (config & E_NDS32_HAS_MFUSR_PC_INST) ++ r += snprintf (buf + r, size -r, ", MFUSR_PC"); ++ ++ if (!(config & E_NDS32_HAS_NO_MAC_INST)) ++ r += snprintf (buf + r, size -r, ", MAC"); ++ ++ if (config & E_NDS32_HAS_DIV_INST) ++ r += snprintf (buf + r, size -r, ", DIV"); ++ ++ if (config & E_NDS32_HAS_16BIT_INST) ++ r += snprintf (buf + r, size -r, ", 16b"); ++ } ++ else ++ { ++ if (config & E_NDS32_HAS_MFUSR_PC_INST) ++ { ++ if (version <= E_NDS32_ELF_VER_1_3) ++ r += snprintf (buf + r, size -r, ", [B8]"); ++ else ++ r += snprintf (buf + r, size -r, ", EX9"); ++ } ++ ++ if (config & E_NDS32_HAS_MAC_DX_INST) ++ r += snprintf (buf + r, size -r, ", MAC_DX"); ++ ++ if (config & E_NDS32_HAS_DIV_DX_INST) ++ r += snprintf (buf + r, size -r, ", DIV_DX"); ++ ++ if (config & E_NDS32_HAS_16BIT_INST) ++ { ++ if (version <= E_NDS32_ELF_VER_1_3) ++ r += snprintf (buf + r, size -r, ", 16b"); ++ else ++ r += snprintf (buf + r, size -r, ", IFC"); ++ } ++ } ++ ++ if (config & E_NDS32_HAS_EXT_INST) ++ r += snprintf (buf + r, size -r, ", PERF1"); ++ ++ if (config & E_NDS32_HAS_EXT2_INST) ++ r += snprintf (buf + r, size -r, ", PERF2"); ++ ++ if (config & E_NDS32_HAS_FPU_INST) ++ { ++ has_fpu = 1; ++ r += snprintf (buf + r, size -r, ", FPU_SP"); ++ } ++ ++ if (config & E_NDS32_HAS_FPU_DP_INST) ++ { ++ has_fpu = 1; ++ r += snprintf (buf + r, size -r, ", FPU_DP"); ++ } ++ ++ if (config & E_NDS32_HAS_FPU_MAC_INST) ++ { ++ has_fpu = 1; ++ r += snprintf (buf + r, size -r, ", FPU_MAC"); ++ } ++ ++ if (config & E_NDS32_HAS_DSP_INST) ++ { ++ r += snprintf (buf + r, size -r, ", DSP"); ++ } ++ ++ if (config & E_NDS32_HAS_ZOL) ++ { ++ r += snprintf (buf + r, size -r, ", ZOL"); ++ } ++ ++ if (has_fpu) ++ { ++ switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT) ++ { ++ case E_NDS32_FPU_REG_8SP_4DP: ++ r += snprintf (buf + r, size -r, ", FPU_REG:8/4"); ++ break; ++ case E_NDS32_FPU_REG_16SP_8DP: ++ r += snprintf (buf + r, size -r, ", FPU_REG:16/8"); ++ break; ++ case E_NDS32_FPU_REG_32SP_16DP: ++ r += snprintf (buf + r, size -r, ", FPU_REG:32/16"); ++ break; ++ case E_NDS32_FPU_REG_32SP_32DP: ++ r += snprintf (buf + r, size -r, ", FPU_REG:32/32"); ++ break; ++ } ++ } ++ ++ if (config & E_NDS32_HAS_AUDIO_INST) ++ r += snprintf (buf + r, size -r, ", AUDIO"); ++ ++ if (config & E_NDS32_HAS_STRING_INST) ++ r += snprintf (buf + r, size -r, ", STR"); ++ ++ if (config & E_NDS32_HAS_REDUCED_REGS) ++ r += snprintf (buf + r, size -r, ", 16REG"); ++ ++ if (config & E_NDS32_HAS_VIDEO_INST) ++ { ++ if (version <= E_NDS32_ELF_VER_1_3) ++ r += snprintf (buf + r, size -r, ", VIDEO"); ++ else ++ r += snprintf (buf + r, size -r, ", SATURATION"); ++ } ++ ++ if (config & E_NDS32_HAS_ENCRIPT_INST) ++ r += snprintf (buf + r, size -r, ", ENCRP"); ++ ++ if (config & E_NDS32_HAS_L2C_INST) ++ r += snprintf (buf + r, size -r, ", L2C"); ++} ++ + static char * + get_machine_flags (unsigned e_flags, unsigned e_machine) + { +@@ -2649,6 +2864,10 @@ + } + break; + ++ case EM_NDS32: ++ decode_NDS32_machine_flags (e_flags, buf, sizeof buf); ++ break; ++ + case EM_SH: + switch ((e_flags & EF_SH_MACH_MASK)) + { +@@ -4171,7 +4390,7 @@ + else + { + char fmt [32]; +- int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX); ++ int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1); + + if (ret >= (int) sizeof (fmt) || ret < 0) + error (_("Internal error: failed to create format string to display program interpreter\n")); +@@ -10257,6 +10476,8 @@ + return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */ + case EM_MT: + return reloc_type == 2; /* R_MT_32. */ ++ case EM_NDS32: ++ return reloc_type == 20; /* R_NDS32_RELA. */ + case EM_ALTERA_NIOS2: + return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */ + case EM_NIOS32: +@@ -10510,6 +10731,8 @@ + return reloc_type == 2; /* R_MSP430_ABS16. */ + case EM_MSP430_OLD: + return reloc_type == 5; /* R_MSP430_16_BYTE. */ ++ case EM_NDS32: ++ return reloc_type == 19; /* R_NDS32_RELA. */ + case EM_ALTERA_NIOS2: + return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */ + case EM_NIOS32: +@@ -10573,6 +10796,12 @@ + return reloc_type == 0; + case EM_AARCH64: + return reloc_type == 0 || reloc_type == 256; ++ case EM_NDS32: ++ return (reloc_type == 0 /* R_XTENSA_NONE. */ ++ || reloc_type == 204 /* R_NDS32_DIFF8. */ ++ || reloc_type == 205 /* R_NDS32_DIFF16. */ ++ || reloc_type == 206 /* R_NDS32_DIFF32. */ ++ || reloc_type == 207 /* R_NDS32_ULEB128. */); + case EM_XTENSA_OLD: + case EM_XTENSA: + return (reloc_type == 0 /* R_XTENSA_NONE. */ +@@ -12954,6 +13183,39 @@ + } + + static int ++process_nds32_specific (FILE * file) ++{ ++ Elf_Internal_Shdr *sect = NULL; ++ ++ sect = find_section (".nds32_e_flags"); ++ if (sect != NULL) ++ { ++ unsigned int *flag; ++ printf ("\nNDS32 elf flags section:\n"); ++ flag = get_data (NULL, file, sect->sh_offset, 1, ++ sect->sh_size, _("NDS32 elf flags section")); ++ ++ switch ((*flag) & 0x3) ++ { ++ case 0: ++ printf ("(VEC_SIZE):\tNo entry.\n"); ++ break; ++ case 1: ++ printf ("(VEC_SIZE):\t4 bytes\n"); ++ break; ++ case 2: ++ printf ("(VEC_SIZE):\t16 bytes\n"); ++ break; ++ case 3: ++ printf ("(VEC_SIZE):\treserved\n"); ++ break; ++ } ++ } ++ ++ return TRUE; ++} ++ ++static int + process_gnu_liblist (FILE * file) + { + Elf_Internal_Shdr * section; +@@ -13779,6 +14041,9 @@ + case EM_MIPS_RS3_LE: + return process_mips_specific (file); + break; ++ case EM_NDS32: ++ return process_nds32_specific (file); ++ break; + case EM_PPC: + return process_power_specific (file); + break; +diff -Nur binutils-2.24.orig/binutils/size.c binutils-2.24/binutils/size.c +--- binutils-2.24.orig/binutils/size.c 2013-11-04 16:33:37.000000000 +0100 ++++ binutils-2.24/binutils/size.c 2016-04-10 20:30:46.000000000 +0200 +@@ -436,6 +436,7 @@ + static bfd_size_type bsssize; + static bfd_size_type datasize; + static bfd_size_type textsize; ++static bfd_size_type rodata_size; + + static void + berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec, +@@ -449,6 +450,10 @@ + return; + + size = bfd_get_section_size (sec); ++ ++ if ((flags & SEC_DATA) != 0 && (flags & SEC_READONLY) != 0 && (flags & SEC_CODE) == 0) ++ rodata_size = rodata_size + size; ++ + if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0) + textsize += size; + else if ((flags & SEC_HAS_CONTENTS) != 0) +@@ -466,13 +471,15 @@ + bsssize = 0; + datasize = 0; + textsize = 0; ++ rodata_size = 0; + + bfd_map_over_sections (abfd, berkeley_sum, NULL); + + bsssize += common_size; + if (files_seen++ == 0) +- puts ((radix == octal) ? " text\t data\t bss\t oct\t hex\tfilename" : +- " text\t data\t bss\t dec\t hex\tfilename"); ++ puts ((radix == octal) ? ++ " text (code + rodata)\t data\t bss\t oct\t hex\tfilename" : ++ " text (code + rodata)\t data\t bss\t dec\t hex\tfilename"); + + total = textsize + datasize + bsssize; + +@@ -484,6 +491,11 @@ + } + + rprint_number (7, textsize); ++ printf (" ("); ++ rprint_number (4, (textsize - rodata_size)); ++ printf (" + "); ++ rprint_number (6, rodata_size); ++ printf (")"); + putchar ('\t'); + rprint_number (7, datasize); + putchar ('\t'); +diff -Nur binutils-2.24.orig/binutils/sysinfo.c binutils-2.24/binutils/sysinfo.c +--- binutils-2.24.orig/binutils/sysinfo.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/sysinfo.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1962 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton implementation for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* C LALR(1) parser skeleton written by Richard Stallman, by +- simplifying the original so-called "semantic" parser. */ +- +-/* All symbols defined below should begin with yy or YY, to avoid +- infringing on user name space. This should be done even for local +- variables, as they might otherwise be expanded by user macros. +- There are some unavoidable exceptions within include files to +- define necessary library symbols; they are noted "INFRINGES ON +- USER NAME SPACE" below. */ +- +-/* Identify Bison output. */ +-#define YYBISON 1 +- +-/* Bison version. */ +-#define YYBISON_VERSION "2.3" +- +-/* Skeleton name. */ +-#define YYSKELETON_NAME "yacc.c" +- +-/* Pure parsers. */ +-#define YYPURE 0 +- +-/* Using locations. */ +-#define YYLSP_NEEDED 0 +- +- +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- COND = 258, +- REPEAT = 259, +- TYPE = 260, +- NAME = 261, +- NUMBER = 262, +- UNIT = 263 +- }; +-#endif +-/* Tokens. */ +-#define COND 258 +-#define REPEAT 259 +-#define TYPE 260 +-#define NAME 261 +-#define NUMBER 262 +-#define UNIT 263 +- +- +- +- +-/* Copy the first part of user declarations. */ +-#line 21 "sysinfo.y" +- +-#include +-#include +- +-static char writecode; +-static char *it; +-static int code; +-static char * repeat; +-static char *oldrepeat; +-static char *name; +-static int rdepth; +-static char *names[] = {" ","[n]","[n][m]"}; +-static char *pnames[]= {"","*","**"}; +- +-static int yyerror (char *s); +-extern int yylex (void); +- +- +-/* Enabling traces. */ +-#ifndef YYDEBUG +-# define YYDEBUG 0 +-#endif +- +-/* Enabling verbose error messages. */ +-#ifdef YYERROR_VERBOSE +-# undef YYERROR_VERBOSE +-# define YYERROR_VERBOSE 1 +-#else +-# define YYERROR_VERBOSE 0 +-#endif +- +-/* Enabling the token table. */ +-#ifndef YYTOKEN_TABLE +-# define YYTOKEN_TABLE 0 +-#endif +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 40 "sysinfo.y" +-{ +- int i; +- char *s; +-} +-/* Line 193 of yacc.c. */ +-#line 135 "sysinfo.c" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +- +- +-/* Copy the second part of user declarations. */ +- +- +-/* Line 216 of yacc.c. */ +-#line 148 "sysinfo.c" +- +-#ifdef short +-# undef short +-#endif +- +-#ifdef YYTYPE_UINT8 +-typedef YYTYPE_UINT8 yytype_uint8; +-#else +-typedef unsigned char yytype_uint8; +-#endif +- +-#ifdef YYTYPE_INT8 +-typedef YYTYPE_INT8 yytype_int8; +-#elif (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-typedef signed char yytype_int8; +-#else +-typedef short int yytype_int8; +-#endif +- +-#ifdef YYTYPE_UINT16 +-typedef YYTYPE_UINT16 yytype_uint16; +-#else +-typedef unsigned short int yytype_uint16; +-#endif +- +-#ifdef YYTYPE_INT16 +-typedef YYTYPE_INT16 yytype_int16; +-#else +-typedef short int yytype_int16; +-#endif +- +-#ifndef YYSIZE_T +-# ifdef __SIZE_TYPE__ +-# define YYSIZE_T __SIZE_TYPE__ +-# elif defined size_t +-# define YYSIZE_T size_t +-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYSIZE_T size_t +-# else +-# define YYSIZE_T unsigned int +-# endif +-#endif +- +-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) +- +-#ifndef YY_ +-# if defined YYENABLE_NLS && YYENABLE_NLS +-# if ENABLE_NLS +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YY_(msgid) dgettext ("bison-runtime", msgid) +-# endif +-# endif +-# ifndef YY_ +-# define YY_(msgid) msgid +-# endif +-#endif +- +-/* Suppress unused-variable warnings by "using" E. */ +-#if ! defined lint || defined __GNUC__ +-# define YYUSE(e) ((void) (e)) +-#else +-# define YYUSE(e) /* empty */ +-#endif +- +-/* Identity function, used to suppress warnings about constant conditions. */ +-#ifndef lint +-# define YYID(n) (n) +-#else +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static int +-YYID (int i) +-#else +-static int +-YYID (i) +- int i; +-#endif +-{ +- return i; +-} +-#endif +- +-#if ! defined yyoverflow || YYERROR_VERBOSE +- +-/* The parser invokes alloca or malloc; define the necessary symbols. */ +- +-# ifdef YYSTACK_USE_ALLOCA +-# if YYSTACK_USE_ALLOCA +-# ifdef __GNUC__ +-# define YYSTACK_ALLOC __builtin_alloca +-# elif defined __BUILTIN_VA_ARG_INCR +-# include /* INFRINGES ON USER NAME SPACE */ +-# elif defined _AIX +-# define YYSTACK_ALLOC __alloca +-# elif defined _MSC_VER +-# include /* INFRINGES ON USER NAME SPACE */ +-# define alloca _alloca +-# else +-# define YYSTACK_ALLOC alloca +-# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# endif +-# endif +-# endif +- +-# ifdef YYSTACK_ALLOC +- /* Pacify GCC's `empty if-body' warning. */ +-# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +-# ifndef YYSTACK_ALLOC_MAXIMUM +- /* The OS might guarantee only one guard page at the bottom of the stack, +- and a page size can be as small as 4096 bytes. So we cannot safely +- invoke alloca (N) if N exceeds 4096. Use a slightly smaller number +- to allow for a few compiler-allocated temporary stack slots. */ +-# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +-# endif +-# else +-# define YYSTACK_ALLOC YYMALLOC +-# define YYSTACK_FREE YYFREE +-# ifndef YYSTACK_ALLOC_MAXIMUM +-# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +-# endif +-# if (defined __cplusplus && ! defined _STDLIB_H \ +- && ! ((defined YYMALLOC || defined malloc) \ +- && (defined YYFREE || defined free))) +-# include /* INFRINGES ON USER NAME SPACE */ +-# ifndef _STDLIB_H +-# define _STDLIB_H 1 +-# endif +-# endif +-# ifndef YYMALLOC +-# define YYMALLOC malloc +-# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# ifndef YYFREE +-# define YYFREE free +-# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-void free (void *); /* INFRINGES ON USER NAME SPACE */ +-# endif +-# endif +-# endif +-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ +- +- +-#if (! defined yyoverflow \ +- && (! defined __cplusplus \ +- || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) +- +-/* A type that is properly aligned for any stack member. */ +-union yyalloc +-{ +- yytype_int16 yyss; +- YYSTYPE yyvs; +- }; +- +-/* The size of the maximum gap between one aligned stack and the next. */ +-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) +- +-/* The size of an array large to enough to hold all stacks, each with +- N elements. */ +-# define YYSTACK_BYTES(N) \ +- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ +- + YYSTACK_GAP_MAXIMUM) +- +-/* Copy COUNT objects from FROM to TO. The source and destination do +- not overlap. */ +-# ifndef YYCOPY +-# if defined __GNUC__ && 1 < __GNUC__ +-# define YYCOPY(To, From, Count) \ +- __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +-# else +-# define YYCOPY(To, From, Count) \ +- do \ +- { \ +- YYSIZE_T yyi; \ +- for (yyi = 0; yyi < (Count); yyi++) \ +- (To)[yyi] = (From)[yyi]; \ +- } \ +- while (YYID (0)) +-# endif +-# endif +- +-/* Relocate STACK from its old location to the new one. The +- local variables YYSIZE and YYSTACKSIZE give the old and new number of +- elements in the stack, and YYPTR gives the new location of the +- stack. Advance YYPTR to a properly aligned location for the next +- stack. */ +-# define YYSTACK_RELOCATE(Stack) \ +- do \ +- { \ +- YYSIZE_T yynewbytes; \ +- YYCOPY (&yyptr->Stack, Stack, yysize); \ +- Stack = &yyptr->Stack; \ +- yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ +- yyptr += yynewbytes / sizeof (*yyptr); \ +- } \ +- while (YYID (0)) +- +-#endif +- +-/* YYFINAL -- State number of the termination state. */ +-#define YYFINAL 3 +-/* YYLAST -- Last index in YYTABLE. */ +-#define YYLAST 38 +- +-/* YYNTOKENS -- Number of terminals. */ +-#define YYNTOKENS 11 +-/* YYNNTS -- Number of nonterminals. */ +-#define YYNNTS 19 +-/* YYNRULES -- Number of rules. */ +-#define YYNRULES 27 +-/* YYNRULES -- Number of states. */ +-#define YYNSTATES 55 +- +-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +-#define YYUNDEFTOK 2 +-#define YYMAXUTOK 263 +- +-#define YYTRANSLATE(YYX) \ +- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +- +-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +-static const yytype_uint8 yytranslate[] = +-{ +- 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +- 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, +- 7, 8, 9, 10 +-}; +- +-#if YYDEBUG +-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in +- YYRHS. */ +-static const yytype_uint8 yyprhs[] = +-{ +- 0, 0, 3, 4, 7, 10, 11, 12, 19, 22, +- 25, 28, 29, 30, 37, 38, 45, 46, 57, 59, +- 60, 64, 67, 71, 72, 73, 77, 78 +-}; +- +-/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +-static const yytype_int8 yyrhs[] = +-{ +- 12, 0, -1, -1, 13, 14, -1, 15, 14, -1, +- -1, -1, 5, 8, 9, 16, 17, 6, -1, 22, +- 17, -1, 20, 17, -1, 18, 17, -1, -1, -1, +- 5, 4, 8, 19, 17, 6, -1, -1, 5, 3, +- 8, 21, 17, 6, -1, -1, 5, 25, 5, 24, +- 26, 6, 27, 23, 28, 6, -1, 7, -1, -1, +- 5, 8, 6, -1, 9, 10, -1, 5, 8, 6, +- -1, -1, -1, 5, 29, 6, -1, -1, 29, 5, +- 8, 8, 6, -1 +-}; +- +-/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +-static const yytype_uint16 yyrline[] = +-{ +- 0, 54, 54, 54, 92, 93, 98, 97, 169, 170, +- 171, 172, 176, 175, 223, 222, 250, 249, 357, 358, +- 362, 367, 373, 374, 377, 378, 380, 382 +-}; +-#endif +- +-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. +- First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +-static const char *const yytname[] = +-{ +- "$end", "error", "$undefined", "COND", "REPEAT", "'('", "')'", "TYPE", +- "NAME", "NUMBER", "UNIT", "$accept", "top", "@1", "it_list", "it", "@2", +- "it_field_list", "repeat_it_field", "@3", "cond_it_field", "@4", +- "it_field", "@5", "attr_type", "attr_desc", "attr_size", "attr_id", +- "enums", "enum_list", 0 +-}; +-#endif +- +-# ifdef YYPRINT +-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to +- token YYLEX-NUM. */ +-static const yytype_uint16 yytoknum[] = +-{ +- 0, 256, 257, 258, 259, 40, 41, 260, 261, 262, +- 263 +-}; +-# endif +- +-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +-static const yytype_uint8 yyr1[] = +-{ +- 0, 11, 13, 12, 14, 14, 16, 15, 17, 17, +- 17, 17, 19, 18, 21, 20, 23, 22, 24, 24, +- 25, 26, 27, 27, 28, 28, 29, 29 +-}; +- +-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +-static const yytype_uint8 yyr2[] = +-{ +- 0, 2, 0, 2, 2, 0, 0, 6, 2, 2, +- 2, 0, 0, 6, 0, 6, 0, 10, 1, 0, +- 3, 2, 3, 0, 0, 3, 0, 5 +-}; +- +-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state +- STATE-NUM when YYTABLE doesn't specify something else to do. Zero +- means the default is an error. */ +-static const yytype_uint8 yydefact[] = +-{ +- 2, 0, 5, 1, 0, 3, 5, 0, 4, 6, +- 11, 0, 0, 11, 11, 11, 0, 0, 0, 0, +- 7, 10, 9, 8, 14, 12, 0, 19, 11, 11, +- 20, 18, 0, 0, 0, 0, 0, 15, 13, 21, +- 23, 0, 16, 0, 24, 22, 26, 0, 0, 17, +- 0, 25, 0, 0, 27 +-}; +- +-/* YYDEFGOTO[NTERM-NUM]. */ +-static const yytype_int8 yydefgoto[] = +-{ +- -1, 1, 2, 5, 6, 10, 12, 13, 29, 14, +- 28, 15, 44, 32, 19, 36, 42, 47, 48 +-}; +- +-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing +- STATE-NUM. */ +-#define YYPACT_NINF -14 +-static const yytype_int8 yypact[] = +-{ +- -14, 8, 4, -14, 2, -14, 4, 3, -14, -14, +- 6, 0, 7, 6, 6, 6, 9, 10, 11, 15, +- -14, -14, -14, -14, -14, -14, 16, 14, 6, 6, +- -14, -14, 5, 17, 18, 19, 20, -14, -14, -14, +- 22, 23, -14, 24, 27, -14, -14, 28, 1, -14, +- 25, -14, 29, 30, -14 +-}; +- +-/* YYPGOTO[NTERM-NUM]. */ +-static const yytype_int8 yypgoto[] = +-{ +- -14, -14, -14, 32, -14, -14, -13, -14, -14, -14, +- -14, -14, -14, -14, -14, -14, -14, -14, -14 +-}; +- +-/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If +- positive, shift that token. If negative, reduce the rule which +- number is the opposite. If zero, do what YYDEFACT says. +- If YYTABLE_NINF, syntax error. */ +-#define YYTABLE_NINF -1 +-static const yytype_uint8 yytable[] = +-{ +- 21, 22, 23, 16, 17, 18, 50, 51, 3, 4, +- 7, 11, 9, 20, 35, 33, 34, 24, 25, 26, +- 27, 31, 30, 37, 38, 0, 40, 41, 0, 39, +- 45, 43, 46, 52, 49, 0, 54, 53, 8 +-}; +- +-static const yytype_int8 yycheck[] = +-{ +- 13, 14, 15, 3, 4, 5, 5, 6, 0, 5, +- 8, 5, 9, 6, 9, 28, 29, 8, 8, 8, +- 5, 7, 6, 6, 6, -1, 6, 5, -1, 10, +- 6, 8, 5, 8, 6, -1, 6, 8, 6 +-}; +- +-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing +- symbol of state STATE-NUM. */ +-static const yytype_uint8 yystos[] = +-{ +- 0, 12, 13, 0, 5, 14, 15, 8, 14, 9, +- 16, 5, 17, 18, 20, 22, 3, 4, 5, 25, +- 6, 17, 17, 17, 8, 8, 8, 5, 21, 19, +- 6, 7, 24, 17, 17, 9, 26, 6, 6, 10, +- 6, 5, 27, 8, 23, 6, 5, 28, 29, 6, +- 5, 6, 8, 8, 6 +-}; +- +-#define yyerrok (yyerrstatus = 0) +-#define yyclearin (yychar = YYEMPTY) +-#define YYEMPTY (-2) +-#define YYEOF 0 +- +-#define YYACCEPT goto yyacceptlab +-#define YYABORT goto yyabortlab +-#define YYERROR goto yyerrorlab +- +- +-/* Like YYERROR except do call yyerror. This remains here temporarily +- to ease the transition to the new meaning of YYERROR, for GCC. +- Once GCC version 2 has supplanted version 1, this can go. */ +- +-#define YYFAIL goto yyerrlab +- +-#define YYRECOVERING() (!!yyerrstatus) +- +-#define YYBACKUP(Token, Value) \ +-do \ +- if (yychar == YYEMPTY && yylen == 1) \ +- { \ +- yychar = (Token); \ +- yylval = (Value); \ +- yytoken = YYTRANSLATE (yychar); \ +- YYPOPSTACK (1); \ +- goto yybackup; \ +- } \ +- else \ +- { \ +- yyerror (YY_("syntax error: cannot back up")); \ +- YYERROR; \ +- } \ +-while (YYID (0)) +- +- +-#define YYTERROR 1 +-#define YYERRCODE 256 +- +- +-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. +- If N is 0, then set CURRENT to the empty location which ends +- the previous symbol: RHS[0] (always defined). */ +- +-#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +-#ifndef YYLLOC_DEFAULT +-# define YYLLOC_DEFAULT(Current, Rhs, N) \ +- do \ +- if (YYID (N)) \ +- { \ +- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ +- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ +- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ +- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ +- } \ +- else \ +- { \ +- (Current).first_line = (Current).last_line = \ +- YYRHSLOC (Rhs, 0).last_line; \ +- (Current).first_column = (Current).last_column = \ +- YYRHSLOC (Rhs, 0).last_column; \ +- } \ +- while (YYID (0)) +-#endif +- +- +-/* YY_LOCATION_PRINT -- Print the location on the stream. +- This macro was not mandated originally: define only if we know +- we won't break user code: when these are the locations we know. */ +- +-#ifndef YY_LOCATION_PRINT +-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +-# define YY_LOCATION_PRINT(File, Loc) \ +- fprintf (File, "%d.%d-%d.%d", \ +- (Loc).first_line, (Loc).first_column, \ +- (Loc).last_line, (Loc).last_column) +-# else +-# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +-# endif +-#endif +- +- +-/* YYLEX -- calling `yylex' with the right arguments. */ +- +-#ifdef YYLEX_PARAM +-# define YYLEX yylex (YYLEX_PARAM) +-#else +-# define YYLEX yylex () +-#endif +- +-/* Enable debugging if requested. */ +-#if YYDEBUG +- +-# ifndef YYFPRINTF +-# include /* INFRINGES ON USER NAME SPACE */ +-# define YYFPRINTF fprintf +-# endif +- +-# define YYDPRINTF(Args) \ +-do { \ +- if (yydebug) \ +- YYFPRINTF Args; \ +-} while (YYID (0)) +- +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +-do { \ +- if (yydebug) \ +- { \ +- YYFPRINTF (stderr, "%s ", Title); \ +- yy_symbol_print (stderr, \ +- Type, Value); \ +- YYFPRINTF (stderr, "\n"); \ +- } \ +-} while (YYID (0)) +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_value_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (!yyvaluep) +- return; +-# ifdef YYPRINT +- if (yytype < YYNTOKENS) +- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +-# else +- YYUSE (yyoutput); +-# endif +- switch (yytype) +- { +- default: +- break; +- } +-} +- +- +-/*--------------------------------. +-| Print this symbol on YYOUTPUT. | +-`--------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +-#else +-static void +-yy_symbol_print (yyoutput, yytype, yyvaluep) +- FILE *yyoutput; +- int yytype; +- YYSTYPE const * const yyvaluep; +-#endif +-{ +- if (yytype < YYNTOKENS) +- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +- else +- YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); +- +- yy_symbol_value_print (yyoutput, yytype, yyvaluep); +- YYFPRINTF (yyoutput, ")"); +-} +- +-/*------------------------------------------------------------------. +-| yy_stack_print -- Print the state stack from its BOTTOM up to its | +-| TOP (included). | +-`------------------------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +-#else +-static void +-yy_stack_print (bottom, top) +- yytype_int16 *bottom; +- yytype_int16 *top; +-#endif +-{ +- YYFPRINTF (stderr, "Stack now"); +- for (; bottom <= top; ++bottom) +- YYFPRINTF (stderr, " %d", *bottom); +- YYFPRINTF (stderr, "\n"); +-} +- +-# define YY_STACK_PRINT(Bottom, Top) \ +-do { \ +- if (yydebug) \ +- yy_stack_print ((Bottom), (Top)); \ +-} while (YYID (0)) +- +- +-/*------------------------------------------------. +-| Report that the YYRULE is going to be reduced. | +-`------------------------------------------------*/ +- +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +-#else +-static void +-yy_reduce_print (yyvsp, yyrule) +- YYSTYPE *yyvsp; +- int yyrule; +-#endif +-{ +- int yynrhs = yyr2[yyrule]; +- int yyi; +- unsigned long int yylno = yyrline[yyrule]; +- YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", +- yyrule - 1, yylno); +- /* The symbols being reduced. */ +- for (yyi = 0; yyi < yynrhs; yyi++) +- { +- fprintf (stderr, " $%d = ", yyi + 1); +- yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], +- &(yyvsp[(yyi + 1) - (yynrhs)]) +- ); +- fprintf (stderr, "\n"); +- } +-} +- +-# define YY_REDUCE_PRINT(Rule) \ +-do { \ +- if (yydebug) \ +- yy_reduce_print (yyvsp, Rule); \ +-} while (YYID (0)) +- +-/* Nonzero means print parse trace. It is left uninitialized so that +- multiple parsers can coexist. */ +-int yydebug; +-#else /* !YYDEBUG */ +-# define YYDPRINTF(Args) +-# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +-# define YY_STACK_PRINT(Bottom, Top) +-# define YY_REDUCE_PRINT(Rule) +-#endif /* !YYDEBUG */ +- +- +-/* YYINITDEPTH -- initial size of the parser's stacks. */ +-#ifndef YYINITDEPTH +-# define YYINITDEPTH 200 +-#endif +- +-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only +- if the built-in stack extension method is used). +- +- Do not make this value too large; the results are undefined if +- YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) +- evaluated with infinite-precision integer arithmetic. */ +- +-#ifndef YYMAXDEPTH +-# define YYMAXDEPTH 10000 +-#endif +- +- +- +-#if YYERROR_VERBOSE +- +-# ifndef yystrlen +-# if defined __GLIBC__ && defined _STRING_H +-# define yystrlen strlen +-# else +-/* Return the length of YYSTR. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static YYSIZE_T +-yystrlen (const char *yystr) +-#else +-static YYSIZE_T +-yystrlen (yystr) +- const char *yystr; +-#endif +-{ +- YYSIZE_T yylen; +- for (yylen = 0; yystr[yylen]; yylen++) +- continue; +- return yylen; +-} +-# endif +-# endif +- +-# ifndef yystpcpy +-# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +-# define yystpcpy stpcpy +-# else +-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in +- YYDEST. */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static char * +-yystpcpy (char *yydest, const char *yysrc) +-#else +-static char * +-yystpcpy (yydest, yysrc) +- char *yydest; +- const char *yysrc; +-#endif +-{ +- char *yyd = yydest; +- const char *yys = yysrc; +- +- while ((*yyd++ = *yys++) != '\0') +- continue; +- +- return yyd - 1; +-} +-# endif +-# endif +- +-# ifndef yytnamerr +-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary +- quotes and backslashes, so that it's suitable for yyerror. The +- heuristic is that double-quoting is unnecessary unless the string +- contains an apostrophe, a comma, or backslash (other than +- backslash-backslash). YYSTR is taken from yytname. If YYRES is +- null, do not copy; instead, return the length of what the result +- would have been. */ +-static YYSIZE_T +-yytnamerr (char *yyres, const char *yystr) +-{ +- if (*yystr == '"') +- { +- YYSIZE_T yyn = 0; +- char const *yyp = yystr; +- +- for (;;) +- switch (*++yyp) +- { +- case '\'': +- case ',': +- goto do_not_strip_quotes; +- +- case '\\': +- if (*++yyp != '\\') +- goto do_not_strip_quotes; +- /* Fall through. */ +- default: +- if (yyres) +- yyres[yyn] = *yyp; +- yyn++; +- break; +- +- case '"': +- if (yyres) +- yyres[yyn] = '\0'; +- return yyn; +- } +- do_not_strip_quotes: ; +- } +- +- if (! yyres) +- return yystrlen (yystr); +- +- return yystpcpy (yyres, yystr) - yyres; +-} +-# endif +- +-/* Copy into YYRESULT an error message about the unexpected token +- YYCHAR while in state YYSTATE. Return the number of bytes copied, +- including the terminating null byte. If YYRESULT is null, do not +- copy anything; just return the number of bytes that would be +- copied. As a special case, return 0 if an ordinary "syntax error" +- message will do. Return YYSIZE_MAXIMUM if overflow occurs during +- size calculation. */ +-static YYSIZE_T +-yysyntax_error (char *yyresult, int yystate, int yychar) +-{ +- int yyn = yypact[yystate]; +- +- if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) +- return 0; +- else +- { +- int yytype = YYTRANSLATE (yychar); +- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); +- YYSIZE_T yysize = yysize0; +- YYSIZE_T yysize1; +- int yysize_overflow = 0; +- enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; +- char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; +- int yyx; +- +-# if 0 +- /* This is so xgettext sees the translatable formats that are +- constructed on the fly. */ +- YY_("syntax error, unexpected %s"); +- YY_("syntax error, unexpected %s, expecting %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s"); +- YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +-# endif +- char *yyfmt; +- char const *yyf; +- static char const yyunexpected[] = "syntax error, unexpected %s"; +- static char const yyexpecting[] = ", expecting %s"; +- static char const yyor[] = " or %s"; +- char yyformat[sizeof yyunexpected +- + sizeof yyexpecting - 1 +- + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) +- * (sizeof yyor - 1))]; +- char const *yyprefix = yyexpecting; +- +- /* Start YYX at -YYN if negative to avoid negative indexes in +- YYCHECK. */ +- int yyxbegin = yyn < 0 ? -yyn : 0; +- +- /* Stay within bounds of both yycheck and yytname. */ +- int yychecklim = YYLAST - yyn + 1; +- int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; +- int yycount = 1; +- +- yyarg[0] = yytname[yytype]; +- yyfmt = yystpcpy (yyformat, yyunexpected); +- +- for (yyx = yyxbegin; yyx < yyxend; ++yyx) +- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) +- { +- if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) +- { +- yycount = 1; +- yysize = yysize0; +- yyformat[sizeof yyunexpected - 1] = '\0'; +- break; +- } +- yyarg[yycount++] = yytname[yyx]; +- yysize1 = yysize + yytnamerr (0, yytname[yyx]); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- yyfmt = yystpcpy (yyfmt, yyprefix); +- yyprefix = yyor; +- } +- +- yyf = YY_(yyformat); +- yysize1 = yysize + yystrlen (yyf); +- yysize_overflow |= (yysize1 < yysize); +- yysize = yysize1; +- +- if (yysize_overflow) +- return YYSIZE_MAXIMUM; +- +- if (yyresult) +- { +- /* Avoid sprintf, as that infringes on the user's name space. +- Don't have undefined behavior even if the translation +- produced a string with the wrong number of "%s"s. */ +- char *yyp = yyresult; +- int yyi = 0; +- while ((*yyp = *yyf) != '\0') +- { +- if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) +- { +- yyp += yytnamerr (yyp, yyarg[yyi++]); +- yyf += 2; +- } +- else +- { +- yyp++; +- yyf++; +- } +- } +- } +- return yysize; +- } +-} +-#endif /* YYERROR_VERBOSE */ +- +- +-/*-----------------------------------------------. +-| Release the memory associated to this symbol. | +-`-----------------------------------------------*/ +- +-/*ARGSUSED*/ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-static void +-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +-#else +-static void +-yydestruct (yymsg, yytype, yyvaluep) +- const char *yymsg; +- int yytype; +- YYSTYPE *yyvaluep; +-#endif +-{ +- YYUSE (yyvaluep); +- +- if (!yymsg) +- yymsg = "Deleting"; +- YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); +- +- switch (yytype) +- { +- +- default: +- break; +- } +-} +- +- +-/* Prevent warnings from -Wmissing-prototypes. */ +- +-#ifdef YYPARSE_PARAM +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void *YYPARSE_PARAM); +-#else +-int yyparse (); +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if defined __STDC__ || defined __cplusplus +-int yyparse (void); +-#else +-int yyparse (); +-#endif +-#endif /* ! YYPARSE_PARAM */ +- +- +- +-/* The look-ahead symbol. */ +-int yychar; +- +-/* The semantic value of the look-ahead symbol. */ +-YYSTYPE yylval; +- +-/* Number of syntax errors so far. */ +-int yynerrs; +- +- +- +-/*----------. +-| yyparse. | +-`----------*/ +- +-#ifdef YYPARSE_PARAM +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void *YYPARSE_PARAM) +-#else +-int +-yyparse (YYPARSE_PARAM) +- void *YYPARSE_PARAM; +-#endif +-#else /* ! YYPARSE_PARAM */ +-#if (defined __STDC__ || defined __C99__FUNC__ \ +- || defined __cplusplus || defined _MSC_VER) +-int +-yyparse (void) +-#else +-int +-yyparse () +- +-#endif +-#endif +-{ +- +- int yystate; +- int yyn; +- int yyresult; +- /* Number of tokens to shift before error messages enabled. */ +- int yyerrstatus; +- /* Look-ahead token as an internal (translated) token number. */ +- int yytoken = 0; +-#if YYERROR_VERBOSE +- /* Buffer for error messages, and its allocated size. */ +- char yymsgbuf[128]; +- char *yymsg = yymsgbuf; +- YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +-#endif +- +- /* Three stacks and their tools: +- `yyss': related to states, +- `yyvs': related to semantic values, +- `yyls': related to locations. +- +- Refer to the stacks thru separate pointers, to allow yyoverflow +- to reallocate them elsewhere. */ +- +- /* The state stack. */ +- yytype_int16 yyssa[YYINITDEPTH]; +- yytype_int16 *yyss = yyssa; +- yytype_int16 *yyssp; +- +- /* The semantic value stack. */ +- YYSTYPE yyvsa[YYINITDEPTH]; +- YYSTYPE *yyvs = yyvsa; +- YYSTYPE *yyvsp; +- +- +- +-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) +- +- YYSIZE_T yystacksize = YYINITDEPTH; +- +- /* The variables used to return semantic value and location from the +- action routines. */ +- YYSTYPE yyval; +- +- +- /* The number of symbols on the RHS of the reduced rule. +- Keep to zero when no symbol should be popped. */ +- int yylen = 0; +- +- YYDPRINTF ((stderr, "Starting parse\n")); +- +- yystate = 0; +- yyerrstatus = 0; +- yynerrs = 0; +- yychar = YYEMPTY; /* Cause a token to be read. */ +- +- /* Initialize stack pointers. +- Waste one element of value and location stack +- so that they stay on the same level as the state stack. +- The wasted elements are never initialized. */ +- +- yyssp = yyss; +- yyvsp = yyvs; +- +- goto yysetstate; +- +-/*------------------------------------------------------------. +-| yynewstate -- Push a new state, which is found in yystate. | +-`------------------------------------------------------------*/ +- yynewstate: +- /* In all cases, when you get here, the value and location stacks +- have just been pushed. So pushing a state here evens the stacks. */ +- yyssp++; +- +- yysetstate: +- *yyssp = yystate; +- +- if (yyss + yystacksize - 1 <= yyssp) +- { +- /* Get the current used size of the three stacks, in elements. */ +- YYSIZE_T yysize = yyssp - yyss + 1; +- +-#ifdef yyoverflow +- { +- /* Give user a chance to reallocate the stack. Use copies of +- these so that the &'s don't force the real ones into +- memory. */ +- YYSTYPE *yyvs1 = yyvs; +- yytype_int16 *yyss1 = yyss; +- +- +- /* Each stack pointer address is followed by the size of the +- data in use in that stack, in bytes. This used to be a +- conditional around just the two extra args, but that might +- be undefined if yyoverflow is a macro. */ +- yyoverflow (YY_("memory exhausted"), +- &yyss1, yysize * sizeof (*yyssp), +- &yyvs1, yysize * sizeof (*yyvsp), +- +- &yystacksize); +- +- yyss = yyss1; +- yyvs = yyvs1; +- } +-#else /* no yyoverflow */ +-# ifndef YYSTACK_RELOCATE +- goto yyexhaustedlab; +-# else +- /* Extend the stack our own way. */ +- if (YYMAXDEPTH <= yystacksize) +- goto yyexhaustedlab; +- yystacksize *= 2; +- if (YYMAXDEPTH < yystacksize) +- yystacksize = YYMAXDEPTH; +- +- { +- yytype_int16 *yyss1 = yyss; +- union yyalloc *yyptr = +- (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); +- if (! yyptr) +- goto yyexhaustedlab; +- YYSTACK_RELOCATE (yyss); +- YYSTACK_RELOCATE (yyvs); +- +-# undef YYSTACK_RELOCATE +- if (yyss1 != yyssa) +- YYSTACK_FREE (yyss1); +- } +-# endif +-#endif /* no yyoverflow */ +- +- yyssp = yyss + yysize - 1; +- yyvsp = yyvs + yysize - 1; +- +- +- YYDPRINTF ((stderr, "Stack size increased to %lu\n", +- (unsigned long int) yystacksize)); +- +- if (yyss + yystacksize - 1 <= yyssp) +- YYABORT; +- } +- +- YYDPRINTF ((stderr, "Entering state %d\n", yystate)); +- +- goto yybackup; +- +-/*-----------. +-| yybackup. | +-`-----------*/ +-yybackup: +- +- /* Do appropriate processing given the current state. Read a +- look-ahead token if we need one and don't already have one. */ +- +- /* First try to decide what to do without reference to look-ahead token. */ +- yyn = yypact[yystate]; +- if (yyn == YYPACT_NINF) +- goto yydefault; +- +- /* Not known => get a look-ahead token if don't already have one. */ +- +- /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ +- if (yychar == YYEMPTY) +- { +- YYDPRINTF ((stderr, "Reading a token: ")); +- yychar = YYLEX; +- } +- +- if (yychar <= YYEOF) +- { +- yychar = yytoken = YYEOF; +- YYDPRINTF ((stderr, "Now at end of input.\n")); +- } +- else +- { +- yytoken = YYTRANSLATE (yychar); +- YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); +- } +- +- /* If the proper action on seeing token YYTOKEN is to reduce or to +- detect an error, take that action. */ +- yyn += yytoken; +- if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) +- goto yydefault; +- yyn = yytable[yyn]; +- if (yyn <= 0) +- { +- if (yyn == 0 || yyn == YYTABLE_NINF) +- goto yyerrlab; +- yyn = -yyn; +- goto yyreduce; +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- /* Count tokens shifted since error; after three, turn off error +- status. */ +- if (yyerrstatus) +- yyerrstatus--; +- +- /* Shift the look-ahead token. */ +- YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); +- +- /* Discard the shifted token unless it is eof. */ +- if (yychar != YYEOF) +- yychar = YYEMPTY; +- +- yystate = yyn; +- *++yyvsp = yylval; +- +- goto yynewstate; +- +- +-/*-----------------------------------------------------------. +-| yydefault -- do the default action for the current state. | +-`-----------------------------------------------------------*/ +-yydefault: +- yyn = yydefact[yystate]; +- if (yyn == 0) +- goto yyerrlab; +- goto yyreduce; +- +- +-/*-----------------------------. +-| yyreduce -- Do a reduction. | +-`-----------------------------*/ +-yyreduce: +- /* yyn is the number of a rule to reduce with. */ +- yylen = yyr2[yyn]; +- +- /* If YYLEN is nonzero, implement the default value of the action: +- `$$ = $1'. +- +- Otherwise, the following line sets YYVAL to garbage. +- This behavior is undocumented and Bison +- users should not rely upon it. Assigning to YYVAL +- unconditionally makes the parser a bit smaller, and it avoids a +- GCC warning that YYVAL may be used uninitialized. */ +- yyval = yyvsp[1-yylen]; +- +- +- YY_REDUCE_PRINT (yyn); +- switch (yyn) +- { +- case 2: +-#line 54 "sysinfo.y" +- { +- switch (writecode) +- { +- case 'i': +- printf("#ifdef SYSROFF_SWAP_IN\n"); +- break; +- case 'p': +- printf("#ifdef SYSROFF_p\n"); +- break; +- case 'd': +- break; +- case 'g': +- printf("#ifdef SYSROFF_SWAP_OUT\n"); +- break; +- case 'c': +- printf("#ifdef SYSROFF_PRINT\n"); +- printf("#include \n"); +- printf("#include \n"); +- printf("#include \n"); +- break; +- } +- } +- break; +- +- case 3: +-#line 76 "sysinfo.y" +- { +- switch (writecode) { +- case 'i': +- case 'p': +- case 'g': +- case 'c': +- printf("#endif\n"); +- break; +- case 'd': +- break; +- } +-} +- break; +- +- case 6: +-#line 98 "sysinfo.y" +- { +- it = (yyvsp[(2) - (3)].s); code = (yyvsp[(3) - (3)].i); +- switch (writecode) +- { +- case 'd': +- printf("\n\n\n#define IT_%s_CODE 0x%x\n", it,code); +- printf("struct IT_%s;\n", it); +- printf("extern void sysroff_swap_%s_in (struct IT_%s *);\n", +- (yyvsp[(2) - (3)].s), it); +- printf("extern void sysroff_swap_%s_out (FILE *, struct IT_%s *);\n", +- (yyvsp[(2) - (3)].s), it); +- printf("extern void sysroff_print_%s_out (struct IT_%s *);\n", +- (yyvsp[(2) - (3)].s), it); +- printf("struct IT_%s { \n", it); +- break; +- case 'i': +- printf("void sysroff_swap_%s_in (struct IT_%s * ptr)\n",(yyvsp[(2) - (3)].s),it); +- printf("{\n"); +- printf("\tunsigned char raw[255];\n"); +- printf("\tint idx = 0;\n"); +- printf("\tint size;\n"); +- printf("\tmemset(raw,0,255);\n"); +- printf("\tmemset(ptr,0,sizeof(*ptr));\n"); +- printf("\tsize = fillup(raw);\n"); +- break; +- case 'g': +- printf("void sysroff_swap_%s_out (FILE * ffile, struct IT_%s * ptr)\n",(yyvsp[(2) - (3)].s),it); +- printf("{\n"); +- printf("\tunsigned char raw[255];\n"); +- printf("\tint idx = 16;\n"); +- printf("\tmemset (raw, 0, 255);\n"); +- printf("\tcode = IT_%s_CODE;\n", it); +- break; +- case 'o': +- printf("void sysroff_swap_%s_out (bfd * abfd, struct IT_%s * ptr)\n",(yyvsp[(2) - (3)].s), it); +- printf("{\n"); +- printf("\tint idx = 0;\n"); +- break; +- case 'c': +- printf("void sysroff_print_%s_out (struct IT_%s *ptr)\n",(yyvsp[(2) - (3)].s),it); +- printf("{\n"); +- printf("itheader(\"%s\", IT_%s_CODE);\n",(yyvsp[(2) - (3)].s),(yyvsp[(2) - (3)].s)); +- break; +- +- case 't': +- break; +- } +- +- } +- break; +- +- case 7: +-#line 149 "sysinfo.y" +- { +- switch (writecode) { +- case 'd': +- printf("};\n"); +- break; +- case 'g': +- printf("\tchecksum(ffile,raw, idx, IT_%s_CODE);\n", it); +- +- case 'i': +- +- case 'o': +- case 'c': +- printf("}\n"); +- } +-} +- break; +- +- case 12: +-#line 176 "sysinfo.y" +- { +- rdepth++; +- switch (writecode) +- { +- case 'c': +- if (rdepth==1) +- printf("\tprintf(\"repeat %%d\\n\", %s);\n",(yyvsp[(3) - (3)].s)); +- if (rdepth==2) +- printf("\tprintf(\"repeat %%d\\n\", %s[n]);\n",(yyvsp[(3) - (3)].s)); +- case 'i': +- case 'g': +- case 'o': +- +- if (rdepth==1) +- { +- printf("\t{ int n; for (n = 0; n < %s; n++) {\n", (yyvsp[(3) - (3)].s)); +- } +- if (rdepth == 2) { +- printf("\t{ int m; for (m = 0; m < %s[n]; m++) {\n", (yyvsp[(3) - (3)].s)); +- } +- +- break; +- } +- +- oldrepeat = repeat; +- repeat = (yyvsp[(3) - (3)].s); +- } +- break; +- +- case 13: +-#line 206 "sysinfo.y" +- { +- repeat = oldrepeat; +- oldrepeat =0; +- rdepth--; +- switch (writecode) +- { +- case 'i': +- case 'g': +- case 'o': +- case 'c': +- printf("\t}}\n"); +- } +- } +- break; +- +- case 14: +-#line 223 "sysinfo.y" +- { +- switch (writecode) +- { +- case 'i': +- case 'g': +- case 'o': +- case 'c': +- printf("\tif (%s) {\n", (yyvsp[(3) - (3)].s)); +- break; +- } +- } +- break; +- +- case 15: +-#line 236 "sysinfo.y" +- { +- switch (writecode) +- { +- case 'i': +- case 'g': +- case 'o': +- case 'c': +- printf("\t}\n"); +- } +- } +- break; +- +- case 16: +-#line 250 "sysinfo.y" +- {name = (yyvsp[(7) - (7)].s); } +- break; +- +- case 17: +-#line 252 "sysinfo.y" +- { +- char *desc = (yyvsp[(2) - (10)].s); +- char *type = (yyvsp[(4) - (10)].s); +- int size = (yyvsp[(5) - (10)].i); +- char *id = (yyvsp[(7) - (10)].s); +-char *p = names[rdepth]; +-char *ptr = pnames[rdepth]; +- switch (writecode) +- { +- case 'g': +- if (size % 8) +- { +- +- printf("\twriteBITS(ptr->%s%s,raw,&idx,%d);\n", +- id, +- names[rdepth], size); +- +- } +- else { +- printf("\twrite%s(ptr->%s%s,raw,&idx,%d,ffile);\n", +- type, +- id, +- names[rdepth],size/8); +- } +- break; +- case 'i': +- { +- +- if (rdepth >= 1) +- +- { +- printf("if (!ptr->%s) ptr->%s = (%s*)xcalloc(%s, sizeof(ptr->%s[0]));\n", +- id, +- id, +- type, +- repeat, +- id); +- } +- +- if (rdepth == 2) +- { +- printf("if (!ptr->%s[n]) ptr->%s[n] = (%s**)xcalloc(%s[n], sizeof(ptr->%s[n][0]));\n", +- id, +- id, +- type, +- repeat, +- id); +- } +- +- } +- +- if (size % 8) +- { +- printf("\tptr->%s%s = getBITS(raw,&idx, %d,size);\n", +- id, +- names[rdepth], +- size); +- } +- else { +- printf("\tptr->%s%s = get%s(raw,&idx, %d,size);\n", +- id, +- names[rdepth], +- type, +- size/8); +- } +- break; +- case 'o': +- printf("\tput%s(raw,%d,%d,&idx,ptr->%s%s);\n", type,size/8,size%8,id,names[rdepth]); +- break; +- case 'd': +- if (repeat) +- printf("\t/* repeat %s */\n", repeat); +- +- if (type[0] == 'I') { +- printf("\tint %s%s; \t/* %s */\n",ptr,id, desc); +- } +- else if (type[0] =='C') { +- printf("\tchar %s*%s;\t /* %s */\n",ptr,id, desc); +- } +- else { +- printf("\tbarray %s%s;\t /* %s */\n",ptr,id, desc); +- } +- break; +- case 'c': +- printf("tabout();\n"); +- printf("\tprintf(\"/*%-30s*/ ptr->%s = \");\n", desc, id); +- +- if (type[0] == 'I') +- printf("\tprintf(\"%%d\\n\",ptr->%s%s);\n", id,p); +- else if (type[0] == 'C') +- printf("\tprintf(\"%%s\\n\",ptr->%s%s);\n", id,p); +- +- else if (type[0] == 'B') +- { +- printf("\tpbarray(&ptr->%s%s);\n", id,p); +- } +- else abort(); +- break; +- } +- } +- break; +- +- case 18: +-#line 357 "sysinfo.y" +- { (yyval.s) = (yyvsp[(1) - (1)].s); } +- break; +- +- case 19: +-#line 358 "sysinfo.y" +- { (yyval.s) = "INT";} +- break; +- +- case 20: +-#line 363 "sysinfo.y" +- { (yyval.s) = (yyvsp[(2) - (3)].s); } +- break; +- +- case 21: +-#line 368 "sysinfo.y" +- { (yyval.i) = (yyvsp[(1) - (2)].i) * (yyvsp[(2) - (2)].i); } +- break; +- +- case 22: +-#line 373 "sysinfo.y" +- { (yyval.s) = (yyvsp[(2) - (3)].s); } +- break; +- +- case 23: +-#line 374 "sysinfo.y" +- { (yyval.s) = "dummy";} +- break; +- +- case 27: +-#line 382 "sysinfo.y" +- { +- switch (writecode) +- { +- case 'd': +- printf("#define %s %s\n", (yyvsp[(3) - (5)].s),(yyvsp[(4) - (5)].s)); +- break; +- case 'c': +- printf("if (ptr->%s%s == %s) { tabout(); printf(\"%s\\n\");}\n", name, names[rdepth],(yyvsp[(4) - (5)].s),(yyvsp[(3) - (5)].s)); +- } +- } +- break; +- +- +-/* Line 1267 of yacc.c. */ +-#line 1715 "sysinfo.c" +- default: break; +- } +- YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); +- +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- +- *++yyvsp = yyval; +- +- +- /* Now `shift' the result of the reduction. Determine what state +- that goes to, based on the state we popped back to and the rule +- number reduced by. */ +- +- yyn = yyr1[yyn]; +- +- yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; +- if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) +- yystate = yytable[yystate]; +- else +- yystate = yydefgoto[yyn - YYNTOKENS]; +- +- goto yynewstate; +- +- +-/*------------------------------------. +-| yyerrlab -- here on detecting error | +-`------------------------------------*/ +-yyerrlab: +- /* If not already recovering from an error, report this error. */ +- if (!yyerrstatus) +- { +- ++yynerrs; +-#if ! YYERROR_VERBOSE +- yyerror (YY_("syntax error")); +-#else +- { +- YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); +- if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) +- { +- YYSIZE_T yyalloc = 2 * yysize; +- if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) +- yyalloc = YYSTACK_ALLOC_MAXIMUM; +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +- yymsg = (char *) YYSTACK_ALLOC (yyalloc); +- if (yymsg) +- yymsg_alloc = yyalloc; +- else +- { +- yymsg = yymsgbuf; +- yymsg_alloc = sizeof yymsgbuf; +- } +- } +- +- if (0 < yysize && yysize <= yymsg_alloc) +- { +- (void) yysyntax_error (yymsg, yystate, yychar); +- yyerror (yymsg); +- } +- else +- { +- yyerror (YY_("syntax error")); +- if (yysize != 0) +- goto yyexhaustedlab; +- } +- } +-#endif +- } +- +- +- +- if (yyerrstatus == 3) +- { +- /* If just tried and failed to reuse look-ahead token after an +- error, discard it. */ +- +- if (yychar <= YYEOF) +- { +- /* Return failure if at end of input. */ +- if (yychar == YYEOF) +- YYABORT; +- } +- else +- { +- yydestruct ("Error: discarding", +- yytoken, &yylval); +- yychar = YYEMPTY; +- } +- } +- +- /* Else will try to reuse look-ahead token after shifting the error +- token. */ +- goto yyerrlab1; +- +- +-/*---------------------------------------------------. +-| yyerrorlab -- error raised explicitly by YYERROR. | +-`---------------------------------------------------*/ +-yyerrorlab: +- +- /* Pacify compilers like GCC when the user code never invokes +- YYERROR and the label yyerrorlab therefore never appears in user +- code. */ +- if (/*CONSTCOND*/ 0) +- goto yyerrorlab; +- +- /* Do not reclaim the symbols of the rule which action triggered +- this YYERROR. */ +- YYPOPSTACK (yylen); +- yylen = 0; +- YY_STACK_PRINT (yyss, yyssp); +- yystate = *yyssp; +- goto yyerrlab1; +- +- +-/*-------------------------------------------------------------. +-| yyerrlab1 -- common code for both syntax error and YYERROR. | +-`-------------------------------------------------------------*/ +-yyerrlab1: +- yyerrstatus = 3; /* Each real token shifted decrements this. */ +- +- for (;;) +- { +- yyn = yypact[yystate]; +- if (yyn != YYPACT_NINF) +- { +- yyn += YYTERROR; +- if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) +- { +- yyn = yytable[yyn]; +- if (0 < yyn) +- break; +- } +- } +- +- /* Pop the current state because it cannot handle the error token. */ +- if (yyssp == yyss) +- YYABORT; +- +- +- yydestruct ("Error: popping", +- yystos[yystate], yyvsp); +- YYPOPSTACK (1); +- yystate = *yyssp; +- YY_STACK_PRINT (yyss, yyssp); +- } +- +- if (yyn == YYFINAL) +- YYACCEPT; +- +- *++yyvsp = yylval; +- +- +- /* Shift the error token. */ +- YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); +- +- yystate = yyn; +- goto yynewstate; +- +- +-/*-------------------------------------. +-| yyacceptlab -- YYACCEPT comes here. | +-`-------------------------------------*/ +-yyacceptlab: +- yyresult = 0; +- goto yyreturn; +- +-/*-----------------------------------. +-| yyabortlab -- YYABORT comes here. | +-`-----------------------------------*/ +-yyabortlab: +- yyresult = 1; +- goto yyreturn; +- +-#ifndef yyoverflow +-/*-------------------------------------------------. +-| yyexhaustedlab -- memory exhaustion comes here. | +-`-------------------------------------------------*/ +-yyexhaustedlab: +- yyerror (YY_("memory exhausted")); +- yyresult = 2; +- /* Fall through. */ +-#endif +- +-yyreturn: +- if (yychar != YYEOF && yychar != YYEMPTY) +- yydestruct ("Cleanup: discarding lookahead", +- yytoken, &yylval); +- /* Do not reclaim the symbols of the rule which action triggered +- this YYABORT or YYACCEPT. */ +- YYPOPSTACK (yylen); +- YY_STACK_PRINT (yyss, yyssp); +- while (yyssp != yyss) +- { +- yydestruct ("Cleanup: popping", +- yystos[*yyssp], yyvsp); +- YYPOPSTACK (1); +- } +-#ifndef yyoverflow +- if (yyss != yyssa) +- YYSTACK_FREE (yyss); +-#endif +-#if YYERROR_VERBOSE +- if (yymsg != yymsgbuf) +- YYSTACK_FREE (yymsg); +-#endif +- /* Make sure YYID is used. */ +- return YYID (yyresult); +-} +- +- +-#line 397 "sysinfo.y" +- +-/* four modes +- +- -d write structure definitions for sysroff in host format +- -i write functions to swap into sysroff format in +- -o write functions to swap into sysroff format out +- -c write code to print info in human form */ +- +-int yydebug; +- +-int +-main (int ac, char **av) +-{ +- yydebug=0; +- if (ac > 1) +- writecode = av[1][1]; +-if (writecode == 'd') +- { +- printf("typedef struct { unsigned char *data; int len; } barray; \n"); +- printf("typedef int INT;\n"); +- printf("typedef char * CHARS;\n"); +- +- } +- yyparse(); +-return 0; +-} +- +-static int +-yyerror (char *s) +-{ +- fprintf(stderr, "%s\n" , s); +- return 0; +-} +- +diff -Nur binutils-2.24.orig/binutils/sysinfo.h binutils-2.24/binutils/sysinfo.h +--- binutils-2.24.orig/binutils/sysinfo.h 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/sysinfo.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,77 +0,0 @@ +-/* A Bison parser, made by GNU Bison 2.3. */ +- +-/* Skeleton interface for Bison's Yacc-like parsers in C +- +- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 +- Free Software Foundation, Inc. +- +- 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, 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. */ +- +-/* As a special exception, you may create a larger work that contains +- part or all of the Bison parser skeleton and distribute that work +- under terms of your choice, so long as that work isn't itself a +- parser generator using the skeleton or a modified version thereof +- as a parser skeleton. Alternatively, if you modify or redistribute +- the parser skeleton itself, you may (at your option) remove this +- special exception, which will cause the skeleton and the resulting +- Bison output files to be licensed under the GNU General Public +- License without this special exception. +- +- This special exception was added by the Free Software Foundation in +- version 2.2 of Bison. */ +- +-/* Tokens. */ +-#ifndef YYTOKENTYPE +-# define YYTOKENTYPE +- /* Put the tokens into the symbol table, so that GDB and other debuggers +- know about them. */ +- enum yytokentype { +- COND = 258, +- REPEAT = 259, +- TYPE = 260, +- NAME = 261, +- NUMBER = 262, +- UNIT = 263 +- }; +-#endif +-/* Tokens. */ +-#define COND 258 +-#define REPEAT 259 +-#define TYPE 260 +-#define NAME 261 +-#define NUMBER 262 +-#define UNIT 263 +- +- +- +- +-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +-typedef union YYSTYPE +-#line 40 "sysinfo.y" +-{ +- int i; +- char *s; +-} +-/* Line 1529 of yacc.c. */ +-#line 70 "sysinfo.h" +- YYSTYPE; +-# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +-# define YYSTYPE_IS_DECLARED 1 +-# define YYSTYPE_IS_TRIVIAL 1 +-#endif +- +-extern YYSTYPE yylval; +- +diff -Nur binutils-2.24.orig/binutils/syslex.c binutils-2.24/binutils/syslex.c +--- binutils-2.24.orig/binutils/syslex.c 2013-11-18 09:49:30.000000000 +0100 ++++ binutils-2.24/binutils/syslex.c 1970-01-01 01:00:00.000000000 +0100 +@@ -1,1906 +0,0 @@ +- +-#line 3 "syslex.c" +- +-#define YY_INT_ALIGNED short int +- +-/* A lexical scanner generated by flex */ +- +-#define FLEX_SCANNER +-#define YY_FLEX_MAJOR_VERSION 2 +-#define YY_FLEX_MINOR_VERSION 5 +-#define YY_FLEX_SUBMINOR_VERSION 35 +-#if YY_FLEX_SUBMINOR_VERSION > 0 +-#define FLEX_BETA +-#endif +- +-/* First, we deal with platform-specific or compiler-specific issues. */ +- +-/* begin standard C headers. */ +-#include +-#include +-#include +-#include +- +-/* end standard C headers. */ +- +-/* flex integer type definitions */ +- +-#ifndef FLEXINT_H +-#define FLEXINT_H +- +-/* C99 systems have . Non-C99 systems may or may not. */ +- +-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +- +-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, +- * if you want the limit (max/min) macros for int types. +- */ +-#ifndef __STDC_LIMIT_MACROS +-#define __STDC_LIMIT_MACROS 1 +-#endif +- +-#include +-typedef int8_t flex_int8_t; +-typedef uint8_t flex_uint8_t; +-typedef int16_t flex_int16_t; +-typedef uint16_t flex_uint16_t; +-typedef int32_t flex_int32_t; +-typedef uint32_t flex_uint32_t; +-typedef uint64_t flex_uint64_t; +-#else +-typedef signed char flex_int8_t; +-typedef short int flex_int16_t; +-typedef int flex_int32_t; +-typedef unsigned char flex_uint8_t; +-typedef unsigned short int flex_uint16_t; +-typedef unsigned int flex_uint32_t; +-#endif /* ! C99 */ +- +-/* Limits of integral types. */ +-#ifndef INT8_MIN +-#define INT8_MIN (-128) +-#endif +-#ifndef INT16_MIN +-#define INT16_MIN (-32767-1) +-#endif +-#ifndef INT32_MIN +-#define INT32_MIN (-2147483647-1) +-#endif +-#ifndef INT8_MAX +-#define INT8_MAX (127) +-#endif +-#ifndef INT16_MAX +-#define INT16_MAX (32767) +-#endif +-#ifndef INT32_MAX +-#define INT32_MAX (2147483647) +-#endif +-#ifndef UINT8_MAX +-#define UINT8_MAX (255U) +-#endif +-#ifndef UINT16_MAX +-#define UINT16_MAX (65535U) +-#endif +-#ifndef UINT32_MAX +-#define UINT32_MAX (4294967295U) +-#endif +- +-#endif /* ! FLEXINT_H */ +- +-#ifdef __cplusplus +- +-/* The "const" storage-class-modifier is valid. */ +-#define YY_USE_CONST +- +-#else /* ! __cplusplus */ +- +-/* C99 requires __STDC__ to be defined as 1. */ +-#if defined (__STDC__) +- +-#define YY_USE_CONST +- +-#endif /* defined (__STDC__) */ +-#endif /* ! __cplusplus */ +- +-#ifdef YY_USE_CONST +-#define yyconst const +-#else +-#define yyconst +-#endif +- +-/* Returned upon end-of-file. */ +-#define YY_NULL 0 +- +-/* Promotes a possibly negative, possibly signed char to an unsigned +- * integer for use as an array index. If the signed char is negative, +- * we want to instead treat it as an 8-bit unsigned char, hence the +- * double cast. +- */ +-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +- +-/* Enter a start condition. This macro really ought to take a parameter, +- * but we do it the disgusting crufty way forced on us by the ()-less +- * definition of BEGIN. +- */ +-#define BEGIN (yy_start) = 1 + 2 * +- +-/* Translate the current start state into a value that can be later handed +- * to BEGIN to return to the state. The YYSTATE alias is for lex +- * compatibility. +- */ +-#define YY_START (((yy_start) - 1) / 2) +-#define YYSTATE YY_START +- +-/* Action number for EOF rule of a given start state. */ +-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +- +-/* Special action meaning "start processing a new file". */ +-#define YY_NEW_FILE yyrestart(yyin ) +- +-#define YY_END_OF_BUFFER_CHAR 0 +- +-/* Size of default input buffer. */ +-#ifndef YY_BUF_SIZE +-#define YY_BUF_SIZE 16384 +-#endif +- +-/* The state buf must be large enough to hold one state per character in the main buffer. +- */ +-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) +- +-#ifndef YY_TYPEDEF_YY_BUFFER_STATE +-#define YY_TYPEDEF_YY_BUFFER_STATE +-typedef struct yy_buffer_state *YY_BUFFER_STATE; +-#endif +- +-#ifndef YY_TYPEDEF_YY_SIZE_T +-#define YY_TYPEDEF_YY_SIZE_T +-typedef size_t yy_size_t; +-#endif +- +-extern yy_size_t yyleng; +- +-extern FILE *yyin, *yyout; +- +-#define EOB_ACT_CONTINUE_SCAN 0 +-#define EOB_ACT_END_OF_FILE 1 +-#define EOB_ACT_LAST_MATCH 2 +- +- #define YY_LESS_LINENO(n) +- +-/* Return all but the first "n" matched characters back to the input stream. */ +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up yytext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- *yy_cp = (yy_hold_char); \ +- YY_RESTORE_YY_MORE_OFFSET \ +- (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ +- YY_DO_BEFORE_ACTION; /* set up yytext again */ \ +- } \ +- while ( 0 ) +- +-#define unput(c) yyunput( c, (yytext_ptr) ) +- +-#ifndef YY_STRUCT_YY_BUFFER_STATE +-#define YY_STRUCT_YY_BUFFER_STATE +-struct yy_buffer_state +- { +- FILE *yy_input_file; +- +- char *yy_ch_buf; /* input buffer */ +- char *yy_buf_pos; /* current position in input buffer */ +- +- /* Size of input buffer in bytes, not including room for EOB +- * characters. +- */ +- yy_size_t yy_buf_size; +- +- /* Number of characters read into yy_ch_buf, not including EOB +- * characters. +- */ +- yy_size_t yy_n_chars; +- +- /* Whether we "own" the buffer - i.e., we know we created it, +- * and can realloc() it to grow it, and should free() it to +- * delete it. +- */ +- int yy_is_our_buffer; +- +- /* Whether this is an "interactive" input source; if so, and +- * if we're using stdio for input, then we want to use getc() +- * instead of fread(), to make sure we stop fetching input after +- * each newline. +- */ +- int yy_is_interactive; +- +- /* Whether we're considered to be at the beginning of a line. +- * If so, '^' rules will be active on the next match, otherwise +- * not. +- */ +- int yy_at_bol; +- +- int yy_bs_lineno; /**< The line count. */ +- int yy_bs_column; /**< The column count. */ +- +- /* Whether to try to fill the input buffer when we reach the +- * end of it. +- */ +- int yy_fill_buffer; +- +- int yy_buffer_status; +- +-#define YY_BUFFER_NEW 0 +-#define YY_BUFFER_NORMAL 1 +- /* When an EOF's been seen but there's still some text to process +- * then we mark the buffer as YY_EOF_PENDING, to indicate that we +- * shouldn't try reading from the input source any more. We might +- * still have a bunch of tokens to match, though, because of +- * possible backing-up. +- * +- * When we actually see the EOF, we change the status to "new" +- * (via yyrestart()), so that the user can continue scanning by +- * just pointing yyin at a new input file. +- */ +-#define YY_BUFFER_EOF_PENDING 2 +- +- }; +-#endif /* !YY_STRUCT_YY_BUFFER_STATE */ +- +-/* Stack of input buffers. */ +-static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +-static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +-static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ +- +-/* We provide macros for accessing buffer states in case in the +- * future we want to put the buffer states in a more general +- * "scanner state". +- * +- * Returns the top of the stack, or NULL. +- */ +-#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ +- ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ +- : NULL) +- +-/* Same as previous macro, but useful when we know that the buffer stack is not +- * NULL or when we need an lvalue. For internal use only. +- */ +-#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] +- +-/* yy_hold_char holds the character lost when yytext is formed. */ +-static char yy_hold_char; +-static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +-yy_size_t yyleng; +- +-/* Points to current character in buffer. */ +-static char *yy_c_buf_p = (char *) 0; +-static int yy_init = 0; /* whether we need to initialize */ +-static int yy_start = 0; /* start state number */ +- +-/* Flag which is used to allow yywrap()'s to do buffer switches +- * instead of setting up a fresh yyin. A bit of a hack ... +- */ +-static int yy_did_buffer_switch_on_eof; +- +-void yyrestart (FILE *input_file ); +-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +-void yy_delete_buffer (YY_BUFFER_STATE b ); +-void yy_flush_buffer (YY_BUFFER_STATE b ); +-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +-void yypop_buffer_state (void ); +- +-static void yyensure_buffer_stack (void ); +-static void yy_load_buffer_state (void ); +-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); +- +-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) +- +-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); +- +-void *yyalloc (yy_size_t ); +-void *yyrealloc (void *,yy_size_t ); +-void yyfree (void * ); +- +-#define yy_new_buffer yy_create_buffer +- +-#define yy_set_interactive(is_interactive) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){ \ +- yyensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- yy_create_buffer(yyin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ +- } +- +-#define yy_set_bol(at_bol) \ +- { \ +- if ( ! YY_CURRENT_BUFFER ){\ +- yyensure_buffer_stack (); \ +- YY_CURRENT_BUFFER_LVALUE = \ +- yy_create_buffer(yyin,YY_BUF_SIZE ); \ +- } \ +- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ +- } +- +-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) +- +-typedef unsigned char YY_CHAR; +- +-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +- +-typedef int yy_state_type; +- +-extern int yylineno; +- +-int yylineno = 1; +- +-extern char *yytext; +-#define yytext_ptr yytext +- +-static yy_state_type yy_get_previous_state (void ); +-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +-static int yy_get_next_buffer (void ); +-static void yy_fatal_error (yyconst char msg[] ); +- +-/* Done after the current pattern has been matched and before the +- * corresponding action - sets up yytext. +- */ +-#define YY_DO_BEFORE_ACTION \ +- (yytext_ptr) = yy_bp; \ +- yyleng = (yy_size_t) (yy_cp - yy_bp); \ +- (yy_hold_char) = *yy_cp; \ +- *yy_cp = '\0'; \ +- (yy_c_buf_p) = yy_cp; +- +-#define YY_NUM_RULES 25 +-#define YY_END_OF_BUFFER 26 +-/* This struct is not used in this scanner, +- but its presence is necessary. */ +-struct yy_trans_info +- { +- flex_int32_t yy_verify; +- flex_int32_t yy_nxt; +- }; +-static yyconst flex_int16_t yy_accept[81] = +- { 0, +- 0, 0, 26, 25, 7, 8, 5, 25, 1, 2, +- 11, 11, 6, 3, 4, 25, 25, 25, 25, 25, +- 25, 25, 0, 9, 11, 0, 6, 0, 0, 0, +- 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, +- 13, 0, 0, 0, 0, 16, 0, 0, 0, 0, +- 0, 12, 15, 0, 23, 0, 0, 0, 0, 0, +- 0, 14, 18, 0, 0, 0, 0, 0, 17, 0, +- 24, 0, 0, 0, 20, 22, 0, 21, 19, 0 +- } ; +- +-static yyconst flex_int32_t yy_ec[256] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 4, 1, 5, 1, 1, 1, 1, 1, 6, +- 7, 1, 1, 1, 1, 1, 1, 8, 9, 9, +- 9, 9, 9, 9, 9, 9, 9, 1, 10, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 11, 1, 12, 1, 1, 1, 13, 14, 15, 16, +- +- 17, 18, 19, 20, 21, 1, 1, 22, 1, 23, +- 24, 25, 1, 26, 27, 28, 29, 30, 1, 31, +- 32, 33, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1 +- } ; +- +-static yyconst flex_int32_t yy_meta[34] = +- { 0, +- 1, 1, 2, 1, 1, 1, 1, 3, 3, 1, +- 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1 +- } ; +- +-static yyconst flex_int16_t yy_base[84] = +- { 0, +- 0, 0, 100, 101, 101, 101, 101, 94, 101, 101, +- 26, 28, 0, 101, 101, 82, 26, 18, 74, 79, +- 78, 81, 88, 101, 32, 0, 0, 76, 65, 62, +- 61, 75, 20, 59, 61, 66, 58, 0, 57, 56, +- 54, 63, 53, 62, 54, 101, 59, 48, 53, 46, +- 59, 101, 44, 43, 101, 41, 55, 46, 53, 44, +- 31, 101, 101, 39, 27, 21, 39, 19, 101, 35, +- 101, 33, 26, 29, 101, 101, 28, 101, 101, 101, +- 58, 61, 41 +- } ; +- +-static yyconst flex_int16_t yy_def[84] = +- { 0, +- 80, 1, 80, 80, 80, 80, 80, 81, 80, 80, +- 80, 80, 82, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 81, 80, 80, 83, 82, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 83, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, +- 80, 80, 80 +- } ; +- +-static yyconst flex_int16_t yy_nxt[135] = +- { 0, +- 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, +- 14, 15, 16, 17, 18, 4, 4, 4, 4, 4, +- 19, 4, 4, 4, 4, 20, 21, 4, 4, 22, +- 4, 4, 4, 25, 25, 25, 25, 32, 29, 25, +- 25, 33, 44, 38, 79, 78, 30, 77, 45, 76, +- 75, 74, 73, 72, 71, 70, 26, 31, 23, 23, +- 23, 27, 69, 27, 68, 67, 66, 65, 64, 63, +- 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, +- 52, 51, 50, 49, 48, 47, 46, 43, 42, 41, +- 40, 39, 24, 37, 36, 35, 34, 28, 24, 80, +- +- 3, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80 +- } ; +- +-static yyconst flex_int16_t yy_chk[135] = +- { 0, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +- 1, 1, 1, 11, 11, 12, 12, 18, 17, 25, +- 25, 18, 33, 83, 77, 74, 17, 73, 33, 72, +- 70, 68, 67, 66, 65, 64, 11, 17, 81, 81, +- 81, 82, 61, 82, 60, 59, 58, 57, 56, 54, +- 53, 51, 50, 49, 48, 47, 45, 44, 43, 42, +- 41, 40, 39, 37, 36, 35, 34, 32, 31, 30, +- 29, 28, 23, 22, 21, 20, 19, 16, 8, 3, +- +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, +- 80, 80, 80, 80 +- } ; +- +-static yy_state_type yy_last_accepting_state; +-static char *yy_last_accepting_cpos; +- +-extern int yy_flex_debug; +-int yy_flex_debug = 0; +- +-/* The intent behind this definition is that it'll catch +- * any uses of REJECT which flex missed. +- */ +-#define REJECT reject_used_but_not_detected +-#define yymore() yymore_used_but_not_detected +-#define YY_MORE_ADJ 0 +-#define YY_RESTORE_YY_MORE_OFFSET +-char *yytext; +-#line 1 "syslex.l" +-#define YY_NO_INPUT 1 +-#line 4 "syslex.l" +-/* Copyright 2001, 2003, 2005, 2007, 2011, 2012 Free Software Foundation, Inc. +- +- This file is part of GNU Binutils. +- +- 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 3, 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 GLD; see the file COPYING. If not, write to the Free +- Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA +- 02110-1301, USA. */ +- +-/* Note: config.h is #included via syslex_wrap.c. */ +- +-#ifdef HAVE_STRING_H +-#include +-#else +-#ifdef HAVE_STRINGS_H +-#include +-#endif +-#endif +- +-#include "sysinfo.h" +- +-#ifndef YY_NO_UNPUT +-#define YY_NO_UNPUT +-#endif +- +-#ifndef yywrap +-static int yywrap (void) { return 1; } +-#endif +- +-extern int yylex (void); +-#line 544 "syslex.c" +- +-#define INITIAL 0 +- +-#ifndef YY_NO_UNISTD_H +-/* Special case for "unistd.h", since it is non-ANSI. We include it way +- * down here because we want the user's section 1 to have been scanned first. +- * The user has a chance to override it with an option. +- */ +-#include +-#endif +- +-#ifndef YY_EXTRA_TYPE +-#define YY_EXTRA_TYPE void * +-#endif +- +-static int yy_init_globals (void ); +- +-/* Accessor methods to globals. +- These are made visible to non-reentrant scanners for convenience. */ +- +-int yylex_destroy (void ); +- +-int yyget_debug (void ); +- +-void yyset_debug (int debug_flag ); +- +-YY_EXTRA_TYPE yyget_extra (void ); +- +-void yyset_extra (YY_EXTRA_TYPE user_defined ); +- +-FILE *yyget_in (void ); +- +-void yyset_in (FILE * in_str ); +- +-FILE *yyget_out (void ); +- +-void yyset_out (FILE * out_str ); +- +-yy_size_t yyget_leng (void ); +- +-char *yyget_text (void ); +- +-int yyget_lineno (void ); +- +-void yyset_lineno (int line_number ); +- +-/* Macros after this point can all be overridden by user definitions in +- * section 1. +- */ +- +-#ifndef YY_SKIP_YYWRAP +-#ifdef __cplusplus +-extern "C" int yywrap (void ); +-#else +-extern int yywrap (void ); +-#endif +-#endif +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char *,yyconst char *,int ); +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * ); +-#endif +- +-#ifndef YY_NO_INPUT +- +-#ifdef __cplusplus +-static int yyinput (void ); +-#else +-static int input (void ); +-#endif +- +-#endif +- +-/* Amount of stuff to slurp up with each read. */ +-#ifndef YY_READ_BUF_SIZE +-#define YY_READ_BUF_SIZE 8192 +-#endif +- +-/* Copy whatever the last rule matched to the standard output. */ +-#ifndef ECHO +-/* This used to be an fputs(), but since the string might contain NUL's, +- * we now use fwrite(). +- */ +-#define ECHO fwrite( yytext, yyleng, 1, yyout ) +-#endif +- +-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, +- * is returned in "result". +- */ +-#ifndef YY_INPUT +-#define YY_INPUT(buf,result,max_size) \ +- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ +- { \ +- int c = '*'; \ +- yy_size_t n; \ +- for ( n = 0; n < max_size && \ +- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ +- buf[n] = (char) c; \ +- if ( c == '\n' ) \ +- buf[n++] = (char) c; \ +- if ( c == EOF && ferror( yyin ) ) \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- result = n; \ +- } \ +- else \ +- { \ +- errno=0; \ +- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ +- { \ +- if( errno != EINTR) \ +- { \ +- YY_FATAL_ERROR( "input in flex scanner failed" ); \ +- break; \ +- } \ +- errno=0; \ +- clearerr(yyin); \ +- } \ +- }\ +-\ +- +-#endif +- +-/* No semi-colon after return; correct usage is to write "yyterminate();" - +- * we don't want an extra ';' after the "return" because that will cause +- * some compilers to complain about unreachable statements. +- */ +-#ifndef yyterminate +-#define yyterminate() return YY_NULL +-#endif +- +-/* Number of entries by which start-condition stack grows. */ +-#ifndef YY_START_STACK_INCR +-#define YY_START_STACK_INCR 25 +-#endif +- +-/* Report a fatal error. */ +-#ifndef YY_FATAL_ERROR +-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +-#endif +- +-/* end tables serialization structures and prototypes */ +- +-/* Default declaration of generated scanner - a define so the user can +- * easily add parameters. +- */ +-#ifndef YY_DECL +-#define YY_DECL_IS_OURS 1 +- +-extern int yylex (void); +- +-#define YY_DECL int yylex (void) +-#endif /* !YY_DECL */ +- +-/* Code executed at the beginning of each rule, after yytext and yyleng +- * have been set up. +- */ +-#ifndef YY_USER_ACTION +-#define YY_USER_ACTION +-#endif +- +-/* Code executed at the end of each rule. */ +-#ifndef YY_BREAK +-#define YY_BREAK break; +-#endif +- +-#define YY_RULE_SETUP \ +- YY_USER_ACTION +- +-/** The main scanner function which does all the work. +- */ +-YY_DECL +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp, *yy_bp; +- register int yy_act; +- +-#line 45 "syslex.l" +- +-#line 726 "syslex.c" +- +- if ( !(yy_init) ) +- { +- (yy_init) = 1; +- +-#ifdef YY_USER_INIT +- YY_USER_INIT; +-#endif +- +- if ( ! (yy_start) ) +- (yy_start) = 1; /* first start state */ +- +- if ( ! yyin ) +- yyin = stdin; +- +- if ( ! yyout ) +- yyout = stdout; +- +- if ( ! YY_CURRENT_BUFFER ) { +- yyensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- yy_create_buffer(yyin,YY_BUF_SIZE ); +- } +- +- yy_load_buffer_state( ); +- } +- +- while ( 1 ) /* loops until end-of-file is reached */ +- { +- yy_cp = (yy_c_buf_p); +- +- /* Support of yytext. */ +- *yy_cp = (yy_hold_char); +- +- /* yy_bp points to the position in yy_ch_buf of the start of +- * the current run. +- */ +- yy_bp = yy_cp; +- +- yy_current_state = (yy_start); +-yy_match: +- do +- { +- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 81 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- ++yy_cp; +- } +- while ( yy_base[yy_current_state] != 101 ); +- +-yy_find_action: +- yy_act = yy_accept[yy_current_state]; +- if ( yy_act == 0 ) +- { /* have to back up */ +- yy_cp = (yy_last_accepting_cpos); +- yy_current_state = (yy_last_accepting_state); +- yy_act = yy_accept[yy_current_state]; +- } +- +- YY_DO_BEFORE_ACTION; +- +-do_action: /* This label is used only to access EOF actions. */ +- +- switch ( yy_act ) +- { /* beginning of action switch */ +- case 0: /* must back up */ +- /* undo the effects of YY_DO_BEFORE_ACTION */ +- *yy_cp = (yy_hold_char); +- yy_cp = (yy_last_accepting_cpos); +- yy_current_state = (yy_last_accepting_state); +- goto yy_find_action; +- +-case 1: +-YY_RULE_SETUP +-#line 46 "syslex.l" +-{ return '(';} +- YY_BREAK +-case 2: +-YY_RULE_SETUP +-#line 47 "syslex.l" +-{ return ')';} +- YY_BREAK +-case 3: +-YY_RULE_SETUP +-#line 48 "syslex.l" +-{ return '[';} +- YY_BREAK +-case 4: +-YY_RULE_SETUP +-#line 49 "syslex.l" +-{ return ']';} +- YY_BREAK +-case 5: +-YY_RULE_SETUP +-#line 50 "syslex.l" +-{ ; } +- YY_BREAK +-case 6: +-YY_RULE_SETUP +-#line 51 "syslex.l" +-{ ; } +- YY_BREAK +-case 7: +-YY_RULE_SETUP +-#line 52 "syslex.l" +-{ ; } +- YY_BREAK +-case 8: +-/* rule 8 can match eol */ +-YY_RULE_SETUP +-#line 53 "syslex.l" +-{ ; } +- YY_BREAK +-case 9: +-/* rule 9 can match eol */ +-YY_RULE_SETUP +-#line 54 "syslex.l" +-{ +- yylval.s = malloc (yyleng - 1); +- memcpy (yylval.s, yytext + 1, yyleng - 2); +- yylval.s[yyleng - 2] = '\0'; +- return NAME; +- } +- YY_BREAK +-case 10: +-YY_RULE_SETUP +-#line 61 "syslex.l" +-{ +- yylval.i = strtol(yytext,0,16); +- return NUMBER; +- } +- YY_BREAK +-case 11: +-YY_RULE_SETUP +-#line 66 "syslex.l" +-{ +- yylval.i = atoi(yytext); +- return NUMBER; +- } +- YY_BREAK +-case 12: +-YY_RULE_SETUP +-#line 72 "syslex.l" +-{ yylval.i =1 ;return UNIT;} +- YY_BREAK +-case 13: +-YY_RULE_SETUP +-#line 73 "syslex.l" +-{ yylval.i = 1; return UNIT;} +- YY_BREAK +-case 14: +-YY_RULE_SETUP +-#line 74 "syslex.l" +-{ yylval.i= 8; return UNIT;} +- YY_BREAK +-case 15: +-YY_RULE_SETUP +-#line 75 "syslex.l" +-{ yylval.i = 8; return UNIT;} +- YY_BREAK +-case 16: +-YY_RULE_SETUP +-#line 77 "syslex.l" +-{ yylval.s = "INT"; return TYPE;} +- YY_BREAK +-case 17: +-YY_RULE_SETUP +-#line 78 "syslex.l" +-{ yylval.s = "BARRAY"; return TYPE;} +- YY_BREAK +-case 18: +-YY_RULE_SETUP +-#line 79 "syslex.l" +-{ yylval.s = "CHARS"; return TYPE;} +- YY_BREAK +-case 19: +-YY_RULE_SETUP +-#line 80 "syslex.l" +-{ yylval.i = 0; return NUMBER;} +- YY_BREAK +-case 20: +-YY_RULE_SETUP +-#line 81 "syslex.l" +-{ yylval.i = -4; return NUMBER;} +- YY_BREAK +-case 21: +-YY_RULE_SETUP +-#line 82 "syslex.l" +-{ yylval.i = -2; return NUMBER; } +- YY_BREAK +-case 22: +-YY_RULE_SETUP +-#line 83 "syslex.l" +-{ yylval.i = -1; return NUMBER; } +- YY_BREAK +-case 23: +-YY_RULE_SETUP +-#line 84 "syslex.l" +-{ return COND;} +- YY_BREAK +-case 24: +-YY_RULE_SETUP +-#line 85 "syslex.l" +-{ return REPEAT;} +- YY_BREAK +-case 25: +-YY_RULE_SETUP +-#line 86 "syslex.l" +-ECHO; +- YY_BREAK +-#line 947 "syslex.c" +-case YY_STATE_EOF(INITIAL): +- yyterminate(); +- +- case YY_END_OF_BUFFER: +- { +- /* Amount of text matched not including the EOB char. */ +- int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; +- +- /* Undo the effects of YY_DO_BEFORE_ACTION. */ +- *yy_cp = (yy_hold_char); +- YY_RESTORE_YY_MORE_OFFSET +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) +- { +- /* We're scanning a new file or input source. It's +- * possible that this happened because the user +- * just pointed yyin at a new source and called +- * yylex(). If so, then we have to assure +- * consistency between YY_CURRENT_BUFFER and our +- * globals. Here is the right place to do so, because +- * this is the first action (other than possibly a +- * back-up) that will match for the new input source. +- */ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; +- } +- +- /* Note that here we test for yy_c_buf_p "<=" to the position +- * of the first EOB in the buffer, since yy_c_buf_p will +- * already have been incremented past the NUL character +- * (since all states make transitions on EOB to the +- * end-of-buffer state). Contrast this with the test +- * in input(). +- */ +- if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- { /* This was really a NUL. */ +- yy_state_type yy_next_state; +- +- (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- /* Okay, we're now positioned to make the NUL +- * transition. We couldn't have +- * yy_get_previous_state() go ahead and do it +- * for us because it doesn't know how to deal +- * with the possibility of jamming (and we don't +- * want to build jamming into it because then it +- * will run more slowly). +- */ +- +- yy_next_state = yy_try_NUL_trans( yy_current_state ); +- +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- +- if ( yy_next_state ) +- { +- /* Consume the NUL. */ +- yy_cp = ++(yy_c_buf_p); +- yy_current_state = yy_next_state; +- goto yy_match; +- } +- +- else +- { +- yy_cp = (yy_c_buf_p); +- goto yy_find_action; +- } +- } +- +- else switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_END_OF_FILE: +- { +- (yy_did_buffer_switch_on_eof) = 0; +- +- if ( yywrap( ) ) +- { +- /* Note: because we've taken care in +- * yy_get_next_buffer() to have set up +- * yytext, we can now set up +- * yy_c_buf_p so that if some total +- * hoser (like flex itself) wants to +- * call the scanner after we return the +- * YY_NULL, it'll still work - another +- * YY_NULL will get returned. +- */ +- (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; +- +- yy_act = YY_STATE_EOF(YY_START); +- goto do_action; +- } +- +- else +- { +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +- } +- break; +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = +- (yytext_ptr) + yy_amount_of_matched_text; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_match; +- +- case EOB_ACT_LAST_MATCH: +- (yy_c_buf_p) = +- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; +- +- yy_current_state = yy_get_previous_state( ); +- +- yy_cp = (yy_c_buf_p); +- yy_bp = (yytext_ptr) + YY_MORE_ADJ; +- goto yy_find_action; +- } +- break; +- } +- +- default: +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--no action found" ); +- } /* end of action switch */ +- } /* end of scanning one token */ +-} /* end of yylex */ +- +-/* yy_get_next_buffer - try to read in a new buffer +- * +- * Returns a code representing an action: +- * EOB_ACT_LAST_MATCH - +- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position +- * EOB_ACT_END_OF_FILE - end of file +- */ +-static int yy_get_next_buffer (void) +-{ +- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; +- register char *source = (yytext_ptr); +- register int number_to_move, i; +- int ret_val; +- +- if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) +- YY_FATAL_ERROR( +- "fatal flex scanner internal error--end of buffer missed" ); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) +- { /* Don't try to fill the buffer, so this is an EOF. */ +- if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) +- { +- /* We matched a single character, the EOB, so +- * treat this as a final EOF. +- */ +- return EOB_ACT_END_OF_FILE; +- } +- +- else +- { +- /* We matched some text prior to the EOB, first +- * process it. +- */ +- return EOB_ACT_LAST_MATCH; +- } +- } +- +- /* Try to read more data. */ +- +- /* First move last chars to start of buffer. */ +- number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; +- +- for ( i = 0; i < number_to_move; ++i ) +- *(dest++) = *(source++); +- +- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) +- /* don't do the read, it's not guaranteed to return an EOF, +- * just force an EOF +- */ +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; +- +- else +- { +- yy_size_t num_to_read = +- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; +- +- while ( num_to_read <= 0 ) +- { /* Not enough room in the buffer - grow it. */ +- +- /* just a shorter name for the current buffer */ +- YY_BUFFER_STATE b = YY_CURRENT_BUFFER; +- +- int yy_c_buf_p_offset = +- (int) ((yy_c_buf_p) - b->yy_ch_buf); +- +- if ( b->yy_is_our_buffer ) +- { +- yy_size_t new_size = b->yy_buf_size * 2; +- +- if ( new_size <= 0 ) +- b->yy_buf_size += b->yy_buf_size / 8; +- else +- b->yy_buf_size *= 2; +- +- b->yy_ch_buf = (char *) +- /* Include room in for 2 EOB chars. */ +- yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); +- } +- else +- /* Can't grow it, we don't own it. */ +- b->yy_ch_buf = 0; +- +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( +- "fatal error - scanner input buffer overflow" ); +- +- (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; +- +- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - +- number_to_move - 1; +- +- } +- +- if ( num_to_read > YY_READ_BUF_SIZE ) +- num_to_read = YY_READ_BUF_SIZE; +- +- /* Read in more data. */ +- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), +- (yy_n_chars), num_to_read ); +- +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- if ( (yy_n_chars) == 0 ) +- { +- if ( number_to_move == YY_MORE_ADJ ) +- { +- ret_val = EOB_ACT_END_OF_FILE; +- yyrestart(yyin ); +- } +- +- else +- { +- ret_val = EOB_ACT_LAST_MATCH; +- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = +- YY_BUFFER_EOF_PENDING; +- } +- } +- +- else +- ret_val = EOB_ACT_CONTINUE_SCAN; +- +- if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { +- /* Extend the array by 50%, plus the number we really need. */ +- yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); +- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); +- } +- +- (yy_n_chars) += number_to_move; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; +- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; +- +- (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; +- +- return ret_val; +-} +- +-/* yy_get_previous_state - get the state just before the EOB char was reached */ +- +- static yy_state_type yy_get_previous_state (void) +-{ +- register yy_state_type yy_current_state; +- register char *yy_cp; +- +- yy_current_state = (yy_start); +- +- for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) +- { +- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 81 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- } +- +- return yy_current_state; +-} +- +-/* yy_try_NUL_trans - try to make a transition on the NUL character +- * +- * synopsis +- * next_state = yy_try_NUL_trans( current_state ); +- */ +- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +-{ +- register int yy_is_jam; +- register char *yy_cp = (yy_c_buf_p); +- +- register YY_CHAR yy_c = 1; +- if ( yy_accept[yy_current_state] ) +- { +- (yy_last_accepting_state) = yy_current_state; +- (yy_last_accepting_cpos) = yy_cp; +- } +- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) +- { +- yy_current_state = (int) yy_def[yy_current_state]; +- if ( yy_current_state >= 81 ) +- yy_c = yy_meta[(unsigned int) yy_c]; +- } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; +- yy_is_jam = (yy_current_state == 80); +- +- return yy_is_jam ? 0 : yy_current_state; +-} +- +-#ifndef YY_NO_INPUT +-#ifdef __cplusplus +- static int yyinput (void) +-#else +- static int input (void) +-#endif +- +-{ +- int c; +- +- *(yy_c_buf_p) = (yy_hold_char); +- +- if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) +- { +- /* yy_c_buf_p now points to the character we want to return. +- * If this occurs *before* the EOB characters, then it's a +- * valid NUL; if not, then we've hit the end of the buffer. +- */ +- if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) +- /* This was really a NUL. */ +- *(yy_c_buf_p) = '\0'; +- +- else +- { /* need more input */ +- yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); +- ++(yy_c_buf_p); +- +- switch ( yy_get_next_buffer( ) ) +- { +- case EOB_ACT_LAST_MATCH: +- /* This happens because yy_g_n_b() +- * sees that we've accumulated a +- * token and flags that we need to +- * try matching the token before +- * proceeding. But for input(), +- * there's no matching to consider. +- * So convert the EOB_ACT_LAST_MATCH +- * to EOB_ACT_END_OF_FILE. +- */ +- +- /* Reset buffer status. */ +- yyrestart(yyin ); +- +- /*FALLTHROUGH*/ +- +- case EOB_ACT_END_OF_FILE: +- { +- if ( yywrap( ) ) +- return 0; +- +- if ( ! (yy_did_buffer_switch_on_eof) ) +- YY_NEW_FILE; +-#ifdef __cplusplus +- return yyinput(); +-#else +- return input(); +-#endif +- } +- +- case EOB_ACT_CONTINUE_SCAN: +- (yy_c_buf_p) = (yytext_ptr) + offset; +- break; +- } +- } +- } +- +- c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ +- *(yy_c_buf_p) = '\0'; /* preserve yytext */ +- (yy_hold_char) = *++(yy_c_buf_p); +- +- return c; +-} +-#endif /* ifndef YY_NO_INPUT */ +- +-/** Immediately switch to a different input stream. +- * @param input_file A readable stream. +- * +- * @note This function does not reset the start condition to @c INITIAL . +- */ +- void yyrestart (FILE * input_file ) +-{ +- +- if ( ! YY_CURRENT_BUFFER ){ +- yyensure_buffer_stack (); +- YY_CURRENT_BUFFER_LVALUE = +- yy_create_buffer(yyin,YY_BUF_SIZE ); +- } +- +- yy_init_buffer(YY_CURRENT_BUFFER,input_file ); +- yy_load_buffer_state( ); +-} +- +-/** Switch to a different input buffer. +- * @param new_buffer The new input buffer. +- * +- */ +- void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +-{ +- +- /* TODO. We should be able to replace this entire function body +- * with +- * yypop_buffer_state(); +- * yypush_buffer_state(new_buffer); +- */ +- yyensure_buffer_stack (); +- if ( YY_CURRENT_BUFFER == new_buffer ) +- return; +- +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- yy_load_buffer_state( ); +- +- /* We don't actually know whether we did this switch during +- * EOF (yywrap()) processing, but the only time this flag +- * is looked at is after yywrap() is called, so it's safe +- * to go ahead and always set it. +- */ +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-static void yy_load_buffer_state (void) +-{ +- (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; +- (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; +- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; +- (yy_hold_char) = *(yy_c_buf_p); +-} +- +-/** Allocate and initialize an input buffer state. +- * @param file A readable stream. +- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. +- * +- * @return the allocated buffer state. +- */ +- YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +-{ +- YY_BUFFER_STATE b; +- +- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); +- +- b->yy_buf_size = size; +- +- /* yy_ch_buf has to be 2 characters longer than the size given because +- * we need to put in 2 end-of-buffer characters. +- */ +- b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); +- if ( ! b->yy_ch_buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); +- +- b->yy_is_our_buffer = 1; +- +- yy_init_buffer(b,file ); +- +- return b; +-} +- +-/** Destroy the buffer. +- * @param b a buffer created with yy_create_buffer() +- * +- */ +- void yy_delete_buffer (YY_BUFFER_STATE b ) +-{ +- +- if ( ! b ) +- return; +- +- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ +- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; +- +- if ( b->yy_is_our_buffer ) +- yyfree((void *) b->yy_ch_buf ); +- +- yyfree((void *) b ); +-} +- +-#ifndef __cplusplus +-extern int isatty (int ); +-#endif /* __cplusplus */ +- +-/* Initializes or reinitializes a buffer. +- * This function is sometimes called more than once on the same buffer, +- * such as during a yyrestart() or at EOF. +- */ +- static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) +- +-{ +- int oerrno = errno; +- +- yy_flush_buffer(b ); +- +- b->yy_input_file = file; +- b->yy_fill_buffer = 1; +- +- /* If b is the current buffer, then yy_init_buffer was _probably_ +- * called from yyrestart() or through yy_get_next_buffer. +- * In that case, we don't want to reset the lineno or column. +- */ +- if (b != YY_CURRENT_BUFFER){ +- b->yy_bs_lineno = 1; +- b->yy_bs_column = 0; +- } +- +- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +- +- errno = oerrno; +-} +- +-/** Discard all buffered characters. On the next scan, YY_INPUT will be called. +- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. +- * +- */ +- void yy_flush_buffer (YY_BUFFER_STATE b ) +-{ +- if ( ! b ) +- return; +- +- b->yy_n_chars = 0; +- +- /* We always need two end-of-buffer characters. The first causes +- * a transition to the end-of-buffer state. The second causes +- * a jam in that state. +- */ +- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; +- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; +- +- b->yy_buf_pos = &b->yy_ch_buf[0]; +- +- b->yy_at_bol = 1; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- if ( b == YY_CURRENT_BUFFER ) +- yy_load_buffer_state( ); +-} +- +-/** Pushes the new state onto the stack. The new state becomes +- * the current state. This function will allocate the stack +- * if necessary. +- * @param new_buffer The new state. +- * +- */ +-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +-{ +- if (new_buffer == NULL) +- return; +- +- yyensure_buffer_stack(); +- +- /* This block is copied from yy_switch_to_buffer. */ +- if ( YY_CURRENT_BUFFER ) +- { +- /* Flush out information for old buffer. */ +- *(yy_c_buf_p) = (yy_hold_char); +- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); +- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); +- } +- +- /* Only push if top exists. Otherwise, replace top. */ +- if (YY_CURRENT_BUFFER) +- (yy_buffer_stack_top)++; +- YY_CURRENT_BUFFER_LVALUE = new_buffer; +- +- /* copied from yy_switch_to_buffer. */ +- yy_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +-} +- +-/** Removes and deletes the top of the stack, if present. +- * The next element becomes the new top. +- * +- */ +-void yypop_buffer_state (void) +-{ +- if (!YY_CURRENT_BUFFER) +- return; +- +- yy_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- if ((yy_buffer_stack_top) > 0) +- --(yy_buffer_stack_top); +- +- if (YY_CURRENT_BUFFER) { +- yy_load_buffer_state( ); +- (yy_did_buffer_switch_on_eof) = 1; +- } +-} +- +-/* Allocates the stack if it does not exist. +- * Guarantees space for at least one push. +- */ +-static void yyensure_buffer_stack (void) +-{ +- yy_size_t num_to_alloc; +- +- if (!(yy_buffer_stack)) { +- +- /* First allocation is just for 2 elements, since we don't know if this +- * scanner will even need a stack. We use 2 instead of 1 to avoid an +- * immediate realloc on the next call. +- */ +- num_to_alloc = 1; +- (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc +- (num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- +- memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); +- +- (yy_buffer_stack_max) = num_to_alloc; +- (yy_buffer_stack_top) = 0; +- return; +- } +- +- if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ +- +- /* Increase the buffer to prepare for a possible push. */ +- int grow_size = 8 /* arbitrary grow size */; +- +- num_to_alloc = (yy_buffer_stack_max) + grow_size; +- (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc +- ((yy_buffer_stack), +- num_to_alloc * sizeof(struct yy_buffer_state*) +- ); +- if ( ! (yy_buffer_stack) ) +- YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- +- /* zero only the new slots.*/ +- memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); +- (yy_buffer_stack_max) = num_to_alloc; +- } +-} +- +-/** Setup the input buffer state to scan directly from a user-specified character buffer. +- * @param base the character buffer +- * @param size the size in bytes of the character buffer +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +-{ +- YY_BUFFER_STATE b; +- +- if ( size < 2 || +- base[size-2] != YY_END_OF_BUFFER_CHAR || +- base[size-1] != YY_END_OF_BUFFER_CHAR ) +- /* They forgot to leave room for the EOB's. */ +- return 0; +- +- b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); +- if ( ! b ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); +- +- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ +- b->yy_buf_pos = b->yy_ch_buf = base; +- b->yy_is_our_buffer = 0; +- b->yy_input_file = 0; +- b->yy_n_chars = b->yy_buf_size; +- b->yy_is_interactive = 0; +- b->yy_at_bol = 1; +- b->yy_fill_buffer = 0; +- b->yy_buffer_status = YY_BUFFER_NEW; +- +- yy_switch_to_buffer(b ); +- +- return b; +-} +- +-/** Setup the input buffer state to scan a string. The next call to yylex() will +- * scan from a @e copy of @a str. +- * @param yystr a NUL-terminated string to scan +- * +- * @return the newly allocated buffer state object. +- * @note If you want to scan bytes that may contain NUL values, then use +- * yy_scan_bytes() instead. +- */ +-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +-{ +- +- return yy_scan_bytes(yystr,strlen(yystr) ); +-} +- +-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will +- * scan from a @e copy of @a bytes. +- * @param bytes the byte buffer to scan +- * @param len the number of bytes in the buffer pointed to by @a bytes. +- * +- * @return the newly allocated buffer state object. +- */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +-{ +- YY_BUFFER_STATE b; +- char *buf; +- yy_size_t n, i; +- +- /* Get memory for full buffer, including space for trailing EOB's. */ +- n = _yybytes_len + 2; +- buf = (char *) yyalloc(n ); +- if ( ! buf ) +- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); +- +- for ( i = 0; i < _yybytes_len; ++i ) +- buf[i] = yybytes[i]; +- +- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; +- +- b = yy_scan_buffer(buf,n ); +- if ( ! b ) +- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); +- +- /* It's okay to grow etc. this buffer, and we should throw it +- * away when we're done. +- */ +- b->yy_is_our_buffer = 1; +- +- return b; +-} +- +-#ifndef YY_EXIT_FAILURE +-#define YY_EXIT_FAILURE 2 +-#endif +- +-static void yy_fatal_error (yyconst char* msg ) +-{ +- (void) fprintf( stderr, "%s\n", msg ); +- exit( YY_EXIT_FAILURE ); +-} +- +-/* Redefine yyless() so it works in section 3 code. */ +- +-#undef yyless +-#define yyless(n) \ +- do \ +- { \ +- /* Undo effects of setting up yytext. */ \ +- int yyless_macro_arg = (n); \ +- YY_LESS_LINENO(yyless_macro_arg);\ +- yytext[yyleng] = (yy_hold_char); \ +- (yy_c_buf_p) = yytext + yyless_macro_arg; \ +- (yy_hold_char) = *(yy_c_buf_p); \ +- *(yy_c_buf_p) = '\0'; \ +- yyleng = yyless_macro_arg; \ +- } \ +- while ( 0 ) +- +-/* Accessor methods (get/set functions) to struct members. */ +- +-/** Get the current line number. +- * +- */ +-int yyget_lineno (void) +-{ +- +- return yylineno; +-} +- +-/** Get the input stream. +- * +- */ +-FILE *yyget_in (void) +-{ +- return yyin; +-} +- +-/** Get the output stream. +- * +- */ +-FILE *yyget_out (void) +-{ +- return yyout; +-} +- +-/** Get the length of the current token. +- * +- */ +-yy_size_t yyget_leng (void) +-{ +- return yyleng; +-} +- +-/** Get the current token. +- * +- */ +- +-char *yyget_text (void) +-{ +- return yytext; +-} +- +-/** Set the current line number. +- * @param line_number +- * +- */ +-void yyset_lineno (int line_number ) +-{ +- +- yylineno = line_number; +-} +- +-/** Set the input stream. This does not discard the current +- * input buffer. +- * @param in_str A readable stream. +- * +- * @see yy_switch_to_buffer +- */ +-void yyset_in (FILE * in_str ) +-{ +- yyin = in_str ; +-} +- +-void yyset_out (FILE * out_str ) +-{ +- yyout = out_str ; +-} +- +-int yyget_debug (void) +-{ +- return yy_flex_debug; +-} +- +-void yyset_debug (int bdebug ) +-{ +- yy_flex_debug = bdebug ; +-} +- +-static int yy_init_globals (void) +-{ +- /* Initialization is the same as for the non-reentrant scanner. +- * This function is called from yylex_destroy(), so don't allocate here. +- */ +- +- (yy_buffer_stack) = 0; +- (yy_buffer_stack_top) = 0; +- (yy_buffer_stack_max) = 0; +- (yy_c_buf_p) = (char *) 0; +- (yy_init) = 0; +- (yy_start) = 0; +- +-/* Defined in main.c */ +-#ifdef YY_STDINIT +- yyin = stdin; +- yyout = stdout; +-#else +- yyin = (FILE *) 0; +- yyout = (FILE *) 0; +-#endif +- +- /* For future reference: Set errno on error, since we are called by +- * yylex_init() +- */ +- return 0; +-} +- +-/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +-int yylex_destroy (void) +-{ +- +- /* Pop the buffer stack, destroying each element. */ +- while(YY_CURRENT_BUFFER){ +- yy_delete_buffer(YY_CURRENT_BUFFER ); +- YY_CURRENT_BUFFER_LVALUE = NULL; +- yypop_buffer_state(); +- } +- +- /* Destroy the stack itself. */ +- yyfree((yy_buffer_stack) ); +- (yy_buffer_stack) = NULL; +- +- /* Reset the globals. This is important in a non-reentrant scanner so the next time +- * yylex() is called, initialization will occur. */ +- yy_init_globals( ); +- +- return 0; +-} +- +-/* +- * Internal utility routines. +- */ +- +-#ifndef yytext_ptr +-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +-{ +- register int i; +- for ( i = 0; i < n; ++i ) +- s1[i] = s2[i]; +-} +-#endif +- +-#ifdef YY_NEED_STRLEN +-static int yy_flex_strlen (yyconst char * s ) +-{ +- register int n; +- for ( n = 0; s[n]; ++n ) +- ; +- +- return n; +-} +-#endif +- +-void *yyalloc (yy_size_t size ) +-{ +- return (void *) malloc( size ); +-} +- +-void *yyrealloc (void * ptr, yy_size_t size ) +-{ +- /* The cast to (char *) in the following accommodates both +- * implementations that use char* generic pointers, and those +- * that use void* generic pointers. It works with the latter +- * because both ANSI C and C++ allow castless assignment from +- * any pointer type to void*, and deal with argument conversions +- * as though doing an assignment. +- */ +- return (void *) realloc( (char *) ptr, size ); +-} +- +-void yyfree (void * ptr ) +-{ +- free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +-} +- +-#define YYTABLES_NAME "yytables" +- +-#line 86 "syslex.l" +diff -Nur binutils-2.24.orig/cgen/AUTHORS binutils-2.24/cgen/AUTHORS +--- binutils-2.24.orig/cgen/AUTHORS 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/cgen/AUTHORS 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1,2 @@ ++CGEN was originally written by Doug Evans ++while at Cygnus. +diff -Nur binutils-2.24.orig/cgen/COPYING.CGEN binutils-2.24/cgen/COPYING.CGEN +--- binutils-2.24.orig/cgen/COPYING.CGEN 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/cgen/COPYING.CGEN 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1,44 @@ ++CGEN - a Cpu tools GENerator ++Copyright 2000 Red Hat, Inc. ++ ++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, 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 software; see the file COPYING. If not, write to the ++Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++02110-1301 USA ++ ++As a special exception, Red Hat gives unlimited permission to copy, ++distribute and modify the code that is the output of CGEN. You need ++not follow the terms of the GNU General Public License when using or ++distributing such code, even though portions of the text of CGEN ++appear in them. The GNU General Public License (GPL) does govern all ++other use of the material that constitutes the CGEN program. ++ ++Certain portions of the CGEN source text are designed to be copied (in ++certain cases, depending on the input) into the output of CGEN. We ++call these the "data" portions. CPU description files are, for the ++purposes of this copyright, deemed "data". The rest of the CGEN ++source text consists of comments plus executable code that decides ++which of the data portions to output in any given case. We call these ++comments and executable code the "non-data" portions. CGEN never ++copies any of the non-data portions into its output. ++ ++This special exception to the GPL applies to versions of CGEN released ++by Red Hat. When you make and distribute a modified version of CGEN, ++you may extend this special exception to the GPL to apply to your ++modified version as well, *unless* your modified version has the ++potential to copy into its output some of the text that was the ++non-data portion of the version that you started with. (In other ++words, unless your change moves or copies text from the non-data ++portions to the data portions.) If your modification has such ++potential, you must delete any notice of this special exception to the ++GPL from your modified version. +diff -Nur binutils-2.24.orig/cgen/ChangeLog binutils-2.24/cgen/ChangeLog +--- binutils-2.24.orig/cgen/ChangeLog 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.24/cgen/ChangeLog 2016-04-10 20:30:46.000000000 +0200 +@@ -0,0 +1,6422 @@ ++2006-02-17 Shrirang Khisti ++ Anil Paranjape ++ Shilin Shakti ++ ++ * cpu/xc16x.cpu: New file containing complete CGEN specific XC16X ++ CPU description. ++ * cpu/xc16x.opc: New file containing supporting XC16C routines. ++ ++2006-02-10 Nick Clifton ++ ++ * cpu/iq2000.opc (parse_hi16): Truncate shifted value to 16 bits. ++ ++2005-12-28 Nathan Sidwell ++ ++ * sid-cpu.scm (-gen-hw-stream-and-destream-fns): Stringize mode ++ for concatenation. ++ (-hw-gen-write-stack-decl): Likewise. ++ ++2005-12-05 Hans-Peter Nilsson ++ ++ * utils-sim.scm (-gen-decode-insn-entry): Correct last change for ++ non-(adata-integral-insn? CURRENT-ARCH) case. ++ ++2005-10-28 Dave Brolley ++ ++ Contribute the following changes: ++ 2005-09-19 Dave Brolley ++ ++ * attr.scm (gen-value-for-defn-raw): New methods. ++ (gen-value-for-defn): Don't test for 'SID-SIMULATOR. Call ++ gen-value-for-defn-raw. ++ * sid.scm (gen-obj-attr-sid-defn): Call gen-value-for-defn-raw. ++ ++ 2002-12-13 Dave Brolley ++ ++ * utils-cgen.scm (gen-attr-type): Moved from sid.scm. ++ (-gen-attr-accessors): New function. ++ (gen-obj-attr-defn): Update terminating initializer. ++ (gen-obj-attr-end-defn): New function. ++ * sid.scm (gen-attr-type): Moved to utils-cgen.scm. ++ * sid-cpu.scm (cgen-desc.h): Generate code to include ++ "opcode/cgen-bitset.h" ++ * intrinsics.scm (kept-insn-isas): Correct the extraction of the isa ++ name. ++ * desc.scm ('gen-defn): Update terminating initializer. ++ * desc-cpu.scm (gen-ifld-decls): Call -gen-attr-accessors. Update ++ terminatinig initializer. ++ (gen-hw-decls): Ditto. ++ (gen-operand-decls): Ditto. ++ (gen-insn-decls): Ditto. ++ (-gen-hash-defines): Generate code to include "opcde/cgen-bitset.h" ++ (gen-insn-table): Update terminating initializer. ++ (-gen-cpu-open): Update generation of @arch@_cgen_rebuild_tables, ++ @arch@_cgen_cpu_open, @arch@_cgen_cpu_close. ++ * attr.scm (charmask-bytes): New function. ++ (bitset-attr->charmask): New function. ++ (): Handle isa-attributes specially. Also handle ++ differences for SID-SIMULATOR. ++ (): Handle differences for SID-SIMULATOR. ++ (): Ditto. ++ ++2005-10-26 Kazuhiro Inaoka ++ ++ * cpu/m32r.opc (parse_hi16): Do not assume a 32-bit host word size. ++ ++2005-10-24 DJ Delorie ++ ++ * operand.scm (-anyof-merge-syntax): Print a more useful error ++ message. ++ ++2005-10-19 Nick Clifton ++ ++ * cpu/m32r.opc (parse_slo16): Fix bad application of previous ++ patch. ++ ++2005-10-18 Andreas Schwab ++ ++ * cpu/m32r.opc (parse_slo16): Better version of previous patch. ++ ++2005-10-14 Kazuhiro Inaoka ++ ++ * cpu/m32r.opc (parse_slo16): Do not assume a 32-bit host word ++ size. ++ ++2005-08-02 Dave Brolley ++ ++ * rtl-c.scm (s-unop): Don't dereference ++ CGEN_CPU_FPU (current_cpu)->ops->xxxxx in the generated code. ++ (s-binop, s-convop, s-cmpop): Likewise. ++ ++2005-07-29 Dave Brolley ++ ++ * sid-cpu.scm (-gen-scache-semantic-fn): Generate a declation of 'written' ++ if with-profile or with-parallel-write. ++ (cgen-semantics.cxx): Make the @prefix@ namespace available if with-parallel. ++ * operand.scm (op:new-mode): Convert (obj:name op) to a string for ++ string-append. ++ ++2005-07-15 Alan Modra ++ ++ * cpu/fr30.opc (print_register_list): Correct format strings. ++ * cpu/ip2k.opc: Likewise. ++ ++2005-07-05 Nick Clifton ++ ++ * cpu/iq2000.opc (parse_lo16, parse_mlo16): Make value parameter ++ unsigned in order to avoid compile time warnings about sign ++ conflicts. ++ ++2005-07-01 Nick Clifton ++ ++ * desc-cpu.scm: Update to ISO C90 function declaration style. ++ * opc-asmdis.scm: Likewise. ++ * opc-ibld.scm: Likewise. ++ * opc-itab.scm: Likewise. ++ * cpu/fr30.opc: Likewise. ++ * cpu/i960.opc: Likewise. ++ * cpu/ip2k.opc: Likewise. ++ * cpu/iq2000.opc: Likewise. ++ * cpu/m32r.opc: Likewise. ++ * cpu/openrisc.opc: Likewise. ++ * cpu/sh.opc: Likewise. ++ * cpu/sparc.opc: Likewise. ++ * cpu/xstormy16.opc: Likewise. ++ ++2005-06-15 Dave Brolley ++ ++ * sid-cpu.scm (-gen-hw-stream-and-destream-fns): New function. ++ (cgen-cpu.h): Call it. ++ ++ Contributed on behalf of Graydon Hoare ++ 2001-06-05 graydon hoare ++ ++ * utils.scm (foldl): Define. ++ (foldr): Define. ++ (filter): Define. ++ (union): Define. ++ (intersection): Simplify. ++ * sid.scm : Set APPLICATION to SID-SIMULATOR. ++ (-op-gen-delayed-set-maybe-trace): Define. ++ ( 'gen-set-{quiet,trace}): Delegate to ++ op-gen-delayed-set-quiet etc. Note: this is still a little tangled ++ up and needs cleaning. ++ (-with-parallel?): Hardwire with-parallel to #t. ++ ( 'cxmake-get): Replace with lookahead-aware code ++ * sid-decode.scm: Remove per-insn writeback fns. ++ (-gen-idesc-decls): Redefine sem_fn type. ++ * sid-cpu.scm (gen-write-stack-structure): Replace parexec stuff ++ with write stack stuff. ++ (cgen-write.cxx): Replace per-insn writebacks with single write ++ stack writeback. Add write stack reset function. ++ (-gen-scache-semantic-fn insn): Replace parexec stuff with write ++ stack stuff. ++ * rtl-c.scm (xop): Clone operand into delayed operand if #:delayed ++ estate attribute set. ++ (delay): Set #:delayed attribute to calculated delay, update ++ maximum delay of cpu, check (delay ...) usage. ++ * operand.scm (): Add delayed slot to . ++ * mach.scm (): Add max-delay slot to . ++ * dev.scm (load-sid): Set APPLICATION to SID-SIMULATOR. ++ * doc/rtl.texi (Expressions): Add section on (delay ...). ++ ++2005-06-13 Jim Blandy ++ ++ * pmacros.scm (-pmacro-upcase, -pmacro-downcase): Handle symbols ++ as well as strings. ++ ++2005-06-07 Zack Weinberg ++ ++ * doc/porting.texi: Change all mention of md_apply_fix3 and ++ gas_cgen_md_apply_fix3 to md_apply_fix and gas_cgen_md_apply_fix ++ respectively. ++ ++2005-05-18 Dave Brolley ++ ++ * utils-sim.scm (-gen-decode-default-entry): New function. ++ (-gen-decode-insn-entry): Now takes 'invalid-insn' argument. Generate ++ code to check that all opcodes bits match. ++ (-gen-decoder-switch): Use -gen-decode-default-entry. ++ ++2005-05-16 Jim Blandy ++ ++ * sid.scm (gen-ifetch): Require BITSIZE to be exactly the size ++ fetched by one of our GETIMEM* methods. ++ * utils-gen.scm (-extract-chunk-specs): Always fetch full ++ base-insn-sized chunks. ++ ++2005-05-10 Nick Clifton ++ ++ * Update the address and phone number of the FSF organization in ++ the GPL notices in the following files: ++ COPYING.CGEN, utils.scm, cpu/iq2000m.cpu, cpu/openrisc.cpu, ++ cpu/powerpc.cpu, slib/random.scm ++ ++2005-05-06 Jim Blandy ++ ++ * pprint.scm, cos-pprint.scm: Add documentation. ++ ++ * pprint.scm (pprint): Don't wipe out elide-table after each call. ++ ++ * pprint.scm, cos-pprint.scm: New files. ++ ++2005-04-04 Nick Clifton ++ ++ * opcodes.scm (-gen-parse-address): Initialise value to zero to ++ avoid a compile time warning. ++ ++2005-03-18 Nick Clifton ++ ++ * cpu/ip2k.opc (parse_lit8): Change wording of error message to ++ "percent-operand" from "%operand" as the latter confuses xgettext ++ into thinking that it is a C printf formating directive, which ++ prevents proper translation. ++ ++2005-02-23 Nick Clifton ++ ++ * opcodes.scm (gen-parse-number): Add a cast to the desired ++ pointer signed'ness in order to prevent compile time warnings. ++ * cpu/ip2k.opc: Fixed compile time warnings about differing ++ signed'ness of pointers passed to functions. ++ * cpu/iq2000.opc: Likewise. ++ * cpu/m32r.opc: Likewise. ++ * cpu/openrisc.opc: Likewise. ++ * cpu/xstormy16.opc: Likewise. ++ ++2005-02-22 Alan Modra ++ ++ * desc-cpu.scm (gen-ifld-decls): Move cgen_ifld_table from here.. ++ (cgen-desc.h): ..to here, after opcode/cgen.h include. ++ ++2005-02-16 Dave Brolley ++ ++ * utils.scm: Update copyright years. ++ * utils-gen.scm (gen-ifld-extract): Pass base-length to -gen-ifld-extract-base. ++ * sid.scm (gen-ifetch): Handle the case where bitsize == 24. ++ * operand.scm (-derived-operand-parse): Move logit message from level 1 ++ to level 2. ++ ++2005-02-15 Nick Clifton ++ ++ * opc-itab.scm (-gen-ifmt-table-1): Add an ATTRIBUTE_UNUSED to ++ prevent compile time warning messages. ++ * opc-opinst.scm (-gen-operand-instance-table): Likewise. ++ * utils-gen.scm (attr-int-gen-defn): Likewise. ++ (attr-gen-defn): Likewise. ++ * cpu/ip2k.opc (parse_addr16_p): Remove unused function. ++ (print_dollarhex16): Remove unused function. ++ ++2005-02-15 Jim Blandy ++ ++ * guile.scm (cgen-call-with-debugging): Doc fix. ++ ++ Make backtraces work more reliably. ++ * guile.scm: Set up debugging parameters, and enable debugging and ++ source positions while loading. ++ (cgen-call-with-debugging, cgen-debugging-stack-start): New ++ functions. ++ * read.scm: Don't set debugging parameters here. ++ (catch-with-backtrace): Function deleted. ++ (-cgen): Simply note the presence or absence of the -b option. ++ Pass the flag to cgen-call-with-debugging, so debugging is turned ++ off here if the user didn't request it, for faster computation. ++ (cgen): Call cgen-debugging-stack-start here, instead of ++ catch-with-backtrace. ++ ++ * Makefile.am (GUILE): Explicitly load guile.scm here, and leave a ++ trailing -s. ++ (desc, html, opcodes, sim-arch, sim-cpu, gas-test, sim-test): ++ Don't write out the trailing -s here. ++ * Makefile.in: Regenerated. ++ * cgen-doc.scm, cgen-gas.scm, cgen-stest.scm): Don't load ++ fixup.scm here; let the caller decide which Scheme's customization ++ file to preload. ++ * dev.scm: Load guile.scm, not fixup.scm. ++ * fixup.scm: Deleted; contents have all moved to guile.scm. ++ * README: Doc fix. ++ ++ * guile.scm (debug-write): New function. ++ ++2005-02-14 Jim Blandy ++ ++ * pmacros.scm (pmacros-init!): For .eval macros, use eval1 as the ++ transformer procedure, not eval. Transformer procedures take one ++ argument. ++ ++2005-02-11 Nick Clifton ++ ++ * cpu/iq2000.opc (parse_jtargq10): Change type of valuep argument ++ to 'bfd_vma *' in order avoid compile time warning message. ++ ++2005-02-09 Jim Blandy ++ ++ * cgen-sim.scm (load-files): Don't load fixup.scm. (See ++ corresponding change in the sim/common directory.) ++ ++2005-02-07 Jim Blandy ++ ++ * cgen-opc.scm: Don't load fixup.scm here. (See corresponding ++ changes in the opcodes directory.) ++ ++ * guile.scm: New file, containing Guile-specific definitions and ++ adaptations. This is loaded by the app-specific shell scripts. ++ Initially identical to fixup.scm. ++ * cgen-sid.scm: Don't load fixup.scm here. ++ ++ * cos.scm: Profile elm-xset! when requested, not elm-set!; the ++ latter is a macro. ++ ++2005-01-27 Jim Blandy ++ ++ * utils.scm (string/symbol->append): Renamed from 'concat'. ++ * opcodes.scm (gen-switch): Use new name. ++ * insn.scm (-sub-insn-make!): Same. ++ * rtl.scm (rtx-dump): Same. ++ * semantics.scm (semantic-compile): Same. ++ ++2005-01-20 Jim Blandy ++ ++ * opcodes.scm (gen-switch): Use concat instead of string-map. ++ ++ * utils.scm (concat): New function. ++ * insn.scm (-sub-insn-make!): Use concat instead of string-map. ++ * rtl.scm (rtx-dump): Same. ++ * semantics.scm (semantic-compile): Same. ++ ++2004-12-16 Jim Blandy ++ ++ * utils-cgen.scm (parse-name): Don't assume that string-map can be ++ applied to symbols. Process everything as strings, and then ++ convert to a symbol at the end. ++ ++ * read.scm (debug-repl): Temporarily redirect input and output to ++ /dev/tty while we debug, so we don't interfere with whatever CGEN ++ is reading or writing. ++ * utils.scm (setter-getter-fluid-let, with-input-and-output-to): ++ New functions. ++ ++2004-11-15 Michael K. Lechner ++ ++ * cpu/iq2000.cpu: Added quotes around macro arguments so that they ++ will work with newer versions of guile. ++ ++2004-10-27 Nick Clifton ++ ++ * cpu/iq2000m.cpu: Import latest version from cpu/ directory. ++ * cpu/iq2000.cpu: Likewise. ++ ++2004-07-21 DJ Delorie ++ ++ * cpu/xstormy16.cpu (movhmemgr): Use hmem8, not lmem8. ++ ++2003-03-14 Frank Ch. Eigler ++ ++ * cpu/iq2000.opc (parse_jtargq10): Add ATTRIBUTE_UNUSED on unused args. ++ (parse_jtargq10, iq2000_cgen_isa_register, parse_mlo16): Declare. ++ ++2004-03-30 Kazuhiro Inaoka ++ ++ * cpu/m32r.opc (parse_hi16): Fixed shigh(0xffff8000) bug. ++ ++2004-03-22 Dave Brolley ++ ++ * utils.scm (copyright-fsf): Update copyright years. ++ (copyright-red-hat): Ditto. ++ * sid.scm (-op-gen-set-trace): Generate trace code before semantic ++ code. ++ (-op-gen-set-trace-parallel): Ditto. ++ ++2004-02-10 Kazuhiro Inaoka ++ ++ * cpu/m32r.opc (my_print_insn): Fixed incorrect output when ++ disassembling codes for 0x*2 addresses. ++ ++2004-01-29 Dave Brolley ++ ++ * decode.scm (-opcode-slots): For short insns, generate 'opcode' with ++ zeroes in the extra bit positions and generate 'opcode-mask' with ones ++ in the extra bit positions. ++ ++2003-12-15 Kazuhiro Inaoka ++ ++ * cpu/m32r.cpu: Add PIPE_O attribute to "pop" instruction. ++ ++2003-12-04 Alan Modra ++ ++ * cpu/openrisc.opc (openrisc_sign_extend_16bit): Don't rely on ++ "short" being 16 bit. ++ (parse_hi16): Likewise. Fix type-punned pointer warnings too, and ++ internationalize error message. ++ (parse_lo16): Likewise. Remove useless code. ++ ++2003-12-03 Kazuhiro Inaoka ++ ++ * cpu/m32r.cpu : Add new model m32r2. ++ Add new instructions. ++ Replace occurrances of 'Mitsubishi' with 'Renesas'. ++ Changed PIPE attr of push from O to OS. ++ Care for Little-endian of M32R. ++ * cpu/m32r.opc (CGEN_DIS_HASH, my_print_insn): ++ Care for Little-endian of M32R. ++ (parse_slo16): signed extension for value. ++ ++2003-10-26 Dave Brolley ++ ++ * sid-decode.scm (-gen-record-profile-args): Test trace_counter_p ++ and final_insn_count_p. Don't test WITH_PROFILE_MODEL_P. ++ (-gen-extract-fn): Call -gen-record-profile-args. ++ ++2003-10-21 Dave Brolley ++ ++ * sid-model.scm (-gen-model-class-decls): Generate MAX_UNITS as ++ a static const int. ++ * decode.scm (-opcode-slots): Correct typo in logit call. ++ ++2003-10-09 Jim Blandy ++ ++ * desc-cpu.scm (gen-hw-table-decls): Emit an 'extern' declaration ++ for @arch@_cgen_hw_table. GDB needs to be able to find this. ++ ++ * mach.scm (def-isa-attr!): hardware can have ISA attributes, too. ++ ++2003-10-06 Dave Brolley ++ ++ * gen-all-doc: Add fr550. ++ ++2003-09-11 Doug Evans ++ ++ * Makefile.am (ARCHFILE): New var. ++ (desc): Pass $(ARCHFILE) for -a parm, not $(ARCH). ++ (html,opcodes,sim-arch,sim-cpu,gas-test,sim-test): Ditto. ++ * Makefile.in: Regenerate. ++ ++2003-09-08 Dave Brolley ++ ++ On behalf of Doug Evans ++ Pass in paths to input files, instead of assuming they live in ++ $srcdir/cpu. Plus misc. option processing cleanup. ++ * cgen-doc.scm (doc-arguments): Make options strings not symbols. ++ Add pre-process pass to all options. ++ * cgen-gas.scm (gas-arguments): Ditto. ++ * cgen-sid.scm (sim-arguments): Ditto. ++ * cgen-sim.scm (sim-arguments): Ditto. ++ * cgen-stest.scm (stest-arguments): Ditto. ++ * cgen-opc.scm (opc-arguments): Ditto. New argument -OPC. ++ (-opc-file-path): New global. ++ (opc-file-path): New fn. ++ * opcodes.scm (read-cpu.opc): Replace srcdir,cpu args with opc-file. ++ All callers updated. ++ (gen-extra-cpu.h,gen-extra-cpu.c,gen-extra-opc.h,gen-extra-opc.c, ++ gen-extra-asm.c,gen-extra-dis.c,gen-extra-ibld.h,gen-extra-ibld.c): ++ Replace srcdir arg with opc-file. All callers updated. ++ * read.scm (-opt-spec-update): Delete. ++ (opt-get-first-pass,opt-get-second-pass): New fns. ++ (-cgen): Process application-specific arguments in two passes. ++ ++2003-08-29 Dave Brolley ++ ++ * cpu/frv.cpu: Removed. ++ * cpu/frv.opc: Removed. ++ ++2003-08-21 Nick Clifton ++ ++ * cpu/frv.cpu (mbtoh): Replace input parameter to ++ u-media-dual-expand and u-media-dual-btoh with output parameter. ++ (cmbtoh): Add profiling hack. ++ ++2003-08-19 Michael Snyder ++ ++ * cpu/frv.cpu: Fix typo, Frintkeven -> FRintkeven ++ ++2003-08-07 Michael Meissner ++ ++ * opc-opinst.scm (-gen-operand-instance-table): Initialize all of ++ the elements for the END record of CGEN_OPINST, silencing warnings. ++ ++2003-07-15 Doug Evans ++ ++ Add guile 1.6.4 support. ++ - empty list must be quoted ++ - string functions have stricter type checking ++ - eval now takes a second argument ++ - symbol-bound? is deprecated ++ * attr.scm (-attr-parse): Use stringsym-append to build errtxt. ++ (bitset-attr->list): Ensure arg to string-cut is a string. ++ (attr-parse): Ensure args to string-ref and string-drop1 are strings. ++ (,gen-value-for-defn): Fetch string name of self. ++ * cos.scm (-class-list): Must quote empty list. ++ (-class-parent-classes,-class-compute-class-desc): Ditto. ++ (class-make,make,object-reset!): Ditto. ++ (method-make-make!): Call eval1 instead of eval. ++ (method-make-forward!,method-make-virtual-forward!): Ditto. ++ * decode.scm (subdtable-add): Use stringsym-append instead of ++ string-append. ++ (-gen-exprtable-name): Fetch string name of exprtable-entry-insn. ++ (-build-decode-table-entry): Fetch string name of insn. ++ * desc-cpu.scm (-gen-isa-table-defns): Fetch string name of isa. ++ (-gen-mach-table-defns): Ditto for mach. ++ (gen-ifld-defns): Ditto for ifld. ++ (gen-hw-table-defns): Ditto for hw. ++ (gen-operand-table): Ditto for op. ++ (gen-insn-table-entry): Ditto for insn. ++ * desc.scm (gen-attr-table-defn): Ditto for attr. ++ (,gen-defn): Don't pass symbols to string-append. ++ * enum.scm (parse-enum-vals): Use symbolstr-append instead of ++ symbol-append. ++ (enum-vals-upcase): Use symbol-upcase to build result. ++ (-enum-parse): Use stringsym-append to build errtxt. ++ * fixup.scm (*guile-major-version*,*guile-minor-version*): New globals. ++ (eval1): New function. ++ (symbol-bound?): Provide own version if >= guile 1.6. ++ * hardware.scm (define-keyword): Use string-append instead of ++ symbol-append. ++ * html.scm (gen-html-header,gen-table-of-contents,gen-arch-intro, ++ cgen.html,cgen-insn.html): Convert current-arch-name to a string ++ before using. ++ (gen-list-entry): Handle either symbol or string `name' arg. ++ (gen-obj-doc-header): Fetch string name of `o' arg. ++ (define-cpu-intro): Ditto for cpu. ++ (gen-mach-intro): Ditto for mach. ++ (gen-model-intro): Ditto for model. ++ (gen-isa-intro): Ditto for isa. ++ (gen-machine-doc-1): Ditto for isa. ++ (gen-reg-doc-1): Convert mach to string first. ++ (gen-insn-doc-1): Ditto. Convert model/unit names to strings first. ++ (gen-insn-doc-list): Fetch string name of mach. Convert insn name ++ to string first. ++ (gen-insn-categories): Fetch string name of mach. Convert ++ enum-val-name to string first. ++ (gen-insn-docs): Fetch string name of mach. ++ * ifield.scm (ifld-ilk): Result is a string. ++ * iformat.scm (-ifmt-search-key): Convert attr value to string first. ++ Fetch string name of ifld. ++ (-sfmt-search-key): Similarily for ifld and op. ++ * insn.scm (syntax-make): Fetch string name of syntax element. ++ * mach.scm (-cpu-parse): Use stringsym-append to build errtxt. ++ * minsn.scm (minsn-make-alias): Fetch string name of minsn. ++ * mode.scm (mode:c-type): Result is a string. ++ (mode:enum): Fetch string name of mode. ++ (-mode-parse): Use stringsym-append to build errtxt. ++ * model.scm (model:enum): Fetch string name of model. ++ (-model-parse): Use stringsym-append to build errtxt. ++ (parse-insn-timing): Must quote empty list. ++ * opc-itab.scm (-gen-minsn-table-entry): Fetch string name of minsn. ++ (-gen-minsn-opcode-entry): Ditto. ++ * opcodes.scm (,gen-function-name): `what' arg is a symbol, ++ convert to string. ++ (read-cpu.opc): Convert current-arch-name to a string before using. ++ * operand.scm (,gen-pretty-name): Ensure `name' is a string. ++ (): Must quote empty list. ++ (op-sort): Simplify, call alpha-sort-obj-list to do sort. ++ * pgmr-tools.scm (pgmr-pretty-print-insn-value): Fetch string name ++ of ifld. ++ * pmacros.scm (-pmacro-build-lambda): Use eval1 instead of eval. ++ (-pmacro-sym): Must convert symbols to strings before passing to ++ string-append. ++ (-pmacro-str): Ditto. ++ (pmacros-init!): Use eval1 instead of eval. ++ * read.scm (keep-mach-atlist?): Simplify, use bitset-attr->list. ++ (keep-isa-atlist?): Ditto. ++ (cmd-if): Use eval1 instead of eval. ++ * rtl-c.scm (,get-name): Fetch string name of self. ++ (-rtl-c-get): Fetch string name of src. ++ (s-unop): Ditto for mode. ++ (s-binop,s-binop-with-bit,s-shop,s-convop,s-cmpop): Ditto. ++ (-gen-par-temp-defns,subword): Ditto. ++ (join): Use stringsym-append instead of string-append. ++ * rtl-traverse.scm (rtx-option?): Convert option to string first. ++ (rtx-traverse-debug): Fetch string name of rtx-obj. ++ * rtl.scm (def-rtx-node): Use eval1 instead of eval. ++ (def-rtx-syntax-node,def-rtx-operand-node,def-rtx-macro-node): Ditto. ++ (rtx-pretty-name): Result is a string. ++ (-rtx-hw-name): Use symbolstr-append instead of symbol-append. ++ * semantics.scm (semantic-compile): Simplify, use alpha-sort-obj-list. ++ * sid-cpu.scm (cgen-write.cxx): Convert current-arch-name to a string ++ before using. ++ (-gen-sfrag-case): Fetch string name of user. ++ * sid-model.scm (unit:enum): Fetch string name of unit. ++ * sid.scm (,cxmake-get): Fetch string name of mode. ++ (,gen-set-quiet): Ditto. ++ (gen-mode-defs): Ditto. ++ (sim-finish!): Convert current-arch-name to a string before using. ++ * sim-cpu.scm (-gen-scache-semantic-fn): Fetch string name of insn. ++ (-gen-no-scache-semantic-fn): Ditto. ++ (cgen-defs.h): Fetch string name of isa. ++ (cgen-read.c): Convert current-arch-name to a string before using. ++ (cgen-write.c): Ditto. ++ * sim-model.scm (unit:enum): Fetch string name of unit. ++ (gen-model-fn-decls): Use stringsym-append instead of string-append. ++ (-gen-model-timing-table): Fetch string name of model. ++ (-gen-mach-model-table): Ditto. ++ (-gen-mach-defns): Fetch string name of mach. ++ * sim.scm (gen-reg-access-defn): Fetch string name of hw. ++ (,cxmake-get): Fetch string name of mode. ++ (,gen-set-quiet): Ditto. ++ (gen-mode-defs): Ditto. ++ (sim-finish!): Must quote empty list. ++ * utils-cgen.scm (): Must quote empty list. ++ (obj:str-name): New fn. ++ (parse-comment): Result is a string. ++ (parse-symbol): Result is a symbol. ++ (parse-string): Result is a string. ++ (keyword-list?): Convert arg to string before calling string-ref. ++ (keyword-list->arg-list): Ditto. ++ (gen-attr-name): Convert attr-name to string first. ++ (alpha-sort-obj-list): Use symbolstring,->symbol): New fns. ++ (reduce): Call eval1 instead of eval. ++ * cpu/m32r.cpu (addi): Don't use `#.'. ++ ++ * gen-all-sim: Fix some typos. ++ ++2003-07-08 Doug Evans ++ ++ * gen-all-doc: Ensure run from cgen src dir. ++ * gen-all-opcodes: Build in ./tmp-opcodes. Don't delete dir when done. ++ * gen-all-sid: Similarily, in ./tmp-sid. ++ * gen-all-sim: Similarily, in ./tmp-sim. ++ ++2003-06-20 Doug Evans ++ ++ * gen-all-sim: Add fr30,sh64 support. Only generate m32r by default. ++ ++2003-06-19 Doug Evans ++ ++ * mach.scm (-ifld-already-defined?): New proc. ++ (current-ifld-add!): Use it. ++ (-op-already-defined?): New proc. ++ (current-op-add!): Use it. ++ (-insn-already-defined?): New proc. ++ (current-insn-add!): Use it. ++ (-minsn-already-defined?): New proc. ++ (current-minsn-add!): Use it. ++ (obj-isa-list): New proc. ++ (isa-supports?): Use it. ++ ++2003-06-10 Doug Evans ++ ++ * insn.scm (insn-builtin!): RELAX renamed to RELAXABLE. ++ * cpu/m32r.cpu (all insns): Ditto. ++ ++ * mach.scm (current-*-add!): Disallow redefinition. Make result ++ "unspecified". ++ ++ * gen-all-doc: Split arm and frv docs up a bit. ++ ++ * cpu/arm.cpu: Add IDOC attribute. ++ * cpu/frv.cpu: Ditto. ++ * cpu/i960.cpu: Ditto. ++ * cpu/openrisc.cpu: Ditto. ++ * cpu/xstormy16.cpu: Ditto. ++ * cpu/m32r.cpu: Ditto. ++ (all insns): Explicitly specify IDOC attribute. ++ ++ * Makefile.am (MACH,ISAS,INSN_FILE_NAME): New vars. ++ (desc,opcodes,sim-arch,sim-cpu,gas-test,sim-test): Use MACH,ISAS. ++ (html): Use MACH,ISAS,INSN_FILE_NAME. Generate insn.html separately. ++ * Makefile.in: Regenerate. ++ * attr.scm (:parse-value-def): Implement. ++ (-attr-read): Defer computing default value until we know the type. ++ (attr-has-attr?): Delete, move contents to :has-attr?. ++ (:attr-present?): New method. ++ (atlist-attr-present?,obj-attr-present?): New fns. ++ (obj-has-attr-value?,obj-has-attr-value-no-default?): New fns. ++ (attr-builtin!): New insn attr IDOC. ++ * cgen-doc.scm (doc-arguments): New args -I,-N. ++ * enum.scm (parse-enum-vals): New arg errtxt, all callers updated. ++ Support comment as fourth element of enum value. ++ (enum-val-name,enum-val-value,enum-val-attrs,enum-val-comment): New fns. ++ * html.scm (gen-html-header): New arg kind, all callers updated. ++ (gen-table-of-contents): New arg insn-file, all callers updated. ++ (gen-list-entry,gen-doc-header): New fn. ++ (get-operands): Delete. ++ (gen-iformat-table): Rewrite. ++ (gen-insn-doc-1): Print constant-folded and trimmed semantics. ++ (gen-insn-doc-list): New args name, comment, insns. All callers updated. ++ (get-insn-properties,guess-insn-idoc-attr!): New fn. ++ (insn-sets-pc?,insn-refs-mem?,insn-uses-fpu?): New fns. ++ (get-insns-for-category,gen-categories-insn-lists): New fns. ++ (gen-insn-docs): Simplify each insn's semantics first. ++ Print insn tables sorted by IDOC categories. ++ (*insn-html-file-name*): New global. ++ (cgen-insn.html): New fn. ++ (cgen-all): Update. ++ * insn.scm (): Create a setter for the `tmp' member. ++ * semantics.scm (insn-build-known-values): Renamed from ++ -build-known-values. All callers updated. ++ ++ * rtl.scm: Move traveral/evaluation support to ... ++ * rtl-traverse.scm: New file. ++ * read.scm: Maybe-load rtl-traverse.scm. ++ ++ * rtl.scm (-rtx-valid-types): Add SETRTX. ++ ++ * rtx-funcs.scm (nop,parallel): Fix mode. ++ ++ * utils.scm (eqv-lookup-index): New fn. ++ (assq-lookup-index): Renamed from lookup-index. All callers updated. ++ ++ * dev.scm (load-doc): Set APPLICATION. ++ ++2003-06-10 Dave Brolley ++ ++ * sid-cpu.scm: Generate #include of config.h into @prefix@-sem.cxx. ++ * sid-decode.scm: Generate #include of config.h into ++ @prefix@-decode.cxx. ++ * sid-model.scm: Generate #include of config.h into @prefix@-model.cxx. ++ ++2003-06-07 Doug Evans ++ ++ * gen-all-sid: New file. ++ * gen-all-opcodes: New file. ++ ++2003-06-05 Nick Clifton ++ ++ * cpu/frv.cpu (FRintieven): New operand. An even-numbered only ++ version of the FRinti operand. ++ (FRintjeven): Likewise for FRintj. ++ (FRintkeven): Likewise for FRintk. ++ (mdcutssi, media-dual-word-rotate-r-r, mqsaths, ++ media-quad-arith-sat-semantics, media-quad-arith-sat, ++ conditional-media-quad-arith-sat, mdunpackh, ++ media-quad-multiply-semantics, media-quad-multiply, ++ conditional-media-quad-multiply, media-quad-complex-i, ++ media-quad-multiply-acc-semantics, media-quad-multiply-acc, ++ conditional-media-quad-multiply-acc, munpackh, ++ media-quad-multiply-cross-acc-semantics, mdpackh, ++ media-quad-multiply-cross-acc, mbtoh-semantics, ++ media-quad-cross-multiply-cross-acc-semantics, ++ media-quad-cross-multiply-cross-acc, mbtoh, mhtob-semantics, ++ media-quad-cross-multiply-acc-semantics, cmbtoh, ++ media-quad-cross-multiply-acc, media-quad-complex, mhtob, ++ media-expand-halfword-to-double-semantics, mexpdhd, cmexpdhd, ++ cmhtob): Use new operands. ++ * cpu/frv.opc (CGEN_VERBOSE_ASSEMBLER_ERRORS): Define. ++ (parse_even_register): New function. ++ ++2003-06-04 Doug Evans ++ ++ Better handling of 64 bit and mixed 32/64 bit architectures. ++ * hardware.scm (hw-update-word-modes!): New fn. ++ * mach.scm (define-cpu)): Call mode-set-word-modes!, ++ hw-update-word-modes!. ++ (state-word-bitsize): Replace FIXME with requested check. ++ (arch-analyze-insns!): Call mode-ensure-word-sizes-defined. ++ * mode.scm (mode-find): Ignore INT,UINT. ++ (-mode-word-sizes-kind): New global. ++ (mode-set-word-modes!,mode-set-identical-word-bitsizes!, ++ mode-set-biggest-word-bitsizes!,mode-ensure-word-sizes-defined): New fns. ++ (mode-init!): Initialize -mode-word-sizes-kind. Move initialization ++ of mode-list to ... ++ (mode-builtin!): ... here. Initialize WI/UWI/AI/IAI to something ++ unusable, correct values set later. ++ (mode-finish!): Remove cruft. ++ * html.scm (doc-init!): Call mode-set-biggest-word-bitsizes!. ++ * opcodes.scm (opcodes-init!): Ditto. ++ * rtx-funcs.scm (annul): Fix mode of pc. ++ * cpu/ia64.cpu: Remove cruft that sets word modes. ++ * cpu/xstormy16.cpu (define-cpu): Set word-bitsize. ++ ++2003-06-03 Nick Clifton ++ ++ * cpu/frv.cpu (media-dual-word-rotate-r-r): Use a signed 6-bit ++ immediate value not unsigned. ++ ++2003-05-21 J"orn Rennecke ++ ++ * cpu/sh.cpu: Amend comments to refer to SuperH. ++ * cpu/sh64-compact.cpu: Change comment to refer to SuperH. ++ * cpu/sh64-media.cpu: Likewise. ++ (Saturation): Update manual reference. ++ ++2003-05-15 Doug Evans ++ ++ * Makefile.am (srcroot): New var. ++ (html): New rule. ++ * Makefile.in: Regenerate. ++ * cgen-doc.scm: New file. ++ * html.scm: New file. ++ * gen-all-doc: New file. ++ * dev.scm (cload): Handle DOC application. ++ (load-doc): New fn. ++ * machs.scm (machs-for-cpu): New fn. ++ * model.scm (models-for-cpu): New fn. ++ * utils.scm (gen-c-copyright): Renamed from gen-copyright. ++ All uses updated. ++ (iota): Rewrite to be identical to pmacro version. All uses updated. ++ * utils-cgen.scm (alpha-sort-obj-list): New fn. ++ ++ * utils-sim.scm (-gen-decoder-switch): Back out patch of 2003-01-09. ++ (-gen-decode-bits): Instead put in better fix here. ++ ++ * cpu/i960.cpu (index): Rename to indx. All uses updated. ++ ++2003-05-01 DJ Delorie ++ ++ * cpu/xstormy16.cpu (alignfix-mem): Correct logic for unaligned ++ word accesses. ++ (set-alignfix-mem): Likewise. ++ ++2003-04-16 Dave Brolley ++ ++ * doc/rtl.texi (Iiming): Correct example to use 'model-name'. ++ * utils.scm (copyright-fsf): Update generate copyright years. ++ (copyright-cygnus): Ditto. ++ * sid.scm (-op-gen-set-trace): Generate code to fill in bitmask of modified ++ operands. ++ (-gen-arch-model-decls): Don't generate unit enum declaration or MAX_UNITS ++ here. ++ ('gen-profile-code): New parameter 'when'. ++ ('gen-profile-code): Ditto. ++ ('gen-profile-code): Ditto. ++ ('gen-profile-code): Ditto. Only generate 'referenced' and ++ 'insn_reference' for the 'after' function. ++ * model.scm (unit:enum): Moved to sim-model.scm. ++ * sim-model.scm (unit:enum): Moved from model.scm. ++ * sid-decode.scm (-gen-scache-decls): Generate the 'written' field. ++ * cgen-sid.scm (sim-arguments): Document the generation of model.h. ++ * sid-model.scm (unit:enum): New version for sid. ++ (gen-model-class-name): New function. ++ (gen-model-unit-fn-decl): New function. ++ (gen-model-fn-decls): Call gen-model-unit-fn-decl. ++ (gen-model-unit-fn-name): New parameter 'when'. ++ (-gen-model-insn-fn-name): Ditto. ++ (-gen-model-insn-qualified-fn-name): New function. ++ (-gen-model-insn-fn-decl): New function. ++ (-gen-model-insn-fn-decls): New function. ++ (-gen-model-insn-fn): New parameter 'when'. Call ++ -gen-model-insn-qualified-fn-name. ++ (-gen-model-insn-fns): Generate the constructor for the model. Generate ++ functions for modelling insn before and after execution. ++ (-gen-model-class-decls): New function. ++ (" (gen-model-class-name model) "): New function. ++ (gen-model-classes): New function. ++ (-gen-insn-timing): Generate functions for modelling insn before and after ++ execution. ++ (-gen-insn-unit-timing): Generate class-qualified names. ++ (-gen-model-timing-table): Ditto. ++ (cgen-model.cxx): Generate #include for @cpu@.h. Omit generation of code ++ not needed (yet) by sid. ++ (cgen-model.h): New function. ++ ++2003-04-15 Rohit Kumar Srivastava ++ ++ * cpu/sh.cpu: Replace occurrances of 'Hitachi' with 'Renesas'. ++ * cpu/sh64-compact.cpu: Likewise. ++ * cpu/sh64-media.cpu: Likewise. ++ ++2003-03-21 DJ Delorie ++ ++ * cpu/xstormy16.cpu (basic-psw): New argument ws (wordsize), ++ which indicates if the sign flag is set from bit 15 or 7. ++ Adjust all callers. ++ (set-psw): New argument ws, propogate it. ++ (set-psw-nowrite): Likewise. ++ (set-mem-psw): Likewise. ++ (set-psw-carry): Likewise. Use temporaries to prevent ++ prematurely overwriting needed inputs. ++ (set-psw-rrotate17): Fix logic. ++ (shrgrgr): Preserve carry for zero-bit shifts. ++ (shrgrimm): Likewise. ++ (shlgrgr): Likewise. ++ (shlgrimm): Likewise. ++ (asrgrgr): Likewise. ++ (asrgrimm): Likewise. ++ (reset): New. ++ ++2003-03-12 Frank Ch. Eigler ++ ++ * sid.scm: Set APPLICATION to SID-SIMULATOR. ++ ++2002-03-05 DJ Delorie ++ ++ * cpu/xstormy16.cpu (set-psw-add): Use temporaries to prevent ++ prematurely overwriting needed inputs. ++ (set-psw-sub): Likewise. ++ ++Fri Feb 21 19:48:19 2003 J"orn Rennecke ++ ++ * cpu/sh64-media.cpu (make-mextr): Fix setting of count. ++ ++2003-02-18 DJ Delorie ++ ++ * xstormy16.cpu (set-mem-alignfix-psw): Remove. ++ (movlmemimm): Just mask the address. ++ (movhmemimm): Likewise. ++ (movlmemgr): Likewise. ++ (movhmemgr): Likewise. ++ (set-psw): Always set the psw last. ++ (set-psw-carry): Likewise. ++ (set-psw-add): Likewise. ++ (set-psw-sub): Likewise. ++ ++ * xstormy16.cpu (set-psw-rrotate17): New. Choose the correct set ++ of 16 patterns from the set-psw-rotate17 function. ++ (movgrigr, movgripostincgr, movgripredecgr, movgriigr, ++ movgriipostincgr, movgriipredecgr): Set psw correctly. ++ (movfgrigr, movfgripostincgr, movfgripredecgr, movfgriigr, ++ movfgriipostincgr, movfgriipredecgr): Fix semantics. ++ (rrcgrgr, rrcgrimm4): Use new set-psw-rrotate17 function. ++ ++2003-02-11 Dave Brolley ++ ++ * desc-cpu.scm (gen-ifld-defns): Add all ifields to the ++ @arch@_cgen-ifld_table. ++ (gen-maybe-multi-ifld): Use the ifield enumerators to index the ++ @arch@_cgen-ifld_table. ++ ++2003-02-03 Frank Ch. Eigler ++ ++ * sid-cpu.scm (-gen-sfrag-engine-fn): Generate more hygienic C++. ++ ++2003-01-09 Graydon Hoare ++ ++ * utils-sim.scm (-gen-decoder-switch): Fix edge condition for ++ empty ISAs. ++ ++2003-01-07 Graydon Hoare ++ ++ * utils-gen.scm (attr-int-gen-defn): Define. ++ ++2002-12-21 Doug Evans ++ ++ * ifield.scm (-ifield-parse): Rewrite computation. ++ (-get-ifld-word-offset,-get-ifld-word-length): New fns. ++ ++ * dev.scm (cload): Update location of .cpu files. ++ ++2002-12-19 Doug Evans ++ ++ * utils-sim.scm (gen-profile-sym): New fn. ++ (,sbuf-profile-sym): New method. ++ (,sbuf-profile-elm): Use it. ++ * sim.scm (,gen-record-profile): Use sbuf-profile-sym instead ++ of hardcoding symbol name. ++ (,gen-profile-code): Ditto. ++ (,gen-profile-code): Use gen-profile-sym instead of hardcoding ++ symbol name. ++ ++ * mode.scm (mode-sem-mode): New fn. ++ * operand.scm (op:new-mode): Update. mode-name. ++ (op-natural-mode?) New fn. ++ * rtl.scm (hw): Set hw-name,mode-name. ++ ++ Back out sim*.scm changes of 2001-04-02 Ben Elliston ++ Instead do: ++ * sim-decode.scm (-gen-decode-insn-globals): Use @PREFIX@_INSN__MAX ++ as size of IDESC-TABLE-VAR. ++ (@prefix@_init_idesc_table): Ditto. ++ * sim-model.scm (-gen-mach-defns): Ditto. ++ * sim.scm (gen-cpu-insn-enum-decl): Rename last elm from max to -max. ++ ++ * utils-sim.scm (-gen-decode-insn-entry): Fix some spacing in output. ++ ++ * insn.scm (-parse-insn-format-symbol): Improve error message. ++ (-parse-insn-format): Ditto. ++ ++ * gen-all-sim: New script. ++ ++2002-12-16 DJ Delorie ++ ++ * cpu/xstormy16.opc (parse_immediate16): Add prototype. ++ ++2002-12-16 Andrew MacLeod ++ ++ * cpu/xstormy16.cpu (imm16): Call handler immediate16. ++ * cpu/xstormy16.opc (parse_small_immediate): Return on '@'. ++ (parse_immediate16): Handle immediate16 values, which now include ++ @hi(label) and @lo(label) ++ ++2002-12-03 Alan Modra ++ ++ * desc-cpu.scm (gen-maybe-multi-ifld): Remove superfluous parens. ++ Add braces and cast for union field. ++ (gen-multi-ifield-nodes): Add braces and cast for union field. ++ (cgen_operand_table): Similarly fix sentinel. ++ (cgen_cpu_close): Constify "insns". Formatting. ++ (cgen-desc.c): Include xregex.h. ++ * cpu/ip2k.opc (ip2k_cgen_insn_supported): Move to opc.c section. ++ Prototype. ++ : Include safe-ctype.h. ++ (ip2k_asm_hash): Use ISSPACE and TOLOWER. ++ (PARSE_FUNC_DECL): Declare. Use to prototype parse_fr, parse_addr16, ++ parse_addr16_p, parse_addr16_cjp, parse_lit8 and parse_bit3. ++ (parse_fr): Constify "old_strp". Correct type of "tempvalue". ++ Don't test it for >= 0. Use ISSPACE rather than isspace. Formatting. ++ (parse_addr16): Correct type of "value". Formatting. ++ (parse_addr16_p): Likewise. ++ (parse_addr16_cjp): Likewise. ++ (parse_lit8): Likewise. ++ (parse_bit3): Formatting. ++ (PRINT_FUNC_DECL): Define. Use to prototype print_fr, print_dollarhex, ++ print_dollarhex8, print_dollarhex16, print_dollarhex_addr16h, ++ print_dollarhex_addr16l, print_dollarhex_p, print_dollarhex_cj and ++ print_decimal. ++ (print_fr): Add ATTRIBUTE_UNUSED on unused args. Formatting. ++ (print_dollarhex): Add ATTRIBUTE_UNUSED on unused args. ++ (print_dollarhex8): Likewise. ++ (print_dollarhex16): Likewise. ++ (print_dollarhex_addr16h): Likewise. ++ (print_dollarhex_addr16l): Likewise. ++ (print_dollarhex_p): Likewise. ++ (print_dollarhex_cj): Likewise. ++ (print_decimal): Likewise. ++ * cpu/xstormy16.opc (parse_mem8): Use ISALNUM rather than isalnum. ++ ++2002-11-30 Hans-Peter Nilsson ++ ++ * doc/rtl.texi (Model variants): Mention current limitations for ++ unit inputs and outputs. ++ (Hardware elements) : Be slightly more ++ verbose. ++ (Instructions) : input/output overrides have a direction ++ operand. ++ ++2002-11-25 DJ Delorie ++ ++ * xstormy16.cpu (sdiv, divlh, sdivlh): Fix sdivlh/divlh encodings. ++ ++2002-11-21 Jeff Johnston ++ ++ * cpu/iq10.cpu: New file. ++ * cpu/iq2000.cpu: Likewise. ++ * cpu/iq2000.opc: Likewise. ++ * cpu/iq2000m.cpu: Likewise. ++ ++2002-11-19 DJ Delorie ++ ++ * cpu/xstormy16.cpu (sdiv, divlh, sdivlh): New. ++ ++2002-11-05 Frank Ch. Eigler ++ ++ * dev.scm: Call getenv with a string, not a symbol. ++ ++2002-10-08 Doug Evans ++ Hans-Peter Nilsson ++ ++ * types.scm (bitrange-overlap?): Handle lsb0?. ++ ++2002-09-07 Frank Ch. Eigler ++ ++ From Robert Cragie : ++ * cpu/arm7.cpu (ldm*-sw*, stm*-sw*): New instructions. ++ ++2002-07-17 Frank Ch. Eigler ++ Ben Elliston ++ John Healy ++ Jeff Johnston ++ Alan Lehotsky ++ Ubicom Inc. ++ ++ * cpu/ip2k.cpu: New file. ++ * cpu/ip2k.opc: Likewise. ++ ++2002-07-01 Hans-Peter Nilsson ++ ++ * utils-gen.scm (-gen-extract-word): Handle lsb0?. ++ ++2002-06-25 J"orn Rennecke ++ ++ * cpu/sh64-compact.cpu (movw5): Use Correct operand field for reg. ++ * cpu/sh64-media.cpu (-ldhi-byte, -ldhi-word, -ldhi-long): New macros. ++ (-ldlo-byte, -ldlo-word, -ldlo-long): Likewise. ++ (-sthi-word, -sthi-long -stlo-byte, -stlo-word, -stlo-long): Likewise. ++ (ldhil, ldhiq, ldlol, ldloq, stlol, stloq): Implement. ++ (mshfhib, mshfhil, mshfhiw, mshflob, mshflol, mshflow): Fix indices. ++ (-sthi-byte): If there is a single byte to store, store it at ++ proper address. ++ (sthil, sthiq): Fix big-endian behaviour. ++ (mcnvslw, mcnvswb, mcnvswub, mmacfxwl, mmacnfx.wl): Fix indices. ++ (mmulfxl, mmulfxw, mmulfxrpw, mmulhiwl, mmullowl): Likewise. ++ (saturate): Use Dimode to check if saturation operation is required. ++ (usaturate): Likewise. ++ (mpermw): Fix mask. ++ (-maddsl, -maddsub): Compute to-be-saturated value in wider mode. ++ (-maddsw, mmacfxwl, mmacnfx.wl, -mshaldsl, -mshaldsw): Likewise. ++ (-mshardl, -mshardw, -msubsl, -msubsub, -msubsw): Likewise. ++ (msadubq): Fix subword index in second operand of first subtraction. ++ ++2002-06-20 Hans-Peter Nilsson ++ ++ * sim-cpu.scm (gen-semantic-code): Prepend with setup-semantics ++ code. ++ ++2002-06-18 Dave Brolley ++ ++ * cpu/frv.cpu: New cpu description. ++ * cpu/frv.opc: New cpu support code. ++ ++2002-05-21 Dave Brolley ++ ++ * decode.scm (-opcode-slots): Don't consider bits beyond the ++ length of the insn. ++ ++2002-05-17 Johan Rydberg ++ ++ * cpu/powerpc.cpu: New file. ++ ++2002-05-01 Graydon Hoare ++ ++ * desc-cpu.scm (@arch@_cgen_cpu_close): Fix memory leaks. ++ ++2002-03-20 Hans-Peter Nilsson ++ ++ * doc/pmacros.texi (Symbol concatenation): Mention that .sym ++ results are expanded recursively. ++ ++2002-03-19 Hans-Peter Nilsson ++ ++ * pmacros.scm (-pmacro-expand,scan): If result is a symbol, ++ call scan-symbol on it, to enable recursive macro-expansion. ++ ++2002-01-25 Frank Ch. Eigler ++ ++ * sid-cpu.scm (-gen-hardware-types): Generate single hardware union ++ for multiple-isa configurations. ++ * sid-decode.scm (-gen-decode-fn): Tolerate empty insn list. ++ ++2002-02-04 Ben Elliston ++ ++ * cpu/sh.cpu, cpu/sh.opc: New files. ++ * cpu/sh64-comact.cpu, cpu/sh64-media.cpu: Likewise. ++ ++2002-01-29 Hans-Peter Nilsson ++ ++ * doc/rtl.texi: Fix typo: define-attr, not define-attribute. ++ (Enumerated constants): Mention that an ifield must not specify a ++ multi-ifield. ++ (Instruction operands): Ditto for index. ++ (Expressions) : Remove misplaced mention of local ++ variables. ++ : Mention that mode must be specified and non-VOID when the ++ result is used. ++ ++2002-01-28 Hans-Peter Nilsson ++ ++ * doc/porting.texi: When referring to *.opc, mention they are in ++ the cpu subdir. Call top-level directory toplevel, not devo. ++ Close string in define-normal-insn example. ++ ++ * doc/pmacros.texi: Fix .substr typo to .substring. ++ Mention that .sym expansions are not further expanded. ++ ++2002-01-22 Graydon Hoare ++ ++ * desc-cpu.scm (ifld-number-cache): Add. ++ (ifld-number): Add. ++ (gen-maybe-multi-ifld-of-op): Add. ++ (gen-maybe-multi-ifld): Add. ++ (gen-multi-ifield-nodes): Add. ++ (cgen-desc.c): Add call to gen-multi-ifield-nodes. ++ ++2002-01-10 matthew green ++ ++ * cpu/xstormy16.cpu (gr-Rbj-names): Rename this ... ++ (gr-Rb-names): ... to this. ++ (h-Rb): New hardware piece. ++ (h-Rbj): Use gr-Rb-names. ++ (Rb): Use h-Rb. ++ (holdx): New instruction. ++ ++2002-01-07 Ben Elliston ++ ++ * utils.scm (package-cygnus-simulators): Rename from this .. ++ (package-red-hat-simulators): .. to this. ++ * opcodes.scm (option-set!): Use package-red-hat-simulators. ++ * sid-cpu.scm (cgen-desc.h): Likewise. ++ (cgen-cpu.h): Likewise. ++ (cgen-defs.h): Likewise. ++ (cgen-write.cxx): Likewise. ++ (cgen-semantics.cxx): Likewise. ++ (cgen-sem-switch.cxx): Likewise. ++ * sid-decode.scm (cgen-decode.h): Likewise. ++ (cgen-decode.cxx): Likewise. ++ * sid-model.scm (cgen-model.cxx): Likewise. ++ * sid.scm (option-set!): Likewise. ++ * sim.scm (option-set!): Likewise. ++ ++2002-01-07 Ben Elliston ++ ++ * utils.scm (copyright-fsf): Add 2002. ++ (copyright-cygnus): Rename to copyright-red-hat. ++ (copyright-red-hat): Add 2002. ++ (CURRENT-COPYRIGHT): Update comment. ++ * opcodes.scm (option-set!): Update callers. ++ * sid-model.scm (cgen-model.cxx): Likewise. ++ * sid-cpu.scm: Likewise. ++ * sid-decode.scm: Likewise. ++ * sid.scm (option-set!): Handle "redhat" as an option for ++ "copyright"; use copyright-red-hat. ++ * sim.scm (option-set!): Likewise. ++ ++2002-01-03 Dave Brolley ++ ++ * decode.scm (-distinguishing-bit-population): Compute num-insns, the ++ number of insns in the list. Update the population count function to ++ identify and prioritize 3 catgories of useful bits. ++ (-population-top-few): Don't consider bits with a population count of ++ zero. ++ (-build-decode-table-entry): Don't call ++ filter-harmlessly-ambiguous-insns. Filter out non-specialized and ++ identical insns at the next tree level. ++ * insn.scm (filter-harmlessly-ambiguous-insns): Note in a comment that ++ this function is no longer used. ++ (filter-non-specialized-ambiguous-insns): New function. ++ (filter-identical-ambiguous-insns): New function. ++ (find-identical-insn): New function. ++ (filter-harmlessly-ambiguous-insns): Removed. ++ ++2001-11-26 Geoffrey Keating ++ matthew green ++ Frank Ch. Eigler ++ Nick Clifton ++ ++ * cpu/xstormy16.cpu: New file. ++ * cpu/xstormy16.opc: New file. ++ ++2001-11-26 Frank Ch. Eigler ++ ++ * doc/sim.texi, rtl.texi, porting.texi: Correct texinfo markup typos. ++ ++2001-11-14 Dave Brolley ++ ++ * utils-gen.scm (-gen-extract-word): Correct computation of the length ++ of the field being extracted. ++ ++2001-10-29 Johan Rydberg ++ ++ * doc/rtl.texi (Expressions): Document the (error ..), (sqrt ..), ++ (cos ...) and (sin ..) rtx. ++ ++2001-10-13 Nick Clifton ++ ++ * desc-cpu.scm: Do not include ctype.h in generated desc ++ files. They will inherit safe-ctype.h instead. ++ ++2001-10-08 Nick Clifton ++ ++ * desc-cpu.scm: Add missing function prototypes (for generated ++ C files). Fix compile time warning messages about unused ++ parameters (for generated C files). ++ * opc-asmdis.scm: The same. ++ * opc-ibld.c: The same. ++ * opc-itab.scm: The same. ++ * cpu/fr30.opc: The same. ++ * cpu/m32r.opc: The same. ++ * cpu/openrisc.opc: The same. ++ ++2001-09-17 graydon hoare ++ ++ * insn.scm (syntax-break-out): Correct logic in handling escaped ++ syntax characters. ++ ++2001-07-12 Jeff Johnston ++ ++ * opc-itab.scm (@arch@_cgen_init_opcode_table): Unconditionally ++ call @arch@_cgen_build_insn_regex now that regex support is in ++ libiberty. ++ ++2001-07-12 Frank Ch. Eigler ++ ++ * insn.scm (filter-harmlessly-ambiguous-insns): Fix msg typo. ++ (mask-superset?): Look for strict supersets to allow rejection of ++ duplicate insns. ++ ++2001-07-11 Frank Ch. Eigler ++ ++ * sid-cpu.scm (-gen-mach-params): New proc to emit ...CHUNK_BITSIZE... ++ (cgen-desc.h): Call it. ++ * sid-decode.scm (-gen-decode-fn): Use base-insn-bitsize as ++ decode-size. ++ * utils-sim.scm (-gen-decode-insn-entry): For SID only, prepare ++ entire_insn for extraction, if it's shorter than base-insn-bitsize. ++ ++2001-07-11 Frank Ch. Eigler ++ ++ * desc-cpu.scm (-gen-mach-table-defns): Emit fourth field: the ++ mach->cpu insn-chunk-bitsize. ++ (-gen-cpu-open): In @arch@_cgen_rebuild_tables, process above new ++ field toward CGEN_CPU_TABLE->insn_chunk_bitsize. ++ * mach.scm (): New field insn-chunk-bitsize. ++ (-cpu-parse, -cpu-read): Parse/initialize it. ++ * doc/rtl.texi (define-cpu): Document it. ++ ++2001-07-09 Geoffrey Keating ++ ++ * ifield.scm ( 'field-start): Don't look at word-len. ++ ++2001-07-06 Ben Elliston ++ ++ * opcodes.scm (read-cpu.opc): Read .opc files from subdir/cpu. ++ ++2001-07-05 Ben Elliston ++ ++ * README: Update. ++ ++ * read.scm (include): Include files from srcdir/cpu. ++ (-cgen): Likewise for loading .cpu files. ++ * sid.scm (sim-finish!): Read .sim files from srcdir/cpu. ++ * *.cpu: Move all cpu descriptions into cpu subdirectory. ++ * *.opc: Likewise. ++ * simplify.inc: Likewise. ++ ++2001-07-04 Ben Elliston ++ ++ * read.scm (include): Log "Including file" message at level 1, ++ rather than outputting it with (display). ++ (cpu-load): Log "Loading cpu description" and "Processing cpu ++ description" messages at levels 1 and 2, respectively, rather than ++ using (display). ++ ++2001-06-14 Geoffrey Keating ++ ++ * desc.scm ( 'gen-defn): Add extra zero into ++ CGEN_KEYWORD_ENTRY initializers. ++ ++ * gas-test.scm (gen-gas-test): Create 8 testcases, not just 5. ++ ( 'test-data): Involve both the index and the hardware ++ in testcase generation. ++ ( 'test-data): Generate test data from the underlying ++ object. ++ ( 'test-data): Generate test data by computing bit ++ patterns for the field, then decoding them. ++ ( 'test-data): Allow for new calling convention. ++ ( 'test-data): Likewise. ++ ( 'test-data): Convert index values into keywords. ++ ( 'test-data): Convert index values into integer strings. ++ ++ * gas-test.scm (cgen-build.sh): Escape '.' as well. ++ ++2001-06-01 Frank Ch. Eigler ++ ++ * rtl.scm (hw): Encode hw access mode into name, since this ++ is required for multi-mode hw types (memory). ++ ++2001-05-11 Ben Elliston ++ ++ * gas-test.scm (cgen-build.sh, gentest): Escape $ with a backslash ++ when generating allinsn.d from objdump output. Without it, the ++ testsuite will treat $ as the regular expression for end of line. ++ ++2001-05-09 Ben Elliston ++ ++ * doc/porting.texi (Doing a GAS port): Replace `cgen_opcode_open' ++ with `cgen_cpu_open'; documentation had become out of date. ++ * doc/rtl.texi (Instruction operands): Likewise. ++ ++2001-05-07 Frank Ch. Eigler ++ ++ * iformat.scm (compute-insn-base-mask-length): Rewrite to tolerate ++ various-base-length instruction sets. ++ ++2001-04-02 Ben Elliston ++ ++ * sid-cpu.scm (-last-insn): New function. ++ (-gen-sem-switch-engine): Loop through idesc while less than or ++ equal to the last instruction enum, not less than the MAX enum. ++ (-gen-sfrag-engine-fn): Clean up frag_label_table initialisation. ++ * sid-decode.scm (-gen-decode-insn-globals): Define the idesc ++ table's size to be the last instruction enum plus one, not ++ @PREFIX@_INSN_MAX. ++ * sid.scm (gen-cpu-insn-enum-decl): Do not append a dummy `max' ++ instruction onto the instruction list. ++ ++ * sim-decode.scm (@prefix@_init_idesc_table): Compute tabsize ++ using the size of the table and its elements. ++ (-gen-decode-insn-globals): Define the idesc table's size to be ++ the last instruction enum plus one, not @PREFIX@_INSN_MAX. ++ * sim-model.scm (-gen-mach-defns): Define CPU_MAX_INSNS as the ++ last instruction enum plus one, not @CPU@_INSN_MAX. ++ ++2001-03-28 Ben Elliston ++ ++ * doc/version.texi (UPDATED, EDITION): Update. ++ * doc/stamp-vti: Likewise. ++ ++2001-03-26 Ben Elliston ++ ++ * doc/credits.texi (Credits): Update. ++ ++ * gas-test.scm (,test-data): Prefix keywords by their ++ specified prefix and, if necessary, escape `$' in gas-build.sh to ++ prevent unwanted shell variable expansion. ++ ++2001-03-24 Ben Elliston ++ ++ * gas-test.scm (,test-data): Choose pseudo-random data. ++ (,test-data): Likewise. ++ (,test-data): Likewise. ++ (,test-data): Likewise. ++ (-collate-test-set): New function. ++ (build-test-set): Use it. ++ (gen-gas-test): Generate five test cases per instruction. ++ (cgen-allinsn.exp): Include "-*- Tcl -*-" in DejaGNU test file. ++ ++ * read.scm: Load "slib/random" if random is not defined. ++ * slib/random.scm: New file. ++ ++ * utils.scm: Remove comments about the Hobbit compiler. ++ (copyright-cygnus): Add 2001. ++ (package-cygnus-simulators): Replace "Cygnus" with "Red Hat". ++ (package-gnu-simulators): Tidy. ++ ++2001-03-23 Ben Elliston ++ ++ * cgen-gas.scm: Inline documentation improvements. ++ ++2001-03-21 Ben Elliston ++ ++ * opc-itab.scm (compute-syntax): Emit a parse error if an operand ++ given in a syntax string is undefined. ++ ++ * opc-itab.scm (compute-syntax): Emit a parse error if an operand ++ name is empty or invalid -- eg. "$(rs)" instead of "($rs)". ++ ++2001-03-20 Patrick Macdonald ++ ++ * desc-cpu.scm (@arch@_cgen_cpu_open): Correct machine calculation ++ for arg_type CGEN_CPU_OPEN_BFDMACH. ++ ++2001-03-20 Ben Elliston ++ ++ * opc-itab.scm (-gen-insn-enum): Do not append a dummy `max' ++ instruction onto the instruction list. Define MAX_INSNS to be the ++ value of the last instruction enum plus one. ++ ++2001-03-14 Nick Clifton ++ ++ * utils.scm (copyright-fsf): Add 2001. Remove (C). ++ ++2001-03-05 Dave Brolley ++ ++ * sim-decode.scm (-gen-extract-case): Generate declaration of "insn" ++ if the number of ifields is greater than zero. ++ ++2001-03-01 Frank Ch. Eigler ++ ++ * sid.cpu (-op-gen-set-trace[-parallel], -create-virtual-insns!): ++ Emit LIKELY/UNLIKELY branch probability hints. ++ * sid-decode.cpu (-gen-record-args): Ditto. ++ ++2001-02-02 Patrick Macdonald ++ ++ * desc-cpu.scm (-gen-hash-defines): Rename ++ CGEN_ACTUAL_MAX_SYNTAX_BYTES to CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS. ++ ++2001-01-26 Frank Ch. Eigler ++ ++ * sid-cpu.scm (gen-parallel-exec-type): Use unsigned long long for ++ writeback tracking. ++ (-gen-write-fn, -gen-sem-case, -gen-sfrag-case): Ditto. ++ * sid-decode.scm (-gen-scache-decls): Exclude writeback tracking field ++ if unnecessary. ++ * sid.scm ( gen-write): Use unsigned long long expression ++ for writeback. ++ (-op-gen-set-trace, -op-gen-set-trace-parallel): Ditto. ++ ( gen-profile-code): Ditto. ++ ++2001-01-23 Johan Rydberg ++ ++ * doc/rtl.texi (Expressions): Document the (index-of ...) and ++ (regno ...) rtx. ++ ++2001-01-08 Frank Ch. Eigler ++ ++ * operand.scm ( pretty-sem-name): New field. ++ ( make): Initialize it from hw-name. ++ (op:set-pretty-sem-name!): New function. ++ ( gen-pretty-name): Default to fetching new field. ++ * rtl.scm (hw): Copy hw-name to pretty-sem-name instead. Restore ++ sem-name setting from -rtx-hw-name. ++ ++2001-01-08 Frank Ch. Eigler ++ ++ * rtl.scm (hw): Copy hw-name to new operand's sem-name, to simplify ++ its subsequent gen-pretty-name. ++ ++ * read.scm: Increase thread working stack limit and backtrace ++ depth limits. ++ ++2001-01-08 Frank Ch. Eigler ++ ++ * doc/rtl.texi: Deprecate and depreciate the decode-assist construct. ++ ++2001-01-06 Johan Rydberg ++ ++ * openrisc.cpu (or32): Setup semantics for h-delay-insn to ++ current insn plus 4. ++ (h-delay-insn): New hardware register. ++ (l-jal): Uses h-delay-insn instead of pc when setting link register. ++ (l-jalr): Likewise. ++ (l-bal): Likewise. ++ ++ * openrisc.opc (parse_hi16): Sign extend value. ++ (parse_lo16): Likewise. ++ ++2001-01-06 Ben Elliston ++ ++ * utils-gen.scm (gen-sfmt-enum-decl): Use @prefix@ and @PREFIX@ ++ instead of @cpu@ and @CPU@ to generically prefix symbol names. ++ * sim-cpu.scm (-gen-sem-fn-table-entry): Likewise. ++ (-gen-semantic-fn-table): Likewise. ++ (-gen-scache-semantic-fn): Likewise. ++ (-gen-no-scache-semantic-fn): Likewise. ++ (cgen-read.c): Likewise. ++ (cgen-sem-switch.c): Likewise. ++ * desc-cpu.scm (cgen-desc.c): Use @arch@, not @prefix@, since this ++ is a filename prefix. ++ * sim-decode.scm (IDESC-TABLE-VAR): Use @prefix@, et al. ++ (-gen-decode-insn-globals): Likewise. ++ (-gen-idesc-decls): Likewise. ++ (cgen-decode.h): Likewise. ++ (cgen-decode.c): Likewise. ++ * sim.scm (gen-cpu-insn-enum-decl): Likewise. ++ (gen-cpu-insn-enum): Likewise. ++ (sim-finish!): Likewise. ++ ++2001-01-05 Johan Rydberg ++ ++ * openrisc.cpu: New file. ++ * openrisc.opc: Likewise. ++ ++2000-12-12 Ben Elliston ++ ++ * doc/rtl.texi (Expressions): Document the (delay ..) rtx. ++ ++2000-12-07 Ben Elliston ++ ++ * sim-decode.scm (-gen-extract-case): Do not emit a definition for ++ "insn" when there are zero ifields to extract. ++ ++2000-12-04 Frank Ch. Eigler ++ ++ * utils-sim.scm (gen-define-argbuf-macro): Handle sfmt=#f case, to be ++ used by simple/non-scache simulators. ++ * sim-cpu.scm (-gen-read-case): Call gen-define/undef-field-macro ++ regardless of with-scache?. ++ (-gen-write-case, -gen-no-scache-semantic-fn, -gen-sem-case): Ditto. ++ ++2000-12-03 Ben Elliston ++ ++ * desc-cpu.scm (cgen-desc.h): Clarify generated filenames. ++ (cgen-desc.c): Likewise. ++ ++2000-12-01 Greg McGary ++ ++ * desc.scm (,gen-defn): Prepend prefix to keyword names. ++ ++2000-12-01 Ben Elliston ++ ++ * sim-cpu.scm (cgen-cpu.h): Only emit argbuf, scache and extract ++ definitions if run without with-multipla-isa?. ++ (cgen-defs.h): New function. Emit an ISA-specific defs file. ++ * cgen-sim.scm (sim-arguments): Accept -G option to generate defs. ++ ++2000-11-24 Ben Elliston ++ ++ * sim-cpu.scm (-gen-hardware-struct): New function. ++ (-gen-hardware-types): If with-multiple-isa is specified, emit all ++ hardware elements wich have share one or more ISAs with the ISAs ++ being kept. ++ ++ * sim.scm (-with-multiple-isa?): New symbol. ++ (with-multiple-isa?): New function. ++ (option-init!): Initialise -with-multiple-isa?. ++ (option-set!): Handle with-multiple-isa option. ++ ++2000-11-21 Ben Elliston ++ ++ * utils.scm (copyright-fsf): Add the year 2000. ++ ++2000-11-20 Frank Ch. Eigler ++ ++ * opc-itab.scm (-gen-ifmt-table, -gen-macro-insn-table: Remove ++ unneeded "\n\n" from F() macro definition. ++ ++2000-11-15 Greg McGary ++ ++ * utils-cgen.scm (gen-define-with-symcat): New function. ++ * desc-cpu.scm (gen-ifld-defns): Use it. ++ (gen-hw-table-defns): Use it. ++ (-gen-hash-defines): Use it. ++ (gen-operand-table): Use it. ++ (gen-insn-table): Use it. Remove spurious `#undef MNEM'. ++ * opc-itab.scm (-gen-ifmt-table): Use it. ++ (-gen-insn-opcode-table): Use it. ++ (-gen-macro-insn-table): Use it. ++ * opc-opinst.scm (-gen-operand-instance-tables): Use it. ++ * sim-cpu.scm (cgen-semantics.c): Use it. ++ (cgen-sem-switch.c): Use it. ++ ++2000-11-10 Frank Ch. Eigler ++ ++ * utils-sim.scm (-gen-decode-insn-entry): Add fn? parameter to signal ++ request to emit calls to insn extractors as functions rather than ++ branches to inline blocks. ++ (-gen-decode-expr-set-itype, -gen-decode-expr-entry): Ditto. ++ (-gen-decode-table-entry, -gen-decoder-switch, gen-decoder): Ditto. ++ ++ * sim-decode.c (-gen-decode-fn): Tell (gen-decode) to emit branches ++ to extractor clauses. ++ ++2000-11-10 Frank Ch. Eigler ++ ++ * decode.scm (-distinguishing-bit-population): Significantly ++ improve popularity heuristic. Renamed from ++ (-mask-bit-population): Gone. ++ (-population-above-threshold): Sort new bit numbers in order of ++ popularity. ++ (-population-top-few): Allow up to three more bits to be selected ++ than requested. Correct selection order to prefer better bits. ++ Correct bug in fewer-than-requested case. Keep threshold as ++ floating-point. ++ (decode-best-get-bits): Pass also the insn-values. ++ ++ * utils-sim.scm (-gen-decoder-switch): Add comment suggesting a ++ future optimization. ++ ++ * utils.scm (message): Format nested lists better. ++ ++2000-11-09 Doug Evans ++ ++ * dev.scm: Add srcdir to %load-path. ++ ++ * rtx-funcs.scm (subword): Mode of argument can be different ++ than mode of result, so don't use OP0 to specify argument's mode. ++ ++2000-11-02 Ben Elliston ++ ++ * doc/porting.texi (Building a GAS test suite): Document my change ++ to gas-build.sh. ++ ++2000-11-01 Ben Elliston ++ ++ * sim-test.scm (cgen-build.sh): Include "-*- Asm -*-" in test cases. ++ ++2000-10-31 Ben Elliston ++ ++ * gas-test.scm (cgen-build.sh): Allow the generated script to run ++ with no command line arguments if the gas build directory can be ++ determined. ++ ++2000-10-26 Doug Evans ++ ++ * insn.scm (-parse-insn-format-symbol): Fix spelling error, ++ op-ifld -> op-ifield. ++ ++2000-10-23 Frank Ch. Eigler ++ ++ * thumb.scm (cc-tests): Add (ISA thumb) attribute. ++ ++2000-10-13 matthew green ++ ++ * utils-cgen.scm (get-ifetch): Move from here ... ++ * sim.scm (get-ifetch): ... to here. ++ * sid.scm (get-ifetch): Copy and port to c++. ++ ++2000-10-06 Dave Brolley ++ ++ * utils-gen.scm (-gen-ifld-extract-base): Compute start position as ++ ifld-start + ifld-word-offset. ++ (gen-ifld-extract): Check adata-integral-insn? before checking whether ++ the field is beyond the base number of bits. ++ (gen-define-ifields): Use a base-length of 32 if adata-integral-insn?. ++ (gen-extract-ifields): Ditto. ++ * gas-test.scm (gentest): Generate backslashes before '[' and ']' ++ characters in the regular expression. ++ ++2000-10-02 Frank Ch. Eigler ++ ++ * desc-cpu.scm: (gen-operand-decls): Emit MAX_OPERANDS as a ++ preprocessor constant. ++ ++2000-09-21 Frank Ch. Eigler ++ ++ * slib/logical.scm: New file from slib. Provides robust bitwise ++ logical operations for large integers. ++ * read.scm: maybe-load it. ++ ++2000-09-15 Frank Ch. Eigler ++ ++ * enum.scm (define-full-insn-enum): Filter with keep-isa predicate. ++ * ifield.scm (-ifield-parse, -multi-ifield-parse): No longer assert ++ single-isa predicate, but support keep-isa filtering. ++ ++2000-09-08 Frank Ch. Eigler ++ ++ * rtl-c.scm (s-sequence): Handle nested c-calls in both ++ statement-expression and comma-expression contexts. ++ (s-c-call, s-c-raw-call): Add warning comment about bad assumption. ++ ++2000-09-08 Frank Ch. Eigler ++ ++ * decode.scm (-population-top-few): Signal error gracefully if ++ decoding is about to become ambiguous. ++ ++2000-09-06 Frank Ch. Eigler ++ ++ * doc/rtl.texi (decode-assist): Describe this field as optional. ++ ++2000-09-06 Frank Ch. Eigler ++ ++ * utils-gen.scm (gen-multi-ifld-extract): Handle case of multi-ifield ++ with decode proc. ++ ++2000-09-05 Dave Brolley ++ ++ * sim.scm (sim-finish!): Honour the definition of FAST_P when calling ++ @cpu@_pbb_begin. Use 0 if FAST_P is not defined. ++ ++2000-08-29 Dave Brolley ++ ++ * utils-gen.scm (gen-ifld-extract): Pass total-len if ++ adata-integral-insn is true for this architecture. ++ ++2000-08-24 Frank Ch. Eigler ++ ++ * hardware.scm ( get-index-mode): Define method. ++ * operand.scm ( gen-pretty-name): Tolerate no op:sem-name. ++ * rtl-c.scm (-c-rtl-get): Improve an error message. ++ * sim.scm (-op-gen-set-trace): Support lvalues. ++ ++2000-08-22 Frank Ch. Eigler ++ ++ * Makefile.in (DIST_COMMON): Regenerated. ++ * ifield.scm ( needed-iflds): New method. ++ * iformat.scm (-ifmt-lookup-sfmt!): Use base ifields for ++ sfmts built from s. ++ * operand.scm (-derived-parse-encoding): Give a fixed ++ type symbol 'derived-ifield, not an unparseable string. ++ * utils-sim.scm (op-needed-iflds) Handler 'derived-ifield case. ++ (-sfmt-contents): Add tracing. ++ ++ From Doug Evans : ++ * sim.scm ( cxmake-get): Result is a , not a string of ++ C code. ++ ++2000-08-20 Doug Evans ++ ++ * rtl-c.scm (rtl-c-expr-with-estate): New fn. ++ (rtl-c-expr-parsed,rtl-c-expr): New fns. ++ (-rtl-c-get): Rename from rtl-c-get. ++ (rtl-c-get): New fn for getter logging. ++ ++2000-07-28 Ben Elliston ++ ++ * NEWS: Update. ++ ++2000-07-25 Ben Elliston ++ ++ * doc/credits.texi (Credits): Add Frank Eigler. ++ ++2000-07-24 Dave Brolley ++ ++ * opc-itab.scm (gen-insn-opcode-table): Initialize the first element ++ fully. ++ * desc.scm (gen-attr-table-defn): Initialize all elements fully. ++ (): Initialize all elements fully. ++ * desc-cpu.scm (-gen-isa-table-defns): Initialize the last element ++ fully. ++ (-gen-mach-table-defns): Ditto. ++ (-gen-ifld-defns): Ditto. ++ (-gen-operand-table): Ditto. ++ (-gen-insn-table): Ditto. ++ (-gen-cpu-open): Nothing to do for the mach table. ++ ++2000-07-13 Ben Elliston ++ ++ * doc/version.texi (UPDATED): Update. ++ ++2000-07-05 Ben Elliston ++ ++ * configure.in (AC_PATH_PROG): Remove. ++ * configure: Regenerate. ++ * Makefile.am (GUILE): Locate guile dynamically. ++ * Makefile.in: Regenerate. ++ * doc/Makefile.in: Likewise. ++ ++2000-07-03 Ben Elliston ++ ++ * desc-cpu.scm (cgen-desc.c): Include "libiberty.h". ++ * opc-itab.scm (cgen-opc.c): Likewise. ++ ++2000-06-28 Frank Ch. Eigler ++ ++ * rtl.scm (-rtx-traverse-locals): Correct call to `symbol?' for ++ guile 1.4 compatibility. ++ (rtx-env-dump): Comment out buggy display calls. ++ ++2000-06-15 matthew green ++ ++ * opc-itab.scm (-gen-ifmt-table-1): Add extra braces to pacify GCC. ++ ++2000-06-14 Frank Ch. Eigler ++ ++ * Makefile.in: Regenerated. ++ ++ * desc-cpu.scm (gen-ifld-decls): Exclude derived ifields. ++ (gen-ifld-defns): Ditto. ++ * pgmr-tools.scm (pgmr-pretty-print-insn-format): Ditto. ++ * rtl.c (rtl-finish!): Ditto. ++ * opc-itab.scm (-gen-ifield-decls): Ditto. ++ * opcodes.scm (gen-switch): Exclude derived operands. ++ * operand.scm (op-iflds-used): Expand derived operands. ++ (hw-index-derived): New dummy function to create dummy object. ++ (-derived-operand-parse): Fix mode arg passed to ++ constructor. Set object's hw-name and index fields. ++ (-anyof-merge-subchoices): Set instance object's index also. ++ (-anyof-name): New helper function. ++ (anyof-merge-semantics): Correct replacement of operand names in ++ anyof instance. ++ (op-ifield): Tolerate derived-operands and their funny indices better. ++ * ifield.scm (ifld-known-values): Expand derived ifields. ++ (non-multi-ifields, non-derived-ifields): New utility functions. ++ (ifld-decode-mode): Tolerate objects with unbound decode field. ++ * iformat.scm (compute-insn-length): Expand derived ifields. ++ (compute-insn-base-mask): Ditto. ++ * insn.scm (insn-base-ifields): Remove. ++ (): Add iflds-values entry to cache ifld-base-ifields values. ++ (insn-value): Call ifld-base-ifields and ifld-constant? instead. ++ * mach.scm (arch-analyze-insns!): Exclude multi-insns. ++ * sem-frags.scm (sim-sfrag-analyze-insns!): Ditto. ++ (-frag-test-data): Ditto. ++ * sid-cpu.scm (cgen-write.cxx,-gen-sem-switch): Ditto. ++ (-gen-sem-switch-engine); Ditto. ++ * sid-model.scm (-gen-model-insn-fns, -gen-model-timing-table): Ditto. ++ * sid-decode.scm (cgen-decode.h, cgen-decode.cxx): Ditto. ++ (-gen-record-args): Tolerate unbound op-ifield. ++ * sid.scm ( cxmake-get): New sketch implementation. ++ (-gen-arch-model-decls, scache-engine-insns, pbb-engine-insns): ++ Exclude multi-insns. ++ * sim-decode.scm (cgen-decode.h, cgen-decode.cxx): Ditto. ++ * utils-sim.scm (op-extract?): Handle derived operands. ++ ++ * gas-test.scm (cgen-build.sh): Quote '*' chars printed by objdump. ++ * semantics.scm (-build-operand!): Handle 'DFLT case during parsing. ++ * hardware.scm (hardware-for-mode): New function. ++ ++ * insn.scm (filter-harmlessly-ambiguous-insns): New function for ++ cleaning up decode tables. ++ (mask-superset?): Little helper function for above. ++ * decode.scm (-build-decode-table-entry): Call it. ++ (-opcode-slots): Add some more tracing. ++ * arm.cpu: Disable decode-splits construct due to implementation ++ conflict with `filter-harmlessly-ambiguous-insns' ++ ++ * decode.scm (-population-top-few): New function for better decode ++ bit generation. Includes minor helper functions. ++ (decode-get-best-bits): Call it instead. ++ (OLDdecode-get-best-bits): Renamed previous version of above. ++ ++ ++2000-06-13 Ben Elliston ++ ++ * configure.in: Use AC_EXEEXT with Cygnus mode. Remove AC_ARG_WITH ++ for the Guile library directory. ++ * configure: Regenerate. ++ * Makefile.in, doc/Makefile.in: Regenerate. ++ ++ * Makefile.in, doc/Makefile.in: Regenerate. ++ * configure.in: Remove unnecessary tests. Move to version 1.0. ++ * acconfig.h, config.in: Remove. ++ * configure, aclocal.m4: Regenerate. ++ * doc/stamp-vti, doc/version.texi: Likewise. ++ * AUTHORS: New file. ++ ++2000-06-07 Ben Elliston ++ ++ * fixup.scm (symbol-bound?): Reduce debugging output. ++ ++2000-06-02 matthew green ++ ++ * insn.scm (insn-base-ifields): Returns all the instruction fields for ++ a given instruction, replacing derived fields with their subfields. ++ (insn-value): Use `insn-base-ifields' to find all constant values. ++ (multi-insn-instantiate!): Comment some debug messages. ++ ++2000-06-01 Ben Elliston ++ ++ * doc/rtl.texi (Expressions): Document a hazard with the choice of ++ symbol names used in a (c-call ..) rtx. ++ ++ * sim-test.scm (build-test-set): Return (()) for an instruction ++ with no operands, so it too is included in the generated test set. ++ ++2000-05-31 Ben Elliston ++ ++ * Makefile.am (gas-test): Ensure $(ISA) is not empty. ++ (sim-test): Likewise. ++ * Makefile.in: Regenerate. ++ ++2000-05-30 Frank Ch. Eigler ++ ++ * read.scm (-cgen): In debugging mode (-b), ask guile for untruncated ++ stack traceback, in an order that resembles gdb's `bt'. ++ ++2000-05-24 Frank Ch. Eigler ++ ++ * desc-cpu.scm (-gen-hash-defines): Use ifmt-ifields again. ++ * opc-itab.scm (-gen-ifmt-table-1): Ditto. ++ * gas-test.scm (gas-test-analyze!, cgen-build.sh): Filter out ++ multi insns. ++ * ifield.scm (multi-ifield): Define workable field-mask and field-value ++ virtual functions. ++ (ifld-base-ifields): New routine to replace ifmt-expanded-ifields. ++ * iformat.scm (ifmt-expanded-ifields): Gone. ++ (ifields-base-ifields): New function. Call ifld-base-ifields for real ++ work. ++ (-ifmt-lookup-ifmt!): Use it to expand derived/multi combos in new ++ ifmt entries. ++ ++ * opcodes.scm (multi-ifield gen-extract): Correct spacing in generated ++ code. ++ ++2000-05-23 Frank Ch. Eigler ++ ++ * sid.scm (with-any-profile?): New function clone. ++ ++2000-05-19 Frank Ch. Eigler ++ ++ * utils-gen.scm (gen-multi-ifld-extract): Fix decode hook for sim. ++ ++2000-05-18 Frank Ch. Eigler ++ ++ * ifield.scm (-multi-ifield-parse): Add encode/decode args. ++ (-multi-ifield-read): Parse them. ++ (define-full-multi-ifield): Pass #f/#f as defaults for them. ++ * opcodes.scm (multi-ifield gen-insert): Add encode hook. ++ (multi-ifield gen-extract): Add decode hook. ++ * utils-gen.scm (gen-multi-ifld-extract): Add decode hook for sim. ++ ++ * insn.scm (syntax-break-out): More correctly handle \-escaped ++ syntax characters. ++ (syntax-make-elements): Ditto. ++ * opc-itab.scm (compute-syntax): Ditto. ++ ++2000-05-17 Ben Elliston ++ ++ * gas-test.scm (cgen-build.sh): Log the correct script filename. ++ ++2000-05-15 Frank Ch. Eigler ++ ++ * gas-test.scm (build-test-set): Return (()) for an instruction ++ with no operands, so it too is included in the generated test set. ++ ++2000-05-15 Frank Ch. Eigler ++ ++ * desc-cpu.scm (-gen-hash-defines): Define CGEN_ACTUAL_MAX values for ++ IFMT_OPERANDS and SYNTAX_BYTES. ++ ++2000-05-15 Frank Ch. Eigler ++ ++ * sim.scm (with-any-profile?): New function. ++ * utils-sim.scm (-sfmt-contents): Use above instead of `with-profile?' ++ to decide whether or not to include profiling counters. ++ ++2000-05-10 Frank Ch. Eigler ++ ++ Fuller derived-operand support for opcodes. ++ * insn.scm (non-multi-insns): New filter to oppose `multi-insns'. ++ * desc-cpu.scm (-define-hash-defines): Compute CGEN_MAX_SYNTAX_BYTES. ++ Correctly compute ..._IFMT_OPERANDS. Omit useless ..._INSN_OPERANDS. ++ (gen-operand-table): Omit derived- and anyof- operands from table. ++ (gen-insn-table): Omit multi-insns from table. ++ * iformat.scm (ifmt-expanded-fields): New function to expand ++ subfields of derived-ifields. ++ (ifmt-compute!): Ignore remaining multi-insns. ++ * mach.scm (isa-min-insn-bitsize, isa-max-insn-bitsize): Ignore ++ multi-insns. ++ * opc-itab.scm (-gen-ifmt-table-1): Use ifmt-expanded-ifields. ++ (-gen-insn-enum, -gen-insn-opcode-table): Ignore multi-insns. ++ * opcodes.scm (derived-operand): Define abort()ing gen-insert, ++ gen-extract, gen-fget, gen-fset, gen-parse, gen-print functions. ++ (gen-switch): Omit anyof-operands. ++ * operand.scm (-anyof-syntax): New function. ++ (-anyof-merge-syntax): Call it. ++ * utils.scm (collect): New idiomatic function. ++ ++2000-05-10 Ben Elliston ++ ++ * m68k.cpu: New file (work in progress). ++ ++2000-05-05 Frank Ch. Eigler ++ ++ * Makefile.am (all-local): New target. Create stamp-cgen. ++ * Makefile.in: Regenerated. ++ * doc/Makefile.in: Regenerated. ++ ++2000-04-26 Frank Ch. Eigler ++ ++ * operand.scm (-operand-g/setter-syntax): Correct off-by-one error. ++ (-operand-parse-setter): Ditto. ++ * utils-sim.scm (needed-iflds): Store ifield (index) in argbuf, even ++ for CACHE-ADDR operands. ++ * sid-decode.scm (-gen-record-args): Remove newly duplicated extract ++ trace entries. Widen byte-wide values for printing. ++ * sid.scm (-op-gen-set-trace): Enhance result trace with op indices. ++ Widen byte-wide values for printing. Hexify memory addresses. ++ ++2000-04-23 matthew green ++ ++ * m32r.cpu: Fix a typo. ++ ++Fri Apr 21 22:18:48 2000 Jim Wilson ++ ++ * ia64.cpu (define-model): Change merced to Itanium. ++ (f-qp): Change quilifying to qualifying. ++ (movbr_ph, movbr_pvec): Delete. ++ (I-I21): Delete uses of movbr_ph and movbr_pvec. ++ ++2000-04-07 Ben Elliston ++ ++ * doc/porting.texi (Building a simulator test suite): Clarify ++ where generated test cases are placed. ++ ++2000-04-07 Ben Elliston ++ ++ * Makefile.am (gas-test): Remove dependency on `cgen'. ++ (sim-test): Ditto. ++ * Makefile.in: Regenerate. ++ ++2000-04-04 Frank Ch. Eigler ++ ++ * hardware.scm ( parse): Allow user to set type for pc register. ++ * mode.scm (mode-finish!): Add placeholder code for mach-dependent ++ type reconfiguration. ++ * utils-sim.scm (-sfmt-contents): Add profile-counters only if ++ with-profile?. ++ ++2000-03-30 Ben Elliston ++ ++ * doc/rtl.texi (Enumerated constants): Add concept index entries. ++ ++2000-03-24 Ben Elliston ++ ++ * Makefile.am (stamp-cgen): Reinstate target. ++ * Makefile.in: Regenerate. ++ ++2000-03-22 Ben Elliston ++ ++ * slib/ppfile.scm: Remove; unused. ++ * slib/defmacex.scm: Likewise. ++ ++2000-03-21 Ben Elliston ++ ++ * doc/internals.texi (Source file overview): Document. ++ ++ * Makefile.am (GUILEDIR): Remove. ++ (CGEN): Ditto. Callers use $(GUILE) instead. ++ (GUILEFLAGS): Ditto. ++ (CGENFILES): Ditto. ++ (APPDESCFILES): Ditto. ++ (OPCODESFILES): Ditto. ++ (SIMFILES): Ditto. ++ (pkgdata_SCRIPTS): Ditto. ++ (stamp-cgen): Remove target. ++ * Makefile.in: Regenerate. ++ ++ * configure.in: Remove header and library tests. ++ * configure: Regenerate. ++ * config.in: Likewise. ++ ++2000-03-20 Ben Elliston ++ ++ * read.scm: Cease loading "hob-sup.scm". ++ * utils.scm: Inherit the fastcall family of procedures (for now). ++ * hob-sup.scm: Remove. ++ ++2000-03-20 Ben Elliston ++ ++ * configure.in (AC_OUTPUT): Do not emit .gdbinit. ++ * configure: Regenerate. ++ * gdbinit.in: Remove. ++ ++2000-03-17 Ben Elliston ++ ++ * Makefile.am (CGEN): Use guile, not cgen. ++ (CGENCFLAGS, LIBIBERTY, INCLUDES): Remove. ++ (bin_PROGRAMS, cgen_SOURCES): Likewise. ++ (CGENFILES): Fold CGEN_HOB_INPUT_FILES and CGEN_NOHOB_FILES. ++ (HOBBIT_INPUT_FILES, HOBBIT_OUTPUT_FILE): Remove. ++ (HOB_OBJS): Likewise. ++ (CGEN_HOB_SRC, CGEN_HOB_OBJ): Likewise. ++ (CGENOBJS): Likewise. ++ (cgen_DEPENDENCIES, cgen_LDFLAGS, cgen_LDADD): Likewise. ++ (hobbit, hobbit.o, hobbit.c): Remove targets. ++ (cos.o, cgen.o, cgen-gh.o, hob-sup.o): Likewise. ++ (CLEANFILES): Update. ++ * acconfig.h (WITH_HOBBIT): Remove. ++ * configure.in: Do not test for 3 arg scm_make_vector. Remove ++ option --with-cgen-hobbit. ++ * cos.h, cos.c, hob-main.c, hob-sup.c, hob-sup.h, hob.sh: Remove. ++ * cgen-gh.h, cgen-gh.c, cgen-hob.scm, cgen.c: Likewise. ++ * hobbit.c, hobbit.h, hobbit.scm: Likewise. ++ * hobscmif.h, hobslib.scm, scmhob.h: Likewise. ++ * Makefile.in: Regenerate. ++ * config.in: Likewise. ++ * aclocal.m4: Likewise. ++ * configure: Likewise. ++ * README (Hobbit support): Remove. ++ * doc/internals.texi (Conventions): Do not mention Hobbit. ++ * doc/porting.texi (Supported Guile versions): Likewise. ++ ++2000-03-16 Frank Ch. Eigler ++ ++ * sid-cpu.scm (-gen-sem-switch-engine): Adjust calling & ++ callback convention to new sid sidutil::basic_cpu code. ++ (-gen-sfrag-engine-fn): Ditto. ++ * sid.scm (-create-virtual-insns!): Ditto. ++ (-hw-gen-set-quiet-pc): Mark delay slot execution specially in pbb ++ mode. ++ (cxmake-skip): Implement properly for pbb mode. ++ ++2000-03-03 Ben Elliston ++ ++ * doc/internals.texi: New file. ++ ++2000-02-29 Ben Elliston ++ ++ * doc/rtl.texi (Derived operands): Remove unnecessary footnote. ++ * doc/porting.texi: Formatting tweaks. ++ ++2000-02-25 Nick Clifton ++ ++ * desc-cpu.scm (*_cgen_cpu_open): Initialise signed_overflow_ok_p ++ field. ++ ++Thu Feb 24 14:09:01 2000 Doug Evans ++ ++ * operand.scm (,make!): Initialize mode-name, not ++ mode. ++ ++2000-02-23 Andrew Haley ++ ++ * m32r.cpu (pcmpbz): Make pcmpbz a special (i.e. hidden) ++ instruction. ++ ++2000-02-24 Ben Elliston ++ ++ * doc/rtl.texi (Derived operands): Add some cindex entries. ++ ++2000-02-23 Ben Elliston ++ ++ * ia32.cpu (dndo): Move general purpose macro from here .. ++ * simplify.inc (dndo): .. to here. ++ ++2000-02-18 Frank Ch. Eigler ++ ++ * arm.cpu (h-tbit): Add c-call setter function. ++ (h-mbits): Ditto. ++ ++2000-02-17 Frank Ch. Eigler ++ ++ * sem-frags.scm (-frag-hash-compute!): Add appstuff arg for traversal. ++ (-frag-cost-compute!): Ditto. ++ * utils.scm (copyright-cygnus): Add Y2K. ++ * sid-cpu.scm (@prefix@_pbb_run): Add unsigned& argument. ++ ++2000-01-25 Nick Clifton ++ ++ * desc-cpu.scm (@arch@_cgen_cpu_open): Add code to initialise ++ flags field of the CGEN_CPU_TABLE structure. ++ ++Sun Dec 12 14:20:36 1999 Doug Evans ++ ++ * operand.scm (): Renamed from . ++ All references updated. ++ ++Tue Nov 30 11:06:22 1999 Doug Evans ++ ++ * ia32.cpu: Rewrite addressing mode support. ++ ++ * ifield.scm (): New member `follows'. ++ (ifld-known-values): New proc. ++ (): New method set-word-offset!. ++ (ifld-set-word-offset!): New proc. ++ (ifld-new-word-offset): New proc. ++ (): New method next-word. ++ (): New method next-word. ++ (ifld-next-word): New proc. ++ (ifld-precedes?): New proc. ++ (-ifield-parse): New args word-offset,word-length,follows. ++ All callers updated. Handle CISC-style vs RISC-style ifields. ++ (-ifield-read): Recognize word-offset,word-length,follows specs. ++ (-ifld-parse-follows): New proc. ++ (-multi-ifield-make-default-insert): New proc. ++ (-multi-ifield-make-default-extract): New proc. ++ (-multi-ifield-parse): Provide default values for insert,extract ++ handlers if not specified. ++ (): New class. ++ (derived-ifield?): New predicate. ++ (ifld-derived-operand?): New predicate. ++ (f-anyof): New global. ++ (ifld-anyof?,ifld-anyof-operand?): New predicates. ++ (f-derived,ifld-derived?): Delete. ++ (ifield-builtin!): Delete init of f-derived. Init f-anyof. ++ * insn.scm (-sub-insn-ifields): New proc. ++ (-sub-insn-make!): New proc. ++ (multi-insn-instantiate!): Provide initial implementation. ++ (-insn-parse): If insn contains "anyof" operands, create a ++ object instead of a plain . ++ (-parse-insn-format-symbol): Rewrite derived operand handling. ++ Add anyof operand handling. ++ (-parse-insn-format-ifield-spec): Rewrite. ++ (-parse-insn-format-operand-spec): Delete. ++ (-parse-insn-format-list): Delete support for `(operand value)'. ++ (anyof-operand-format?): Replaces derived-operand-format?. ++ * operand.scm (-operand-parse-getter): Improve error messages. ++ (-operand-parse-setter): Ditto. ++ (): New members args,syntax,base-ifield,encoding, ++ ifield-assertion. ++ (): Change baseclass from to ++ . Delete member values. New members base-ifield,choices. ++ (anyof-operand?): New predicate. ++ (-derived-parse-encoding,-derived-parse-ifield-assertion): New procs. ++ (-derived-operand-parse): Rewrite. ++ (-derived-operand-read): Rewrite. ++ (-anyof-parse-choice): New proc. ++ (-anyof-operand-parse): Rewrite. ++ (-anyof-operand-read,define-anyof-operand): New procs. ++ (): Rewrite. ++ (-anyof-initial-known): New proc. ++ (anyof-satisfies-assertions?): New proc. ++ (-anyof-merge-syntax,-anyof-merge-encoding): New procs. ++ (-anyof-merge-getter,-anyof-merge-setter): New procs. ++ (-anyof-merge-semantics,-anyof-merge-ifield-assertion): New procs. ++ (-anyof-merge-subchoices,-anyof-all-subchoices): New procs. ++ (-anyof-value-from-derived): New proc. ++ (-anyof-all-choices-1,anyof-all-choices): New procs. ++ (operand-init!): Create define-anyof-operand reader command. ++ ++ * insn (syntax-break-out): Take syntax as argument instead of insn. ++ All callers updated. ++ (syntax-make): Move here, from ???. ++ ++ * types.scm (): Rename accessors from bitrange:foo to ++ bitrange-foo. All uses updated. ++ (bitrange-next-word): New proc. ++ ++ * semantics.scm (-solve-expr-fn,rtx-solve): New procs. ++ ++ * rtl.scm (rtx-canonicalize): Provide initial implementation. ++ (rtx-make-const,rtx-make-enum): New procs. ++ (rtx-arg1,rtx-arg2): Renamed from -rtx-arg[12]. All callers updated. ++ (rtx-mem-addr,rtx-mem-sel): New procs. ++ (rtx-change-address): New proc. ++ (rtx-make-ifield,rtx-make-operand,rtx-make-local): New proc. ++ (rtx-make-set,rtx-single-set?): New procs. ++ (rtx-combine): New proc. ++ ++ * rtl.scm (rtx-traverse): New arg `appstuff'. All callers updated. ++ (rtx-traverse-with-locals): Ditto. ++ (-rtx-traverse,-rtx-traverse-*): Ditto. ++ ++ * rtl.scm (define-subr): New proc. ++ (rtl-init!): Create reader command `define-subr'. ++ ++ * cos.c (_object_mi_p): Ensure argument is an object. ++ (indent): New function. ++ (_object_print_elms): Add pretty-printing support. ++ (_object_print): Ditto. ++ ++ * hobbit.scm (*reckless-s->c-fun-table*): Add fastcall7. ++ (*floats-s->c-fun-table*): Ditto. ++ * hobbit.c,hobbit.h: Rebuild. ++ * hob-sup.c (fastcall7): New proc. ++ * hob-sup.h (fastcall7): Declare. ++ * hob-sup.scm (fastcall7): New macro. ++ ++ * mach.scm (): New member subr-list. ++ (current-subr-list,current-subr-add!,current-subr-lookup): New procs. ++ (arch-finish!): Reverse recorded subr list. ++ ++ * read.scm (debug-env): New global. ++ (debug-var-names,debug-var,debug-repl-env): New procs. ++ (debug-repl): Rewrite. New arg `env-list'. All callers updated. ++ (debug-quit): Renamed from `continue'. ++ ++ * simplify.inc (dsmf): New pmacro. ++ ++ * utils.scm (plus-scan): New proc. ++ (split-bits): Rewrite. ++ (split-value): New proc. ++ ++1999-10-13 Doug Evans ++ ++ * doc/Makefile.am (DOCFILES): Add notes.texi. ++ * doc/Makefile.in: Rebuild. ++ ++1999-10-11 Doug Evans ++ ++ * ifield.scm (ifld-derived?): New proc. ++ (f-derived): New global. ++ (ifield-builtin!): Create ifield f-derived. ++ (): New class. ++ (multi-insn?): New predicate. ++ (multi-insn-instantiate!): New proc. ++ (-insn-parse): Create objects for insns with derived ++ ifields. ++ (-parse-insn-format-symbol): Handle derived ifields. ++ (-parse-insn-format-ifield-spec): New proc. ++ (-parse-insn-format-operand-spec): New proc. ++ (-parse-insn-format-list): Simplify. ++ (-parse-insn-format): No longer allow (ifield-object value) spec. ++ (derived-operand-format?): New proc. ++ (insn-alias?): New proc. ++ (non-alias-insns): Rewrite. ++ (insn-real?): Renamed from real-insn?, all callers updated. ++ (virutal-insns): Rewrite. ++ (multi-insns): New proc. ++ * mach.scm (arch-analyze-insns!): Instantiate multi-insns if present. ++ * operand.scm (op-ifield): Renamed from op:ifield, all callers updated. ++ Return #f if operand doesn't have an index or if index is not an ++ ifield. ++ (hw-index-anyof): New proc. ++ (-operand-parse): Allow integer indices. ++ (): New class. ++ (derived-operand?): New predicate. ++ (): New class. ++ (): New class. ++ (-anyof-parse-value,-anyof-operand-parse): New procs. ++ (-derived-operand-parse,-derived-operand-read): New procs. ++ (define-derived-operand,define-full-derived-operand): New procs. ++ (operand-init!): New reader command define-derived-operand. ++ ++ * utils.scm (list-take): Handle negative amount. ++ (element?): Rewrite. ++ ++1999-10-10 Doug Evans ++ ++ * dev.scm: quick-utils.scm renamed to ~/.cgenrc. ++ ++1999-10-04 Richard Henderson ++ ++ * ia64.cpu: Checkpoint. ++ ++1999-09-29 Doug Evans ++ ++ * sim-cpu.scm (-gen-semantic-fn-table): Virtual insns are always valid. ++ ++ * sim.scm (sim-finish!,x-invalid): Always set pc. Set vpc based on ++ default-insn-bitsize. Pass vpc to sim_engine_invalid_insn. ++ ++Wed Sep 29 14:39:39 1999 Dave Brolley ++ ++ * sim.scm (sim-finish!): Don't call sim_io_error for invalid insn. Use ++ PC returned by sim_engine_invalid_insn. ++ ++1999-09-28 Doug Evans ++ ++ * ia32.cpu: New file. ++ ++1999-09-25 Doug Evans ++ ++ * utils.scm (bit-set?): Fix off by one error. ++ ++ * rtl-c.scm (s-sequence): Fix non-void-mode result output. ++ ++ * rtl.scm (hw): Check for valid hardware element before trying to ++ get its mode. ++ ++ * arm.cpu (arm7f cpu): Renamed from arm. All users updated. ++ * arm7.cpu (bx): Fix name of target address operand in assembler spec. ++ (*): arm_compute_operand2_foo renamed to compute_operand2_foo. ++ * thumb.cpu (*): arm_compute_operand2_foo renamed to ++ compute_operand2_foo. ++ ++ * cgen-sid.scm (sim_arguments): Add support for building defs.h. ++ * sid.scm (-hw-gen-set-quiet-pc): Handle #:delay modifier. ++ Call delayed_branch/branch methods instead of assigning to `vpc'. ++ (,cxmake-skip): Call skip method. ++ (-gen-hw-selector): Call rtl-c++ instead of rtl-c. ++ (,cxmake-skip): Ditto. ++ (-create-virtual-insns!): Ditto. ++ (op:read): Call estate-make-for-normal-c++ instead of estate-...-c. ++ (op:write): Ditto. ++ (op:record-profile): Specify #:output-language "c++". ++ * sid-cpu.scm (-gen-insn-attr-decls): Rename @cpu@_insn_attr to ++ @arch@_insn_attr. ++ (cgen-desc.h): Use @arch@ namespace instead of @cpu@. ++ Define enums here. ++ (-gen-reg-access-defns): Use rtl-c++ instead of rtl-c. ++ (gen-semantic-code): Ditto. ++ (-gen-sem-case,-gen-sfrag-code): Ditto. ++ (-gen-hardware-types): Delete class @cpu@_cpu_base. ++ (cgen-cpu.h): File is now #included by main cpu class, rather than ++ subclassing. ++ (cgen-defs.h): New proc. ++ (-gen-scache-semantic-fn): Change result type to sem_status. ++ New local `status'. Call done_cti_insn/done_insn method at end. ++ (cgen-semantics.cxx): Include @cpu@.h instead of @arch@-main.h, ++ cgen-ops.h. ++ (cgen-sem-switch.cxx): Ditto. ++ * sid-decode.scm (-gen-idesc-decls): Update return type of ++ @prefix@_sem_fn. ++ (cgen-decode.h): Add using namespace @arch@. ++ (cgen-decode.cxx): Include @cpu@.h instead of @arch@-main.h. ++ ++ * rtl-c.scm (): New member output-language. ++ (estate-output-language-c?,estate-output-language-c++?): New procs. ++ (,vmake!): Handle #:output-language. ++ (estate-make-for-normal-rtl-c++): New proc. ++ (rtl-c++-parsed,rtl-c++): New proc. ++ (s-c-call): Invoke cpu class method if c++. ++ (join): Use s-c-raw-call. ++ ++ * rtl-c.scm (subword): Don't pass current_cpu to SUBWORD. ++ (nop): Rewrite. ++ ++ * rtl-c.scm (delay): Mark the sequence as #:delay'd. ++ * rtl.scm (): New member `modifiers'. ++ (,vmake!): Handle #:modifiers. ++ (estate-with-modifiers): New proc. ++ ++ * rtl.scm (rtx-side-effects?): New proc. ++ (rtx-canonical-bool): Don't change expr if it has side effects. ++ * semantics.scm (-simplify-expr-fn): Handle exprs with side-effects ++ better. ++ ++1999-09-23 Doug Evans ++ ++ * sim.scm (gen-scache-type): Fix typo in last patch. ++ ++Tue Sep 21 17:12:55 1999 Dave Brolley ++ ++ * sim.scm (gen-scache-type): Add last_insn_p flag for parallel support. ++ ++1999-09-05 Doug Evans ++ ++ * sid.scm (,cxmake-skip): New method. ++ (,cxmake-skip): New method. ++ ++ * decode.scm (decode-build-table): Delete args startbit,index-list. ++ All callers updated. ++ * utils-sim.scm (gen-decoder): Delete args startbit,index-list. ++ All callers updated. ++ * sim-decode.scm (-gen-decode-fn): Always pass 0 for startbit ++ to decode-get-best-bits. ++ * sid-decode.scm (-gen-decode-fn): Ditto. ++ ++ * hardware.scm (hw-bits): New proc. ++ (-hw-parse): New arg layout. All callers updated. ++ (define-full-hardware): New arg layout. All callers updated. ++ (-hw-validate-layout): New proc. ++ (-hw-create-[gs]etter-from-layout): New procs. ++ (,parse!): Handle layout spec. ++ * types.scm (type-bits): New proc. ++ ++ * sem-frags.scm (-frag-cost-compute!): Fix calculation of ++ UNARY, BINARY, TRINARY rtxs. ++ ++ * attr.scm (,parse-value): Allow strings. ++ * enum.scm (parse-enum-vals): Use reverse! instead of reverse. ++ Support '- as "unused spot" indicator. ++ ++1999-09-03 Doug Evans ++ ++ * pgmr-tools.scm (pgmr-pretty-print-insn-format): Fix typo. ++ ++1999-09-02 Doug Evans ++ ++ * rtx-funcs.scm (subword): Fix mode spec of `value'. ++ ++ * rtl.scm (-rtx-traverse-operands): Fix debugging message ++ construction. ++ (tstate-make): New arg `depth'. All callers updated. ++ (tstate-depth,tstate-set-depth!): New procs. ++ (tstate-incr-depth!,tstate-decr-depth!): New procs. ++ (-rtx-traverse-operands): Indent debugging output by traversal depth. ++ (-rtx-traverse): Ditto. Keep track of traversal depth. ++ ++1999-09-01 Doug Evans ++ ++ * sim-decode.scm (-gen-decoder+supporting cast): Move to utils-sim.scm. ++ * sid-decode.scm (-gen-decoder+supporting cast): Ditto. ++ * utils-sim.scm: Decoder generator support moved here. ++ (-decode-equiv-entries?,-decode-sort-entries): New procs. ++ (-gen-decoder-switch): Sort entries for more fall-throughs. ++ ++ * Makefile.am (gas-test,sim-test): Specify ISA when invoking cgen. ++ * Makefile.in: Rebuild. ++ * sim-test.scm (build-sim-testcase): Add logging message. ++ * dev.scm (cload): Recognize SIM-TEST application. ++ (load-stest): Set APPLICATION to SIM-TEST. ++ ++ * desc-cpu.scm (-gen-hash-defines): Add \n to output. ++ ++ * ifield.scm (-ifield-parse): Allow bit numbers up to 127. ++ * mach.scm (-isa-parse): Allow insn bitsizes from 8 to 128. ++ * mode.scm (mode-make-int,mode-make-uint): Allow values up to 64 bits. ++ ++ * insn.scm (syntax-break-out): Handle ${foo}. ++ ++Sun Aug 29 11:11:15 1999 Doug Evans ++ ++ * Makefile.am (noinst_PROGRAMS,noinst_LIBRARIES): Delete. ++ (bin_PROGRAMS): Define. ++ (CGEN_HOB_INPUT_FILES): Remove $(srcdir)/. ++ (cgen-hob.c): Prepend $(srcdir)/ here. ++ (APPDESCFILES,OPCODESFILES,SIMFILES,pkgdata_SCRIPTS): Define. ++ (libcpu_a_SOURCES): Delete. ++ (cgen_DEPENDENCIES,cgen_LDADD): Rewrite. ++ (CGEN_HOB_OBJ,CGENOBJS): New variables. ++ * configure.in (LIBS): Replace -Wl,-rpath with -R. ++ Add AC_CHECK_LIB(guile,main). ++ * Makefile.in: Rebuild. ++ * doc/Makefile.in: Rebuild. ++ * aclocal.m4: Rebuild. ++ * config.in: Rebuild. ++ * configure: Rebuild. ++ ++1999-08-28 Doug Evans ++ ++ Rename rtx functions from name: to name, accept optional leading ++ modifier and mode. ++ VM -> VOID, DM -> DFLT, use DFLT instead of VM for default mode. ++ * attr.scm (-attr-eval): Update. ++ * hardware.scm (hw-mode-ok?): Rename arg mode to new-mode-name. ++ (,mode-ok?): Disallow VOID. ++ (,mode-ok?): Disallow VOID. ++ (,mode-ok?): Disallow VOID. ++ * mode.scm (mode-name?): New proc. ++ (VOID): Renamed from VM. ++ (DFLT): Renamed from DM. ++ (mode-builtin!): Update. ++ * opcodes.scm (,gen-insert): Update. ++ (,gen-extract): Update. ++ (,gen-insert,gen-extract): Update. ++ * operand.scm (op:mode): Update. ++ (,make!): Update. ++ (op:new-mode): Update. ++ (-operand-read): Update. ++ * rtl.scm (-rtx-valid-types): Add OPTIONS, EXPLNUMMODE, ++ NONVOIDMODE, DFLTMODE. Rename VMMODE to VOIDMODE. ++ (def-rtx-dual-mode,define-rtx-dual-mode): Delete. ++ (-rtx-lazy-sem-mode): Renamed from -rtx-mode. All callers updated. ++ (rtx-make): Call -rtx-munge-mode&options. ++ (rtx accessors): Rewrite. ++ (rtx-pretty-name): Update. ++ (-rtx-traverse-*): Update. ++ (-rtx-traverse-explnummode,-rtx-traverse-nonvoidmode): New procs. ++ (-rtx-traverse-voidmode,-rtx-traverse-dfltmode): New procs. ++ (-rtx-make-traverse-table): Update. ++ (-rtx-traverse-operands): Update. ++ (-rtx-option?,-rtx-option-list?): New procs. ++ (-rtx-munge-mode&options): New proc. ++ (-rtx-traverse-expr): Call -rtx-munge-mode&options. ++ (-rtx-traverse): Update. ++ (rtx-traverse,rtx-traverse-with-locals,rtx-compile): Update. ++ (rtx-compile-time-constant?): Update. ++ (rtx-true?,rtx-false?,rtx-true,rtx-false): Update. ++ (rtx-value): Update. ++ (hw,reg,mem): Renamed from foo:. Update. All callers updated. ++ * rtx-funcs.scm (*): Update. ++ * rtl-c.scm (rtl-c-get): Update. ++ (rtl-c-set-quiet,rtl-c-set-trace): Update. ++ (s-c-call,s-c-raw-call): Update. ++ (s-boolifop,s-convop,s-if,s-cond): Update. ++ (s-case-vm,-gen-non-vm-case-test,s-case): Update. ++ (-par-replace-set-dests,-par-replace-set-srcs): Update. ++ (s-parallel,s-sequence): Update. ++ (rtl-c-build-table): Update. ++ * sem-frags.scm (-frag-hash-compute!): Update. ++ (-frag-cost-compute!): Improperly handle unary,binary,trinary ops ++ for temporary bug compatibility with previous version. ++ (-frag-expr-locals,-frag-expr-stmts): Update. ++ (-frag-compute-desired-frags,-frag-pick-best): Update. ++ * semantics.scm (-simplify-expr-fn): Update. ++ (rtx-simplify): Update. ++ (-rtx-ref-type): Update. Account for modifiers. ++ (-build-operand!,-build-reg-operand!,-build-mem-operand!): Update. ++ (-build-ifield-operand!): Update. ++ (-build-known-values): Update. ++ (semantic-compile): Update. ++ (-gen-reg-access-defns): Update. ++ (gen-semantic-code,-gen-sem-case): Update. ++ (-gen-sfrag-code,-gen-sfrag-case): Update. ++ * sim-cpu (gen-semantic-code): Update. ++ * sim.scm (,gen-write,cxmake-skip): Update. ++ (,gen-write,gen-set-macro,cxmake-get-raw): Update. ++ (-hw-cxmake-get): Update. ++ (,cxmake-get,gen-set-quiet,gen-write): Update. ++ (,cxmake-get): Update. ++ (,gen-type,gen-read,cxmake-get): Update. ++ (,gen-set-quiet,gen-set-trace): Update. ++ (,cxmake-get): Update. ++ (sim-finish!): Update. ++ * utils-gen.scm (-gen-ifld-extract-base): Update. ++ (-gen-ifld-extract-beyond): Update. ++ (gen-multi-ifld-extract): Update. ++ * sid-decode.scm (-decode-expr-ifield-values-used): Update. ++ * sid.scm (,gen-write): Update. ++ (-gen-decode-insn-globals): Update. ++ (-hw-cxmake-get): Update. ++ (,cxmake-get-raw): Update. ++ (,cxmake-get,gen-set-quiet,gen-write): Update. ++ (,cxmake-get): Update. ++ (,gen-type,gen-read,cxmake-get): Update. ++ (,gen-set-quiet,gen-set-trace): Update. ++ (,cxmake-get): Update. ++ (-create-virtual-insns!): Update. ++ (-decode-split-build-assertion): Update. ++ * *.cpu: Update. ++ * simplify.inc: Update. ++ ++1999-08-20 Doug Evans ++ ++ * sim.scm (-op-gen-queued-write): Fix memory address calculation. ++ Prefix queue function name with sim_ instead of @cpu@_. ++ ++ * sim.scm (-with-parallel-only?): New global. ++ (option-init!): Initialize it. ++ (option-set!): Set it. ++ (with-parallel-only?): New proc. ++ * sim-decode.scm (-gen-decode-insn-globals): Don't include parallel ++ and writeback markers if with-parallel-only. ++ (-gen-idesc-init-fn): Update. ++ * sim-cpu.scm (cgen-cpu.h): Don't generate struct parexec if ++ with-generic-write. ++ ++Wed Aug 18 15:04:30 1999 Doug Evans ++ ++ * sim-cpu.scm (-gen-semantic-fn-table): Handle unsupported insns ++ with the invalid insn handler. ++ ++ * utils.scm (list-maybe-ref): New proc. ++ ++ * mach.scm (-isa-parse): Signal error if isa wasn't specified in ++ define-arch. ++ (-mach-parse): Signal error if mach wasn't specified in define-arch. ++ ++ * i960.cpu (test*-*): Delete `expr' arg. ++ (test-op,branch-op): Update. ++ ++1999-08-09 Doug Evans ++ ++ * sim.scm (gen-reg-getter-fn,gen-reg-setter-fn): New procs. ++ (gen-reg-access-decl): Replace `name' arg with `hw'. All callers ++ updated. ++ (gen-reg-access-defn): Ditto. ++ (-gen-hw-addr): Rewrite. ++ (-op-gen-queued-write): Rewrite. ++ * sim-cpu.scm (-gen-cpu-reg-access-decls): ++ (-gen-scache-semantic-fn): Handle with-generic-write. ++ (-gen-no-scache-semantic-fn): Ditto. ++ ++1999-08-08 Doug Evans ++ ++ * utils-gen.scm (gen-define-ifmt-ifields): Tweak output. ++ ++ * sim.scm (-with-generic-write?): New global. ++ (option-init!): Initialize it. ++ (option-set!): Set it. ++ (with-generic-write?): New proc. ++ (-gen-hw-addr): New proc. ++ (-op-gen-queued-write): New proc. ++ (-op-gen-set-{quiet,trace}-parallel): Use it if with-generic-write?. ++ ++ * sim-cpu.scm (-gen-hardware-types): Output code with parallel support ++ turned off. ++ (-gen-sem-switch): Preserve existing with-parallel? value. ++ (-gen-sem-parallel-switch): Ditto. ++ (-gen-write-case): Add /indent support. ++ (cgen-write.c): Rewrite. ++ ++ * utils.scm (-current-print-state): New global. ++ (make-print-state): New proc. ++ (pstate-indent,pstate-set-indent!): New procs. ++ (pstate-cmd?,pstate-cmd-do): New procs. ++ (/indent): New global. ++ (/indent-set,/indent-add): New procs. ++ (string-write): Set -current-print-state. ++ (-string-write): New arg pstate, all callers updated. ++ Handle print-state commands. ++ (-string-list-flatten): New proc. ++ (string-list->string): Use it. ++ ++ * sim-cpu.scm (-gen-sem-fn-name): Move here from sim-decode.scm. ++ (-gen-sem-fn-table-entry): New proc. ++ (-gen-semantic-fn-table): New proc. ++ (-gen-scache-semantic-fn): Make fn static. ++ (-gen-no-scache-semantic-fn): Ditto. ++ (cgen-semantics.c): Define macro SEM_FN_NAME. ++ * sim-decode.scm (-gen-decode-insn-globals): Delete FMT,TYPE,IDX, ++ FAST,FULL. Update @cpu@_insn_sem contents. ++ (-gen-semf-fn-name): Delete. ++ (-gen-sem-fn-decls): Delete. ++ (-gen-idesc-decls): Output prototypes of @cpu@_sem_init_idesc_table, ++ @cpu@_semf_init_idesc_table. ++ (-gen-idesc-init-fn): Update. Don't initialize pointers to semantic ++ handlers here. ++ (cgen-decode.h): Print sfmt enum. ++ * sid-decode.scm (-gen-semf-fn-name): Delete. ++ * utils-gen.scm (gen-sfmt-enum-decl): New proc. ++ ++ * iformat.scm (sfmt-build): Rename sformats from fmt-foo to sfmt-foo. ++ (ifmt-compute!): Ditto. ++ * sim-decode.scm (-gen-decoder-switch): Ditto. ++ * sid-decode.scm (-gen-decode-expr-entry): Ditto. ++ (-gen-decoder-switch): Ditto. ++ ++ * insn.scm (insn-virtual?): New proc. ++ ++ * enum.scm (gen-enum-decl): Speed up, build string as list and then ++ convert to string. ++ * mach.scm (): attr-list is now a pair of lists. ++ (current-attr-list): Rewrite. ++ (current-attr-add!,current-attr-lookup): Rewrite. ++ * sim.scm (gen-cpu-insn-enum-decl): Replace append with append!. ++ ++1999-08-06 Richard Henderson ++ ++ * ia64.cpu: Initial checkpoint. ++ ++1999-08-06 Doug Evans ++ ++ * pmacros.scm (-pmacro-apply): Fix definition, takes only 1 arg. ++ (pmacros-init!): Update .apply help string. ++ ++1999-08-03 Doug Evans ++ ++ * sim.scm (-hw-gen-set-quiet-pc): Update call to SEM_BRANCH_VIA_CACHE. ++ (,cxmake-skip): New method. ++ (,cxmake-skip): New method. ++ (-gen-argbuf-fields-union): Add branch_target to `chain' member. ++ (gen-argbuf-type): New member `skip_count'. ++ (sim-finish!): Update calls to @cpu@_pbb_cti_chain. ++ * utils-cgen.scm (atlist-cti?): Don't include SKIP-CTI insns. ++ ++ * utils-sim.scm: New file. ++ * dev.scm (load-sim): Load it. ++ (load-sid): Load it. ++ * cgen-sid.scm: Load it. ++ * cgen-sim.scm: Load it. ++ * iformat.scm (): New member sbuf, not initialized by ++ default make. ++ * rtx-funcs.scm (skip): Rewrite. ++ * rtl-c.scm (skip): Rewrite. ++ * m32r.cpu (sc,snc): Update `skip' usage. ++ * mode.scm (mode-real-mode): New proc. ++ * sem-frags.scm (-frag-split-by-sbuf): Rename from -frag-split-by-sfmt. ++ Distinguish fragments by the they use. ++ * sim.scm (gen-profile-index-type): Delete. ++ (ifield argbuf support): Move to utils-sim.scm and sim-decode.scm. ++ (-gen-ifld-decoded-val): Delete, use gen-extracted-ifld-value instead. ++ (hardware argbuf support): Move to utils-sim.scm and sim-decode.scm. ++ (operand argbuf support): Move to utils-sim.scm and sim-decode.scm. ++ (-gen-argbuf-elm): Rewrite. ++ (-gen-argbuf-hw-elm): Delete. ++ (-gen-argbuf-fields-union): Generate structs for each sbuf instead ++ of each sfmt. ++ (-sim-sformat-argbuf-list,-sim-insns-analyzed?): New globals. ++ (sim-init!): Initialize them. ++ (sim-analyze-insns!): Set them. ++ (current-sbuf-list): New proc. ++ * sim-cpu.scm (-gen-no-scache-semantic-fn): Update calls to ++ gen-sfmt-op-argbuf-defns,gen-sfmt-op-argbuf-assigns. ++ * sim-model.scm (-gen-model-insn-fn): Ditto. ++ * sim-decode.scm (-gen-extract-decls): Delete. ++ (-gen-record-argbuf-ifld,-gen-trace-argbuf-ifld): New procs. ++ (,gen-extract,gen-trace-extract): Move here from ++ sim.scm. ++ (,gen-extract,gen-trace-extract): Move here from ++ sid.scm. ++ ( ++ ++ * sid-cpu.scm (-gen-sem-switch-engine): Move definition of `count' ++ up to avoid g++ 'goto crosses initialization' warning. ++ (-gen-sfrag-engine-fn): Delete vpc arg to NEXT_FRAG. ++ (-gen-sfrag-case): Update use of NEXT_FRAG. ++ ++1999-07-22 Doug Evans ++ ++ * cos.c (cos_init): Protect _make_x_symbol from garbage collection. ++ ++ * read.scm: Load sem-frags.scm. ++ * sem-frags.scm (*): Lots rewritten. ++ * sid.scm (-with-sem-frags?): New global ++ (with-sem-frags?): New proc. ++ (option-init!): Initialize -with-sem-frags?. ++ (option-set!): Recognize with-sem-frags. ++ (sim-init!): Call sim-sfrag-init! if with-sem-frags. ++ * sid-cpu.scm (cgen-sem-switch.cxx): Generate semantic frag version ++ if asked to. ++ (-gen-sfrag-engine-decls): New proc. ++ (-gen-sfrag-code,-gen-sfrag-case,-gen-sfrag-enum-decl): New procs. ++ (-gen-sfrag-engine-frag-table,-gen-sfrag-engine-fn): New procs. ++ (-gen-sfrag-engine): New proc. ++ (-gen-sem-case): Emit setup-semantics if specified. ++ (-gen-sem-switch-engine): Update init/use of computed goto label. ++ * sid-decode.scm (-gen-decode-expr-entry): Fetch ifield values ++ from local vars. ++ (-gen-idesc-decls): Replace sem_address with cgoto. ++ (-gen-scache-decls): Rewrite definition of `execute' member. ++ * arm.cpu (arm isa): Enable decode-splits. ++ * arm7.cpu (multiply insns): Rename result to mul-result. ++ ++ Rename decode-specialize to decode-split. ++ * decode.scm (*): Update. ++ * insn.scm (*): Update. ++ * mach.scm (*): Update. ++ * sid.scm (*): Update. ++ ++1999-07-19 Doug Evans ++ ++ Record objects as a smob. ++ * cos.c (scm_tc16_object): New static global. ++ (cos_init): Initialize it. ++ (OBJECT_P,OBJECT_ELEMENTS,OBJECT_CLASS_DESC): Update macros. ++ (OBJECT_CLASS,OBJECT_ELEMENT_OFFSET): Update. ++ (_object_tag): Delete. ++ (_object_make_smob): New function. ++ (_object_make_x,_object_make_with_values_x): Rewrite. ++ (_object_elements,_object_class_desc): Rewrite. ++ (_object_copy,object_p): Rewrite. ++ (_object_specialize): Rewrite. ++ (_object_print_elms,_object_print): New functions. ++ (object_smob): New static global. ++ (default_make_x): Use OBJECT_ELEMENT_OFFSET instead of magic number. ++ ++ * cos.c (_make_x_symbol): New static global. ++ (object_make): Use it. ++ (cos_init): Initialize it. ++ ++1999-07-15 Doug Evans ++ ++ * rtl-c.scm (ifield): Back out last patch, use estate-ifield-var? ++ instead to determine whether to use FLD macro. ++ (): New member ifield-var?. ++ (,vmake!): Recognize #:ifield-var?. ++ * utils-gen.scm (-gen-ifld-extract-base): Specify #:ifield-var? #f. ++ (-gen-ifld-extract-beyond,gen-multi-ifld-extract): Ditto. ++ ++ * rtl.scm (rtx-sequence-assq-locals): New proc. ++ ++ * cos.scm (-object-error): Don't crash on non-objects. ++ ++ * Makefile.am (CLEANFILES): Add hobbit. ++ * Makefile.in: Rebuild. ++ ++ * rtl-c.scm (s-c-call): Delete unnecessary code. ++ ++1999-07-14 Doug Evans ++ ++ * rtl-c.scm (ifield): Always reference value via `FLD'. ++ ++ * cos.c (elm_bound_p): Return problem SCM boolean values. ++ ++ * utils-cgen.scm (display-argv): New proc. ++ * cgen-opc.scm (cgen): Call it. ++ * cgen-sim.scm (cgen): Ditto. ++ * cgen-gas.scm (cgen): Ditto. ++ * cgen-stest.scm (cgen): Ditto. ++ * cgen-sid.scm (cgen): Ditto. ++ ++1999-07-05 Doug Evans ++ ++ * opc-asmdis.scm (-gen-parse-switch): New local var `junk'. ++ * opc-ibld.scm (-gen-insert-switch): Initialize result to NULL. ++ (-gen-extract-switch): Initialize result to 1. ++ * opcodes.scm (gen-ifield-default-type): New proc. ++ (gen-ifield-value-decl): Renamed from gen-ifield-type. All callers ++ updated. ++ (,gen-insert): Handle non-ifield indices. ++ (,gen-extract): Ditto. ++ (,gen-parse): Ditto. ++ (,gen-print): Ditto. ++ (,gen-parse): Ditto. ++ (,gen-print): Ditto. ++ (,gen-fget): Ditto. ++ (,gen-fset): Ditto. ++ ++ * sim.scm (-gen-hw-index-raw): Handle scalar indices. ++ (-gen-hw-index): Ditto. ++ * sid.scm (-gen-hw-index-raw): Handle scalar indices. ++ (-gen-hw-index): Ditto. ++ ++ * sem-frags.scm: New file. ++ ++ * attr.scm (attr-parse): Add better checking of input. ++ ++ * hardware.scm (-hw-parse-getter): Renamed from -hw-parse-get. ++ All uses updated. ++ (-hw-parse-setter): Renamed from -hw-parse-set. All uses updated. ++ ++ * ifield.scm (ifld-nil?): New proc. ++ ++ * operand.scm (): New members getter,setter. ++ (,make!): New args getter,setter. All uses updated. ++ (op:getter,op:setter): New procs. ++ (,field-start): Return 0 for non-ifield indices. ++ (,field-length): Return 0 for non-ifield indices. ++ (-operand-parse-getter,-operand-parse-setter): New procs. ++ (-operand-parse): New args getter,setter. All callers updated. ++ Always use hw-index-scalar for scalar operands. ++ (-operand-read): Handle getter,setter. ++ (define-full-operand): New args getter,setter. All uses updated. ++ * semantics.scm (-build-ifield-operand!): Update. ++ (-build-index-of-operand!): Update. ++ * sim.scm (,cxmake-get): If operand has getter, use it. ++ * simplify.inc (define-normal-operand): Update. ++ ++ * rtl.scm (abs,sqrt,cos,sin,min,max,umin,umax): New rtx fns. ++ * rtl-c.scm (s-unop): Indirect fp ops through fpu op vector. ++ (s-binop,s-cmpop,s-convop): Ditto. ++ (abs,sqrt,cos,sin,min,max,umin,umax): New rtx fns. ++ * sparc.cpu (insn-fmt2): Add FPOPS1,FPOPS2. ++ (fcc-tests): New insn-enum. ++ (fcc-value): Rename from fcc-type. ++ * sparcfpu.cpu: New file. All fp support moved here. ++ ++ * rtl.scm (): New member class. ++ (rtx-class-*?): New procs. ++ (def-rtx-node): New arg class. All callers updated. ++ (def-rtx-syntax-node,def-rtx-operand-node,def-rtx-dual-node): Ditto. ++ * rtx-funcs.scm (*): Specify class. ++ ++ * utils-cgen.scm (context-make-reader): New proc. ++ ++ * utils.scm (assert-fail-msg): New variable. ++ (assert): Use it. ++ (list-drop,list-tail-drop): New procs. ++ ++1999-06-22 Doug Evans ++ ++ * desc-cpu.scm (-gen-hash-defines): Restore generation of ++ CGEN_MIN_INSN_SIZE deleted on March 22. ++ ++ * ifield.scm (,needed-iflds): New method. ++ (,needed-iflds): New method. ++ (ifld-needed-iflds): New proc. ++ (multi-ifield?): New proc. ++ * iformat.scm (): Delete member ifmt. New members length,iflds. ++ (-sfmt-search-key): Include insn length in key. ++ (-sfmt-order-iflds,-sfmt-used-iflds): New procs. ++ (): Delete members ifmt-key,sfmt-key. New member used-iflds. ++ (-ifmt-lookup-ifmt!): Compute key here. ++ (-ifmt-lookup-sfmt!): Compute key here. Delete arg ifmt. ++ All callers updated. ++ (ifmt-build): Delete arg desc. New args search-key,iflds. ++ All callers updated. ++ (sfmt-build): Delete args desc,ifmt. New args search-key,cti?, ++ in-ops,out-ops,sorted-used-iflds. All callers updated. ++ * minsn.scm (minsn-make-alias): Use insn-set-ifmt!. Update call ++ to ifmt-build. ++ * operand.scm (op-iflds-used): New proc. ++ * utils-gen.scm (gen-ifld-type): Move here from sim.scm ++ and sim-cpu.scm. ++ And from sid.scm,sid-cpu.scm as well. ++ (gen-ifld-extract-decl,-gen-ifld-extract-base): Ditto. ++ (-gen-extract-word,-gen-ifld-extract-beyond): Ditto. ++ (gen-ifld-extract,gen-multi-ifld-extract): Ditto. ++ (gen-extracted-ifld-value): Ditto. ++ (-extract-chunk-specs): Ditto. ++ (gen-define-ifields,gen-define-ifmt-ifields): Ditto. ++ (-extract-chunk,-gen-extract-beyond-var-list): Ditto. ++ (gen-extract-ifields,gen-extract-ifmt-ifields): Ditto. ++ (-extract-insert-subfields): New function. ++ * sim.scm (gen-record-argbuf-ifld): Renamed from gen-ifld-extract. ++ (gen-record-argvar-ifld): Renamed from gen-ifld-extract-argvar. ++ * sim-cpu.scm (-gen-extract-ifmt-macro): Replace calls to ++ gen-define-ifields with gen-define-ifmt-ifields. Ditto for ++ gen-extract-foo. ++ (-gen-no-scache-semantic-fn): Ditto. ++ (-gen-sem-case): Ditto. ++ (-gen-read-case): Update calls to gen-define-ifields, ++ gen-extract-ifields. ++ * sim-decode.scm (-gen-record-args): Update. ++ (-gen-sfmt-argvars-assigns): Update. ++ (-gen-extract-case): Update. ++ * sim-model.scm (-gen-model-insn-fn): Replace calls to ++ gen-define-ifields with gen-define-ifmt-ifields. Ditto for ++ gen-extract-foo. ++ * sid.scm (gen-ifld-argbuf-defn): Use gen-ifld-type. ++ (gen-record-argbuf-ifld): Rename from gen-ifld-extract. ++ (gen-record-argvar-ifld): Rename from gen-ifld-extract-argvar. ++ * sid-decode.scm (-gen-decode-expr-entry): Update calls to ++ gen-define-ifields, gen-extract-ifields. ++ (-gen-record-args): Update. ++ (gen-sfmt-argvars-assigns): Update. ++ (-gen-extract-case): Replace calls to gen-define-ifmt-ifields ++ with gen-define-ifields. Ditto for gen-extract-foo. ++ (-gen-decode-fn): Use gen-ifld-extract-decl/gen-ifld-extract ++ procs rather than method calls. ++ ++1999-06-18 Doug Evans ++ ++ * sid.scm (-create-virtual-insns!): New local `context', pass it ++ to insn-read. ++ ++ * rtl.scm (-rtx-traverse): Output symbol shortcuts in source form, ++ (operand name) not (operand object), (local name) not (local object). ++ (rtx-traverse-with-locals): New proc. ++ (-compile-expr-fn): New proc. ++ (rtx-compile): Rewrite. ++ * rtl-c.scm (rtl-c-get): Handle operand/local names for src arg. ++ (rtl-c-set-quiet): Don't accept operand/local names for dest arg. ++ (rtl-c-set-trace): Ditto. ++ (operand define-fn): Recognize operand name argument. ++ (local define-fn): Recognize sequence temp name argument. ++ * rtx-funcs.scm (operand): Argument is operand name, not object, ++ so call current-op-lookup. ++ (local): Similarily, so call rtx-temp-lookup. ++ ++ * rtl.scm (rtx-field?): Use rtx-name instead of car. ++ (rtx-operand?): Ditto. ++ (rtx-pretty-name): Ditto. ++ (rtx-local-obj): Flag symbol argument as an error. ++ (rtx-local-name): New proc. ++ (rtx-sequence-locals,rtx-sequence-exprs): New procs. ++ ++ * rtl.scm (-rtx-traverse-operands): Fix debugging output of arg-types. ++ ++ * read.scm (debug-repl): Renamed from -debug-repl. All callers ++ updated. ++ ++ * arm7.cpu (do-word/byte-store): Use (trunc: QI rd) rather than ++ (and: QI rd #xff). ++ ++ * hobbit.scm (*reckless-s->c-fun-table*): Add fastcall4, fastcall6. ++ (*floats-s->c-fun-table*): Ditto. ++ * hobbit.c,hobbit.h: Rebuild. ++ * rtl.scm (-rtx-traverse-expr): Use fastcall6. ++ * semantics.scm (rtx-simplify): Use /fastcall-make. ++ ++ * iformat.scm (-sfmt-search-key): Don't include memory modes. ++ ++ * insn.scm (): Delete members condition, compiled-condition. ++ (,make!): Update ++ ( getters,setters): Update. ++ (-insn-parse,insn-read,define-full-insn): Update. ++ * minsn.scm (minsn-make-alias): Update. ++ * iformat.scm (ifmt-analyze): Delete insn-condition reference. ++ (ifmt-compute!): Ditto. ++ * sim.scm (sim-finish!): Update. ++ * simplify.inc: (define-normal-insn): Update. ++ * sid-cpu.scm (gen-semantic-code): Update. ++ ++ * iformat.scm (-ifmt-lookup-ifmt!): Use insn-set-ifmt!. ++ (-ifmt-lookup-sfmt!): Use insn-set-sfmt!. ++ (ifmt-compute!): Ditto. ++ ++1999-06-16 Doug Evans ++ ++ * minsn.scm (minsn-compute-iflds): Print better error message for ++ missing ifields. ++ ++1999-06-12 Doug Evans ++ ++ * rtl.scm (tstate->estate): Don't copy over expr-fn. ++ ++ * Makefile.am (HOBFLAGS): New variable. ++ (cgen-hob.c): Use it. ++ (hobbit.c): Use it. ++ (libcpu_a_SOURCES): Add hob-sup.c. ++ (hob-sup.o): New rule. ++ * Makefile.in: Rebuild. ++ * cgen.c: #include hob-sup.h. ++ (cgen_init_c): Call hobbit_init_support. ++ * hobbit.scm (*fastcall-make*,*c-symbol*): New variables. ++ (*special-scm->c-functions*): Add them. ++ (display-c-expression): Handle *c-symbol*. ++ (*reckless-s->c-fun-table*): Add *fastcall-make*, fastcall5. ++ (*floats-s->c-fun-table*): Ditto. ++ (normalize): Recognize /fastcall-make. ++ (normalize-fastcall-make): New proc. ++ * hobbit.c,hobbit.h: Rebuild. ++ * hob-sup.scm: New file. ++ * hob-sup.c: New file. ++ * hob-sup.h: New file. ++ * read.scm: Load hob-sup.scm. ++ * rtl.scm (-rtx-name-list): New variable. ++ (rtx-name-list): New proc. ++ (rtx-lookup): Try symbol first. ++ (def-rtx-node): Add name to -rtx-name-list. ++ (def-rtx-syntax-node,def-rtx-operand-node,def-rtx-macro-node): Ditto. ++ (-rtx-traverse-anymode): New proc. ++ (-rtx-traverse-{emode,intmode,floatmode,nummode,vmmode}): New procs. ++ (-rtx-traverse-{rtx,setrtx,testrtx,condrtx,casertx}): New procs. ++ (-rtx-traverse-{locals,env,attrs,symbol,string,number}): New procs. ++ (-rtx-traverse-{symornum,object}): New procs. ++ (-rtx-make-traverse-table): Rewrite. ++ (-rtx-traverse-operands): Rewrite arg-types handling. ++ Handle #f result of traverser. ++ (-rtx-traverse): Renamed from -rtx-traverse-normal. ++ Move debug handling here. ++ (-rtx-traverse-debug): Delete. ++ (rtl-finish!): Change -rtx-traverse-table into list of handlers ++ for each rtx. ++ * semantics.scm (semantic-compile:process-expr!): Fix call to ++ -rtx-traverse. ++ * utils.scm (map1-improper): New proc. ++ ++1999-06-08 Doug Evans ++ ++ * arm.sim (h-tbit): Replace FUN-ACCESS with FUN-SET. ++ (h-mbits): Ditto. ++ * sid.scm (-hw-cxmake-get): s/FUN-ACCESS/FUN-GET/. ++ (-hw-gen-set-quiet): s/FUN-ACCESS/FUN-SET/. ++ (,cxmake-get): Tweak. ++ (sim-finish!): Delete FUN-ACCESS attribute. Create FUN-GET,FUN_SET. ++ ++1999-06-07 Doug Evans ++ ++ * thumb.cpu (dnti): Delete timing spec. ++ (all insn): Update. ++ ++ * arm.cpu (arm isa): New fields condition, setup-semantics. ++ (thumb isa): New field setup-semantics. ++ (h-gr): Add attribute CACHE-ADDR. ++ * arm7.cpu (dnai): Delete condition. ++ (eval-cond): Delete. ++ ++ * mach.scm (): New member setup-semantics. ++ (-isa-parse-setup-semantics): New proc. ++ (-isa-parse): New arg setup-semantics. ++ (-isa-read): Recognize setup-semantics. ++ ++ * sid-cpu.scm (gen-extract-fields): Split into two: ++ gen-extract-ifields, gen-extract-ifmt-ifields. ++ (-gen-scache-semantic-fn): Delete `taken_p'. Delete ++ tracing begin/end messages (done by caller now). ++ (-gen-sem-case): Delete `taken_p'. Add npc,br_status. Delete ++ tracing begin/end messages (done by x-before,x-after virtual insns). ++ (-gen-sem-switch-engine): Redo vpc initialization. Save vpc at ++ end so don't have to look it up again next time. ++ * sid-decode.scm (-decode-expr-ifield-values): New proc. ++ (-decode-expr-ifield-tracking-key): New proc. ++ (-decode-expr-ifield-tracking): New proc. ++ (-decode-expr-ifield-values-used): New proc. ++ (-decode-expr-ifield-mark-used!): New proc. ++ (-gen-decode-expr-set-itype): New proc. ++ (-gen-decode-expr-entry): Rewrite. ++ (-gen-decode-table-entry): New proc. ++ (-gen-decoder-switch): Use it. ++ (-gen-virtual-insn-finder): New proc. ++ (-gen-argbuf-elm): Move here from sid.scm. ++ (-gen-argbuf-hw-elm): Ditto. ++ (-gen-argbuf-fields-union): Add entries for chain,before insns. ++ (-gen-scache-decls): Add `cond' member to @prefix@_scache for ++ conditional-execution isas. ++ (-gen-decode-fn): Record conditional-exec ifield. ++ * sid.scm (-current-pbb-engine?): New global. ++ (current-pbb-engine?,set-current-pbb-engine?!): New procs. ++ (,gen-ifld-extract): New arg `indent'. ++ (,gen-ifld-extract): Ditto. ++ (-hw-gen-set-quiet-pc): Add pbb support. Delete `taken_p'. ++ (-op-gen-set-trace): Don't print tracing messages for pbb engine. ++ (-gen-arch-model-decls): Only scan real insns. ++ (scache-engine-insns,pbb-engine-insns): New procs. ++ (-create-virtual-insns!): New proc. ++ (sim-finish!): Call it. ++ (-decode-specialize-insn?): New proc. ++ (-decode-specialize-build-assertion): New proc. ++ (-decode-specialize-insn-1): New proc. ++ (-decode-specialize-insn): New proc. ++ (-fill-sim-insn-list!): New proc. ++ (sim-analyze!): Create copies of insns to be specialized. ++ * utils-cgen.scm (obj-set-name!): New proc. ++ ++ * attr.scm (-attr-eval): Rewrite calls to rtx-simplify/rtx-compile. ++ * iformat.scm (ifmt-analyze): Pass `insn' to semantic-compile, ++ semantic-attrs. ++ (ifmt-compute!): Delete arg `arch'. Result is list of iformats, ++ sformats. ++ * mach.scm (arch-analyze-insns!): Update call to ifmt-compute!. ++ * rtl-c.scm (rtl-c-get): Use DM for default mode instead of VM. ++ Avoid infinite loop when rtx-eval-with-estate leaves expr alone. ++ (attr): Rewrite test for insn owner. ++ (member): New rtx function. ++ * rtl.scm (rtx-* accessors): Define as cxr directly rather than ++ as separate function. ++ (rtx-ifield?,rtx-ifield-name): New procs. ++ (rtx-operand-obj): Rewrite. ++ (rtx-operand-name): New proc. ++ (rtx-cmp-op-mode,rtx-cmp-op-arg): New procs. ++ (rtx-number-list-values,rtx-member-value,rtx-member-set): New procs. ++ (tstate-make): New args owner, known. All callers updated. ++ (tstate-known-lookup): New proc. ++ (rtx-traverse): New arg owner. All callers updated. ++ (rtx-make-bool): New proc. ++ (rtl-find-ifields): Rewrite. ++ (rtx-simplify,rtx-simplify-eq-attr-{insn,mach}): Moved to ... ++ * semantics.scm: ... here. ++ (rtx-const-equal,rtx-const-list-equal): New procs. ++ (-build-known-values): New proc. ++ (semantic-compile): New arg `insn'. Call rtx-simplify. ++ (semantic-attrs): Ditto. ++ * rtx-funcs.scm (member,number-list): New rtx functions. ++ ++ * attr.scm (attr-remove-meta-attrs-alist): Delete leading '-' in name. ++ Rewrite. Delete arg `all-attrs'. All callers updated. ++ (attr-remove-meta-attrs): Delete leading '-' in name. All callers ++ updated. ++ * utils-cgen.scm (gen-bool-attrs): Remove meta attrs. ++ ++ * decode.scm (subdtable-add): Handle `expr' entries. ++ (exprtable-entry-make): Use vector. Record ifields refered to by expr. ++ (exprtable-entry-*): Update. ++ (exprtable-entry-iflds): New proc. ++ (exprentry-cost): New proc. ++ (exprtable-sort,-gen-exprtable-name): New procs. ++ (exprtable-make): New arg `name'. All callers updated. use vector. ++ (exprtable-*): Update. ++ (-build-decode-table-entry): Don't issue collision warning if all are ++ specialized insns. Sort exprtable entries before building table. ++ ++ * read.scm (-reader-process-expanded-1): Move pretty printing of ++ input to logging level 4. ++ ++ * utils.scm (string-list->string): New proc. ++ ++ * insn.scm (): Define setters for ifield-assertion, condition, ++ semantics. ++ (insn-read): Delete leading '-' in name. All callers updated. ++ (real-insn?): New proc. ++ (real-insns): Rewrite. ++ (insn-has-ifield?): New proc. ++ (insn-builtin!): Create insn attribute SPECIALIZED. ++ ++ * mach.scm (): Delete member app-data. ++ (current-raw-insn-list): New proc. ++ (insn-list-car,insn-list-splice!): New procs. ++ (): New class. ++ (-isa-parse-decode-specialize): New proc. ++ (-isa-parse-decode-specializes): New proc. ++ (): New members `condition', `decode-specializes'. ++ (-isa-parse-condition): New proc. ++ (-isa-parse): New args condition, decode-specializes. ++ (-isa-read): Recognize condition, decode-specializes. ++ (-isa-add-decode-specialize!): New proc. ++ (modify-isa): New proc. ++ (isa-conditional-exec?,state-conditional-exec?): New procs. ++ (arch-init!): New reader command `modify-isa'. ++ ++ * mode.scm (mode-class-signed?,mode-class-unsigned?): New procs. ++ (mode-signed,mode-unsigned?): New procs. ++ ++Thu Jun 3 16:00:40 1999 Doug Evans ++ ++ * types.scm (): New method get-shape. ++ * hardware.scm (): Forward get-shape,get-num-elms ++ onto type. ++ (hw-shape,hw-num-elms): New procs. ++ * sim.scm (,gen-profile-index-type): Use "unsigned short" ++ if there's more than 255 registers. ++ * sid.scm (,gen-profile-index-type): Ditto. ++ ++ * hardware.scm (-hw-parse): Flag as error CACHE-ADDR specified ++ with get/set specs. ++ ++1999-05-21 Doug Evans ++ ++ * cgen-sid.scm (sim-arguments): Add -X. ++ * sid-cpu.scm (-gen-hardware-types): Comment out scache vars. ++ (-gen-all-semantic-fns): Don't include PBB support virtual insns. ++ (-gen-sem-case): Use CASE/NEXT macros again. Tweak indenting. ++ Simplify by supporting pbb engine only. ++ (-gen-sem-switch-init): New proc. ++ (-gen-sem-switch-engine): Rename from -gen-sem-switch-fn. ++ (cgen-sem-switch.cxx): New proc. ++ * sid-decode.scm (-gen-decode-insn-globals): Replace with-sem-switch? ++ with with-pbb?. Support dual scache/pbb engines. ++ (-gen-idesc-decls): Replace with-sem-switch? with with-pbb?. ++ Support dual scache/pbb engines. ++ (cgen-decode.h): Generate semantic fn decls if with-scache?. ++ * sid.scm (*) with-pbb? replaces with-sem-switch?. ++ (sim-finish!): Create pbb support virtual insns if with-pbb?. ++ ++1999-05-10 Ben Elliston ++ ++ * arm7.cpu: Remove coprocessor related fields, operands and insn ++ definitions for now. Take the undefined instruction trap instead. ++ (ldmda-wb): New instruction. ++ (ldmib-wb): Likewise. ++ (ldmdb-wb): Likewise. ++ (stmdb-wb): Likewise. ++ (stmib-wb): Likewise. ++ (stmda-wb): Likewise. ++ ++1999-05-08 Doug Evans ++ ++ * sid.scm (,cxmake-get): Call GETMEM method, not function. ++ (,gen-set-quiet): Call SETMEM method, not function. ++ ++ * utils-cgen.scm (keyword-list->arg-list): Fix call to substring, ++ hobbit can't handle optional third arg. ++ ++1999-05-07 Doug Evans ++ ++ * arm.cpu (h-tbit): Delete set spec. ++ (h-mbits): Don't call arm_mbits_set in set spec. ++ * arm.sim: New file. ++ * hardware.scm (modify-hardware): New proc. ++ (hardware-init!): Add modify-hardware command. ++ * sid.scm (-hw-cxmake-get): Use method call if FUN-ACCESS specified. ++ (-hw-gen-set-quiet): Ditto. ++ (sim-finish!): Call invalid_insn method. Define FUN-ACCESS builtin ++ hardware attribute. Load $arch.sim file if present. ++ * utils-cgen.scm (keyword-list?): New proc. ++ (keyword-list->arg-list,arg-list-validate-name): New procs. ++ (arg-list-check-no-args,arg-list-symbol-arg): New procs. ++ ++ * arm7.cpu (eval-cond): Pass pc to @cpu@_eval_cond handler. ++ ++ * sid-cpu.scm (-gen-hardware-types): Rename @cpu@_cpu to ++ @cpu@_cpu_cgen. ++ ++ * attr.scm (obj-prepend-atlist!): New proc. ++ ++ * opc-opinst.scm (cgen-opinst.c): Analyze instructions if necessary. ++ ++ * sid.scm (,profilable?): Use op:type. ++ * sim.scm (,profilable?): Use op:type. ++ ++1999-05-04 Doug Evans ++ ++ * utils.scm (find-index,find): Be more stack friendly. ++ ++ * arm7.cpu (arith-imm-op): Compute pc before setting cpsr. ++ (bic-imm): Ditto. ++ ++1999-05-01 Doug Evans ++ ++ * arm.cpu (h-gr-usr): New hardware element. ++ (h-gr-fiq,h-gr-svc,h-gr-abt,h-gr-irq,h-gr-und): New hardware elements. ++ (arm-mode): New keyword. ++ (h-mbits): Add set spec. ++ (h-spsr): Implement get/set specs. ++ ++ * read.scm: Load slib/pp.scm, slib/genwrite.scm. ++ (-reader-process-expanded-1): Pretty print logging output. ++ ++ * sid-cpu.scm (-gen-reg-access-defns): Make getters `const'. ++ (cgen-cpu.h): Print enums before hardware elements. ++ (cgen-semantics.cxx): @arch@-cgen.h renamed to @arch@-main.h. ++ * sid-decode.scm (cgen-decode.cxx): Ditto. ++ * sid-model.scm (cgen-model.cxx): Ditto. ++ ++ * utils-cgen.scm (context-error): Accept variable number of ++ trailing args. ++ ++ * rtx-funcs.scm (error:): New rtx function. ++ * rtl-c.scm (s-case-vm): New proc. ++ (-gen-non-vm-case-get,s-case-non-vm): New procs. ++ (s-case): Simplify, handle non-VM result. ++ (error:): New rtx function. ++ ++1999-04-30 Doug Evans ++ ++ * arm.cpu (h-pc): Add set spec to zero bottom bits. ++ (test-hi,test-ls): Fix cbit handling. ++ (shift-type,h-operand2-shifttype): Move here ... ++ * arm7.cpu: ... from here. ++ (set-cond,set-cond-maybe,dnix): Delete, unused. ++ (set-zn-flags,set-logical-cc,set-add-flags,set-sub-flags): Move ... ++ * arm.cpu: ... to here. ++ * thumb.cpu (cmp,alu-cmp): Use set-sub-flags. ++ (alu-cmn): Use set-add-flags. ++ (alu-tst): Use set-zn-flags. ++ (alu-cmp): Use set-sub-flags. ++ (lsl,lsr,asr): Set condition codes. ++ (add,addi,sub,subi,mov,addi8,subi8): Ditto. ++ (alu-op): Split into three: alu-logical-op,alu-arith-op, ++ alu-shift-op. ++ (hireg-op): Split sem-fn into lo-dest-sem-fn,hi-dest-sem-fn. ++ All callers updated. ++ (sub-sp): Rename from add-sp-neg. ++ (f-lbwl-offset): Delete. ++ (f-lbwl-hi,f-lbwl-lo): New ifields. ++ (lbwl-hi,lbwl-lo): Update. ++ (bl-hi): Add 4 to pc. ++ (push-reg,pop-reg): Simplify. ++ (push,push-lr): Push registers in correct order. ++ (pop,pop-pc): Pop registers in correct order. ++ (save-reg-inc,load-reg-inc): Simplify. ++ (ldmia): Save registers in correct order. ++ ++1999-04-30 Ben Elliston ++ ++ * arm7.cpu (f-op-hdt): Remove; unused. ++ (f-ror-imm8-value,f-ror-imm-rotate): New fields. ++ (f-ror-imm8): New multi-ifield. ++ (f-operand2-bit7): Remove; use the generic `f-bit7' instead. All ++ callers updated. ++ (f-uimm12): New field. ++ (ror-imm8): New operand. ++ (uimm12): Likewise. ++ (hdt-offset8): Reinstate operand. ++ (offset4-hi,offset4-lo): Remove. ++ (set-cond): Remove macro; unused. ++ (set-cond-maybe): Likewise. ++ (load-word/byte): Use uimm12 operand for a true 12-bit immediate. ++ (store-word/byte): Likewise. ++ (load-halfword): Use hdt-offset8 multifield operand instead of two ++ 4-bit operands that are explicitly combined by semantic code. ++ (do-halfword-store): Bug fix. Set address when not preindexing. ++ (store-halfword): Also use hdt-offset8 operand. ++ (arith-op): Avoid clobbering source registers when one of them is ++ the destination register. ++ (arith-imm-op): Likewise. ++ (tst-imm): Use ror-imm8 operand. Handle special case of rot 0. ++ (teq-imm): Likewise. ++ (ldm-p): Rename to ldmdb. ++ (stm-pw): Rename to stmdb-wb. ++ (multi-action): New macro; test reg-list bits and execute a ++ semantic fn if the bit is set. ++ (ldmda,ldmib,ldmia,ldmia-wb,ldmdb): New multiple load insns. ++ (stmdb,stmib,stmia,stmia-wb,stmda,stmdb-wb): Store insns. ++ (all insns): Use dnai entries for simplicity rather than dni. ++ (*): Use short-form of (const ..). ++ ++1999-04-29 Doug Evans ++ ++ * rtl.scm (): Rename member type to style. Rename ++ member eval to evaluator. ++ (rtx-foo accessors): Rename from rtx:foo. All callers updated. ++ (tstate-make): Delete arg op-fn. All callers updated. ++ (tstate-op-fn,tstate-set-op-fn!): Delete. ++ (rtx-traverse): Delete op-fn arg. All callers updated. ++ * semantics.scm (-simplify-for-compilation-process-expr): New proc, ++ split out of -simplify-for-compilation. ++ ++ * Makefile.am (CGEN_NONHOB_FILES,CGENFILES): New variables. ++ (cgen_DEPENDENCIES): Add stamp-cgen. ++ (stamp-cgen): New rule. ++ * Makefile.in: Rebuild. ++ ++ * rtl-c.scm (enum:): Define emitter for. ++ * rtl.scm (rtx-constant?): Rename from rtx-const? and check for ++ enums as well. ++ (rtx-constant-value,rtx-enum-value): New procs. ++ (-rtx-traverse-normal): Expand enum-value to (enum enum-value). ++ (rtx-compile-time-constant?): Return #t for enums. ++ (rtx-true?,rtx-false?): Handle enums. ++ (rtx-simplify-eq-attr-mach): Use rtx-true,rtx-false instead of ++ building result by hand. ++ (rtx-simplify-eq-attr-insn): Ditto. ++ * rtx-funcs.scm (enum:,enum): New rtx functions. ++ ++ * mach.scm (): New members insns-analyzed?, semantics-analyzed?, ++ aliases-analyzed?. ++ (arch-analyze-insns!): New proc. ++ * opcodes.scm (opcodes-analyze!): Call arch-analyze-insns! instead ++ of calling ifmt-compute! directly. ++ * sid.scm (-sim-insns-analyzed?): Delete. ++ (sim-analyze!): Call arch-analyze-insns! instead of calling ++ ifmt-compute! directly. ++ * sim.scm (-sim-insns-analyzed?): Delete. ++ (sim-analyze!): Call arch-analyze-insns! instead of calling ++ ifmt-compute! directly. ++ ++ * utils.scm (string-take-with-filler): New proc. ++ (string-take): Use it. ++ ++ * pgmr-tools.scm: New file. ++ * read.scm: Load it. ++ * insn.scm (pretty-print-insn-format): Move to pgmr.scm. ++ ++ * insn.scm (insn-base-mask): Renamed from insn:mask. ++ All callers updated. ++ (insn-base-mask-length): Renamed from insn:mask-length. ++ All callers updated. ++ (insn-foo): Renamed from insn:foo. All callers updated. ++ * minsn.scm (minsn-foo): Renamed from minsn:foo. All callers updated. ++ * iformat.scm (compute-insn-base-mask-length): Renamed from ++ compute-insn-mask-length. All callers updated. ++ (compute-insn-base-mask): Renamed from compute-insn-mask. ++ All callers updated. ++ ++ * enum.scm (-enum-parse-prefix): New proc. ++ (,make!): Don't parse enum values here. ++ (-enum-parse): Do it here. Call -enum-parse-prefix. ++ (define-full-insn-enum): Ditto. ++ (enum-vals-upcase): New proc. ++ * hardware.scm (define-keyword): Make enum prefix uppercase. ++ * hobscmif.h (CHAR_LOWERP,CHAR_UPPERP,CHAR_WHITEP): New macros. ++ ++ * ifield.scm (,field-mask): Allow container to be #f. ++ (,field-extract): New method. ++ (,field-extract): New method. ++ (ifld-extract): New proc. ++ * opcodes.scm (ifld-insert-fn-name): Renamed from ifld-insert. ++ (ifld-extract-fn-name): Renamed from ifld-extract. ++ ++ * ifield.scm (ifld-new-value): Renamed from ifield-make. ++ All callers updated. ++ ++ * ifield.scm (ifld-lsb0?): New proc. ++ (sort-ifield-list): New arg up?. All callers updated. ++ * iformat.scm (compute-insn-mask): Get lsb0? flag from argument, ++ rather than global state. ++ ++1999-04-27 Doug Evans ++ ++ * insn.scm (pretty-print-insn-format): New proc. ++ ++ * Makefile.in: Rebuild. ++ * aclocal.m4: Rebuild ++ * configure: Rebuild. ++ ++Mon Apr 26 10:30:18 1999 Doug Evans ++ ++ * configure.in (AM_INIT_AUTOMAKE): Update version to 0.7.2. ++ * configure: Rebuild. ++ * aclocal.m4: Rebuild. ++ * Makefile.in: Rebuild. ++ * doc/Makefile.in: Rebuild. ++ * doc/version.texi: Rebuild. ++ ++1999-04-25 Doug Evans ++ ++ * utils.scm (bits->bools): New proc. ++ ++1999-04-23 Doug Evans ++ ++ * sid.scm (,gen-ifld-extract-decl): Fix call to ++ subfield's gen-ifld-extract-decl method. ++ ++1999-04-23 Ben Elliston ++ ++ * arm7.cpu (ldrsh-pu): Remove. ++ (do-halfword-load): New pmacro. ++ (load-halfword): Likewise. ++ (do-halfword-store): Likewise. ++ (store-halfword): Likewise. ++ (strh-*): New instructions. ++ (ldrsb-*): Likewise. ++ (ldrh-*): Likewise. ++ (ldrsh-*): Likewise. ++ ++1999-04-22 Doug Evans ++ ++ * ifield.scm (ifld-constant?): Delete special handling of RESERVED ++ fields. ++ ++ * arm7.cpu (do-word/byte-store): Fix typo. ++ ++1999-04-22 Ben Elliston ++ ++ * arm7.cpu (do-word/byte-load): Handle cases where the destination ++ register is the program counter (R15). ++ ++ * arm7.cpu (do-word/byte-store,store-word/byte): New pmacros. ++ (str-*): Implement using store-word-byte. Remove older versions. ++ (bic): Use the `inv' rtx for obtaining bitwise complements. ++ (bic-imm): Likewise. ++ (mvn): Likewise. ++ (mvn-imm): Likewise. ++ (store-indev-reg): Remove crufty pmacro. ++ (load-indiv-reg): Likewise. ++ (ldm-p): Reverse the order of register processing for decrement. ++ (stm-p): Likewise. ++ (stbi): Remove; handled by the str-* insns. ++ ++1999-04-21 Doug Evans ++ ++ * thumb.cpu (cmp): Fix carry bit computation. ++ (alu-cmp): Ditto. ++ ++1999-04-20 Doug Evans ++ ++ * arm.cpu (h-tbit): Specify set spec. ++ (h-cpsr): Ditto. ++ * arm7.cpu (bx): Don't call C routine, just set h-tbit. ++ (set-sub-flags): Interpret "carry bit" as a borrow. ++ (all sub/cmp insns): Carry bit is actually a borrow bit. ++ * thumb.cpu (bx-rs,bx-hs): Don't call C routine, just set h-tbit. ++ (add-carry,sub-carry,thumb-neg,thumb-bic,thumb-inv): Delete. Use ++ .pmacro instead. ++ (hireg-add,hireg-cmp,hireg-move): Ditto. ++ ++ * read.scm (-CGEN-VERSION): Change version to 0.7.2. ++ (-CGEN-LANG-VERSION): Ditto. ++ ++1999-04-18 Doug Evans ++ ++ * pmacros.scm (-pmacro-make): New arg `default-values', ++ all callers updated. ++ (-pmacro-default-values): New proc. ++ (-pmacro-process-keyworded-args): New proc. ++ (-pmacro-process-args): New proc. ++ (-pmacro-invoke): Process arguments before expanding macro. ++ (-pmacro-get-arg-spec,-pmacro-get-default-values): New procs. ++ (define-pmacro): Handle default values specified in arg list. ++ * rtl.scm (rtx-alu-op-mode,rtx-alu-op-arg): New procs. ++ (rtx-boolif-op-arg[01]): New procs. ++ (rtx-true,rtx-false,rtx-canonical-bool): New procs. ++ (rtx-simplify): Handle not,orif,andif. ++ * semantics.scm (-simplify-for-compilation): Simplify not,orif,andif. ++ * utils.scm (alist-copy): New proc. ++ * arm7.cpu (do-word/byte-load,load-word/byte): New pmacros. ++ (ldr*): Rewrite. ++ (swi): Explicitly set pc. ++ ++ * thumb.cpu (bx-rs,bx-hs): Reverse test for switch to arm mode. ++ ++1999-04-17 Ben Elliston ++ ++ * arm7.cpu (ldr-pu): Do not add 8 to R15; the step() method ++ correctly adjusts the program counter now. ++ ++ * arm7.cpu (f-halfword?): Rename from `f-hdt-halfword?'. ++ (f-signed?): Rename from `f-hdt-signed?'. ++ (f-offset4-hi): Rename from `h-hdt-off4-ms'. ++ (f-offset4-lo): Rename from `h-hdt-off4-ls'. ++ (f-hdt-offset8): Use new field names. ++ (ldr): Use `imm12' field, not `offset12', since we do our own ++ address arithmetic. ++ (str, str-*): Likewise. ++ (ldu-*): Remove most; better not implemented than broken. ++ (ldrh*): Likewise. ++ (ldrsh-pu): New insn. ++ (stri): Likewise. ++ (stri-p): Likewise. ++ (stbi): Likewise. ++ (ldm-p): Likewise; replace (load-indiv-reg) version. ++ ++1999-04-15 Doug Evans ++ ++ * arm.cpu (h-pc): Delete VIRTUAL attribute, get/set specs. ++ * arm7.cpu (*): Fix mode of result of arm_compute_carry_out_*. ++ (*): Explicitly specify mode in c-call. ++ (logical-op): Recognize sets of h-gr[15] as sets of pc. ++ (arith-op): Ditto. ++ (and-imm,orr-imm,xor-imm,mov-imm,bic-imm,mvn-imm): Ditto. ++ (arith-imm-op): New pmacro. ++ (add-imm,adc-imm,sub-imm,sbc-imm,rsb-imm,rsc-imm): Use it. ++ * thumb.cpu (bx-rs,bx-hs): Rewrite. ++ ++1999-04-14 Doug Evans ++ ++ * rtl.scm (rtx-simplify-eq-attr-insn): Fix call to context-error. ++ ++ * rtl.scm (rtl-find-ifields): Implement. ++ ++ * utils-gen.scm: New file. ++ * read.scm: Load it. ++ * desc.scm: Move generic attribute code to utils-gen.scm. ++ * Makefile.am (CGEN_HOB_INPUT_FILES): Add it. ++ * Makefile.in: Rebuild. ++ ++ * arm7.cpu (R15-OFFSET): New attribute. ++ (dnai): New pmacro. ++ (logical-op): Delete arg `result?'. All callers updated. Use dnai. ++ Delete use of eval-cond (dnai specifies it). Specify R15-OFFSET of 12 ++ for reg-shift version. ++ (arith-op): Ditto. ++ (data processing insns): Reorganize. Use dnai. ++ ++ * attr.scm (attr-kind): New proc. ++ (attr-list-enum-list): Rewrite. ++ (-attr-sort): Split result into two lists, bools and non-bools. ++ (current-attr-list-for): Update. ++ ++ * cgen-sid.scm (sim-arguments): Add -H -> build desc.h file. ++ * sid-cpu.scm (-gen-attr-decls): New proc. ++ (-gen-insn-attr-decls): New proc. ++ (cgen-desc.h): New proc. ++ (cgen-cpu.h): Put everything in @cpu@ namespace. ++ (gen-parallel-exec-type): Change prefix of parexec struct from ++ @cpu@ to @prefix@. ++ (-gen-trace-record-type): Ditto for trace_record struct. ++ (-gen-write-case): Update. ++ (-gen-scache-semantic-fn): Change function prefix from @cpu@ to ++ @prefix@. Update scache struct references. ++ (-gen-sem-case): Update scache struct references. ++ (-gen-sem-switch-fn): Update idesc struct reference. ++ Update insn_type enum reference. ++ (cgen-write.cxx): Update scache,argbuf references. ++ (cgen-semantics.cxx): Simplify namespace choice (always @cpu@). ++ * sid-decode.scm (IDESC-TABLE-VAR): Change prefix of insn_data ++ from @cpu@ to @prefix@. ++ (-gen-decode-insn-entry): Use gen-cpu-insn-enum. ++ (-gen-decode-expr-entry): Ditto. Change prefix of INSN_X_INVALID ++ from @CPU@ to @PREFIX@. ++ (-gen-decoder-switch): Change prefix of INSN_X_INVALID ++ from @CPU@ to @PREFIX@. ++ (-gen-decode-insn-globals): Generate insn attributes. ++ (-gen-sem-fn-name): Change function prefix from @cpu@ to @prefix@. ++ (-gen-sem-fn-decls): Use -gen-sem-fn-name. Add `using' for ++ semantic fn typedef. ++ (-gen-idesc-decls): Simplify cpu class name (always @cpu@_cpu). ++ Change prefix of scache struct from @cpu@ to @prefix@. ++ Change prefix of semantic fn typedef from @cpu@ to @prefix@. ++ Change prefix of idesc struct from @cpu@ to @prefix@. ++ Change prefix of insn_type enum from @cpu@ to @prefix@. ++ (-gen-argbuf-fields-union): Change prefix of sem_fields union ++ from @cpu@ to @prefix@. ++ (-gen-scache-decls): Change prefix of scache struct from ++ @cpu@ to @prefix@. Update idesc struct name. ++ Update decode,execute methods. ++ (-gen-extract-case): Update to type name changes. ++ (-gen-decode-fn): Ditto. ++ (cgen-decode.h): Put everything in @cpu@ namespace (except ++ semantic fn decls). Change prefix of insn_word from @cpu@ to @prefix@. ++ (cgen-decode.cxx): Add using namespace @cpu@. ++ * sid-model.scm (-gen-hw-profile-decls): Change prefix of ++ model_mark_get/set from @cpu@ to @prefix@. ++ (gen-model-unit-fn-name): Change function prefix from @cpu@ to ++ @prefix@. ++ (gen-model-fn-decls): Update idesc struct name. Change prefix ++ of model_insn_before/after from @cpu@ to @prefix@. ++ (-gen-model-insn-fn): Update scache/idesc/argbuf struct names. ++ Update insn_word type name. ++ (-gen-model-timing-table): Update INSN_TIMING struct name. ++ (-gen-model-init-fn): Update MODEL_DATA struct name. ++ (-gen-mach-defns): Update name of init_idesc_table fn. ++ (cgen-model.cxx): Add using namespace @cpu@. ++ * sid.scm (gen-cpu-class): Delete. ++ (gen-attr-type): New proc. ++ (gen-obj-attr-sid-defn): New proc. ++ (,gen-profile-code): Update name of model_mark_get/set fn. ++ (gen-cpu-insn-enum-decl): Change prefix of insn_type enum from ++ @CPU@ to @PREFIX@. ++ (gen-cpu-insn-enum): Update name of insn enum. ++ * thumb.cpu (bx-rs): Rename @cpu@_do_bx to @prefix@_do_bx. ++ (bx-hs): Ditto. ++ (swi): Rename @cpu@_swi to @prefix@_swi. ++ ++ * decode.scm (-build-decode-table-entry): Remove heuristic for ++ distinguishing insns, and use insn ifield-assertion specs. ++ ++ * desc-cpu.scm (gen-A-attr-mask): Simplify. ++ (gen-ifld-defns): Boolean attributes begin at number 0 now. ++ (gen-hw-table-defns,gen-operand-table,gen-insn-table): Ditto. ++ * opc-itab.scm (-gen-macro-insn-table): Ditto. ++ * utils-cgen.scm (gen-attr-enum-decl): Change type arg to prefix, ++ all callers updated. ++ (gen-attr-name): New proc ++ (gen-attr-mask): Use it. Boolean attributes start at 0 now. ++ (gen-obj-attr-defn): Delete num_nonbools count. ++ ++ * iformat.scm (ifmt-analyze): Handle insn-condition. ++ (ifmt-compute!): Ditto. ++ * insn.scm (): Specify default value for condition, ++ post-cond-trap,compiled-condition,compiled-semantics. ++ (,make!): New arg condition. ++ (): Add getters for condition,compiled-condition. ++ (-insn-parse): New arg condition, all callers updated. ++ (-insn-read): Recognize condition spec. ++ (define-full-insn): New arg condition. ++ * minsn.scm (minsn-make-alias): Update call to (make ...). ++ * semantics.scm (semantic-compile): Change arg sem-code to ++ sem-code-list. ++ (semantic-attrs): Ditto. ++ * sim.scm (sim-finish!): Update calls to define-full-insn. ++ * simplify.inc (define-normal-insn): Update call to define-full-insn. ++ * sid-cpu.scm (gen-semantic-code): Handle insn-condition. ++ * sid.scm (sim-finish!): Update call to define-full-insn. ++ ++Tue Apr 13 17:04:34 1999 Doug Evans ++ ++ * Makefile.am (sim-cpu): Allow specification of ISA. ++ * Makefile.in: Rebuild. ++ ++Sun Apr 11 00:37:56 1999 Jim Wilson ++ ++ * i960.cpu (sll-expr, srl-expr, sra-expr): Handle large shift counts. ++ ++1999-04-10 Doug Evans ++ ++ * sparccom.cpu (check-fp-enable): Wrap TRAP32_FP_DIS in c-code. ++ ++ * arm.cpu (gr-names): Put pc first so it gets prefered in disassembly. ++ ++ * attr.scm (atlist?): New proc. ++ (-attr-eval): Rewrite. ++ (attr-parse): New proc. ++ (atlist-parse): Use it. ++ ++ * decode.scm (exprtable-entry-make): New proc. ++ (exprtable-entry-insn,exprtable-entry-expr): New procs. ++ (exprtable-make,exprtable-insns): New procs. ++ ++ * hardware.scm (hw-mode-ok?): Delete argument `set?'. ++ All uses updated. ++ (hardware-builtin!): Make h-memory a vector. ++ ++ * iformat.scm (ifmt-ifields): Renamed from ifmt-fields. ++ All callers updated. ++ (ifmt-analyze): Use csem-* accessors on result of semantic-compile. ++ ++ * insn.scm (). Rename ifld-assertions to ifield-assertion. ++ All uses updated. ++ (-insn-parse): Set semantics to #f if not specified. ++ (define-insn,define-full-insn): Take out code that ignores ALIAS's ++ if simulator. ++ (-parse-insn-format): Recognize `=' iformat spec. ++ ++ * mach.scm (isa-min-insn-bitsize): Ignore ALIAS's. ++ (isa-max-insn-bitsize): Ditto. ++ ++ * opcodes.scm (,gen-insert): Call rtl-c instead of ++ rtl-c-with-alist. ++ (,gen-extract): Ditto. ++ (,gen-insert,gen-extract): Ditto. ++ * sid-cpu.scm (-gen-reg-access-defns): Ditto. ++ (gen-define-ifmt-ifields): New proc. ++ (gen-semantic-code): Rewrite. ++ * sid-decode.scm (-gen-decode-expr-entry): New proc. ++ (-gen-decoder-switch): Handle expression tables. ++ (-gen-extract-case): Call gen-define-ifmt-ifields instead of ++ gen-define-fields. ++ * sid-model.scm (-gen-model-insn-fn): Call gen-define-ifmt-ifields ++ instead of gen-define-fields. ++ * sid.scm (,gen-ifld-extract-decl): New arg `indent', all ++ callers updated. ++ (,gen-ifld-extract): Ditto. ++ (<*>,cxmake-get,gen-set-quiet,gen-set-trace,gen-write): Update to new ++ rtl evaluation code. ++ (op:read): Build an to pass to gen-read. ++ (op:write): Build an to pass to gen-write. ++ (op:record-profile): Build an to pass to ++ gen-record-profile. ++ * sim-cpu.scm (gen-semantic-code): Rewrite. ++ * sim.scm (-gen-ifld-extract-base): Call rtl-c instead of ++ rtl-c-with-alist. ++ (-gen-ifld-extract-beyond): Ditto. ++ (,gen-ifld-extract): Ditto. ++ (,gen-get-macro,gen-set-macro): Ditto. ++ (<*>,cxmake-get,gen-set-quiet,gen-set-trace,gen-write): Update to new ++ rtl evaluation code. ++ (op:read): Build an to pass to gen-read. ++ (op:write): Build an to pass to gen-write. ++ (op:record-profile): Build an to pass to ++ gen-record-profile. ++ ++ * operand.scm (): Give `selector' default value of #f. ++ Give `num' default value of -1. Give `cond?' default value of #f. ++ (op:new-mode): Delete arg `set?', all uses updated. ++ ++ * read.scm (reader-error): Handle #f return from port-filename. ++ (-init-parse-cpu!): Call rtl-c-init!. ++ (reader-install-builtin!): Call rtl-builtin!. ++ ++ * rtl-c.scm: New file. ++ * semantics.scm: New file. ++ * read.scm: Load them. ++ * rtl.scm: C generation moved to rtl-c.scm. Semantic analysis moved ++ to semantics.scm. ++ (): Delete members syntax?,macro,c,expr. New members ++ type,eval,num. ++ (rtx-lookup): Renamed from -rtx-func-lookup. All callers updated. ++ (-rtx-num-text,-rtx-max-num): New globals. ++ (def-rtx-operand-node,define-rtx-operand-node): New procs. ++ (-rtx-macro-lookup): New proc. ++ (rtx-lvalue-mode-name): Renamed from rtx-expr-mode-name. ++ (rtx-env-stack-empty?,rtx-env-stack-head): New procs. ++ (rtx-env-var-list,rtx-env-empty-stack,rtx-env-init-stack1): New procs. ++ (rtx-env-make,rtx-env-empty?,rtx-env-make-locals): New procs. ++ (rtx-env-push,rtx-temp-lookup,-rtx-closure-make): New procs. ++ (rtx-make,rtx-kind?,rtx-const?,rtx-const-value,rtx-symbol-name, ++ rtx-operand?,rtx-operand-obj,rtx-local?,rtx-local-obj, rtx-xop-obj, ++ rtx-index-of-value,rtx-if-mode,rtx-if-test,rtx-if-then,rtx-if-else, ++ rtx-eq-attr-owner,rtx-eq-attr-attr,rtx-eq-attr-value): New procs. ++ (rtx-pretty-name): New proc. ++ (-rtx-traverser-table,-rtx-make-traverse-table): New procs. ++ (rtx-traverse-*): Rewrite rtx traversing. ++ (rtx-eval-*): Rewrite rtx evaluation. ++ (rtx-compile): New proc. ++ (rtx-simplify): New proc. ++ (rtx-simply-eq-attr-mach,rtx-simplify-eq-attr-insn): New procs. ++ * rtx-funcs.scm: C generation moved to rtl-c.scm. ++ (ifield,index-of): Rewrite. ++ (name): Renamed from `operand:'. ++ (operand,xop,local): New rtx's. ++ (current-insn): Rewrite. ++ * Makefile.am (CGEN_HOB_INPUT_FILES): Add rtl-c.scm, semantics.scm. ++ (cgen-hob.h): Remove rule for. ++ (cgen-hob.o): Depend on cgen-hob.c only. ++ * Makefile.in: Rebuild. ++ ++ * utils-cgen.scm (vmake): New proc. ++ (): New class. ++ (context-make-prefix,context-error): New procs. ++ ++Fri Apr 9 19:26:28 1999 Jim Wilson ++ ++ * i960.cpu: Add some ??? comments. ++ (xnor, ornot): New instructions. ++ (*): Delete obsolete COND-CTI and UNCOND-CTI attributes. ++ ++1999-04-08 Doug Evans ++ ++ * cos.scm (-object-error): Print better error message. ++ ++ * pmacros.scm (-pmacro-env-make): Renamed from -env-make. ++ (-pmacro-env-ref): Renamed from -env-ref. ++ ++1999-03-31 Doug Evans ++ ++ * hardware.scm (,parse!): Allow get/set specs. ++ (h-pc): Delete. ++ (hardware-builtin!): Delete h-pc builtin. ++ * arm.cpu (h-pc): Define. ++ (h-gr): Delete get,set specs. Make array of 16 regs again. ++ * arm7.cpu (set-logical-cc-maybe): Delete. ++ (set-zn-flags,set-add-flags,set-sub-flags): New macros. ++ (data processing insns): Rewrite. ++ * m32r.cpu (h-pc): Define. ++ * fr30.cpu (h-pc): Define. ++ * i960.cpu (h-pc): Define. ++ * sparc.cpu (h-pc): Define. ++ ++ * rtl.scm (-rtx-traverse-operands): Add some error checking to LOCALS. ++ (s-parallel): Replace do {...} while (0) with {...}. ++ (s-sequence): Ditto. ++ ++ * sid-cpu.scm (gen-parallel-exec-type): Make type of `written' ++ consistent. ++ (-gen-write-case,-gen-sem-case): Ditto. ++ (-gen-sem-case): Only specify `written' if profiling or ++ parallel-write-back. ++ (-gen-scache-semantic-fn,-gen-all-semantic-fns): Put procs back in. ++ (-gen-sem-switch-fn): New proc. ++ (cgen-semantics.cxx): Emit either semantic fns or semantic switch ++ based on with-sem-switch option. ++ * sid-decode.scm (-gen-decode-insn-globals): Only define ++ idesc_table_initialized_p if with-sem-switch. Record semantic fn ++ addresses in idesc_table if !with-sem-switch. ++ (-gen-sem-fn-decls): Rewrite. ++ (-gen-idesc-decls): Define @cpu@_sem_fn type. Define `execute' ++ member based on with-sem-switch. Only define ++ `idesc_table_initialized_p' member if with-sem-switch. ++ (cgen-decode.h): If !with-sem-switch, declare semantic fns. ++ * sid.scm (-with-sem-switch?): New variable. ++ (option-init!): Initialize it. ++ (option-set!): Set it. ++ (with-sem-switch?): New proc. ++ (-op-gen-set-trace): Only emit `written' reference if profiling. ++ (sim-finish!): Use h_pc_set to set pc. ++ ++1999-03-30 Doug Evans ++ ++ * sparccom.cpu (arith-cc-binop): New args s32-set-flags,s64-set-flags. ++ All callers updated. ++ (arith-carry-cc-binop): New arg set-flags. All callers updated. ++ ++ * sid.scm (gen-argbuf-type): Delete. ++ (-gen-argbuf-fields-union): Move to ... ++ * sid-decode.scm: ... here. ++ ++ * read.scm (-reader-process-expanded-1): New proc. ++ (-reader-process-expanded): Call it to catch nested begin's. ++ (reader-process): Move `begin' handling to -reader-process-expanded. ++ ++ * insn.scm (-insn-read): Fix name of `format' spec. ++ ++ * pmacros.scm (.pmacro): New builtin. ++ (scan-symbol): If procedure macro, return macro rather than its symbol. ++ (check-macro): Don't do lookup, instead check if (car expr) is ++ macro object. ++ (scan-list): Handle .pmacro. ++ (scan): No longer re-examine text for another macro invocation. ++ (-pmacro-build-lambda): New proc. ++ (define-pmacro): Rewrite. If defining one pmacro to be an alias of ++ another, fetch the other's value (rather than doing it during ++ expansion). ++ ++1999-03-27 Doug Evans ++ ++ * Makefile.am (CGEN_HOB_INPUT_FILES): Add decode.scm. ++ * Makefile.in: Rebuild. ++ ++ * decode.scm (decode-get-best-bits): Use memq instead of element?. ++ (-fill-slot!): Simplify. ++ (-build-slots): Simplify. ++ ++ * dev.scm (load-sid): Don't load sid-arch.scm. ++ ++ * sid-decode.scm: Replace computed goto decoder/extractor with plain ++ switch's. ++ * sim-decode.scm: Replace computed goto decoder/extractor with plain ++ switch's. ++ ++1999-03-26 Doug Evans ++ ++ * sim-decode.scm: Clean up pass. Move decoder computation into ... ++ * decode.scm: ... here. New file. ++ * sid-decode.scm: Use decoder computation code in decode.scm. ++ * read.scm: Load decode.scm. ++ ++ * arm.cpu (arm710 model): Add u-exec function unit. ++ (h-gr): Delete CACHE-ADDR for now. Make array of 15, not 16 regs. ++ Add get/set specs to redirect reg 15 to h-pc. ++ (h-*): Indicate for both ARM and THUMB isas. ++ (cbit,nbit,vbit,zbit): Ditto. ++ (h-ibit,h-fbit,h-tbit,h-mbits): New hardware elements. ++ (h-cpsr): Make virtual. Add get/set specs. ++ (h-spsr-fiq,h-spsr-svc,h-spsr-abt,h-spsr-irq,h-spsr-und): New hw. ++ (h-spsr): New virtual reg. ++ * arm7.cpu (shift-type): New explicitly defined keyword. ++ (h-operand2-shifttype): Use it. ++ (set-logical-cc-maybe): Delete carry-out arg. New args arg1,arg2. ++ All callers updated. Don't set cbit. ++ (logical-op): Add rm to ifield list. Change case to case:. Use ++ shift-type enum as case choices. Set cbit. ++ (and,orr,eor,add-imm): Uncomment out. ++ (undefined): Temporarily comment out. ++ * thumb.scm (mov,cmp,addi8,subi8,str-sprel,ldr-sprel): s/rd/bit10-rd/. ++ (lda-pc,lda-sp): Ditto. ++ (ldr-pc): Rename from ldr. ++ (cbranch): Mark insns as being thumb insns. ++ ++ * attr.scm (,parse-value): Recognize strings. ++ ++ * cgen-sid.scm: Don't load sid-arch.scm. ++ (sim-arguments): Delete unused entries. ++ * sid-arch.scm: Delete. ++ ++ * insn.scm (,iflds): Renamed from flds. All uses updated. ++ (,ifld-assertions): New member. ++ (,make!): New arg ifld-assertions, all callers updated. ++ ( accessors): Change insn:foo to insn-foo. All callers updated. ++ (insn:fields): Delete. ++ (-insn-parse): New arg ifld-assertions. All callers updated. ++ (-insn-read,define-insn): New procs. ++ (define-full-insn): New arg ifld-assertions. All callers updated. ++ (insn-init!): New comment define-insn. ++ ++ * model.scm (-model-parse): Ensure at least one unit specified. ++ ++ * rtl.scm (-rtx-traverse-operands): Recognize environments. ++ (,get-name): New method. ++ (-rtx-make-current-closure,s-closure): New proc. ++ (hw:): Wrap rtx indices in a closure. ++ (-gen-case-prefix): New proc. ++ (s-case): Simplify. ++ * rtx-funcs.scm (case:): Fix call to s-case. ++ (closure): New rtx func. ++ ++ * hardware.scm (): New member isas-cache. ++ (,get-isas): New method. ++ (hardware-builtin): Indicate for all isas. ++ * ifield.scm (-ifield-parse): Only keep if isa+mach are kept. ++ * mach.scm (current-arch-mach-name-list): Return list of names. ++ (current-isa-mach-name-list): Ditto. ++ (define-arch): Install builtin objects here. ++ * read.scm (keep-atlist?): Only keep if both mach and isa are ++ being kept. ++ (keep-mach-atlist?): New proc. ++ (keep-isa-multiple?,current-keep-isa-name-list): New proc. ++ (reader-install-builtin!): Renamed from -install-builtin!. ++ * sid-cpu.scm (-gen-reg-access-defns): Renamed from ++ -gen-cpu-reg-access-defns. Rewrite. ++ (gen-reg-access-defn): Delete. ++ (-gen-hardware-struct): New proc. ++ (-gen-hardware-types): Simplify. Add multiple-isa support. ++ (gen-semantic-fn,-gen-all-semantics): Delete. ++ (-gen-read-args,-gen-read-case,-gen-read-switch): Delete. ++ (cgen-cpu.c,cgen-read.c,cgen-sem-switch.c,cgen-mainloop.in): Delete. ++ (cgen-write.cxx,cgen-semantics.cxx,cgen-decode.cxx): Renamed from *.c. ++ Call sem-analyze-insns!. ++ (cgen-semantics.cxx): Add multiple-isa support. ++ * sid-decode.c (-gen-idesc-decls): Add multiple-isa support. ++ (-gen-scache-decls,-gen-decode-fn): Ditto. ++ (cgen-decode.h): Call sem-analyze-insns!. ++ * sid-model.scm (cgen-model.cxx): Renamed from cgen-model.c. ++ * sid.scm (-with-multiple-isa?): New variable. ++ (option-init!): Initialize it. ++ (option-set!): Set it. ++ (with-multiple-isa?): New proc. ++ (gen-cpu-ref): New arg isas. All callers updated. ++ (gen-cpu-class): New proc. ++ (*-get-macro,*-set-macro): Delete. ++ (gen-reg-get-fun-name,gen-reg-set-fun-name): New procs. ++ (-hw-gen-fun-get): Call gen-reg-get-fun-name. ++ (-hw-gen-fun-set): Call gen-reg-set-fun-name. ++ (-gen-hw-index): Call rtx-c instead of rtx-c-with-temps for rtxs. ++ (-sim-insns-analyzed): New global variable. ++ (sim-init!): Reset it. ++ (sim-analyze-insns!): New proc. ++ (sim-analyze!): Don't do instruction analysis here. ++ (sim-finish!): Specify isa of x-invalid insn. ++ * sim.scm (sim-finish!): Specify isa of added x-* virtual insns. ++ ++1999-03-22 Doug Evans ++ ++ * thumb.cpu (cpu,mach,model): Delete. ++ (dntf): New pmacro. Use it for all field definitions. ++ (dntop): New pmacro. Use it for all operand definitions. ++ (asr): Correct field list. ++ (add,addi,sub,subi,add-sp,add-sp-neg): Ditto. ++ ++ * utils-cgen.scm (define-getters): New macro to simplify ++ writing class accessors. ++ (define-setters): Ditto. ++ (sanitize): Recognize isa elements. ++ ++ * sid-cpu.scm (*): Replace cpu:parallel-exec? call with ++ state-parallel-exec?. ++ * sid-model.scm (*): Ditto. ++ * sid-decode.scm (*): Ditto. Replace cpu:decode-assist with ++ state-decode-assist. ++ ++ * sid-decode.scm (decode-bits): Replace list-reverse! with reverse!. ++ (-gen-decode-switch): Rewrite to not generate deeply nested lists. ++ * sim-decode.scm (-gen-decode-switch): Ditto. ++ ++ * sim-arch.scm (-regs-for-access-fns): Delete. ++ (-biggest-reg-mode,-gen-arch-reg-access-decls): Delete. ++ (-gen-arch-reg-access-defns): Delete. ++ ++ * sim-cpu.scm (*): Replace cpu:liw-insns with state-liw-insns, ++ cpu:parallel-insns with state-parallel-insns, cpu:parallel-exec? ++ with state-parallel=exec?. ++ (cgen-*): Call sim-analyze-insns! here. ++ * sim-decode.scm (cgen-*): Ditto. ++ * sim-model.scm (cgen-*): Ditto. ++ * sim.scm (-sim-insns-analyzed): New global variable. ++ (sim-init!): Reset it. ++ (sim-analyze-insns!): Renamed from sim-analyze!. Keep track if we've ++ already done the analysis. ++ ++ * sim-model.scm (-gen-mach-defns): Add mach attribute number to ++ MACH struct. ++ ++ * arm.cpu: Only include arm7.cpu,thumb.cpu if necessary. ++ (arm arch): Update isa spec. ++ (arm,thumb isas): Define. ++ (arm7 cpu): default-insn-bitsize,base-insn-bitsize moved to isas. ++ (arm7tdmi mach): Add isa spec. ++ * arm7.cpu (*): Replace subreg: with subword:. Remove unnecessary ++ `const' on word number. ++ * fr30.cpu (fr30 arch): Update isa spec. ++ (fr30 isa): Define. ++ (fr30bf cpu): default-insn-bitsize,base-insn-bitsize,decode-assist, ++ moved to isa spec. ++ * i960.cpu (i960 arch): Update isa spec. ++ (i960 isa): Define. ++ (i960base cpu): default-insn-bitsize,base-insn-bitsize,decode-assist, ++ liw-insns,parallel-insns moved to isas spec. ++ * m32r.cpu (m32r arch): Update isas spec. ++ (m32r isa): Define. ++ (m32rbf cpu): default-insn-bitsize,base-insn-bitsize,decode-assist, ++ liw-insns,parallel-insns moved to isa spec. ++ * sparc.cpu (sparc arch): Update isas spec. ++ (sparc isa): Define. ++ * sparc32.cpu (sparc32 cpu): default-insn-bitsize,base-insn-bitsize, ++ decode-assist moved to isa spec. ++ * sparc64.cpu (sparc64 cpu): Ditto. ++ * sparccom.cpu (trap insns): Correct mode of result of c-call:. ++ * desc-cpu.scm (-gen-isa-table-defns): New proc. ++ (-gen-mach-table-defns): Output mach table. ++ (-gen-hash-defines): Delete insn size macros, except for ++ CGEN_MAX_INSN_SIZE. ++ (-cgen-cpu-open): Rewrite cpu_open handling. Take stdarg list of args. ++ (cgen-desc.h): Define MAX_ISAS. ++ (cgen-desc.c): Include stdarg.h. Call -gen-isa-table-defns. ++ * mach.scm (): Rename arch-data to data. New member isa-list. ++ (arch-* accessors): Renamed from arch:*. All callers updated. ++ (current-arch-isa-name-list): New proc. ++ (-arch-parse-isas): Renamed from -arch-parse-isa. ++ (def-isa-attr!): Rewrite. ++ (